Skip to content

Commit

Permalink
Enable all payments through Stripe. Resolve #587
Browse files Browse the repository at this point in the history
  • Loading branch information
acasazza committed Oct 29, 2024
1 parent 6f30dac commit 06ce918
Show file tree
Hide file tree
Showing 5 changed files with 2,005 additions and 2,215 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
},
"devDependencies": {
"@commercelayer/eslint-config-ts-react": "^1.4.5",
"husky": "^9.1.5",
"husky": "^9.1.6",
"lerna": "^8.1.3",
"typescript": "^5.4.5"
"typescript": "^5.6.3"
},
"pnpm": {
"overrides": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +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'

interface ChildrenProps extends Omit<Props, 'children'> {
/**
Expand Down Expand Up @@ -126,6 +127,7 @@ export function PlaceOrderButton(props: Props): JSX.Element {
paymentSource
])
useEffect(() => {
// PayPal redirect flow
if (
paymentType === 'paypal_payments' &&
options?.paypalPayerId &&
Expand All @@ -137,19 +139,64 @@ export function PlaceOrderButton(props: Props): JSX.Element {
}
}, [options?.paypalPayerId, paymentType])
useEffect(() => {
// Stripe redirect flow
if (
paymentType === 'stripe_payments' &&
['succeeded', 'pending'].includes(
options?.stripe?.redirectStatus ?? ''
) &&
options?.stripe?.paymentIntentClientSecret &&
// @ts-expect-error no type
order?.payment_source?.publishable_key &&
order?.status &&
['draft', 'pending'].includes(order?.status) &&
autoPlaceOrder
) {
void handleClick()
// @ts-expect-error no type
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'
}
])
})
}
}, [options?.stripe?.redirectStatus, paymentType])
}, [
options?.stripe?.paymentIntentClientSecret != null,
paymentType != null,
order?.payment_source != null
])
useEffect(() => {
// Adyen redirect flow
if (order?.status != null && ['draft', 'pending'].includes(order?.status)) {
const resultCode =
// @ts-expect-error no type
Expand Down Expand Up @@ -230,6 +277,7 @@ export function PlaceOrderButton(props: Props): JSX.Element {
order?.payment_source?.payment_response?.resultCode
])
useEffect(() => {
// Checkout.com redirect flow
if (
paymentType === 'checkout_com_payments' &&
options?.checkoutCom?.session_id &&
Expand Down
7 changes: 6 additions & 1 deletion packages/react-components/src/reducers/PlaceOrderReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ export interface PlaceOrderOptions {
session_id: string
}
stripe?: {
redirectStatus: string
/**
* @deprecated
* Use `paymentIntentClientSecret` instead
*/
redirectStatus?: string
paymentIntentClientSecret: string
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { loadStripe, type PaymentIntentResult } from '@stripe/stripe-js'

interface StripePaymentIntentParams {
publicApiKey: string
paymentIntentClientSecret: string
}

type PaymentIntentResultPromise = Promise<
PaymentIntentResult | undefined | null
>

export async function retrievePaymentIntent({
publicApiKey,
paymentIntentClientSecret
}: StripePaymentIntentParams): PaymentIntentResultPromise {
const stripe = await loadStripe(publicApiKey)
try {
const paymentIntent = await stripe?.retrievePaymentIntent(
paymentIntentClientSecret
)
return paymentIntent
} catch (error) {
console.error('Error retrieving payment intent:', error)
return null
}
}
Loading

0 comments on commit 06ce918

Please sign in to comment.