From 5fe41c4edd22da0b4e472215d8fc7314dc807524 Mon Sep 17 00:00:00 2001 From: shij Date: Tue, 16 Jul 2024 14:06:04 +0000 Subject: [PATCH] tmp --- .../workflows/create-payment-session.ts | 17 +++++++++----- packages/core/js-sdk/src/store/index.ts | 16 ++++++++++++++ packages/core/types/src/payment/provider.ts | 22 ++++++++++++++++++- .../medusa/src/api/store/orders/[id]/route.ts | 15 +++++++------ .../[id]/payment-sessions/route.ts | 5 +++-- .../store/payment-collections/validators.ts | 1 + .../payment/src/services/payment-module.ts | 9 ++++++++ .../payment-stripe/src/core/stripe-base.ts | 15 +++++++++++-- 8 files changed, 82 insertions(+), 18 deletions(-) diff --git a/packages/core/core-flows/src/payment-collection/workflows/create-payment-session.ts b/packages/core/core-flows/src/payment-collection/workflows/create-payment-session.ts index f2176f40d87a8..1e360770e3e1b 100644 --- a/packages/core/core-flows/src/payment-collection/workflows/create-payment-session.ts +++ b/packages/core/core-flows/src/payment-collection/workflows/create-payment-session.ts @@ -1,4 +1,5 @@ import { PaymentProviderContext, PaymentSessionDTO } from "@medusajs/types" +import { PaymentSessionStatus } from "@medusajs/utils" import { WorkflowData, createWorkflow, @@ -14,6 +15,7 @@ interface WorkflowInput { provider_id: string data?: Record context?: PaymentProviderContext + amount?: number } export const createPaymentSessionsWorkflowId = "create-payment-sessions" @@ -35,7 +37,11 @@ export const createPaymentSessionsWorkflow = createWorkflow( provider_id: data.input.provider_id, data: data.input.data, context: data.input.context, - amount: data.paymentCollection.amount, + amount: + data.input.amount || + data.paymentCollection.amount - + data.paymentCollection.authorized_amount + + data.paymentCollection.refunded_amount, currency_code: data.paymentCollection.currency_code, } } @@ -46,15 +52,14 @@ export const createPaymentSessionsWorkflow = createWorkflow( (data) => { return { ids: - data.paymentCollection?.payment_sessions?.map((ps) => ps.id) || [], + data.paymentCollection?.payment_sessions + ?.filter((ps) => ps.status !== PaymentSessionStatus.AUTHORIZED) + ?.map((ps) => ps.id) || [], } } ) - // Note: We are deleting an existing active session before creating a new one - // for a payment collection as we don't support split payments at the moment. - // When we are ready to accept split payments, this along with other workflows - // need to be handled correctly + // Note: We are deleting all existing non-authorized session before creating a new one const [created] = parallelize( createPaymentSessionStep(paymentSessionInput), deletePaymentSessionsWorkflow.runAsStep({ diff --git a/packages/core/js-sdk/src/store/index.ts b/packages/core/js-sdk/src/store/index.ts index 78ec553880892..cc460fa06a059 100644 --- a/packages/core/js-sdk/src/store/index.ts +++ b/packages/core/js-sdk/src/store/index.ts @@ -313,6 +313,22 @@ export class Store { query, }) }, + + addPaymentSession: async ( + paymentCollectionId: string, + body: Record, + query?: SelectParams, + headers?: ClientHeaders + ) => { + return this.client.fetch<{ + payment_collection: HttpTypes.StorePaymentCollection + }>(`/store/payment-collections/${paymentCollectionId}/payment-sessions`, { + method: "POST", + headers, + body, + query, + }) + }, } public order = { diff --git a/packages/core/types/src/payment/provider.ts b/packages/core/types/src/payment/provider.ts index 9d17846cb28ec..c0e6c468beebf 100644 --- a/packages/core/types/src/payment/provider.ts +++ b/packages/core/types/src/payment/provider.ts @@ -40,10 +40,20 @@ export type PaymentProviderContext = { email?: string /** - * The ID of payment session the provider payment is associated with. + * The associated payment session's ID. */ session_id?: string + /** + * The associated cart's ID. + */ + cart_id?: string + + /** + * The associated order's ID. + */ + order_id?: string + /** * The customer associated with this payment. */ @@ -184,6 +194,16 @@ export type WebhookActionData = { */ session_id: string + /** + * The associated cart's ID. + */ + cart_id: string + + /** + * The associated order's ID. + */ + order_id: string + /** * The amount to be captured or authorized (based on the action's type.) */ diff --git a/packages/medusa/src/api/store/orders/[id]/route.ts b/packages/medusa/src/api/store/orders/[id]/route.ts index 217e87cbea7f9..a4eab69080ad6 100644 --- a/packages/medusa/src/api/store/orders/[id]/route.ts +++ b/packages/medusa/src/api/store/orders/[id]/route.ts @@ -1,5 +1,5 @@ +import { getOrderDetailWorkflow } from "@medusajs/core-flows" import { MedusaRequest, MedusaResponse } from "../../../../types/routing" -import { refetchOrder } from "../helpers" import { StoreGetOrdersParamsType } from "../validators" // TODO: Do we want to apply some sort of authentication here? My suggestion is that we do @@ -7,11 +7,12 @@ export const GET = async ( req: MedusaRequest, res: MedusaResponse ) => { - const order = await refetchOrder( - req.params.id, - req.scope, - req.remoteQueryConfig.fields - ) + const { result } = await getOrderDetailWorkflow(req.scope).run({ + input: { + fields: req.remoteQueryConfig.fields, + order_id: req.params.id, + }, + }) - res.json({ order }) + res.json({ order: result }) } diff --git a/packages/medusa/src/api/store/payment-collections/[id]/payment-sessions/route.ts b/packages/medusa/src/api/store/payment-collections/[id]/payment-sessions/route.ts index e11e4552679b9..ffc56ff0db179 100644 --- a/packages/medusa/src/api/store/payment-collections/[id]/payment-sessions/route.ts +++ b/packages/medusa/src/api/store/payment-collections/[id]/payment-sessions/route.ts @@ -11,7 +11,7 @@ export const POST = async ( res: MedusaResponse ) => { const collectionId = req.params.id - const { context = {}, data, provider_id } = req.body + const { context = {}, data, provider_id, amount } = req.body // If the customer is logged in, we auto-assign them to the payment collection if (req.auth_context?.actor_id) { @@ -21,7 +21,8 @@ export const POST = async ( } const workflowInput = { payment_collection_id: collectionId, - provider_id: provider_id, + provider_id, + amount, data, context, } diff --git a/packages/medusa/src/api/store/payment-collections/validators.ts b/packages/medusa/src/api/store/payment-collections/validators.ts index d7b2514bc1814..559c54c09ad46 100644 --- a/packages/medusa/src/api/store/payment-collections/validators.ts +++ b/packages/medusa/src/api/store/payment-collections/validators.ts @@ -14,6 +14,7 @@ export const StoreCreatePaymentSession = z provider_id: z.string(), context: z.record(z.unknown()).optional(), data: z.record(z.unknown()).optional(), + amount: z.number().optional(), }) .strict() diff --git a/packages/modules/payment/src/services/payment-module.ts b/packages/modules/payment/src/services/payment-module.ts index eee96f5fa1ed8..4800fc931259b 100644 --- a/packages/modules/payment/src/services/payment-module.ts +++ b/packages/modules/payment/src/services/payment-module.ts @@ -862,6 +862,15 @@ export default class PaymentModuleService {}, sharedContext ) + + if (event.data.order_id && !event.data.cart_id) { + await this.authorizePaymentSession( + event.data.session_id, + {}, + sharedContext + ) + } + if (payment && !payment.captured_at) { await this.capturePayment( { payment_id: payment.id, amount: event.data.amount }, diff --git a/packages/modules/providers/payment-stripe/src/core/stripe-base.ts b/packages/modules/providers/payment-stripe/src/core/stripe-base.ts index a8d0dc5576864..be25beced5fda 100644 --- a/packages/modules/providers/payment-stripe/src/core/stripe-base.ts +++ b/packages/modules/providers/payment-stripe/src/core/stripe-base.ts @@ -110,7 +110,8 @@ abstract class StripeBase extends AbstractPaymentProvider { input: CreatePaymentProviderSession ): Promise { const intentRequestData = this.getPaymentIntentOptions() - const { email, extra, session_id, customer } = input.context + const { email, extra, session_id, cart_id, order_id, customer } = + input.context const { currency_code, amount } = input const description = (extra?.payment_description ?? @@ -120,7 +121,11 @@ abstract class StripeBase extends AbstractPaymentProvider { description, amount: getSmallestUnit(amount, currency_code), currency: currency_code, - metadata: { session_id: session_id! }, + metadata: { + session_id: session_id!, + cart_id: cart_id as string | null, + order_id: order_id as string | null, + }, capture_method: this.options_.capture ? "automatic" : "manual", ...intentRequestData, } @@ -330,6 +335,8 @@ abstract class StripeBase extends AbstractPaymentProvider { action: PaymentActions.AUTHORIZED, data: { session_id: intent.metadata.session_id, + cart_id: intent.metadata.cart_id, + order_id: intent.metadata.order_id, amount: getAmountFromSmallestUnit( intent.amount_capturable, currency @@ -341,6 +348,8 @@ abstract class StripeBase extends AbstractPaymentProvider { action: PaymentActions.SUCCESSFUL, data: { session_id: intent.metadata.session_id, + cart_id: intent.metadata.cart_id, + order_id: intent.metadata.order_id, amount: getAmountFromSmallestUnit(intent.amount_received, currency), }, } @@ -349,6 +358,8 @@ abstract class StripeBase extends AbstractPaymentProvider { action: PaymentActions.FAILED, data: { session_id: intent.metadata.session_id, + cart_id: intent.metadata.cart_id, + order_id: intent.metadata.order_id, amount: getAmountFromSmallestUnit(intent.amount, currency), }, }