Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 1x 7x 7x 7x 7x 7x 1x 6x 1x 1x 6x 2x 2x 2x 1x 1x 1x 1x 6x 1x 1x | import {
PayPalScriptProvider,
PayPalButtons,
type PayPalButtonsComponentProps,
} from '@paypal/react-paypal-js'
import { useTranslation } from 'react-i18next'
import { CardContent, CardFooter } from '@core/components/ui/card'
import { Button } from '@core/components/ui/button'
import type { PaymentProviderProps } from '../../types/payment.types'
export const PayPalPaymentForm = (props: PaymentProviderProps) => {
const { sessionData, config, onSuccess, onError, onBack, amount, currency } = props
const { t } = useTranslation('common')
// For PayPal, sessionData might contain an orderID pre-created on the backend, or we might create it here.
// Assuming backend creation for security (consistent with our Stripe intent flow).
const initialOrderId = sessionData.orderID || sessionData.id
const clientId = config?.clientId as string | undefined
if (!clientId) {
return <div className="text-red-500">{t('payment.error_missing_config')}</div>
}
const createOrder: PayPalButtonsComponentProps['createOrder'] = async (_data, actions) => {
// If we already have an orderID from the backend intention
Iif (initialOrderId) {
return initialOrderId
}
// Fallback: Create order on client (less secure, but valid for simple flows)
return actions.order.create({
intent: 'CAPTURE',
purchase_units: [
{
amount: {
currency_code: currency.toUpperCase(),
value: amount.toString(),
},
},
],
})
}
const onApprove: PayPalButtonsComponentProps['onApprove'] = async (_data, actions) => {
try {
Iif (!actions.order) {
throw new Error('PayPal actions.order is undefined')
}
// Capture the funds from the transaction
const details = await actions.order.capture()
console.log('PayPal Transaction completed:', details)
Eif (onSuccess) onSuccess()
} catch (err) {
console.error('PayPal Capture Error', err)
Eif (onError) onError(t('payment.error_processing'))
}
}
return (
<PayPalScriptProvider
options={{
clientId: clientId,
currency: currency.toUpperCase(),
intent: 'capture',
}}
>
<CardContent className="space-y-4 pt-6">
<div className="min-h-[150px] flex flex-col justify-center">
<PayPalButtons
style={{ layout: 'vertical', shape: 'rect', label: 'donate' }}
createOrder={createOrder}
onApprove={onApprove}
onError={(err) => {
console.error('PayPal Error', err)
Eif (onError) onError(t('payment.error_generic'))
}}
/>
</div>
</CardContent>
<CardFooter>
{onBack && (
<Button variant="ghost" onClick={onBack} className="w-full">
{t('common.back')}
</Button>
)}
</CardFooter>
</PayPalScriptProvider>
)
}
|