UNPKG

@wepublish/api

Version:
201 lines 8.92 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PayrexxPaymentProvider = void 0; const tslib_1 = require("tslib"); const payment_provider_1 = require("./payment-provider"); const api_1 = require("../../../../utils-api/src"); const client_1 = require("@prisma/client"); const crypto_1 = require("crypto"); function timeConstantCompare(a, b) { try { return (0, crypto_1.timingSafeEqual)(Buffer.from(a, 'utf8'), Buffer.from(b, 'utf8')); } catch (_a) { return false; } } class PayrexxPaymentProvider extends payment_provider_1.BasePaymentProvider { constructor(props) { super(props); this.gatewayClient = props.gatewayClient; this.transactionClient = props.transactionClient; this.webhookApiKey = props.webhookApiKey; this.psp = props.psp; this.pm = props.pm; this.vatRate = props.vatRate; } webhookForPaymentIntent(props) { var _a; return tslib_1.__awaiter(this, void 0, void 0, function* () { const apiKey = (_a = props.req.query) === null || _a === void 0 ? void 0 : _a.apiKey; if (!timeConstantCompare(apiKey, this.webhookApiKey)) { return { status: 403, message: 'Invalid Api Key' }; } if (!props.req.body.transaction) { return { status: 200, message: 'Skipping non-transaction webhook' }; } const transaction = props.req.body.transaction; if (transaction.subscription) { return { status: 200, message: 'Skipping transaction related to subscription' }; } const state = this.mapPayrexxEventToPaymentStatus(transaction.status); if (state === null) { return { status: 200, paymentStates: [] }; } const intentState = { paymentID: transaction.referenceId, paymentData: JSON.stringify(transaction), state }; if (state === 'paid' && transaction.preAuthorizationId) { intentState.customerID = String(transaction.preAuthorizationId); } return { status: 200, paymentStates: [intentState] }; }); } createIntent(createPaymentIntentProps) { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (createPaymentIntentProps.customerID) { const offsiteTransactionIntent = yield this.createOffsiteTransactionIntent(createPaymentIntentProps); if (offsiteTransactionIntent.state === 'paid') { return offsiteTransactionIntent; } } return this.createGatewayIntent(createPaymentIntentProps); }); } checkIntentStatus({ intentID }) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const transaction = yield this.transactionClient.retrieveTransaction(intentID); if (transaction) { return this.checkTransactionIntentStatus(transaction); } const gateway = yield this.gatewayClient.getGateway(intentID); if (gateway) { return this.checkGatewayIntentStatus(gateway); } (0, api_1.logger)('payrexxPaymentProvider').error('No Payrexx Gateway nor Transaction with intendID: %s for paymentProvider %s found', intentID, this.id); throw new Error('Payrexx Gateway/Transaction not found'); }); } createOffsiteTransactionIntent({ customerID, invoice, paymentID, successURL }) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const amount = invoice.items.reduce((accumulator, { amount, quantity }) => accumulator + amount * quantity, 0); const transaction = yield this.transactionClient.chargePreAuthorizedTransaction(parseInt(customerID), { amount, referenceId: paymentID }); const state = this.mapPayrexxEventToPaymentStatus(transaction.status); if (state === null) { throw new Error('Invalid payrexx transaction status'); } return { intentID: transaction.id.toString(), intentSecret: successURL !== null && successURL !== void 0 ? successURL : '', intentData: JSON.stringify(transaction), state }; }); } createGatewayIntent({ invoice, paymentID, successURL, failureURL }) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const amount = invoice.items.reduce((accumulator, { amount, quantity }) => accumulator + amount * quantity, 0); const gateway = yield this.gatewayClient.createGateway({ psp: this.psp, pm: this.pm, referenceId: paymentID, amount, fields: { email: { value: invoice.mail } }, successRedirectUrl: successURL, failedRedirectUrl: failureURL, cancelRedirectUrl: failureURL, vatRate: this.vatRate, currency: 'CHF', preAuthorization: true, chargeOnAuthorization: true }); (0, api_1.logger)('payrexxPaymentProvider').info('Created Payrexx intent with ID: %s for paymentProvider %s', gateway.id, this.id); return { intentID: gateway.id.toString(), intentSecret: gateway.link, intentData: JSON.stringify(gateway), state: client_1.PaymentState.submitted }; }); } checkTransactionIntentStatus(transaction) { const state = this.mapPayrexxEventToPaymentStatus(transaction.status); if (!state) { (0, api_1.logger)('payrexxPaymentProvider').error('Payrexx gateway with ID: %s for paymentProvider %s returned with an unmappable status %s', transaction.id, this.id, transaction.status); throw new Error('Unmappable Payrexx transaction status'); } if (!transaction.referenceId) { (0, api_1.logger)('payrexxPaymentProvider').error('Payrexx transaction with ID: %s for paymentProvider %s returned with empty referenceId', transaction.id, this.id); throw new Error('empty referenceId'); } return { state, paymentID: transaction.referenceId, paymentData: JSON.stringify(transaction) }; } checkGatewayIntentStatus(gateway) { var _a; const state = this.mapPayrexxEventToPaymentStatus(gateway.status); if (!state) { (0, api_1.logger)('payrexxPaymentProvider').error('Payrexx gateway with ID: %s for paymentProvider %s returned with an unmappable status %s', gateway.id, this.id, gateway.status); throw new Error('Unmappable Payrexx gateway status'); } const transaction = (_a = gateway.invoices[0]) === null || _a === void 0 ? void 0 : _a.transactions[0]; if (!transaction) { (0, api_1.logger)('payrexxPaymentProvider').error('Payrexx gateway with ID: %s for paymentProvider %s returned without transaction despite preAuthorization set to true.', gateway.id, this.id); } if (!gateway.referenceId) { (0, api_1.logger)('payrexxPaymentProvider').error('Payrexx gateway with ID: %s for paymentProvider %s returned with empty referenceId', gateway.id, this.id); throw new Error('empty referenceId'); } return { state, paymentID: gateway.referenceId, paymentData: JSON.stringify(gateway), customerID: (transaction === null || transaction === void 0 ? void 0 : transaction.preAuthorizationId) ? transaction.preAuthorizationId.toString() : undefined }; } mapPayrexxEventToPaymentStatus(event) { switch (event) { case 'waiting': return client_1.PaymentState.processing; case 'confirmed': return client_1.PaymentState.paid; case 'cancelled': return client_1.PaymentState.canceled; case 'declined': return client_1.PaymentState.declined; default: return null; } } } exports.PayrexxPaymentProvider = PayrexxPaymentProvider; //# sourceMappingURL=payrexx-payment-provider.js.map