Skip to main content

Setup

Please follow the common Adyen instructions to get set up with SEPA. Next, make sure to enable SEPA as a payment method on your configured account.

Usage

To create a SEPA payment, set the method to sepa when calling the transaction API.
{
    "amount": 1800,
    "currency": "EUR",
    "country": "DE",
    "intent": "capture",
    "payment_method": {
        "method": "sepa",
        "country": "DE",
        "currency": "EUR",
        "redirect_url": "https://example.com"
    }
}

Recurring payments

SEPA via Adyen supports recurring payments. To process a recurring payment, please be aware of the following limitations when storing a SEPA payment method for future use.
  • To store a SEPA payment for future use, set store: true on the transaction request.
  • When stored, a SEPA payment method is initially in a processing state until a webhook is received from Adyen. You need to set up the Adyen RECURRING_CONTRACT webhooks for this update to be received.
  • A stored SEPA payment method in a processing state can not be used in Embed until it is ready and marked as succeeded
Once a SEPA payment method is successfully stored, you can use it to create a subsequent payment.
{
    "amount": 1800,
    "currency": "EUR",
    "country": "DE",
    "intent": "capture",
    "payment_method": {
        "method": "id",
        "id": "f758d736-9a81-4bd0-85a9-2d3ee361b863"
    },
    "is_subsequent_payment": true,
    "merchant_initiated": true,
    "payment_source": "recurring"
}
When processing a recurring payment please note the following.
  • SEPA supports the payment_source of recurring and instalment, which maps to Subscription on the Adyen API. In all other scenarios it sets the recurring processing mode as UnscheduledCardOnFile.
  • Until the first transaction is settled, a stored SEPA payment uses a different mandate for the subsequent request. In a production environment, this might lead to a subsequent payment failing if the original mandate has not been fully settled yet.

Auto-rescue

Adyen’s auto-rescue feature is supported by this connector. This feature will automatically retry customer-not-present direct debit transactions when they receive a chargeback. To enable this feature, pass in the following connection options for Adyen when making a subsequent payment request.
POST /transactions

{
    "amount": 1299,
    "country": "DE",
    "currency": "EUR",
    "intent": "capture",
    "payment_method": {
        "method": "id",
        "id": "7f6fb9ca-eb1c-42c6-9b65-8f1c699b84bd"
    },
    "connection_options": {
        "adyen-sepa": {
            "autoRescue": true,
            "maxDaysToRescue": 5
        }
    },
    "payment_source": "card_on_file",
    "is_subsequent_payment": true,
    "merchant_initiated": true
}
Please note that this feature only works for customer-not-present transaction where is_subsequent_payment is set to true.
The following fields need to be set.
  • autoRescue - A boolean value that enables the feature. This defaults to false.
  • maxDaysToRescue - The rescue window, in days. You can specify between 1 and 42 days. Adyen recommends using a rescue window of one calendar month (30 days).
  • autoRescueScenario - This is one of the test scenarios as defined by Adyen. This only works in sandbox.
  • ownerName - Set this to the type of chargeback that you want to simulate. Use a concatenation of chargeback and the reason code. For example, chargeback:MS03 or chargeback:AM04. This only works in sandbox.
Auto-rescued SEPA transactions are always capture_succeeded in the system as the payment is always processed successfully initially. Instead, the auto-rescue fights the chargeback by re-attempting the payment. The system does not report on this attempts, but may report the chargeback in settlement reports.

Testing

In a test environment, you can simulate an SEPA payment. Adyen has extensive instructions on how to help with this.

Integration

For the alternative payment methods the default integration for Adyen is through a redirect to a hosted payments page.

Redirect integration

Start by creating a new transaction with the following required fields.
POST /transactions
{
  "amount": 100,
  "currency": "EUR",
  "country": "NL",
  "intent": "capture",
  "payment_method": {
    "method": "<method>",
    "redirect_url": "https://example.com/callback",
    "country": "NL",
    "currency": "EUR"
  }
}
Please use "" for the value of the <method>.
After the transaction is created, the API response includes payment_method.approval_url and the transaction will be in the buyer_approval_pending state.
{
  "type": "transaction",
  "id": "ea1efdd0-20f9-44d9-9b0b-0a3d71e9b625",
  "payment_method": {
    "type": "payment-method",
    "approval_url": "https://cdn.sandbox.spider.gr4vy.app/connectors/adyen/apm.html?token=..."
  },
  "method": "<method>"
}
Redirect the buyer to the approval_url (open in a browser or Webview) so they can complete authentication and approve the payment. After approval the buyer is redirected to the redirect_url you provided when creating the transaction. Do not rely solely on the redirect — either poll the transaction or (recommended) rely on webhooks to detect the final status (for example capture_succeeded or failure states).

Direct integration

Adyen provides web, Android and iOS for a direct integration. For these flows you should indicate the platform by setting an appropriate integration_client when creating the transaction, and then build a client-side integration that uses the POST /transactions/:transaction_id/session API to initialize the Adyen SDK. To start, create a new transaction with the appropriate integration_client.
POST /transactions

{
  "amount": 100,
  "currency": "EUR",
  "country": "NL",
  "intent": "capture",
  "integration_client": "web",
  "payment_method": {
    "method": "<method>",
    "redirect_url": "https://example.com/callback",
    "country": "NL",
    "currency": "EUR"
  }
}
Please use "" for the value of the <method>.
After the transaction is created, the API response includes a session_token which can be used to get the session data for that transaction.
POST /transactions/:transaction_id/session?token=:session_token
{
  "session_data": {
    "sessionId": "CS04C0B8AC9849A7D8E25B20D",
    "sessionData": "Ab02b4c0!BQABAgBLgbLpvkt1r3",
    "environment": "live",
    "clientKey": "client-key",
    "returnUrl": "https://example.com/callback",
    "paymentMethod": "<method>",
    "storePaymentMethod": true // this is an optional key
  },
  "default_completion_url": "https://api.sandbox.spider.gr4vy.app/transactions/approve/some-token",
  "integration_client": "web"
}
This session data provides the sessionId and sessionData required to load the Adyen SDK.
// Determine the URL of the script, and the method to invoke on the Adyen SDK
const adyenEnvironment = sessionData.environment;
const clientKey = sessionData.clientKey;
const sessionId = sessionData.sessionId;
const adyenSessionData = sessionData.sessionData;
const returnUrl = sessionData.returnUrl;
const paymentMethod = sessionData.paymentMethod;
const storePaymentMethod = sessionData.storePaymentMethod;
const configuration = {
    environment: adyenEnvironment,
    clientKey,
    analytics: {
      enabled: false,
    },
    session: {
      id: sessionId,
      sessionData: adyenSessionData,
    },
    paymentMethodsConfiguration: {
      cashapp: { // only cashapp requires this configuration
        storePaymentMethod: storePaymentMethod,
      },
    },
}
AdyenCheckout(configuration).then(function (checkout) {
  let component = checkout
    .create(paymentMethod)
    .mount('#component');
  });

Complete the transaction

Recommended On mobile integrations, after the buyer completes the payment flow, the Adyen SDK provides the developer with an onFinished call, which includes a statusCode. The system automatically syncs the status through webhooks, but to complete the transaction it is also recommended sending a GET request to the default_completion_url provided in the session response with the sessionId and the sessionResult as query parameters to finalize the transaction. This also moves the transaction to a completed status without waiting for the webhook to be sent. The call returns a 204 No Content response. After receiving this response, you can also optionally fetch the transaction to confirm final status.
// On the didComplete callback
func didComplete(with result: AdyenSessionResult,
            component: Component,
            session: AdyenSession)
{
    var urlComponents = URLComponents(string: defaultCompletionUrl)!
    urlComponents.queryItems = [
        URLQueryItem(name: "sessionId", value: session.session.id),
        URLQueryItem(name: "sessionResult", value: result.sessionResult)
    ]
    
    var request = URLRequest(url: urlComponents.url!)
    request.httpMethod = "GET"
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        // Handle 204 response, you can now poll the transaction
    }
    task.resume()
}
Please refer to the Adyen documentation for the web, Android and iOS for further guidance