bc-payments-sdk
Version:
BetterCommerce's Payments NodeJS SDK is a complete solution for storefront clients that integrate payments. `bc-payments-sdk` is a single point interface for storefront clients for interacting with payment gateways.
496 lines • 63.5 kB
JavaScript
"use strict";
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BetterCommerceOperation = void 0;
// Other Imports
const Logger_1 = require("../modules/better-commerce/Logger");
const B2B_1 = require("../modules/better-commerce/B2B");
const Order_1 = require("../modules/better-commerce/Order");
const PaymentMethod_1 = require("../modules/better-commerce/PaymentMethod");
const PayPalPayment_1 = require("../modules/payments/PayPalPayment");
const CheckoutPayment_1 = require("../modules/payments/CheckoutPayment");
const Checkout_1 = require("../modules/better-commerce/Checkout");
const constants_1 = require("../constants/constants");
const PaymentStatus_1 = require("../constants/enums/PaymentStatus");
const PaymentMethodType_1 = require("../constants/enums/PaymentMethodType");
const PaymentStatus_2 = require("../constants/enums/PaymentStatus");
const StripePayment_1 = require("../modules/payments/StripePayment");
const OrderStatus_1 = require("../constants/enums/OrderStatus");
const KlarnaPayment_1 = require("../modules/payments/KlarnaPayment");
const ClearPayPament_1 = require("../modules/payments/ClearPayPament");
const constants_2 = require("../constants");
const parse_util_1 = require("../utils/parse-util");
const payment_util_1 = require("../utils/payment-util");
/**
* Class {BetterCommerceOperation} is the main entry point for all the operations related to BetterCommerce.
* It contains methods for getting order details, creating orders, updating orders, getting payment methods, processing payments and more.
* @implements {ICommerceProvider}
*/
class BetterCommerceOperation {
/**
* Retrieves the company details by user id. This method is used to get the company details which is linked to the user
* API Reference - https://api20.bettercommerce.io/swagger/ui/index#!/B2B/B2BGetCompanyDetailByUserId
* @param data - The data which contains the user id
* @returns The company details
*/
async getCompanyDetails(data) {
var _a;
const companyDetailsResult = await B2B_1.B2B.getCompanyDetailsByUserId(data, { cookies: (_a = data === null || data === void 0 ? void 0 : data.extras) === null || _a === void 0 ? void 0 : _a.cookies });
return companyDetailsResult;
}
/**
* Converts a basket into an order on the CommerceHub platform.
* API Reference - https://api20.bettercommerce.io/swagger/ui/index#!/Checkout/CheckoutConvertBasket
* @param data - The data which contains the basket id
* @returns The order details response from the CommerceHub platform
*/
async convertOrder(data) {
var _a;
const createOrderResult = await Checkout_1.Checkout.convertOrder(data, { cookies: (_a = data === null || data === void 0 ? void 0 : data.extras) === null || _a === void 0 ? void 0 : _a.cookies });
return createOrderResult;
}
/**
* Processes a payment based on the provided payment data.
*
* This method handles different payment gateways, including PayPal, Checkout,
* Stripe, Klarna, and ClearPay. It retrieves payment method details, constructs
* the order model with payment information, and updates the payment response.
* The method also handles Cash on Delivery (COD) orders and different payment
* statuses such as authorized, paid, declined, and pending.
*
* @param data - The payment processing data, including order details, payment
* method, extras, and more.
* @returns A promise that resolves to the payment status or an error object
* if an error occurs during the payment process.
*/
async processPayment(data) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6;
try {
const getPaymentInfoPayload = (paymentInfo) => {
/* ******
Info
******
paymentInfo1 is for [pspInformation[]
paymentInfo2 is for [paymentIdentifier]
paymentInfo3 is for gateway type i.e. Billdesk, Razorpay, etc
paymentInfo4 is for [cardType]
paymentInfo5 is for [cardIssuer]
paymentInfo6 is for [cardBrand]
paymentInfo7 is for [chequeNumber]
paymentInfo8 is untilized
*/
let info = {};
if (paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo1) {
info = Object.assign(Object.assign({}, info), { paymentInfo1: paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo1 });
}
if (paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo2) {
info = Object.assign(Object.assign({}, info), { paymentInfo2: paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo2 });
}
if (paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo3) {
info = Object.assign(Object.assign({}, info), { paymentInfo3: paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo3 });
}
if (paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo4) {
info = Object.assign(Object.assign({}, info), { paymentInfo4: paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo4 });
}
if (paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo5) {
info = Object.assign(Object.assign({}, info), { paymentInfo5: paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo5 });
}
if (paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo6) {
info = Object.assign(Object.assign({}, info), { paymentInfo6: paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo6 });
}
if (paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo7) {
info = Object.assign(Object.assign({}, info), { paymentInfo7: paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo7 });
}
if (paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo8) {
info = Object.assign(Object.assign({}, info), { paymentInfo8: paymentInfo === null || paymentInfo === void 0 ? void 0 : paymentInfo.paymentInfo8 });
}
return info;
};
let orderModel;
const isCancelled = (_b = (_a = data === null || data === void 0 ? void 0 : data.extras) === null || _a === void 0 ? void 0 : _a.isCancelled) !== null && _b !== void 0 ? _b : false;
const gateway = ((_c = data === null || data === void 0 ? void 0 : data.extras) === null || _c === void 0 ? void 0 : _c.gateway) || constants_1.Defaults.String.Value;
let paymentType = ((_d = data === null || data === void 0 ? void 0 : data.extras) === null || _d === void 0 ? void 0 : _d.paymentType) || constants_2.PaymentSelectionType.FULL; // Default value is FULL
let partialAmount = ((_e = data === null || data === void 0 ? void 0 : data.extras) === null || _e === void 0 ? void 0 : _e.partialAmount) || constants_1.Defaults.Int.Value; // Default value is 0
if (gateway) {
let paymentGatewayOrderTxnId = "";
// For PayPal, Checkout, Stripe, Klarna & ClearPay
if ((gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()) === ((_f = PaymentMethodType_1.PaymentMethodType.PAYPAL) === null || _f === void 0 ? void 0 : _f.toLowerCase()) || (gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()) === ((_g = PaymentMethodType_1.PaymentMethodType.CHECKOUT) === null || _g === void 0 ? void 0 : _g.toLowerCase()) || (gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()) === ((_h = PaymentMethodType_1.PaymentMethodType.STRIPE) === null || _h === void 0 ? void 0 : _h.toLowerCase()) || (gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()) === ((_j = PaymentMethodType_1.PaymentMethodType.KLARNA) === null || _j === void 0 ? void 0 : _j.toLowerCase()) || (gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()) === ((_k = PaymentMethodType_1.PaymentMethodType.CLEAR_PAY) === null || _k === void 0 ? void 0 : _k.toLowerCase())) {
// For PayPal, Checkout, Stripe, Klarna & ClearPay, the order id is the payment gateway order txn id
paymentGatewayOrderTxnId = (_l = data === null || data === void 0 ? void 0 : data.extras) === null || _l === void 0 ? void 0 : _l.orderId;
}
// Get payment method
const paymentMethod = await this.getPaymentMethod(gateway, { cookies: (_m = data === null || data === void 0 ? void 0 : data.extras) === null || _m === void 0 ? void 0 : _m.cookies });
// If payment method is found
if (paymentMethod) {
// Get additional service charge
const additionalServiceCharge = ((_o = paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.settings) === null || _o === void 0 ? void 0 : _o.length)
? ((_q = (_p = paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.settings) === null || _p === void 0 ? void 0 : _p.find((x) => (x === null || x === void 0 ? void 0 : x.key) === "AdditionalServiceCharge")) === null || _q === void 0 ? void 0 : _q.value) || "0"
: "0";
const { isCOD, orderId, txnOrderId, bankOfferDetails } = data;
// Get order details
const { result: orderResult } = await Order_1.Order.get(orderId, { cookies: (_r = data === null || data === void 0 ? void 0 : data.extras) === null || _r === void 0 ? void 0 : _r.cookies });
const _7 = data === null || data === void 0 ? void 0 : data.extras, { headers, cookies } = _7, rest = __rest(_7, ["headers", "cookies"]);
// If order is found
if (orderResult) {
let paymentStatus;
// Get order amount
const orderAmount = ((_t = (_s = orderResult === null || orderResult === void 0 ? void 0 : orderResult.grandTotal) === null || _s === void 0 ? void 0 : _s.raw) === null || _t === void 0 ? void 0 : _t.withTax) || 0;
// Get amount to be paid
let amountToBePaid = (paymentType === constants_2.PaymentSelectionType.FULL) ? orderAmount : partialAmount;
//console.log({ gateway, paymentType, orderAmount, partialAmount })
// If this is COD order.
if (isCOD) {
let paymentInfo9 = 0;
let isLastPartialPayment = false;
if (paymentType === constants_2.PaymentSelectionType.PARTIAL) {
const payments = (orderResult === null || orderResult === void 0 ? void 0 : orderResult.payments) || [];
const orderPayments = (payments === null || payments === void 0 ? void 0 : payments.filter((x) => (x === null || x === void 0 ? void 0 : x.isPartialPaymentEnabled) && (x === null || x === void 0 ? void 0 : x.orderAmount) == orderAmount)) || [];
const totalPartiallyPaidAmount = (orderPayments === null || orderPayments === void 0 ? void 0 : orderPayments.reduce((sum, x) => sum + x.paidAmount, 0)) || 0;
console.log('totalPartiallyPaidAmount', totalPartiallyPaidAmount);
if (totalPartiallyPaidAmount > 0) {
isLastPartialPayment = ((totalPartiallyPaidAmount + partialAmount) === orderAmount);
}
paymentInfo9 = !isLastPartialPayment ? partialAmount : orderAmount;
}
orderModel = Object.assign({ id: txnOrderId === null || txnOrderId === void 0 ? void 0 : txnOrderId.split('-')[1], cardNo: null, orderNo: parseInt(txnOrderId === null || txnOrderId === void 0 ? void 0 : txnOrderId.split('-')[0]), orderAmount: orderAmount, paidAmount: 0.0, balanceAmount: orderAmount, isValid: true, status: !isCancelled ? PaymentStatus_1.PaymentStatus.AUTHORIZED : PaymentStatus_1.PaymentStatus.DECLINED, authCode: null, issuerUrl: null, paRequest: null, pspSessionCookie: null, pspResponseCode: null, pspResponseMessage: null, paymentGatewayId: paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.id, paymentGateway: paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.systemName, token: null, payerId: null, cvcResult: null, avsResult: null, secure3DResult: null, cardHolderName: null, issuerCountry: null, info1: '', fraudScore: null, paymentMethod: gateway, cardType: null, operatorId: null, refStoreId: null, tillNumber: null, externalRefNo: null, expiryYear: null, expiryMonth: null, isMoto: true, upFrontPayment: false, upFrontAmount: '0.00', upFrontTerm: '76245369', isPrePaid: false, additionalServiceCharge: additionalServiceCharge }, Object.assign(Object.assign({}, getPaymentInfoPayload((_u = data === null || data === void 0 ? void 0 : data.extras) === null || _u === void 0 ? void 0 : _u.paymentInfo)), { paymentInfo9 }));
paymentStatus = {
statusId: PaymentStatus_1.PaymentStatus.AUTHORIZED,
};
}
else {
if ((gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()) === ((_v = PaymentMethodType_1.PaymentMethodType.ACCOUNT_CREDIT) === null || _v === void 0 ? void 0 : _v.toLowerCase()) || (gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()) === ((_w = PaymentMethodType_1.PaymentMethodType.WALLET) === null || _w === void 0 ? void 0 : _w.toLowerCase())) {
paymentStatus = { statusId: PaymentStatus_1.PaymentStatus.PAID, purchaseAmount: orderAmount };
}
else if ((gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()) === ((_x = PaymentMethodType_1.PaymentMethodType.CHEQUE) === null || _x === void 0 ? void 0 : _x.toLowerCase())) {
paymentStatus = { statusId: PaymentStatus_1.PaymentStatus.AUTHORIZED, purchaseAmount: orderAmount };
}
else {
// Call gateway specific SDK API to get the order/payment status.
paymentStatus = await this.getPaymentStatus(gateway, paymentGatewayOrderTxnId);
paymentType = paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.paymentType;
partialAmount = paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.partialAmount;
amountToBePaid = (paymentType === constants_2.PaymentSelectionType.FULL) ? orderAmount : partialAmount;
}
/**************** This block is for partial payments only (STARTS) ****************/
let paymentInfo9 = 0;
let isLastPartialPayment = false;
let isPartialPaymentEnabled = (paymentType === constants_2.PaymentSelectionType.PARTIAL);
// For partial payment, re-evaluate the payment status.
// Except for COD & Cheque, all other payment methods support partial payments.
if (![(_y = PaymentMethodType_1.PaymentMethodType.COD) === null || _y === void 0 ? void 0 : _y.toLowerCase(), (_z = PaymentMethodType_1.PaymentMethodType.CHEQUE) === null || _z === void 0 ? void 0 : _z.toLowerCase()].includes(gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase())) {
// Get all payments for this order.
const payments = (orderResult === null || orderResult === void 0 ? void 0 : orderResult.payments) || [];
// Get all partial payments for this order.
const orderPayments = (payments === null || payments === void 0 ? void 0 : payments.filter((x) => (x === null || x === void 0 ? void 0 : x.isPartialPaymentEnabled) && (x === null || x === void 0 ? void 0 : x.orderAmount) == orderAmount)) || [];
// Calculate the total partially paid amount for this order.
const totalPartiallyPaidAmount = (orderPayments === null || orderPayments === void 0 ? void 0 : orderPayments.reduce((sum, x) => sum + x.paidAmount, 0)) || 0;
console.log('totalPartiallyPaidAmount', totalPartiallyPaidAmount);
// Is this a partial payment?
let isPartialPayment = (paymentType === constants_2.PaymentSelectionType.PARTIAL);
// If payment type is FULL and there are any partial payments, then it is next partial payment.
if (paymentType === constants_2.PaymentSelectionType.FULL && totalPartiallyPaidAmount > 0) {
// This is a partial payment.
isPartialPayment = true;
isPartialPaymentEnabled = true;
// Calculate the partial amount.
partialAmount = orderAmount - totalPartiallyPaidAmount;
}
// If this is a partial payment.
if (isPartialPayment) {
// Always set paymentInfo9 to partial amount.
paymentInfo9 = partialAmount;
// If there are any partial payments, check if the total paid amount is equal to the order amount.
if (totalPartiallyPaidAmount > 0) {
isLastPartialPayment = ((totalPartiallyPaidAmount + partialAmount) === orderAmount);
paymentStatus = {
// If the [total partially paid + current partial amount] is equal to the order amount, then the payment status is PAID.
statusId: isLastPartialPayment ? PaymentStatus_1.PaymentStatus.PAID : PaymentStatus_1.PaymentStatus.PENDING,
purchaseAmount: isLastPartialPayment ? orderAmount : amountToBePaid
};
}
else {
paymentStatus = {
statusId: PaymentStatus_1.PaymentStatus.PENDING,
purchaseAmount: amountToBePaid
};
}
}
}
/**************** This block is for partial payments only (ENDS) ****************/
//console.log('paymentStatus', paymentStatus)
orderModel = Object.assign({ id: txnOrderId === null || txnOrderId === void 0 ? void 0 : txnOrderId.split('-')[1], cardNo: null, orderNo: parseInt(txnOrderId === null || txnOrderId === void 0 ? void 0 : txnOrderId.split('-')[0]), orderAmount, paidAmount: !isCancelled ? paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.purchaseAmount : 0, balanceAmount: (paymentType === constants_2.PaymentSelectionType.PARTIAL) ? (orderAmount - partialAmount) : 0, isValid: true, status: !isCancelled ? paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.statusId : PaymentStatus_1.PaymentStatus.DECLINED, authCode: !isCancelled
? ((gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()) === ((_0 = PaymentMethodType_1.PaymentMethodType.PAYPAL) === null || _0 === void 0 ? void 0 : _0.toLowerCase())) ? (_1 = data === null || data === void 0 ? void 0 : data.extras) === null || _1 === void 0 ? void 0 : _1.token : paymentGatewayOrderTxnId
: null, issuerUrl: null, paRequest: null, pspSessionCookie: JSON.stringify(Object.assign({}, rest)), pspResponseCode: null, pspResponseMessage: null, paymentGatewayId: paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.id, paymentGateway: paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.systemName, token: null, payerId: null, cvcResult: null, avsResult: null, secure3DResult: null, cardHolderName: null, issuerCountry: null, info1: '', fraudScore: null, paymentMethod: gateway, cardType: null, operatorId: null, refStoreId: null, tillNumber: null, externalRefNo: null, expiryYear: null, expiryMonth: null, isMoto: false, upFrontPayment: false, upFrontAmount: '0.00', isPrePaid: !isCOD, isPartialPaymentEnabled, discountedTotal: (_2 = bankOfferDetails === null || bankOfferDetails === void 0 ? void 0 : bankOfferDetails.discountedTotal) !== null && _2 !== void 0 ? _2 : 0, externalPromoCode: (_3 = bankOfferDetails === null || bankOfferDetails === void 0 ? void 0 : bankOfferDetails.voucherCode) !== null && _3 !== void 0 ? _3 : null, externalVoucher: (bankOfferDetails === null || bankOfferDetails === void 0 ? void 0 : bankOfferDetails.voucherCode)
? {
code: bankOfferDetails === null || bankOfferDetails === void 0 ? void 0 : bankOfferDetails.offerCode,
additionalInfo1: bankOfferDetails === null || bankOfferDetails === void 0 ? void 0 : bankOfferDetails.value,
additionalInfo2: bankOfferDetails === null || bankOfferDetails === void 0 ? void 0 : bankOfferDetails.status,
}
: null }, Object.assign(Object.assign({}, getPaymentInfoPayload((_4 = data === null || data === void 0 ? void 0 : data.extras) === null || _4 === void 0 ? void 0 : _4.paymentInfo)), { paymentInfo9 }));
}
if (orderModel) {
const paymentResponseInput = {
model: orderModel,
orderId: orderId,
};
console.log('---- paymentResponseInput ----', JSON.stringify(paymentResponseInput));
await Logger_1.Logger.logPayment({ data: orderModel, message: `${gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()} | UpdatePaymentResponse API20 Request` }, { headers: {}, cookies: {} });
const { result: paymentResponseResult } = await Checkout_1.Checkout.updatePaymentResponse(paymentResponseInput, { cookies: (_5 = data === null || data === void 0 ? void 0 : data.extras) === null || _5 === void 0 ? void 0 : _5.cookies });
if (paymentResponseResult) {
await Logger_1.Logger.logPayment({ data: paymentResponseResult, message: `${gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()} | UpdatePaymentResponse API20 Response` }, { headers: {}, cookies: {} });
// Get order details
const { result: orderResultPostPaymentResponse } = await Order_1.Order.get(orderId, { cookies: (_6 = data === null || data === void 0 ? void 0 : data.extras) === null || _6 === void 0 ? void 0 : _6.cookies });
console.log("---- orderResultPostPaymentResponse ----", orderResultPostPaymentResponse);
return isCancelled
? PaymentStatus_1.PaymentStatus.DECLINED
: (((paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.statusId) === PaymentStatus_1.PaymentStatus.PAID || (paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.statusId) === PaymentStatus_1.PaymentStatus.AUTHORIZED) || ((orderResultPostPaymentResponse === null || orderResultPostPaymentResponse === void 0 ? void 0 : orderResultPostPaymentResponse.id) && (orderResultPostPaymentResponse === null || orderResultPostPaymentResponse === void 0 ? void 0 : orderResultPostPaymentResponse.orderStatusCode) === OrderStatus_1.OrderStatus.APPROVED))
? PaymentStatus_1.PaymentStatus.PAID
: PaymentStatus_1.PaymentStatus.PENDING;
/*return isCancelled
? PaymentStatus.DECLINED
: ((gateway?.toLowerCase() === PaymentMethodType.PAYPAL?.toLowerCase() && paymentStatus?.statusId === PaymentStatus.PAID) || (orderResultPostPaymentResponse?.id && orderResultPostPaymentResponse?.orderStatusCode === OrderStatus.APPROVED))
? PaymentStatus.PAID
: PaymentStatus.PENDING;*/
}
}
}
}
}
}
catch (error) {
await Logger_1.Logger.logPayment(error, { headers: {}, cookies: {} });
return { hasError: true, error: error };
}
return null;
}
/**
* Process the payment hook.
* @param {IPaymentHookProcessingData} data The payment hook processing data.
* @returns {Promise<any>} The promise of the processed payment hook result.
*/
async processPaymentHook(data) {
var _a, _b, _c, _d, _e, _f, _g;
try {
let paymentNo, orderNo;
let paymentGatewayOrderTxnId = constants_1.Defaults.String.Value;
const { paymentMethodTypeId, paymentMethodType, data: hookData } = data;
// Read transaction type from the incoming hook data.
const paymentTransactionStatus = (0, payment_util_1.getPaymentTransactionStatus)(paymentMethodTypeId, hookData);
console.log('--- paymentTransactionStatus ---', paymentTransactionStatus);
// If web hook transaction is applicable for further processing.
if (paymentTransactionStatus.toLowerCase() !== constants_1.PaymentTransactionStatus.NONE) {
let orderId;
if (paymentMethodTypeId === constants_2.PaymentMethodTypeId.PAYPAL) {
const details = await (0, payment_util_1.getPaymentTransactionOrderId)(paymentMethodTypeId, hookData);
console.log('--- details ---', details);
if (details) {
orderId = details === null || details === void 0 ? void 0 : details.split(',')[0];
const paymentNoDetails = details === null || details === void 0 ? void 0 : details.split(',')[1];
if (paymentNoDetails && ((_a = paymentNoDetails === null || paymentNoDetails === void 0 ? void 0 : paymentNoDetails.split('-')) === null || _a === void 0 ? void 0 : _a.length)) {
orderNo = paymentNoDetails === null || paymentNoDetails === void 0 ? void 0 : paymentNoDetails.split('-')[0];
paymentNo = paymentNoDetails === null || paymentNoDetails === void 0 ? void 0 : paymentNoDetails.split('-')[1];
}
}
}
else {
orderId = await (0, payment_util_1.getPaymentTransactionOrderId)(paymentMethodTypeId, hookData);
}
console.log('--- orderId ---', orderId);
if (orderId != constants_1.Defaults.Guid.Value) {
const { result: orderResult } = await Order_1.Order.get(orderId, { cookies: constants_1.Defaults.Object.Value });
console.log('--- orderResult ---', orderResult);
if ((orderResult === null || orderResult === void 0 ? void 0 : orderResult.id) && (orderResult === null || orderResult === void 0 ? void 0 : orderResult.id) != constants_1.Defaults.Guid.Value) {
if (paymentMethodTypeId === constants_2.PaymentMethodTypeId.CHECKOUT) {
paymentGatewayOrderTxnId = (_b = hookData === null || hookData === void 0 ? void 0 : hookData.data) === null || _b === void 0 ? void 0 : _b.id;
}
else if (paymentMethodTypeId === constants_2.PaymentMethodTypeId.PAYPAL) {
paymentGatewayOrderTxnId = (_e = (_d = (_c = hookData === null || hookData === void 0 ? void 0 : hookData.resource) === null || _c === void 0 ? void 0 : _c.supplementary_data) === null || _d === void 0 ? void 0 : _d.related_ids) === null || _e === void 0 ? void 0 : _e.order_id;
}
console.log('--- paymentGatewayOrderTxnId ---', paymentGatewayOrderTxnId);
const payments = orderResult === null || orderResult === void 0 ? void 0 : orderResult.payments;
if (payments === null || payments === void 0 ? void 0 : payments.length) {
// Call gateway specific SDK API to get the order/payment status.
const paymentStatus = await this.getPaymentStatus(paymentMethodType, paymentGatewayOrderTxnId, true);
console.log('--- paymentStatus ---', paymentStatus);
if (paymentMethodTypeId !== constants_2.PaymentMethodTypeId.PAYPAL) {
paymentNo = (0, payment_util_1.getPaymentNo)(paymentMethodTypeId, paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.orderDetails);
}
console.log('--- paymentNo ---', paymentNo);
const dbOrderAmount = ((_g = (_f = orderResult === null || orderResult === void 0 ? void 0 : orderResult.grandTotal) === null || _f === void 0 ? void 0 : _f.raw) === null || _g === void 0 ? void 0 : _g.withTax) || 0;
// Get all partial payments for this order.
const orderPayments = (payments === null || payments === void 0 ? void 0 : payments.filter((x) => (x === null || x === void 0 ? void 0 : x.isPartialPaymentEnabled) && (x === null || x === void 0 ? void 0 : x.orderAmount) == dbOrderAmount)) || [];
// Calculate the total partially paid amount for this order.
const totalPartiallyPaidAmount = (orderPayments === null || orderPayments === void 0 ? void 0 : orderPayments.reduce((sum, x) => sum + x.paidAmount, 0)) || 0;
console.log('totalPartiallyPaidAmount', totalPartiallyPaidAmount);
let isPartialPaymentEnabled = ((paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.paymentType) === constants_2.PaymentSelectionType.PARTIAL);
// If payment type is FULL and there are any partial payments, then it is a last partial payment.
if ((paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.paymentType) === constants_2.PaymentSelectionType.FULL && totalPartiallyPaidAmount > 0) {
// This is a partial payment.
isPartialPaymentEnabled = true;
}
if (paymentTransactionStatus.toLowerCase() === constants_1.PaymentTransactionStatus.ORDER_REFUNDED.toLowerCase()) {
// Order Refunded
}
else {
const processTxn = (paymentTransactionStatus.toLowerCase() === constants_1.PaymentTransactionStatus.TXN_CHARGED.toLowerCase() || paymentTransactionStatus.toLowerCase() === constants_1.PaymentTransactionStatus.TXN_FAILED.toLowerCase());
let statusId = PaymentStatus_1.PaymentStatus.DECLINED;
const payment = payments === null || payments === void 0 ? void 0 : payments.find((x) => (x === null || x === void 0 ? void 0 : x.id) == paymentNo && (x === null || x === void 0 ? void 0 : x.status) == PaymentStatus_1.PaymentStatus.PENDING);
console.log('--- payment ---', payment);
if (payment && processTxn /*&& paymentStatus?.statusId === PaymentStatus.PENDING*/) {
let result = constants_1.Defaults.Object.Value;
const orderValue = paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.purchaseAmount;
const paymentStatusId = paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.statusId;
if (paymentStatusId === PaymentStatus_1.PaymentStatus.PAID) {
console.log('--- SuccessUpdate ---');
result = await this.paymentHookOrderSuccessUpdate(paymentMethodType, paymentMethodTypeId, orderId, paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.orderDetails, statusId, orderValue, orderResult, { paymentNo, orderNo, hookData, paymentType: paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.paymentType, partialAmount: paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.partialAmount, isPartialPaymentEnabled, totalPartiallyPaidAmount, });
}
else if (paymentStatusId == PaymentStatus_1.PaymentStatus.DECLINED) {
console.log('--- FailureUpdate ---');
result = await this.paymentHookOrderFailureUpdate(paymentMethodType, paymentMethodTypeId, orderId, paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.orderDetails, statusId, orderValue, orderResult, { paymentNo, orderNo, hookData, paymentType: paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.paymentType, partialAmount: paymentStatus === null || paymentStatus === void 0 ? void 0 : paymentStatus.partialAmount, isPartialPaymentEnabled, totalPartiallyPaidAmount, });
}
return result;
}
}
}
}
}
}
}
catch (error) {
await Logger_1.Logger.logPayment(error, { headers: {}, cookies: {} });
return { hasError: true, error: error };
}
return null;
}
/**
* Retrieves the payment status for a given payment gateway and transaction data.
*
* This method interacts with specific payment gateway SDKs to obtain the order or payment status.
* It supports various payment gateways including PayPal, Checkout, Klarna, Stripe, and ClearPay.
* The method determines the payment status based on the gateway-specific response and calculates
* the purchase amount from the order details.
*
* @param gateway - The name of the payment gateway used for the transaction.
* @param data - The transaction data required to fetch the payment status from the gateway.
* @param returnOrderDetails - Flag indicating whether to return order details in the response.
* @returns A promise that resolves to an object containing the status ID, purchase amount, and
* optionally the order details if `returnOrderDetails` is true.
*/
async getPaymentStatus(gateway, data, returnOrderDetails = false) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
let orderDetails = constants_1.Defaults.Object.Value;
let purchaseAmount = 0, paymentType = constants_2.PaymentSelectionType.FULL, partialAmount = 0;
let statusId = PaymentStatus_1.PaymentStatus.PENDING;
switch (gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()) {
case (_a = PaymentMethodType_1.PaymentMethodType.PAYPAL) === null || _a === void 0 ? void 0 : _a.toLowerCase():
// Get PayPal payment details
let paypalOrderDetails = orderDetails = await new PayPalPayment_1.PayPalPayment().getOrderDetails(data);
try {
await Logger_1.Logger.logPayment({ data: paypalOrderDetails, message: `${gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()} | GetPaymentStatus` }, { headers: {}, cookies: {} });
}
catch (error) {
// Bypass error incurred due to logging.
}
// Call get payment status once again if status received is uncaptured.
if (!((paypalOrderDetails === null || paypalOrderDetails === void 0 ? void 0 : paypalOrderDetails.status) === PaymentStatus_2.PayPal.PaymentStatus.COMPLETED || (paypalOrderDetails === null || paypalOrderDetails === void 0 ? void 0 : paypalOrderDetails.status) === PaymentStatus_2.PayPal.PaymentStatus.APPROVED || (paypalOrderDetails === null || paypalOrderDetails === void 0 ? void 0 : paypalOrderDetails.status) === PaymentStatus_2.PayPal.PaymentStatus.VOIDED)) {
paypalOrderDetails = orderDetails = await new PayPalPayment_1.PayPalPayment().getOrderDetails(data);
try {
await Logger_1.Logger.logPayment({ data: paypalOrderDetails, message: `${gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()} | GetPaymentStatus` }, { headers: {}, cookies: {} });
}
catch (error) {
// Bypass error incurred due to logging.
}
}
if ((paypalOrderDetails === null || paypalOrderDetails === void 0 ? void 0 : paypalOrderDetails.status) === PaymentStatus_2.PayPal.PaymentStatus.COMPLETED || (paypalOrderDetails === null || paypalOrderDetails === void 0 ? void 0 : paypalOrderDetails.status) === PaymentStatus_2.PayPal.PaymentStatus.APPROVED) {
statusId = PaymentStatus_1.PaymentStatus.PAID;
}
else if ((paypalOrderDetails === null || paypalOrderDetails === void 0 ? void 0 : paypalOrderDetails.status) === PaymentStatus_2.PayPal.PaymentStatus.VOIDED) {
statusId = PaymentStatus_1.PaymentStatus.DECLINED;
}
purchaseAmount = ((_b = paypalOrderDetails === null || paypalOrderDetails === void 0 ? void 0 : paypalOrderDetails.purchase_units) === null || _b === void 0 ? void 0 : _b.length)
? parseFloat(((_d = (_c = paypalOrderDetails === null || paypalOrderDetails === void 0 ? void 0 : paypalOrderDetails.purchase_units[0]) === null || _c === void 0 ? void 0 : _c.amount) === null || _d === void 0 ? void 0 : _d.value.toString()) || constants_1.Defaults.Int.Value.toString())
: constants_1.Defaults.Int.Value;
const customId = ((_e = paypalOrderDetails === null || paypalOrderDetails === void 0 ? void 0 : paypalOrderDetails.purchase_units) === null || _e === void 0 ? void 0 : _e.length)
? (_f = paypalOrderDetails === null || paypalOrderDetails === void 0 ? void 0 : paypalOrderDetails.purchase_units[0]) === null || _f === void 0 ? void 0 : _f.custom_id
: constants_1.Defaults.String.Value;
if (customId) {
const customIdObj = (0, parse_util_1.tryParseJson)(customId);
paymentType = (customIdObj === null || customIdObj === void 0 ? void 0 : customIdObj.paymentType) || constants_2.PaymentSelectionType.FULL;
partialAmount = (customIdObj === null || customIdObj === void 0 ? void 0 : customIdObj.partialAmount) || purchaseAmount;
}
break;
case (_g = PaymentMethodType_1.PaymentMethodType.CHECKOUT) === null || _g === void 0 ? void 0 : _g.toLowerCase():
// Get Checkout payment details
const checkoutOrderDetails = orderDetails = await new CheckoutPayment_1.CheckoutPayment().getOrderDetails(data);
try {
await Logger_1.Logger.logPayment({ data: checkoutOrderDetails, message: `${gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()} | GetPaymentStatus` }, { headers: {}, cookies: {} });
}
catch (error) {
// Bypass error incurred due to logging.
}
if ((checkoutOrderDetails === null || checkoutOrderDetails === void 0 ? void 0 : checkoutOrderDetails.approved) || ((checkoutOrderDetails === null || checkoutOrderDetails === void 0 ? void 0 : checkoutOrderDetails.status) === PaymentStatus_2.Checkout.PaymentStatus.PAID || (checkoutOrderDetails === null || checkoutOrderDetails === void 0 ? void 0 : checkoutOrderDetails.status) === PaymentStatus_2.Checkout.PaymentStatus.CAPTURED)) {
statusId = PaymentStatus_1.PaymentStatus.PAID;
}
else {
if ((checkoutOrderDetails === null || checkoutOrderDetails === void 0 ? void 0 : checkoutOrderDetails.status) === PaymentStatus_2.Checkout.PaymentStatus.DECLINED || (checkoutOrderDetails === null || checkoutOrderDetails === void 0 ? void 0 : checkoutOrderDetails.status) === PaymentStatus_2.Checkout.PaymentStatus.CANCELED || (checkoutOrderDetails === null || checkoutOrderDetails === void 0 ? void 0 : checkoutOrderDetails.status) === PaymentStatus_2.Checkout.PaymentStatus.EXPIRED) {
statusId = PaymentStatus_1.PaymentStatus.DECLINED;
}
}
purchaseAmount = (checkoutOrderDetails === null || checkoutOrderDetails === void 0 ? void 0 : checkoutOrderDetails.amount) / 100.0;
paymentType = ((_h = checkoutOrderDetails === null || checkoutOrderDetails === void 0 ? void 0 : checkoutOrderDetails.metadata) === null || _h === void 0 ? void 0 : _h.paymentType) || constants_2.PaymentSelectionType.FULL;
partialAmount = ((_j = checkoutOrderDetails === null || checkoutOrderDetails === void 0 ? void 0 : checkoutOrderDetails.metadata) === null || _j === void 0 ? void 0 : _j.partialAmount) || purchaseAmount;
break;
case (_k = PaymentMethodType_1.PaymentMethodType.KLARNA) === null || _k === void 0 ? void 0 : _k.toLowerCase():
// Get Klarna payment details
const klarnaOrderDetails = orderDetails = await new KlarnaPayment_1.KlarnaPayment().getOrderDetails(data);
if (((_l = klarnaOrderDetails === null || klarnaOrderDetails === void 0 ? void 0 : klarnaOrderDetails.status) === null || _l === void 0 ? void 0 : _l.toLowerCase()) === ((_m = PaymentStatus_2.Klarna.PaymentStatus.AUTHORIZED) === null || _m === void 0 ? void 0 : _m.toLowerCase()) || ((_o = klarnaOrderDetails === null || klarnaOrderDetails === void 0 ? void 0 : klarnaOrderDetails.status) === null || _o === void 0 ? void 0 : _o.toLowerCase()) === ((_p = PaymentStatus_2.Klarna.PaymentStatus.CAPTURED) === null || _p === void 0 ? void 0 : _p.toLowerCase())) {
statusId = PaymentStatus_1.PaymentStatus.PAID;
}
purchaseAmount = parseFloat(klarnaOrderDetails === null || klarnaOrderDetails === void 0 ? void 0 : klarnaOrderDetails.order_amount.toString()) / 100.0;
const merchantData = (klarnaOrderDetails === null || klarnaOrderDetails === void 0 ? void 0 : klarnaOrderDetails.merchant_data) || constants_1.Defaults.String.Value;
if (merchantData) {
const merchantDataObj = (0, parse_util_1.tryParseJson)(merchantData);
paymentType = (merchantDataObj === null || merchantDataObj === void 0 ? void 0 : merchantDataObj.paymentType) || constants_2.PaymentSelectionType.FULL;
partialAmount = (merchantDataObj === null || merchantDataObj === void 0 ? void 0 : merchantDataObj.partialAmount) || purchaseAmount;
}
break;
case (_q = PaymentMethodType_1.PaymentMethodType.STRIPE) === null || _q === void 0 ? void 0 : _q.toLowerCase():
// Get Stripe payment details
const stripeOrderDetails = orderDetails = await new StripePayment_1.StripePayment().getOrderDetails(data);
if (((_r = stripeOrderDetails === null || stripeOrderDetails === void 0 ? void 0 : stripeOrderDetails.status) === null || _r === void 0 ? void 0 : _r.toLowerCase()) === ((_s = PaymentStatus_2.Stripe.PaymentStatus.SUCCEEDED) === null || _s === void 0 ? void 0 : _s.toLowerCase())) {
statusId = PaymentStatus_1.PaymentStatus.PAID;
}
purchaseAmount = parseFloat(stripeOrderDetails === null || stripeOrderDetails === void 0 ? void 0 : stripeOrderDetails.amount_received.toString()) / 100.0;
paymentType = ((_t = stripeOrderDetails === null || stripeOrderDetails === void 0 ? void 0 : stripeOrderDetails.metadata) === null || _t === void 0 ? void 0 : _t.paymentType) || constants_2.PaymentSelectionType.FULL;
partialAmount = parseFloat(((_v = (_u = stripeOrderDetails === null || stripeOrderDetails === void 0 ? void 0 : stripeOrderDetails.metadata) === null || _u === void 0 ? void 0 : _u.partialAmount) === null || _v === void 0 ? void 0 : _v.toString()) || "0") || purchaseAmount;
break;
case (_w = PaymentMethodType_1.PaymentMethodType.CLEAR_PAY) === null || _w === void 0 ? void 0 : _w.toLowerCase():
// Get ClearPay payment details
const clearPayOrderDetails = orderDetails = await new ClearPayPament_1.ClearPayPayment().getOrderDetails(data);
try {
await Logger_1.Logger.logPayment({ data: clearPayOrderDetails, message: `${gateway === null || gateway === void 0 ? void 0 : gateway.toLowerCase()} | GetPaymentStatus` }, { headers: {}, cookies: {} });
}
catch (error) {
// Bypass error incurred due to logging.
}
if (((_x = clearPayOrderDetails === null || clearPayOrderDetails === void 0 ? void 0 : clearPayOrderDetails.status) === null || _x === void 0 ? void 0 : _x.toLowerCase()) === ((_y = PaymentStatus_2.ClearPay.PaymentStatus.APPROVED) === null || _y === void 0 ? void 0 : _y.toLowerCase())) {
statusId = PaymentStatus_1.PaymentStatus.PAID;
}
else {
statusId = PaymentStatus_1.PaymentStatus.DECLINED;
}
purchaseAmount = parseFloat((_0 = (_z = clearPayOrderDetails === null || clearPayOrderDetails === void 0 ? void 0 : clearPayOrderDetails.originalAmount) === null || _z === void 0 ? void 0 : _z.amount) === null || _0 === void 0 ? void 0 : _0.toString());
const merchantReference = clearPayOrderDetails === null || clearPayOrderDetails === void 0 ? void 0 : clearPayOrderDetails.merchantReference;
if (merchantReference) {
const merchantReferenceObj = (0, parse_util_1.tryParseJson)(merchantReference);
paymentType = (merchantReferenceObj === null || merchantReferenceObj === void 0 ? v