payload-payment-adyen
v0.8.2
Published
Adyen payment adapter and checkout helpers for Payload Ecommerce.
Maintainers
Readme
payload-payment-adyen
Adyen payment adapter and checkout helpers for Payload Ecommerce.
This package is developed inside a Payload Ecommerce Starter so it can be tested against a real storefront while remaining installable as a standalone package.
Install
Install the package and Adyen Web in a Payload Ecommerce app:
pnpm add payload-payment-adyen @adyen/adyen-webThe package exports compiled ESM from dist, so consuming apps should not need transpilePackages for normal registry installs.
Starter Migration CLI
For a fresh Payload Ecommerce Starter, run the migration helper from the target project:
pnpm exec payload-payment-adyen migrate-starter --dry-run
pnpm exec payload-payment-adyen migrate-starterUse --remove-stripe only when the project is a fresh starter and you do not need Stripe for historical transactions:
pnpm exec payload-payment-adyen migrate-starter --remove-stripe
pnpm install
pnpm generate:typesThe script detects the known starter layout, adds Adyen env vars and CSS, patches the server/client adapter wiring, patches known Stripe-specific checkout sections in place, and with --remove-stripe converts known Stripe seed transactions to Adyen seed transactions. See docs/payload-ecommerce-starter.md.
Package Development
This package is developed inside a Payload Ecommerce Starter so it can be tested against a real storefront while remaining installable as a standalone package.
Workspace development from this repository:
pnpm add payload-payment-adyen@workspace:*Local tarball testing:
pnpm --filter payload-payment-adyen pack
pnpm add ./path/to/payload-payment-adyen-0.8.1.tgz @adyen/adyen-webBuild the package:
pnpm --filter payload-payment-adyen buildCheck what would be published:
pnpm --filter payload-payment-adyen pack:dryThe package publishes only dist, docs, README.md, and package.json.
Server Adapter
import { adyenAdapter } from 'payload-payment-adyen'
ecommercePlugin({
payments: {
paymentMethods: [
adyenAdapter({
apiKey: process.env.ADYEN_API_KEY!,
clientKey: process.env.NEXT_PUBLIC_ADYEN_CLIENT_KEY!,
environment: process.env.ADYEN_ENVIRONMENT === 'live' ? 'live' : 'test',
forceRedirectThreeDS: process.env.ADYEN_FORCE_REDIRECT_3DS === 'true',
hmacKey: process.env.ADYEN_HMAC_KEY,
liveEndpointUrlPrefix: process.env.ADYEN_LIVE_ENDPOINT_URL_PREFIX,
merchantAccount: process.env.ADYEN_MERCHANT_ACCOUNT!,
}),
],
},
})Client Adapter
import { adyenAdapterClient } from 'payload-payment-adyen/client'
<EcommerceProvider
paymentMethods={[
adyenAdapterClient({
clientKey: process.env.NEXT_PUBLIC_ADYEN_CLIENT_KEY || '',
environment: process.env.NEXT_PUBLIC_ADYEN_ENVIRONMENT === 'live' ? 'live' : 'test',
}),
]}
>
{children}
</EcommerceProvider>React Helpers
Import Adyen Web CSS once in your app layout:
import '@adyen/adyen-web/styles/adyen.css'Mount Drop-in after calling initiatePayment('adyen'):
import { AdyenCheckoutForm } from 'payload-payment-adyen/react'
<AdyenCheckoutForm
customerEmail={email}
billingAddress={billingAddress}
paymentData={paymentData}
shippingAddress={shippingAddress}
/>Handle redirect returns:
import { AdyenRedirectReturn } from 'payload-payment-adyen/react'
<AdyenRedirectReturn
sessionID={sessionID}
redirectResult={redirectResult}
onOrderConfirmed={({ customerEmail, result }) => {
// route to your order page
}}
/>Environment
ADYEN_API_KEY=
ADYEN_MERCHANT_ACCOUNT=
ADYEN_ENVIRONMENT=test
ADYEN_HMAC_KEY=
ADYEN_LIVE_ENDPOINT_URL_PREFIX=
ADYEN_FORCE_REDIRECT_3DS=false
NEXT_PUBLIC_ADYEN_CLIENT_KEY=
NEXT_PUBLIC_ADYEN_ENVIRONMENT=test
NEXT_PUBLIC_SERVER_URL=http://localhost:3000Endpoints
The adapter registers:
POST /api/payments/adyen/initiatePOST /api/payments/adyen/confirm-orderPOST /api/payments/adyen/outcomePOST /api/payments/adyen/webhooksPOST /api/payments/adyen/transactions/:transactionID/capturePOST /api/payments/adyen/transactions/:transactionID/refundPOST /api/payments/adyen/transactions/:transactionID/cancel
The capture/refund/cancel endpoints are admin-only and asynchronous. Adyen webhooks remain the source of truth for final operation status.
Webhook Security And Idempotency
When hmacKey is configured, Standard webhook notifications are verified with Adyen HMAC validation before they are processed.
Processed webhook events are recorded on the related transaction under adyen.webhookEvents using eventCode:pspReference as the idempotency key. Duplicate notifications for an already-recorded key are skipped before transaction reconciliation or custom webhook handlers run. This covers normal Adyen retry delivery and duplicate notification batches. As with any webhook processor, database-level transaction isolation still determines how strongly concurrent duplicate deliveries are serialized.
Migration
The migration examples and CLI do not migrate in-flight Stripe PaymentIntents, Stripe Checkout Sessions, stored Stripe payment methods, saved cards, mandates, subscriptions, refunds, disputes, or reconciliation history. Keep Stripe available for old/live payment state during a production migration.
