UNPKG

bc-checkout-sdk

Version:

BetterCommerce's Checkout NodeJS SDK enables BC client applications to integrate with Checkout merchant API system. It publishes an interface to interact with [Checkout API](https://api-reference.checkout.com/#operation/getPaymentDetails/) endpoints.

197 lines (196 loc) 9.52 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const api_1 = __importDefault(require("../../base/api")); const CheckoutEnvironment_1 = require("../../base/config/CheckoutEnvironment"); const entity_1 = require("../../base/entity"); const RequestMethod_1 = require("../../constants/enums/RequestMethod"); const SingletonFactory = (function () { let accessToken = ''; const axiosInstance = api_1.default.create({ baseURL: CheckoutEnvironment_1.CheckoutEnvironment.baseUrl, withCredentials: true, }); const getToken = () => accessToken; const setToken = (token) => (accessToken = token); const clearToken = () => (accessToken = ''); axiosInstance.interceptors.request.use((config) => { const token = getToken(); //this is to be changed when we implement currency / language switcher if (token) { config.headers['Authorization'] = 'Bearer ' + token; } return config; }, (err) => Promise.reject(err)); /** * This function creates an Axios response interceptor that handles 401 responses and * refreshes the token by calling the /connect/token endpoint. It also logs the * activity of the request and response. * * @private * @returns {void} */ function createAxiosResponseInterceptor() { const interceptor = axiosInstance.interceptors.response.use((response) => response, (error) => { var _a, _b, _c; const extras = CheckoutEnvironment_1.CheckoutEnvironment.getExtras(); const logActivity = extras === null || extras === void 0 ? void 0 : extras.logActivity; //console.log(error) // Reject promise if usual error if (((_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.status) !== 400 && ((_b = error === null || error === void 0 ? void 0 : error.response) === null || _b === void 0 ? void 0 : _b.status) !== 401 && ((_c = error === null || error === void 0 ? void 0 : error.response) === null || _c === void 0 ? void 0 : _c.status) !== 404) { return Promise.reject(error); } if (logActivity) { logActivity({ data: { error: error }, message: "Checkout.com OAuth Cached Token Expired", }); } /* * When response code is 401, try to refresh the token. * Eject the interceptor so it doesn't loop in case * token refresh causes the 401 response */ axiosInstance.interceptors.response.eject(interceptor); // return getAuthToken().finally(createAxiosResponseInterceptor) const url = new URL('connect/token', CheckoutEnvironment_1.CheckoutEnvironment.getAuthUrl()); const auth = Buffer.from(`${CheckoutEnvironment_1.CheckoutEnvironment.getAccessId()}:${CheckoutEnvironment_1.CheckoutEnvironment.getAccessSecret()}`).toString("base64"); const requestConfig = { url: url.href, method: RequestMethod_1.RequestMethod.POST, data: `grant_type=client_credentials&client_id=${CheckoutEnvironment_1.CheckoutEnvironment.getAccessId()}&client_secret=${CheckoutEnvironment_1.CheckoutEnvironment.getAccessSecret()}&scope=gateway`, headers: { Authorization: `Basic ${auth}`, }, }; if (logActivity) { logActivity({ data: requestConfig, message: "Checkout.com OAuth Request", }); } return axiosInstance(requestConfig).then((res) => { var _a, _b, _c; //console.log("token", res.data.access_token) setToken((_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.access_token); if (logActivity) { logActivity({ data: { data: (_b = res === null || res === void 0 ? void 0 : res.data) === null || _b === void 0 ? void 0 : _b.access_token }, message: "Checkout.com OAuth Response", }); } error.response.config.headers['Authorization'] = `Bearer ${(_c = res === null || res === void 0 ? void 0 : res.data) === null || _c === void 0 ? void 0 : _c.access_token}`; //console.log(error.response.config) return axiosInstance(error.response.config); }).catch((error) => { if (logActivity) { logActivity({ data: { error: error }, message: "Checkout.com OAuth Error", }); } console.log(error); return Promise.reject(error); }).finally(createAxiosResponseInterceptor); }); } createAxiosResponseInterceptor(); return { axiosInstance }; })(); const axiosInstance = SingletonFactory.axiosInstance; Object.freeze(axiosInstance); /** * This function makes a request to the Checkout.com API and handles the response. * * @param {string} url - The URL of the API endpoint. * @param {string} method - The HTTP method to use. Defaults to 'post'. * @param {object} data - The data to send in the request body. * @param {object} params - The URL parameters to send with the request. * @param {object} headers - The headers to send with the request. * @param {object} cookies - The cookies to send with the request. * @param {string} baseUrl - The base URL of the API. Defaults to the value of `CheckoutEnvironment.getBaseUrl()`. * * @returns {Promise<object | { hasError: true, error: any }>} - A promise that resolves to the response data or an object with an error property. */ const fetcher = async ({ url = '', method = 'post', data = {}, params = {}, headers = {}, cookies = {}, baseUrl = "", }) => { const computedUrl = new URL(url, baseUrl || CheckoutEnvironment_1.CheckoutEnvironment.getBaseUrl()); const config = { method: method, url: computedUrl.href, headers, }; if (Object.keys(params).length) { config.params = params; } if (Object.keys(data).length) { config.data = data; } //console.log(JSON.stringify(config)) try { const response = await axiosInstance(config); let responseCode = response.status; let responseBody = response.data; if (responseCode >= 200 && responseCode < 300) { return responseBody; } else { let status = undefined; let errorCode = undefined; let errorMessage = undefined; if (responseBody != undefined) { if ("status" in responseBody != undefined) { status = responseBody.status; } if ("error_code" in responseBody != undefined) { errorCode = responseBody.error_code; } if ("error_message" in responseBody != undefined) { errorMessage = responseBody.error_message; } } switch (responseCode) { case 400: case 404: throw new entity_1.InvalidRequestException(responseCode, status, errorCode, errorMessage); case 401: throw new entity_1.AuthenticationException(responseCode, status, errorCode, errorMessage); default: throw new entity_1.APIException(responseCode, "internal_error", "internal_error", "Something went wrong."); } } } catch (error) { let errorData = {}; if (error.response) { //errorData = error.response; errorData = { //headers: error.response.headers, status: error.response.status, data: error.response.data, }; // The request was made and the server responded with a status code // that falls out of the range of 2xx console.log(error.response.data); console.log(error.response.status); console.log(error.response.headers); } else if (error.request) { errorData = error.request; // The request was made but no response was received // `error.request` is an instance of XMLHttpRequest in the browser and an instance of // http.ClientRequest in node.js console.log(error.request); } else { errorData = error.message; // Something happened in setting up the request that triggered an Error console.log('Error: ' + error.message); } return { hasError: true, error: errorData }; //console.log(error, 'error inside fetcher'); //throw new Error(error.response.data.message); } }; exports.default = fetcher;