From 0c6a0dd6e22d3c92d17c0f9f3337fb381117ae6a Mon Sep 17 00:00:00 2001 From: shij Date: Thu, 26 Sep 2024 17:39:10 +0800 Subject: [PATCH] feat: add payment authorization workflow --- .../src/cart/workflows/complete-cart.ts | 3 +- .../mark-payment-collection-as-paid.ts | 7 +- .../steps/authorize-payment-session.ts | 48 ++++++++++ .../src/payment-collection/steps/index.ts | 1 + .../workflows/authorize-payment-session.ts | 19 ++++ .../workflows/cancel-payment-session.ts | 2 +- .../steps/authorize-payment-session.ts | 89 ------------------- .../core-flows/src/payment/steps/index.ts | 1 - 8 files changed, 73 insertions(+), 97 deletions(-) create mode 100644 packages/core/core-flows/src/payment-collection/steps/authorize-payment-session.ts create mode 100644 packages/core/core-flows/src/payment-collection/workflows/authorize-payment-session.ts delete mode 100644 packages/core/core-flows/src/payment/steps/authorize-payment-session.ts diff --git a/packages/core/core-flows/src/cart/workflows/complete-cart.ts b/packages/core/core-flows/src/cart/workflows/complete-cart.ts index c5f8b016333d3..d7c95d15fc251 100644 --- a/packages/core/core-flows/src/cart/workflows/complete-cart.ts +++ b/packages/core/core-flows/src/cart/workflows/complete-cart.ts @@ -17,7 +17,7 @@ import { useRemoteQueryStep, } from "../../common" import { createOrdersStep } from "../../order/steps/create-orders" -import { authorizePaymentSessionStep } from "../../payment/steps/authorize-payment-session" +import { authorizePaymentSessionStep } from "../../payment-collection" import { registerUsageStep } from "../../promotion/steps/register-usage" import { updateCartsStep, validateCartPaymentsStep } from "../steps" import { reserveInventoryStep } from "../steps/reserve-inventory" @@ -58,7 +58,6 @@ export const completeCartWorkflow = createWorkflow( // We choose the first payment session, as there will only be one active payment session // This might change in the future. id: paymentSessions[0].id, - context: { cart_id: cart.id }, }) const { variants, items, sales_channel_id } = transform( diff --git a/packages/core/core-flows/src/order/workflows/mark-payment-collection-as-paid.ts b/packages/core/core-flows/src/order/workflows/mark-payment-collection-as-paid.ts index 36aa96ceec93f..d7ab363cd27e1 100644 --- a/packages/core/core-flows/src/order/workflows/mark-payment-collection-as-paid.ts +++ b/packages/core/core-flows/src/order/workflows/mark-payment-collection-as-paid.ts @@ -7,11 +7,11 @@ import { createWorkflow, } from "@medusajs/workflows-sdk" import { useRemoteQueryStep } from "../../common" +import { capturePaymentWorkflow } from "../../payment" import { authorizePaymentSessionStep, - capturePaymentWorkflow, -} from "../../payment" -import { createPaymentSessionsWorkflow } from "../../payment-collection" + createPaymentSessionsWorkflow, +} from "../../payment-collection" /** * This step validates that the payment collection is not_paid @@ -63,7 +63,6 @@ export const markPaymentCollectionAsPaid = createWorkflow( const payment = authorizePaymentSessionStep({ id: paymentSession.id, - context: { order_id: input.order_id }, }) capturePaymentWorkflow.runAsStep({ diff --git a/packages/core/core-flows/src/payment-collection/steps/authorize-payment-session.ts b/packages/core/core-flows/src/payment-collection/steps/authorize-payment-session.ts new file mode 100644 index 0000000000000..303f6f1f7eaa3 --- /dev/null +++ b/packages/core/core-flows/src/payment-collection/steps/authorize-payment-session.ts @@ -0,0 +1,48 @@ +import { IPaymentModuleService, Logger } from "@medusajs/types" +import { + ContainerRegistrationKeys, + ModuleRegistrationName, + PaymentSessionStatus, +} from "@medusajs/utils" +import { StepResponse, createStep } from "@medusajs/workflows-sdk" + +export type AuthorizePaymentSessionStepInput = { + id: string + provider_token?: string +} + +export const authorizePaymentSessionStepId = "authorize-payment-session-step" +/** + * This step authorizes a payment session. + */ +export const authorizePaymentSessionStep = createStep( + authorizePaymentSessionStepId, + async (input: AuthorizePaymentSessionStepInput, { container }) => { + const paymentModule = container.resolve( + ModuleRegistrationName.PAYMENT + ) + const payment = await paymentModule.authorizePaymentSession(input.id, { + provider_token: input.provider_token, + }) + return new StepResponse(payment) + }, + // If payment or any other part of complete cart fails post payment step, we cancel any payments made + async (payment, { container }) => { + if (!payment) { + return + } + + const logger = container.resolve(ContainerRegistrationKeys.LOGGER) + const paymentModule = container.resolve( + ModuleRegistrationName.PAYMENT + ) + + try { + await paymentModule.cancelPayment(payment.id) + } catch (e) { + logger.error( + `Error was thrown trying to cancel payment - ${payment.id} - ${e}` + ) + } + } +) diff --git a/packages/core/core-flows/src/payment-collection/steps/index.ts b/packages/core/core-flows/src/payment-collection/steps/index.ts index 28c08dcb37f45..2e2bd37ce0dbe 100644 --- a/packages/core/core-flows/src/payment-collection/steps/index.ts +++ b/packages/core/core-flows/src/payment-collection/steps/index.ts @@ -6,3 +6,4 @@ export * from "./update-payment-collection" export * from "./update-refund-reasons" export * from "./validate-deleted-payment-sessions" export * from "./cancel-payment-session" +export * from "./authorize-payment-session" diff --git a/packages/core/core-flows/src/payment-collection/workflows/authorize-payment-session.ts b/packages/core/core-flows/src/payment-collection/workflows/authorize-payment-session.ts new file mode 100644 index 0000000000000..ebbbf93b2cda4 --- /dev/null +++ b/packages/core/core-flows/src/payment-collection/workflows/authorize-payment-session.ts @@ -0,0 +1,19 @@ +import { + WorkflowData, + WorkflowResponse, + createWorkflow, +} from "@medusajs/workflows-sdk" +import { authorizePaymentSessionStep } from "../steps" + +export const authorizePaymentSessionWorkflowId = + "authorize-payment-session-workflow" + +/** + * This workflow authorizes a payment session. + */ +export const authorizePaymentSessionWorkflow = createWorkflow( + authorizePaymentSessionWorkflowId, + (input: WorkflowData<{ id: string; provider_token?: string }>) => { + return new WorkflowResponse(authorizePaymentSessionStep(input)) + } +) diff --git a/packages/core/core-flows/src/payment-collection/workflows/cancel-payment-session.ts b/packages/core/core-flows/src/payment-collection/workflows/cancel-payment-session.ts index c35c761c18ca5..ebb37395a2ff0 100644 --- a/packages/core/core-flows/src/payment-collection/workflows/cancel-payment-session.ts +++ b/packages/core/core-flows/src/payment-collection/workflows/cancel-payment-session.ts @@ -3,7 +3,7 @@ import { WorkflowResponse, createWorkflow, } from "@medusajs/workflows-sdk" -import { cancelPaymentSessionStep } from "../steps/cancel-payment-session" +import { cancelPaymentSessionStep } from "../steps" export const cancelPaymentSessionWorkflowId = "cancel-payment-session-workflow" diff --git a/packages/core/core-flows/src/payment/steps/authorize-payment-session.ts b/packages/core/core-flows/src/payment/steps/authorize-payment-session.ts deleted file mode 100644 index 330c9c52fadc5..0000000000000 --- a/packages/core/core-flows/src/payment/steps/authorize-payment-session.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { IPaymentModuleService, Logger, PaymentDTO } from "@medusajs/types" -import { - ContainerRegistrationKeys, - MedusaError, - ModuleRegistrationName, - PaymentSessionStatus, -} from "@medusajs/utils" -import { StepResponse, createStep } from "@medusajs/workflows-sdk" - -export type AuthorizePaymentSessionStepInput = { - id: string - context: Record -} - -export const authorizePaymentSessionStepId = "authorize-payment-session-step" -/** - * This step authorizes a payment session. - */ -export const authorizePaymentSessionStep = createStep( - authorizePaymentSessionStepId, - async (input: AuthorizePaymentSessionStepInput, { container }) => { - let payment: PaymentDTO | undefined - const logger = container.resolve(ContainerRegistrationKeys.LOGGER) - const paymentModule = container.resolve( - ModuleRegistrationName.PAYMENT - ) - - try { - payment = await paymentModule.authorizePaymentSession( - input.id, - input.context || {} - ) - } catch (e) { - logger.error( - `Error was thrown trying to authorize payment session - ${input.id} - ${e}` - ) - } - - const paymentSession = await paymentModule.retrievePaymentSession(input.id) - - // Throw a special error type when the status is requires_more as it requires a specific further action - // from the consumer - if (paymentSession.status === PaymentSessionStatus.REQUIRES_MORE) { - throw new MedusaError( - MedusaError.Types.PAYMENT_REQUIRES_MORE_ERROR, - `More information is required for payment` - ) - } - - // If any other error other than requires_more shows up, this usually requires the consumer to create a new payment session - // This could also be a system error thats caused by invalid setup or a failure in connecting to external providers - if (paymentSession.status !== PaymentSessionStatus.AUTHORIZED || !payment) { - throw new MedusaError( - MedusaError.Types.PAYMENT_AUTHORIZATION_ERROR, - `Payment authorization failed` - ) - } - - return new StepResponse(payment) - }, - // If payment or any other part of complete cart fails post payment step, we cancel any payments made - async (payment, { container }) => { - if (!payment) { - return - } - - const logger = container.resolve(ContainerRegistrationKeys.LOGGER) - const paymentModule = container.resolve( - ModuleRegistrationName.PAYMENT - ) - - // If the payment session status is requires_more, we don't have to revert the payment. - // Return the same status for the cart completion to be re-run. - if ( - payment.payment_session && - payment.payment_session.status === PaymentSessionStatus.REQUIRES_MORE - ) { - return - } - - try { - await paymentModule.cancelPayment(payment.id) - } catch (e) { - logger.error( - `Error was thrown trying to cancel payment - ${payment.id} - ${e}` - ) - } - } -) diff --git a/packages/core/core-flows/src/payment/steps/index.ts b/packages/core/core-flows/src/payment/steps/index.ts index af0294b7892c0..6a6e956966464 100644 --- a/packages/core/core-flows/src/payment/steps/index.ts +++ b/packages/core/core-flows/src/payment/steps/index.ts @@ -1,4 +1,3 @@ -export * from "./authorize-payment-session" export * from "./cancel-payment" export * from "./capture-payment" export * from "./refund-payment"