Payment UI
Stripe Payment Element, Easypay, and Ifthenpay payment interfaces in the checkout app.
The checkout app renders provider-specific payment UI on /c/[id]. The active provider is determined by the session configuration and tenant integration settings.
Provider selection
Priority order:
providerfield in session creation request- Tenant's configured default in
integration_config DEFAULT_PAYMENT_PROVIDERenv var (default:stripe)
At payment time, @prood/checkout-host rebuilds the provider with tenant credentials:
const provider = getPaymentProvider(session.providerId, tenantConfig)
// tenantConfig from decryptConfig(integration_config.config)
// env vars as fallback for missing fieldsStripe (embedded Payment Element)
Component: components/stripe-payment.tsx
Uses @stripe/react-stripe-js with the Payment Element:
<Elements stripe={stripePromise} options={{ clientSecret }}>
<PaymentElement />
<Button onClick={handleSubmit}>Pay now</Button>
</Elements>Flow
- Session loaded →
submitPayment()creates Stripe PaymentIntent - Client receives
clientSecretfrom payment session - Payment Element renders card form
- Customer submits → Stripe handles 3DS if required
- On success → redirect to
/confirm/{id}or/success/{id}
Test cards
| Card number | Result |
|---|---|
4242 4242 4242 4242 | Success |
4000 0000 0000 3220 | 3DS required |
4000 0000 0000 9995 | Declined |
Required env vars
| Variable | Purpose |
|---|---|
STRIPE_SECRET_KEY | Server-side (via tenant config or env) |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | Client-side Payment Element |
Easypay (Portugal)
Component: components/reference-payment.tsx
Reference-based payment for Portuguese methods:
| Method | UI |
|---|---|
| Multibanco | Entity + reference number for ATM/homebanking |
| MB WAY | Phone number input → push notification |
| Credit card | Redirect to Easypay hosted page |
Flow
- Customer selects payment method
submitPayment({ method: 'multibanco' })creates Easypay charge- Reference numbers displayed for Multibanco
- Customer pays asynchronously (ATM, app)
- Easypay webhook confirms payment → order updated
Sandbox
Set EASYPAY_BASE_URL=https://api.test.easypay.pt for testing.
Ifthenpay (Portugal)
Component: components/reference-payment.tsx
Similar reference-based flow:
| Method | Key env var |
|---|---|
| Multibanco | IFTHENPAY_MB_KEY |
| MB WAY | IFTHENPAY_MBWAY_KEY |
| Credit card | IFTHENPAY_CC_KEY |
Anti-phishing verification via IFTHENPAY_ANTIPHISHING_KEY.
Shared payment page
Component: components/payment-page-client.tsx
Orchestrates the payment page:
- Loads session snapshot
- Determines provider type
- Renders Stripe Element or reference payment UI
- Handles submit, loading states, and error display
- Redirects on success/failure
Error handling
| Error | UI behavior |
|---|---|
| Session expired | "Session expired" message with link back to storefront |
| Payment declined | Retry button — state machine allows failed → payment |
| Provider error | Error toast with provider message |
| Network error | Retry with exponential backoff |