@wepublish/api
Version:
API core for we.publish.
201 lines • 8.92 kB
JavaScript
"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