UNPKG

@tecafrik/africa-payment-sdk

Version:

A single SDK to integrate all african payment providers seamlessly

239 lines 12.2 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TaarihTransactionStatus = void 0; const libphonenumber_js_1 = require("libphonenumber-js"); const payment_provider_interface_1 = require("../payment-provider.interface"); const apisauce_1 = require("apisauce"); const payment_error_1 = require("../payment-error"); const lodash_1 = require("lodash"); var TaarihTransactionStatus; (function (TaarihTransactionStatus) { TaarihTransactionStatus["PENDING"] = "PENDING"; TaarihTransactionStatus["COMPLETED"] = "COMPLETED"; TaarihTransactionStatus["FAILED"] = "FAILED"; })(TaarihTransactionStatus || (exports.TaarihTransactionStatus = TaarihTransactionStatus = {})); class TaarihPaymentProvider { constructor(config) { this.config = config; this.api = (0, apisauce_1.create)({ baseURL: config.mode === "test" ? "https://api-dev.taarih.com/api" : "https://api-prod.taarih.com/api", headers: { "Content-Type": "application/json", }, }); this.api.addResponseTransform((response) => { if (!response.ok) { const defaultErrorMessage = "Taarih error: " + response.problem + ". Status: " + response.status + ". Data: " + JSON.stringify(response.data); console.error(response); throw new payment_error_1.PaymentError(response.data && (0, lodash_1.isObject)(response.data) ? "message" in response.data ? String(response.data.message) : "response_text" in response.data ? String(response.data.response_text) : defaultErrorMessage : defaultErrorMessage); } }); } useEventEmitter(eventEmitter) { this.eventEmitter = eventEmitter; } getTaarihPaymentMethod(paymentMethod) { switch (paymentMethod) { case payment_provider_interface_1.PaymentMethod.WAVE: return "WAVE_TO_ACCOUNT"; case payment_provider_interface_1.PaymentMethod.ORANGE_MONEY: return "OM_TO_ACCOUNT"; case payment_provider_interface_1.PaymentMethod.CREDIT_CARD: return "CARD_TO_ACCOUNT"; default: throw new payment_error_1.PaymentError("Invalid payment method: " + paymentMethod); } } login() { return __awaiter(this, void 0, void 0, function* () { const signEndUserResponse = yield this.api.post("/auth/signin-end-user", { callingCode: this.config.callingCode, phoneNumber: this.config.phoneNumber, authMode: "SMS", visitorId: this.config.visitorId, password: this.config.password, }); if (signEndUserResponse.data && "otpRequired" in signEndUserResponse.data) { throw new payment_error_1.PaymentError("Taarih error: " + signEndUserResponse.data.message); } if (signEndUserResponse.data && "invalidData" in signEndUserResponse.data) { throw new payment_error_1.PaymentError("Taarih error: " + signEndUserResponse.data.message + " " + signEndUserResponse.data.invalidData ? JSON.stringify(signEndUserResponse.data.invalidData) : ""); } if (signEndUserResponse.data && "token" in signEndUserResponse.data) { return signEndUserResponse.data; } throw new payment_error_1.PaymentError("Taarih error: No token in response"); }); } checkoutPreAuth(options, token, bankAccountId) { return __awaiter(this, void 0, void 0, function* () { const taarihCheckoutResponse = yield this.api.post("/transaction/preauth-external-to-account", { bankAccountId: bankAccountId, amount: options.amount, callingCode: this.config.callingCode, phoneNumber: options.customer.phoneNumber, paymentMethod: this.getTaarihPaymentMethod(options.paymentMethod), currency: options.currency, }, { headers: Object.assign(Object.assign({}, this.api.headers), { "x-access-token": token }), }); if (!taarihCheckoutResponse) { throw new payment_error_1.PaymentError("Taarih error: no payment response data"); } if (taarihCheckoutResponse.data && "amount" in taarihCheckoutResponse.data) { return taarihCheckoutResponse.data; } throw new payment_error_1.PaymentError("Taarih error: response data is not valid"); }); } checkout(options) { return __awaiter(this, void 0, void 0, function* () { if (options.paymentMethod === payment_provider_interface_1.PaymentMethod.CREDIT_CARD) { throw new payment_error_1.PaymentError("Taarih does not support credit card checkout", payment_error_1.PaymentErrorType.UNSUPPORTED_PAYMENT_METHOD); } if (options.currency !== payment_provider_interface_1.Currency.XOF) { throw new payment_error_1.PaymentError("Taarih does not support the currency: " + options.currency, payment_error_1.PaymentErrorType.UNSUPPORTED_PAYMENT_METHOD); } const isMobileMoney = options.paymentMethod === payment_provider_interface_1.PaymentMethod.WAVE || options.paymentMethod === payment_provider_interface_1.PaymentMethod.ORANGE_MONEY; const user = yield this.login(); const bankAccountId = user.userBankAccounts[0].id; yield this.checkoutPreAuth(options, user.token, bankAccountId); const taarihCheckoutResponse = yield this.api.post("/transaction/external-to-account", { bankAccountId: bankAccountId, amount: options.amount, callingCode: this.config.callingCode, phoneNumber: options.customer.phoneNumber, paymentMethod: this.getTaarihPaymentMethod(options.paymentMethod), currency: options.currency, }, { headers: Object.assign(Object.assign({}, this.api.headers), { "x-access-token": user.token }), }); if (isMobileMoney) { const parsedCustomerPhoneNumber = (0, libphonenumber_js_1.parsePhoneNumber)(options.customer.phoneNumber, "SN"); if (!parsedCustomerPhoneNumber.isValid()) { throw new payment_error_1.PaymentError("Invalid phone number: " + options.customer.phoneNumber, payment_error_1.PaymentErrorType.INVALID_PHONE_NUMBER); } if (!parsedCustomerPhoneNumber.isPossible()) { throw new payment_error_1.PaymentError("Phone number is not possible: " + options.customer.phoneNumber, payment_error_1.PaymentErrorType.INVALID_PHONE_NUMBER); } } if (!taarihCheckoutResponse) { throw new payment_error_1.PaymentError("Taarih error: no payment response data"); } if (taarihCheckoutResponse.data && "externalId" in taarihCheckoutResponse.data && "internalId" in taarihCheckoutResponse.data && "payment_link" in taarihCheckoutResponse.data) { const result = { transactionAmount: options.amount, transactionCurrency: options.currency, transactionId: taarihCheckoutResponse.data.externalId, transactionReference: taarihCheckoutResponse.data.internalId, transactionStatus: payment_provider_interface_1.TransactionStatus.PENDING, redirectUrl: taarihCheckoutResponse.data.payment_link, }; return result; } throw new payment_error_1.PaymentError("Taarih error: response data is not valid"); }); } checkoutMobileMoney(options) { return __awaiter(this, void 0, void 0, function* () { return this.checkout(options); }); } checkoutCreditCard(options) { return __awaiter(this, void 0, void 0, function* () { throw new payment_error_1.PaymentError("Taarih does not support credit card checkout", payment_error_1.PaymentErrorType.UNSUPPORTED_PAYMENT_METHOD); }); } checkoutRedirect(options) { return __awaiter(this, void 0, void 0, function* () { throw new payment_error_1.PaymentError("Taarih redirect checkout not yet implemented", payment_error_1.PaymentErrorType.UNSUPPORTED_PAYMENT_METHOD); }); } refund(options) { return __awaiter(this, void 0, void 0, function* () { throw new payment_error_1.PaymentError("Taarih refund not yet implemented", payment_error_1.PaymentErrorType.UNSUPPORTED_PAYMENT_METHOD); }); } payoutMobileMoney(options) { return __awaiter(this, void 0, void 0, function* () { throw new payment_error_1.PaymentError("Taarih payout not yet implemented", payment_error_1.PaymentErrorType.UNSUPPORTED_PAYMENT_METHOD); }); } handleWebhook(rawBody) { return __awaiter(this, void 0, void 0, function* () { return null; }); } callback(internalId, timeInterval = 3000, maxAttempts = 4) { return __awaiter(this, void 0, void 0, function* () { const user = yield this.login(); let attempts = 0; while (true) { const taarihTransactionStatusResponse = yield this.api.get(`/transaction/verify-transaction-status/${internalId}`, {}, { headers: Object.assign(Object.assign({}, this.api.headers), { "x-access-token": user.token }), }); if (taarihTransactionStatusResponse.data && "invalidData" in taarihTransactionStatusResponse.data) { throw new payment_error_1.PaymentError("Taarih error: " + taarihTransactionStatusResponse.data.message); } const { data } = taarihTransactionStatusResponse; if (!data) { throw new payment_error_1.PaymentError("Taarih error: no transaction status data"); } const status = data.status; if (status !== TaarihTransactionStatus.PENDING) { return (0, lodash_1.pick)(data, [ "status", "amount", "currency", "bankAccountSender", ]); } attempts++; if (attempts >= maxAttempts) { return (0, lodash_1.pick)(data, [ "status", "amount", "currency", "bankAccountSender", ]); } yield new Promise((resolve) => setTimeout(resolve, timeInterval)); } }); } } exports.default = TaarihPaymentProvider; //# sourceMappingURL=taarih.js.map