> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.paymentkit.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.paymentkit.com/_mcp/server.

# Adyen

> Accept card and SEPA Direct Debit payments through Adyen using PaymentKit. PaymentKit handles PCI compliance and securely orchestrates every payment operation with Adyen — 3D Secure, network tokens, off-session subscription renewals, refunds, and SEPA (euro bank debit), including its mandate and asynchronous settlement flow.

# Set up summary

To accept payments with Adyen in PaymentKit, you will need to:

1. Generate Adyen API credentials
2. Confirm your Adyen account uses immediate capture
3. Connect Adyen to PaymentKit and turn on the payment methods you want
4. Configure an Adyen standard webhook and add its HMAC signing key to PaymentKit (required for refunds and SEPA)

# What Adyen supports in PaymentKit

PaymentKit supports the following with Adyen:

* **Card payments** — one-time and customer-initiated (CIT)
* **Off-session / merchant-initiated payments (MIT)** — including subscription renewals and dunning retries
* **3D Secure 2 (3DS2)** — both the frictionless and challenge flows
* **Network tokens**
* **Refunds** — see [Refunds](#refunds) below
* **SEPA Direct Debit** — euro bank debit; see [How SEPA Direct Debit works](#how-sepa-direct-debit-works) below

The following is **not currently supported**:

* Manual capture / authorization holds (**immediate capture only** — see below)
* Partial capture
* Digital wallets (Apple Pay and Google Pay)
* Adyen local payment methods
* ACH direct debit

For non-euro bank debit or any of the methods above, use a different processor.

# Generate API credentials in Adyen

PaymentKit requires an **API key** and your **merchant account** name to securely connect to your Adyen account.

1. Log in to your [Adyen Customer Area](https://ca-live.adyen.com/) (use the [test Customer Area](https://ca-test.adyen.com/) for sandbox)
2. Navigate to **Developers → API credentials**
3. Select (or create) a web-service user, then generate an **API key** and copy it
4. Note your **merchant account** name — shown in the Customer Area account switcher

For a production connection, Adyen assigns your account a unique **live URL prefix**. Find it in the Customer Area under **Developers → API URLs**. PaymentKit needs this prefix to reach your live Adyen endpoints — sandbox connections do not require it.

A **cards-only** connection needs only these values: API key, merchant account, and the environment (plus the live URL prefix in production). The webhook HMAC key described later is required for refund settlement and for SEPA.

# Set your Adyen account to immediate capture

**Your Adyen account — and the merchant account you connect — must be configured
for immediate (instant) capture.** This integration does **not** support manual or
delayed capture.

With **manual** or **delayed** capture, PaymentKit's charges are only *authorized*
at Adyen and never captured. The payment appears successful, but any later
**refund will fail** — Adyen returns *"Transaction hasn't been captured, refund not
possible."*

In your Adyen Customer Area, set your **capture delay / capture mode to immediate**
before you start accepting live payments.

# Connect Adyen to PaymentKit

1. Navigate to **Orchestration → Payment processors**
2. Click the **add (+)** button, then choose **Adyen** from the **Payment processor** list
3. Enter a **Label** for the connection, select the **Environment** (Sandbox or Production), and enter your **API Key** and **Merchant account**
4. For a **Production** connection, also enter your **Live URL prefix**
5. Turn on the payment methods you want to accept

**SEPA Direct Debit** cannot be enabled until you add the webhook **HMAC signing
key** (next step). SEPA payments settle asynchronously, and PaymentKit can only
confirm them from a signed Adyen webhook — without the signing key those outcomes
could never be verified, so SEPA stays unavailable.

# Configure the Adyen webhook and HMAC key

Set up a **standard webhook** in Adyen so PaymentKit can receive asynchronous notifications.

Card **authorization and capture happen synchronously** — cards work without a
webhook configured. A webhook is required for **refund settlement** and for
**SEPA**, both of which are asynchronous.

1. In your Adyen Customer Area, navigate to **Developers → Webhooks**
2. Click **Add webhook** and choose **Standard webhook**
3. Under **Server configuration**, paste the **webhook URL** shown on your Adyen connection in PaymentKit. It is unique per connection and ends with your connection's ID (a `proc_…` value) — for example `https://<paymentkit-webhook-domain>/proc_prod_a1b2c3d4e5f6g7h8`. Always copy the exact URL from the connect/edit form rather than typing it by hand
4. Enable the **REFUND** event so refund outcomes are delivered. If you accept **SEPA**, also enable the **AUTHORISATION** event — that is the notification that settles a SEPA charge
5. Under **Security**, generate an **HMAC Key** and copy it (Adyen issues a hex key and signs each notification with HMAC-SHA256)
6. Save the webhook, and make sure it is **enabled**
7. Back in PaymentKit, edit your Adyen connection and paste the key into the **Webhook HMAC key** field

Enable HMAC signing on the webhook and use the same key in both places. PaymentKit
verifies every incoming notification's signature with this key and ignores any
notification that does not match — so a missing or mismatched key means refund and
SEPA outcomes never settle.

Keep the webhook **enabled** in Adyen for as long as you accept SEPA or process
refunds. If it is disabled or misconfigured, Adyen stops delivering results — the
affected refunds stay **pending** and SEPA payments stay **processing** indefinitely.

# Refunds

Adyen refunds are **asynchronous**. When you issue a refund, PaymentKit sends it to Adyen and records it as **pending**; it resolves to **succeeded** only once Adyen confirms it with a **REFUND** webhook notification.

If you have not configured the webhook and its HMAC key, a refund still executes at
Adyen, but PaymentKit has no way to learn the outcome — so the refund **stays
pending** in PaymentKit indefinitely. Configure the webhook (above) before
processing refunds.

# How SEPA Direct Debit works

SEPA Direct Debit lets euro-zone customers pay directly from their bank account instead of using a card. It behaves differently from card payments, so it helps to set expectations for both you and your customers.

The webhook **HMAC key is required** to enable SEPA. Because SEPA settles
asynchronously, PaymentKit will not offer or charge SEPA on a connection that has no
HMAC key configured.

## At checkout

1. SEPA is offered only when the payment currency is **EUR** and your Adyen connection has SEPA enabled with a webhook configured.
2. The customer enters their **IBAN** and account-holder name, and accepts a **mandate** — their standing authorization for you to debit the account, including future subscription renewals.
3. The payment is submitted to Adyen, which normally accepts the debit instruction and returns a **processing** result — not a final "paid". (A submission Adyen cannot accept — for example a malformed IBAN — is declined immediately at checkout instead.)

## Settlement is asynchronous

Money physically moves through the banking system, so the final result arrives later — typically within a few minutes in test, and anywhere from minutes to a few business days in production. Until it does:

* The payment shows as **processing**, not paid.
* The related invoice stays **open**.
* A new subscription stays **incomplete** — it is **not** activated yet, and no confirmation email is sent.

When the bank result arrives via the Adyen webhook:

* **Success** → the payment and its invoice are both marked **paid**, any subscription **activates**, the stored mandate is saved for future renewals, and the success receipt is sent.
* **Failure** (for example insufficient funds or a closed account) → the payment is marked failed and your normal dunning / decline handling runs.

A **processing** SEPA payment is normal and expected — it does not mean anything went wrong. Unlike a card authorization that resolves instantly, bank debit is inherently asynchronous. Avoid granting access or shipping goods until the payment reaches **paid**.

## SEPA refunds

SEPA refunds are asynchronous too. When you refund a settled SEPA payment, the refund is recorded as **pending** and resolves to **succeeded** — or **failed** if the bank rejects it — once Adyen confirms the outcome via webhook.

SEPA Direct Debit is **EUR-only**. A SEPA payment in any other currency is rejected before it reaches Adyen. Use a card processor for non-euro charges.

---