Skip to content

Commit

Permalink
Fix redirect url
Browse files Browse the repository at this point in the history
  • Loading branch information
acasazza committed Nov 5, 2024
1 parent f73d43e commit 5c84f4a
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import OrderContext from '#context/OrderContext'
import getCardDetails from '#utils/getCardDetails'
import type { BaseError } from '#typings/errors'
import type { Order } from '@commercelayer/sdk'
import { retrievePaymentIntent } from '#utils/stripe/retrievePaymentIntent'
import { checkPaymentIntent } from '#utils/stripe/retrievePaymentIntent'

interface ChildrenProps extends Omit<Props, 'children'> {
/**
Expand Down Expand Up @@ -153,42 +153,35 @@ export function PlaceOrderButton(props: Props): JSX.Element {
const publicApiKey = order?.payment_source?.publishable_key
const paymentIntentClientSecret =
options?.stripe?.paymentIntentClientSecret
retrievePaymentIntent({
publicApiKey,
paymentIntentClientSecret
})
.then((paymentIntentResult) => {
if (paymentIntentResult != null) {
if (paymentIntentResult.error == null) {
const status = paymentIntentResult.paymentIntent.status
if (status != null) {
void handleClick()
}
} else {
setPaymentMethodErrors([
{
code: 'PAYMENT_INTENT_AUTHENTICATION_FAILURE',
resource: 'payment_methods',
field: currentPaymentMethodType,
message:
paymentIntentResult?.error?.message ??
'Payment intent verification error'
}
])
}
}
})
.catch((error) => {
console.error('Error retrieving payment intent:', error)
setPaymentMethodErrors([
{
code: 'PAYMENT_INTENT_AUTHENTICATION_FAILURE',
resource: 'payment_methods',
field: currentPaymentMethodType,
message: error?.message ?? 'Payment intent verification error'
}
])

const getPaymentIntent = async (): Promise<void> => {
const paymentIntentResult = await checkPaymentIntent({
publicApiKey,
paymentIntentClientSecret
})
switch (paymentIntentResult.status) {
case 'valid':
void handleClick()
break
case 'processing':
// Set a timeout to check the payment intent status again
setTimeout(() => {
void getPaymentIntent()
}, 1000)
break
case 'invalid':
setPaymentMethodErrors([
{
code: 'PAYMENT_INTENT_AUTHENTICATION_FAILURE',
resource: 'payment_methods',
field: currentPaymentMethodType,
message: paymentIntentResult.message
}
])
break
}
}
void getPaymentIntent()
}
}, [
options?.stripe?.paymentIntentClientSecret != null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,12 @@ function StripePaymentForm({
state: billingInfo?.state_code
}
}
const url = new URL(window.location.href)
const cleanUrl = `${url.origin}${url.pathname}?accessToken=${url.searchParams.get('accessToken')}`
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: window.location.href,
return_url: cleanUrl,
payment_method_data: {
billing_details: billingDetails
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type PaymentIntentResultPromise = Promise<
PaymentIntentResult | undefined | null
>

export async function retrievePaymentIntent({
async function retrievePaymentIntent({
publicApiKey,
paymentIntentClientSecret
}: StripePaymentIntentParams): PaymentIntentResultPromise {
Expand All @@ -24,3 +24,56 @@ export async function retrievePaymentIntent({
return null
}
}

interface PaymentIntentValidationProps {
paymentIntent: PaymentIntentResult['paymentIntent']
}

type PaymentVerificationState = 'valid' | 'invalid' | 'processing'

function paymentIntentValidation({
paymentIntent
}: PaymentIntentValidationProps): PaymentVerificationState {
const status = paymentIntent?.status
switch (status) {
case 'succeeded':
case 'requires_capture':
return 'valid'
case 'processing':
return 'processing'
case 'requires_payment_method':
return 'invalid'
default:
return 'invalid'
}
}

type PaymentProcessingFeedback =
| {
status: Exclude<PaymentVerificationState, 'invalid'>
message?: string
}
| {
status: 'invalid'
message: string
}

export async function checkPaymentIntent({
publicApiKey,
paymentIntentClientSecret
}: StripePaymentIntentParams): Promise<PaymentProcessingFeedback> {
const paymentIntentResult = await retrievePaymentIntent({
publicApiKey,
paymentIntentClientSecret
})
if (!paymentIntentResult) {
return { status: 'invalid', message: 'Payment intent not found' }
}
const paymentIntent = paymentIntentResult.paymentIntent
const error = paymentIntent?.last_payment_error
const status = paymentIntentValidation({ paymentIntent })
return {
status,
message: status === 'invalid' && error?.message != null ? error.message : ''
}
}

0 comments on commit 5c84f4a

Please sign in to comment.