UNPKG

medusa-payment-comgate-jc

Version:
464 lines (404 loc) 12.4 kB
import ComgateClient from "comgate-node"; import { EOL } from "os"; import { AbstractPaymentProcessor, CartService, isPaymentProcessorError, PaymentProcessorContext, PaymentProcessorError, PaymentSessionStatus, } from "@medusajs/medusa"; import { ComgatePaymentOptions, ComgatePaymentProcessorSessionResponse, ComgateSessionData, PaymentProviderKeys, } from "../types"; import { StatusResponseStatus } from "comgate-node/dist/types/endpoints/status"; abstract class ComgateBase extends AbstractPaymentProcessor { static identifier = PaymentProviderKeys.COMGATE_CARD; protected readonly options_: ComgatePaymentOptions; public comgateClient: ComgateClient; protected readonly cartService: CartService; protected constructor(_, options) { super(_, options); this.options_ = options; this.init(); this.cartService = _.cartService; } protected init(): void { this.comgateClient = this.comgateClient || new ComgateClient({ merchant: this.options_.merchant, secret: this.options_.secret, test: this.options_.test, }); } async getPaymentStatus( paymentSessionData: ComgateSessionData ): Promise<PaymentSessionStatus> { if (this.options_.debug) { console.log("ComgateMedusa: " + "getPaymentStatus", "start"); } const transId = paymentSessionData.comgateData.transId as string; if (this.options_.debug) { console.log("ComgateMedusa: " + "getPaymentStatus", "data: ", { transId: transId, }); } try { const transactionStatus = await this.getComgateTransactionStatus(transId); if (this.options_.debug) { console.log("ComgateMedusa: " + "getPaymentStatus", "response: ", { transId: transactionStatus, }); } return transactionStatus.status; } catch (error) { if (this.options_.debug) { console.log("ComgateMedusa: " + "getPaymentStatus", "error: ", error); } return PaymentSessionStatus.ERROR; } } async initiatePayment( context: PaymentProcessorContext ): Promise<PaymentProcessorError | ComgatePaymentProcessorSessionResponse> { if (this.options_.debug) { console.log("ComgateMedusa: " + "initiatePayment", "start"); } const session_data: ComgateSessionData = { status: PaymentSessionStatus.PENDING, comgateData: { transId: null, status: "INITIATED", redirect: null, error: null, }, }; if (this.options_.debug) { console.log( "ComgateMedusa: " + "initiatePayment", "session_data: ", session_data ); } return { session_data: session_data, }; } async authorizePayment( paymentSessionData: ComgateSessionData, context?: Record<string, unknown> ): Promise< | PaymentProcessorError | { status: PaymentSessionStatus; data: ComgatePaymentProcessorSessionResponse["session_data"]; } > { if (this.options_.debug) { console.log("ComgateMedusa: " + "authorizePayment", "start"); } const transId = paymentSessionData.comgateData.transId as string; if (this.options_.debug) { console.log("ComgateMedusa: " + "authorizePayment", "transId: ", transId); } const transactionStatus = await this.getComgateTransactionStatus(transId); if (this.options_.debug) { console.log( "ComgateMedusa: " + "authorizePayment", "response: ", transactionStatus ); } const sessionData = { status: transactionStatus.status, data: { status: transactionStatus.status, comgateData: { transId: paymentSessionData.comgateData.transId, status: transactionStatus.comgateStatus, redirect: paymentSessionData.comgateData.redirect, error: transactionStatus.comgateError, }, }, }; if (this.options_.debug) { console.log( "ComgateMedusa: " + "authorizePayment", "sessionData: ", sessionData ); } return sessionData; } async cancelPayment( paymentSessionData: ComgateSessionData ): Promise< | PaymentProcessorError | ComgatePaymentProcessorSessionResponse["session_data"] > { if (this.options_.debug) { console.log("ComgateMedusa: " + "cancelPayment", "start"); } const transId = paymentSessionData.comgateData.transId as string; if (this.options_.debug) { console.log("ComgateMedusa: " + "cancelPayment", "transId: ", transId); } try { const { code, message } = await this.comgateClient.cancel({ transId: transId, }); if (this.options_.debug) { console.log( "ComgateMedusa: " + "cancelPayment", "response: ", code, message ); } if (code === 0) { return { status: PaymentSessionStatus.CANCELED, comgateData: { transId: paymentSessionData.comgateData.transId, status: "CANCELLED", redirect: paymentSessionData.comgateData.redirect, error: null, }, }; } else if (code === 1400) { const error: PaymentProcessorError = { error: message, code: String(code), }; return error; } else { const error: PaymentProcessorError = { error: message, code: String(code), }; return error; } } catch (error: any) { return this.buildError("An error occurred in cancelPayment", error); } } async capturePayment( paymentSessionData: ComgateSessionData ): Promise< | PaymentProcessorError | ComgatePaymentProcessorSessionResponse["session_data"] > { if (this.options_.debug) { console.log("ComgateMedusa: " + "capturePayment", "start"); } return paymentSessionData; } async deletePayment( paymentSessionData: ComgateSessionData ): Promise< | PaymentProcessorError | ComgatePaymentProcessorSessionResponse["session_data"] > { if (this.options_.debug) { console.log("ComgateMedusa: " + "deletePayment", "start"); } return await this.cancelPayment(paymentSessionData); } async refundPayment( paymentSessionData: ComgateSessionData, refundAmount: number ): Promise< | PaymentProcessorError | ComgatePaymentProcessorSessionResponse["session_data"] > { if (this.options_.debug) { console.log("ComgateMedusa: " + "refundPayment", "start"); } const transId = paymentSessionData.comgateData.transId as string; if (this.options_.debug) { console.log("ComgateMedusa: " + "refundPayment", "transId: ", transId); console.log( "ComgateMedusa: " + "refundPayment", "amount: ", String(refundAmount) ); } try { const refundPayment = await this.comgateClient.refund({ transId: transId, amount: String(refundAmount), }); if (this.options_.debug) { console.log( "ComgateMedusa: " + "refundPayment", "response: ", refundPayment ); } if (refundPayment.code !== 0) { const error: PaymentProcessorError = { error: String(refundPayment.message), code: String(refundPayment.code), }; return this.buildError("Failed to refund payment", error); } return { status: paymentSessionData.status, comgateData: { transId: paymentSessionData.comgateData.transId, status: paymentSessionData.comgateData.status, redirect: paymentSessionData.comgateData.redirect, error: null, }, }; } catch (error: any) { return this.buildError("Failed to refund payment", error); } } async retrievePayment( paymentSessionData: ComgateSessionData ): Promise< | PaymentProcessorError | ComgatePaymentProcessorSessionResponse["session_data"] > { if (this.options_.debug) { console.log("ComgateMedusa: " + "retrievePayment", "start"); } const transId = paymentSessionData.comgateData.transId as string; if (this.options_.debug) { console.log("ComgateMedusa: " + "retrievePayment", "transId: ", transId); } try { const transactionStatus = await this.getComgateTransactionStatus(transId); if (this.options_.debug) { console.log( "ComgateMedusa: " + "retrievePayment", "response: ", transactionStatus ); } return { status: transactionStatus.status, comgateData: { transId: paymentSessionData.comgateData.transId, status: transactionStatus.comgateStatus, redirect: paymentSessionData.comgateData.redirect, error: transactionStatus.comgateError, }, }; } catch (error: any) { return this.buildError("Failed to retrieve payment", error); } } async updatePayment( context: PaymentProcessorContext ): Promise< PaymentProcessorError | ComgatePaymentProcessorSessionResponse | void > { if (this.options_.debug) { console.log("ComgateMedusa: " + "updatePayment", "start"); } // const { amount, customer } = context; const paymentSessionData = context.paymentSessionData as ComgateSessionData; // const transId = paymentSessionData.comgateData.transId as string; if (this.options_.debug) { console.log( "ComgateMedusa: " + "updatePayment", "paymentSessionData: ", paymentSessionData ); } return { session_data: paymentSessionData, }; } async updatePaymentData( sessionId: string, data: ComgateSessionData ): Promise< | ComgatePaymentProcessorSessionResponse["session_data"] | PaymentProcessorError > { if (this.options_.debug) { console.log("ComgateMedusa: " + "updatePaymentData", "start"); console.log("ComgateMedusa: " + "updatePaymentData", "data: ", data); } return data; } protected buildError( message: string, e: PaymentProcessorError | Error ): PaymentProcessorError { return { error: message, code: "code" in e ? e.code : "", detail: isPaymentProcessorError(e) ? `${e.error}${EOL}${e.detail ?? ""}` : "detail" in e ? e.detail : e.message ?? "", }; } private async getComgateTransactionStatus(transId: string): Promise<{ status: PaymentSessionStatus; comgateStatus: StatusResponseStatus | "ERROR"; comgateError: PaymentProcessorError | null; }> { let status: PaymentSessionStatus; let comgateStatus: StatusResponseStatus | "ERROR"; let comgateError: PaymentProcessorError | null = null; try { const paymentStatus = await this.comgateClient.status({ transId, }); if (paymentStatus.code !== "0") { status = PaymentSessionStatus.ERROR; comgateStatus = "ERROR"; const error: PaymentProcessorError = { error: paymentStatus.message, code: String(paymentStatus.code), detail: paymentStatus.message, }; comgateError = this.buildError( "Error Comgate API payment status Response", error ); } else { switch (paymentStatus.status.toUpperCase()) { case "PENDING": status = PaymentSessionStatus.AUTHORIZED; break; case "PAID": status = PaymentSessionStatus.AUTHORIZED; break; case "AUTHORIZED": status = PaymentSessionStatus.AUTHORIZED; break; case "CANCELLED": status = PaymentSessionStatus.CANCELED; break; default: status = PaymentSessionStatus.PENDING; } comgateStatus = paymentStatus.status; } } catch (error) { status = PaymentSessionStatus.ERROR; comgateStatus = "ERROR"; comgateError = this.buildError( "Error in calling Comgate API payment status", error ); } return { status: status, comgateStatus: comgateStatus, comgateError: comgateError, }; } } export default ComgateBase;