UNPKG

@tecafrik/africa-payment-sdk

Version:

A single SDK to integrate all african payment providers seamlessly

230 lines 12 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()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const payment_provider_interface_1 = require("../payment-provider.interface"); const payment_events_1 = require("../payment-events"); const stripe_1 = __importDefault(require("stripe")); const payment_error_1 = require("../payment-error"); const lodash_1 = require("lodash"); class StripePaymentProvider { constructor(config) { this.config = config; this.stripe = new stripe_1.default(config.privateKey, { apiVersion: "2023-08-16", }); this.init().catch((error) => { console.error("Error initializing stripe provider", error); }); this.webhookSecret = config.webhookSecret; } init() { return __awaiter(this, void 0, void 0, function* () { if (this.config.webhookUrl) { const existingWebhooks = yield this.stripe.webhookEndpoints.list(); const existingWebhook = existingWebhooks.data.find((webhook) => webhook.url === this.config.webhookUrl); if (!existingWebhook) { const installedWebhook = yield this.stripe.webhookEndpoints.create({ enabled_events: [ "checkout.session.completed", "checkout.session.expired", "checkout.session.async_payment_succeeded", "checkout.session.async_payment_failed", ], url: this.config.webhookUrl, }); this.webhookSecret = installedWebhook.secret; } } }); } useEventEmitter(eventEmitter) { this.eventEmitter = eventEmitter; } checkoutMobileMoney(options) { return __awaiter(this, void 0, void 0, function* () { throw new payment_error_1.PaymentError("Stripe does not support mobile money payments", payment_error_1.PaymentErrorType.UNSUPPORTED_PAYMENT_METHOD); }); } checkoutCreditCard(options) { return __awaiter(this, void 0, void 0, function* () { throw new payment_error_1.PaymentError("Stripe does not support credit card payments. Use credit card tokens instead", payment_error_1.PaymentErrorType.UNSUPPORTED_PAYMENT_METHOD); }); } checkoutRedirect(options) { return __awaiter(this, void 0, void 0, function* () { const checkoutSession = yield this.stripe.checkout.sessions.create({ customer_email: options.customer.email, payment_method_types: options.paymentMethod === payment_provider_interface_1.PaymentMethod.CREDIT_CARD ? ["card"] : undefined, line_items: [ { price_data: { currency: options.currency, product_data: { name: options.description, }, unit_amount: options.amount, }, quantity: 1, }, ], mode: "payment", success_url: options.successRedirectUrl, cancel_url: options.failureRedirectUrl, metadata: Object.assign(Object.assign({}, (0, lodash_1.mapValues)(options.metadata, (value) => JSON.stringify(value))), { transactionId: options.transactionId }), }); if (!checkoutSession.url) { throw new payment_error_1.PaymentError("Stripe did not return a checkout URL", payment_error_1.PaymentErrorType.UNKNOWN_ERROR); } return { transactionAmount: options.amount, transactionCurrency: options.currency, transactionId: options.transactionId, transactionReference: checkoutSession.id, transactionStatus: payment_provider_interface_1.TransactionStatus.PENDING, redirectUrl: checkoutSession.url, }; }); } refund(options) { return __awaiter(this, void 0, void 0, function* () { const checkoutSession = yield this.stripe.checkout.sessions.retrieve(options.refundedTransactionReference); if (!checkoutSession) { throw new payment_error_1.PaymentError("No checkout session found with reference " + options.refundedTransactionReference, payment_error_1.PaymentErrorType.UNKNOWN_ERROR); } if (!checkoutSession.payment_intent) { throw new payment_error_1.PaymentError("No payment intent found for checkout session " + checkoutSession.id, payment_error_1.PaymentErrorType.UNKNOWN_ERROR); } const refund = yield this.stripe.refunds.create({ payment_intent: (0, lodash_1.isString)(checkoutSession.payment_intent) ? checkoutSession.payment_intent : checkoutSession.payment_intent.id, amount: options.refundedAmount, reason: "requested_by_customer", }); return { transactionAmount: refund.amount, transactionCurrency: refund.currency, transactionId: options.transactionId, transactionReference: refund.id, transactionStatus: payment_provider_interface_1.TransactionStatus.SUCCESS, }; }); } payoutMobileMoney(options) { throw new payment_error_1.PaymentError("Stripe does not support mobile money payouts", payment_error_1.PaymentErrorType.UNSUPPORTED_PAYMENT_METHOD); } handleWebhook(rawBody, options) { var _a, _b, _c, _d, _e, _f, _g; return __awaiter(this, void 0, void 0, function* () { const signature = (_a = options.headers) === null || _a === void 0 ? void 0 : _a["stripe-signature"]; if (!signature) { console.warn("No signature found in stripe webhook request"); return null; } if (!this.webhookSecret) { console.warn("No stripe webhook secret found"); return null; } let event; try { event = this.stripe.webhooks.constructEvent(rawBody, signature, this.webhookSecret); } catch (error) { console.warn("Error verifying stripe webhook signature", error); return null; } const emitSuccessfulPayment = (session) => { var _a, _b, _c; if (!((_a = session.metadata) === null || _a === void 0 ? void 0 : _a.transactionId)) { console.warn("No transaction ID found in stripe webhook"); return null; } const paymentSuccessfulEvent = { type: payment_events_1.PaymentEventType.PAYMENT_SUCCESSFUL, paymentMethod: payment_provider_interface_1.PaymentMethod.CREDIT_CARD, transactionAmount: Number(session.amount_total), transactionCurrency: session.currency, transactionId: (_b = session.metadata) === null || _b === void 0 ? void 0 : _b.transactionId, transactionReference: session.id, metadata: parseMetadata(session.metadata), paymentProvider: StripePaymentProvider.name, }; (_c = this.eventEmitter) === null || _c === void 0 ? void 0 : _c.emit(payment_events_1.PaymentEventType.PAYMENT_SUCCESSFUL, paymentSuccessfulEvent); return paymentSuccessfulEvent; }; const parseMetadata = (metadata) => { return (0, lodash_1.mapValues)(metadata, (value) => { try { return JSON.parse(value); } catch (error) { return value; } }); }; if (event.type === "checkout.session.completed") { const session = event.data.object; if (!((_b = session.metadata) === null || _b === void 0 ? void 0 : _b.transactionId)) { console.warn("No transaction ID found in stripe webhook"); return null; } const paymentInitiatedEvent = { type: payment_events_1.PaymentEventType.PAYMENT_INITIATED, paymentMethod: payment_provider_interface_1.PaymentMethod.CREDIT_CARD, transactionAmount: Number(session.amount_total), transactionCurrency: session.currency, transactionId: (_c = session.metadata) === null || _c === void 0 ? void 0 : _c.transactionId, transactionReference: session.id, metadata: parseMetadata(session.metadata), paymentProvider: StripePaymentProvider.name, }; (_d = this.eventEmitter) === null || _d === void 0 ? void 0 : _d.emit(payment_events_1.PaymentEventType.PAYMENT_INITIATED, paymentInitiatedEvent); if (session.payment_status === "paid") { return emitSuccessfulPayment(session); } return paymentInitiatedEvent; } else if (event.type === "checkout.session.async_payment_succeeded") { const session = event.data.object; return emitSuccessfulPayment(session); } else if (event.type === "checkout.session.async_payment_failed") { const session = event.data.object; if (!((_e = session.metadata) === null || _e === void 0 ? void 0 : _e.transactionId)) { console.warn("No transaction ID found in stripe webhook"); return null; } const paymentFailedEvent = { type: payment_events_1.PaymentEventType.PAYMENT_FAILED, paymentMethod: payment_provider_interface_1.PaymentMethod.CREDIT_CARD, transactionAmount: Number(session.amount_total), transactionCurrency: session.currency, transactionId: (_f = session.metadata) === null || _f === void 0 ? void 0 : _f.transactionId, transactionReference: session.id, metadata: parseMetadata(session.metadata), reason: "Payment failed", paymentProvider: StripePaymentProvider.name, }; (_g = this.eventEmitter) === null || _g === void 0 ? void 0 : _g.emit(payment_events_1.PaymentEventType.PAYMENT_FAILED, paymentFailedEvent); return paymentFailedEvent; } return null; }); } } exports.default = StripePaymentProvider; //# sourceMappingURL=stripe.js.map