diff --git a/packages/core/types/src/payment/provider.ts b/packages/core/types/src/payment/provider.ts index 3237b91b6b..9d17846cb2 100644 --- a/packages/core/types/src/payment/provider.ts +++ b/packages/core/types/src/payment/provider.ts @@ -40,9 +40,9 @@ export type PaymentProviderContext = { email?: string /** - * The ID of the resource the payment is associated with. For example, the ID of the payment session. + * The ID of payment session the provider payment is associated with. */ - resource_id?: string + session_id?: string /** * The customer associated with this payment. @@ -180,10 +180,9 @@ export interface PaymentProviderError { */ export type WebhookActionData = { /** - * The associated resource's ID. For example, - * a payment session's ID. + * The associated payment session's ID. */ - resource_id: string + session_id: string /** * The amount to be captured or authorized (based on the action's type.) diff --git a/packages/modules/payment/src/services/payment-module.ts b/packages/modules/payment/src/services/payment-module.ts index afa3411aa8..eee96f5fa1 100644 --- a/packages/modules/payment/src/services/payment-module.ts +++ b/packages/modules/payment/src/services/payment-module.ts @@ -294,33 +294,44 @@ export default class PaymentModuleService input: CreatePaymentSessionDTO, @MedusaContext() sharedContext?: Context ): Promise { - let paymentSession: PaymentSession + let paymentSession: PaymentSession | undefined try { - const providerSessionSession = - await this.paymentProviderService_.createSession(input.provider_id, { - context: input.context ?? {}, - amount: input.amount, - currency_code: input.currency_code, - }) - - input.data = { - ...input.data, - ...providerSessionSession, - } - paymentSession = await this.createPaymentSession_( paymentCollectionId, input, sharedContext ) + + const providerSessionSession = + await this.paymentProviderService_.createSession(input.provider_id, { + context: { ...input.context, session_id: paymentSession.id }, + amount: input.amount, + currency_code: input.currency_code, + }) + + paymentSession = ( + await this.paymentSessionService_.update( + { + id: paymentSession.id, + data: { ...input.data, ...providerSessionSession }, + }, + sharedContext + ) + )[0] } catch (error) { - // In case the session is created at the provider, but fails to be created in Medusa, - // we catch the error and delete the session at the provider and rethrow. - await this.paymentProviderService_.deleteSession({ - provider_id: input.provider_id, - data: input.data, - }) + if (paymentSession) { + // In case the session is created, but fails to be updated in Medusa, + // we catch the error and delete the session and rethrow. + await this.paymentProviderService_.deleteSession({ + provider_id: input.provider_id, + data: input.data, + }) + await this.paymentSessionService_.delete( + paymentSession.id, + sharedContext + ) + } throw error } @@ -846,21 +857,22 @@ export default class PaymentModuleService case PaymentActions.SUCCESSFUL: { const [payment] = await this.listPayments( { - payment_session_id: event.data.resource_id, + payment_session_id: event.data.session_id, }, {}, sharedContext ) - - await this.capturePayment( - { payment_id: payment.id, amount: event.data.amount }, - sharedContext - ) + if (payment && !payment.captured_at) { + await this.capturePayment( + { payment_id: payment.id, amount: event.data.amount }, + sharedContext + ) + } break } case PaymentActions.AUTHORIZED: await this.authorizePaymentSession( - event.data.resource_id as string, + event.data.session_id, {}, sharedContext ) 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 32f0f97377..a8d0dc5576 100644 --- a/packages/modules/providers/payment-stripe/src/core/stripe-base.ts +++ b/packages/modules/providers/payment-stripe/src/core/stripe-base.ts @@ -98,8 +98,9 @@ abstract class StripeBase extends AbstractPaymentProvider { case "canceled": return PaymentSessionStatus.CANCELED case "requires_capture": - case "succeeded": return PaymentSessionStatus.AUTHORIZED + case "succeeded": + return PaymentSessionStatus.CAPTURED default: return PaymentSessionStatus.PENDING } @@ -109,7 +110,7 @@ abstract class StripeBase extends AbstractPaymentProvider { input: CreatePaymentProviderSession ): Promise { const intentRequestData = this.getPaymentIntentOptions() - const { email, extra, resource_id, customer } = input.context + const { email, extra, session_id, customer } = input.context const { currency_code, amount } = input const description = (extra?.payment_description ?? @@ -119,7 +120,7 @@ abstract class StripeBase extends AbstractPaymentProvider { description, amount: getSmallestUnit(amount, currency_code), currency: currency_code, - metadata: { resource_id: resource_id ?? "Medusa Payment" }, + metadata: { session_id: session_id! }, capture_method: this.options_.capture ? "automatic" : "manual", ...intentRequestData, } @@ -328,7 +329,7 @@ abstract class StripeBase extends AbstractPaymentProvider { return { action: PaymentActions.AUTHORIZED, data: { - resource_id: intent.metadata.resource_id, + session_id: intent.metadata.session_id, amount: getAmountFromSmallestUnit( intent.amount_capturable, currency @@ -339,7 +340,7 @@ abstract class StripeBase extends AbstractPaymentProvider { return { action: PaymentActions.SUCCESSFUL, data: { - resource_id: intent.metadata.resource_id, + session_id: intent.metadata.session_id, amount: getAmountFromSmallestUnit(intent.amount_received, currency), }, } @@ -347,7 +348,7 @@ abstract class StripeBase extends AbstractPaymentProvider { return { action: PaymentActions.FAILED, data: { - resource_id: intent.metadata.resource_id, + session_id: intent.metadata.session_id, amount: getAmountFromSmallestUnit(intent.amount, currency), }, }