fix(payment, stripe) stripe payment cannot be captured (#8075)

This commit is contained in:
shij authored and GitHub committed 2024-07-13 10:45:03 -03:00
1 parent 7e82f981f9
commit ba58842d81
3 files changed
+41 -29

No files matched your search

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