--- title: "Advanced flow integration guide" description: "Accept payments using the Advanced flow." url: "https://docs.adyen.com/online-payments/build-your-integration/advanced-flow" source_url: "https://docs.adyen.com/online-payments/build-your-integration/advanced-flow.md" canonical: "https://docs.adyen.com/online-payments/build-your-integration/advanced-flow" last_modified: "2026-08-18T15:57:03+02:00" language: "en" --- # Advanced flow integration guide Accept payments using the Advanced flow. [View source](/online-payments/build-your-integration/advanced-flow.md) ## Web Drop-in Use our pre-built UI for accepting payments ### Intro Drop-in is our pre-built UI solution for accepting payments on your website. Drop-in shows all payment methods as a list, in the same block. This integration requires you to make API requests to [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods), [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments), and [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) endpoints. Adding new payment methods usually doesn't require more development work. Drop-in supports [cards](/payment-methods/cards/web-drop-in), [wallets](/payment-methods), and [most local payment methods](/payment-methods). ### Version Update ## Introducing Web v6 ### Improvements The Web v6 library introduces the following improvements: * Reduced bundle size through tree shaking * Enhanced design * Enhanced Typescript developer experience * Better alignment of express payment methods * Added support for 6 localizations * Support for Apple Pay Order tracking * Improve AVS checks for Google Pay and Apple Pay To upgrade your existing integration, see [Upgrade to Adyen Web v6](/online-payments/upgrade-your-integration/upgrade-to-web-v6) ### Before You Begin ## Requirements ##### Check out our Node.js + Express tutorial Follow our tutorial to [integrate Drop-in with Node.js and Express](/online-payments/build-your-integration/advanced-flow/web-drop-in-tutorial). Before you begin to integrate, make sure you have followed the [Get started with Adyen guide](/get-started-with-adyen) to: * Get an overview of the steps needed to accept live payments. * Create your test account. After you have created your test account: * [Get your API key](/development-resources/api-credentials#generate-api-key). * [Get your client key](/development-resources/client-side-authentication#get-your-client-key). * [Set up webhooks](/development-resources/webhooks) to know the payment outcome. To make sure that your 3D Secure integration works on Chrome, your cookies need to have the SameSite attribute. For more information, refer to [Chrome SameSite Cookie policy](https://developers.google.com/search/blog/2020/01/get-ready-for-new-samesitenone-secure). ## How it works When making a card payment with native 3D Secure 2 authentication: 1. [Show the available cards in your payment form](#show-cards). 2. [Configure Drop-in](#configure-drop-in) to collect the cardholder name. 3. Provide additional parameters [when making a payment request](#make-a-payment). 4. [Submit authentication result](#submit-authentication-result) if you receive an `action` object in response to your [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) or [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request. 5. [Handle the redirect result](/online-payments/build-your-integration/sessions-flow/?platform=Web\&integration=Drop-in#optional-configuration) if the payment was routed to the 3D Secure 2 redirect flow. ### Install Api Library ## Install an API library Payment server We provide server-side API libraries for several programming languages, available through common package managers, like Gradle and npm, for easier installation and version management. Our API libraries will save you development time, because they: * Use an API version that is up to date. * Have generated models to help you construct requests. * Send the request to Adyen using their built-in HTTP client, so you do not have to create your own. ### Tab: Java ##### Try our example integration ![](/reuse/development-resources/install-api-library/java/advanced/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-java-spring-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/java/advanced/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-java-spring-online-payments). #### Requirements * Java 11 or later. #### Installation You can use [Maven](https://maven.apache.org), adding this dependency to your project's POM. **Add the API library** ```xml com.adyen adyen-java-api-library LATEST_VERSION ``` You can find the latest version on GitHub. Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-java-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```java // Import the required classes. package com.adyen.service; import com.adyen.Client; import com.adyen.service.checkout.PaymentsApi; import com.adyen.model.checkout.Amount; import com.adyen.enums.Environment; import com.adyen.service.exception.ApiException; import java.io.IOException; public class Snippet { public Snippet() throws IOException, ApiException { // Set up the client and service. Client client = new Client("ADYEN_API_KEY", Environment.TEST); } } ``` ### Tab: PHP ##### Try our example integration ![](/reuse/development-resources/install-api-library/php/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-php-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/php/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-php-online-payments). #### Requirements * PHP 7.3 or later. * cURL with SSL support. * The JSON PHP extension. * The list of dependencies from the composer require list. #### Installation You can use [Composer](https://getcomposer.org/). Follow the [installation instructions](https://getcomposer.org/doc/00-intro.md) if you do not already have composer installed. **Install the API library** ```bash composer require adyen/php-api-library ``` In your PHP script, make sure you include the autoloader: **Include the autoloader** ```php require __DIR__ . '/vendor/autoload.php'; ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-php-api-library/releases). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```php use Adyen\Model\Checkout\Amount; use Adyen\Model\Checkout\CreateCheckoutSessionRequest; use Adyen\Service\Checkout\PaymentsApi; // Include your idempotency key when you make an API request. $requestOptions['idempotencyKey'] = "YOUR_IDEMPOTENCY_KEY"; // Set up the client and service. $client = new \Adyen\Client(); $client->setXApiKey('ADYEN_API_KEY'); $client->setEnvironment(\Adyen\Environment::TEST); $service = new PaymentsApi($client); ``` ### Tab: C\# #### Requirements * .NET standard 2.0 or later. * For Terminal API certificate validation, set the application to either of the following: * .NET core 2.1 or later * .NET framework 4.6.1 or later #### Installation You can use [NuGet](https://www.nuget.org/packages/Adyen/): **Install the API library** ```bash PM> Install-Package Adyen -Version LATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-dotnet-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```cs using Adyen; using Adyen.Model.Checkout; using Adyen.Service.Checkout; using Environment = Adyen.Model.Environment; class Program { static void Main() { // Set up the client and service. var config = new Config { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); var checkout = new PaymentsService(client); // Include your idempotency key when you make an API request. var requestOptions = new Adyen.Model.RequestOptions { IdempotencyKey = "YOUR_IDEMPOTENCY_KEY" }; } } ``` ### Tab: NodeJS ##### Try our example integration ![](/reuse/development-resources/install-api-library/node-js/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-node-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/node-js/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-node-online-payments). #### Requirements * Node.js version 18 or later. #### Installation You can use [npm](https://www.npmjs.com/): **Install the API library** ```bash npm install --save @adyen/api-library npm update @adyen/api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-node-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```js // Require the parts of the module you want to use. const { Client, CheckoutAPI, Types} = require("@adyen/api-library"); // Set up the client and service. const client = new Client({ apiKey: "ADYEN_API_KEY", environment: "TEST" }); const checkoutApi = new CheckoutAPI(client); // Include your idempotency key when you make an API request. const requestOptions = { idempotencyKey: "YOUR_IDEMPOTENCY_KEY" }; ``` ### Tab: Go ##### Try our example integration ![](/reuse/development-resources/install-api-library/go/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-golang-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/go/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-golang-online-payments). #### Requirements * Go 1.13 or later. #### Installation You can use [Go modules](https://github.com/golang/go/wiki/Modules): **Install the API library** ```shell go get github.com/adyen/adyen-go-api-library/vLATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-go-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```go package main import ( "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/adyen" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/checkout" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/common" ) // Create a payment object. func main () { client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) service := client.Checkout() ``` ### Tab: Python ##### Try our example integration ![](/reuse/development-resources/install-api-library/python/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-python-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/python/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-python-online-payments). #### Requirements * Python 3.6 or later. * (Optional) Packages: Requests or PycURL #### Installation You can use [pip](https://pip.pypa.io/en/stable/): **Install the API library** ```py pip install Adyen ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-python-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```py import Adyen # Set up the client and service. adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment that the library is used in. ``` ### Tab: Ruby ##### Try our example integration ![](/reuse/development-resources/install-api-library/ruby/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-rails-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/ruby/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-rails-online-payments). #### Requirements * Ruby 2.7 or later. #### Installation You can use [RubyGems](https://rubygems.org/): **Install the API library** ```bash gem install adyen-ruby-api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-ruby-api-library/releases). Run `bundle install` to install dependencies. #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```ruby require 'adyen-ruby-api-library' # Set up the client and service. adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # The environment that the library is used in. ``` ## Get available payment methods Payment server When your shopper is ready to pay, get a list of the available payment methods based on their country, device, and the payment amount. From your server, make a [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) request, specifying: | Parameter name | Required | Description | | ----------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | | The `currency` and `value` of the payment, in [minor units](/development-resources/currency-codes). This is used to filter the list of available payment methods to your shopper. | | `channel` | | The platform of the shopper's device; use **Web**. This is used to filter the list of available payment methods to your shopper. | | `countryCode` | | The shopper's country/region. This is used to filter the list of available payment methods to your shopper. Format: the two-letter [ISO-3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. Exception: **QZ** (Kosovo). | | `shopperLocale` | | By default, the `shopperlocale` is set to **en-US**. To change the language, set this to the shopper's language and country code. You also need to set the same `locale` within your Drop-in configuration. | The following example shows how to get the available payment methods for a shopper in the **Netherlands**, for a payment of **EUR 10**: #### curl ```bash curl https://checkout-test.adyen.com/v72/paymentMethods \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Web", "shopperLocale": "nl-NL" }' ``` #### Java ```java // Adyen Java API Library v28.4.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the live environment, additionally include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) Amount amount = new Amount() .currency("EUR") .value(1000L); PaymentMethodsRequest paymentMethodsRequest = new PaymentMethodsRequest() .amount(amount) .merchantAccount("ADYEN_MERCHANT_ACCOUNT") .countryCode("NL") .channel(PaymentMethodsRequest.ChannelEnum.WEB) .shopperLocale("nl-NL"); // Send the request PaymentsApi service = new PaymentsApi(client); PaymentMethodsResponse response = service.paymentMethods(paymentMethodsRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php // Adyen PHP API Library v20.3.0 use Adyen\Client; use Adyen\Environment; use Adyen\Model\Checkout\Amount; use Adyen\Model\Checkout\PaymentMethodsRequest; use Adyen\Service\Checkout\PaymentsApi; $client = new Client(); $client->setXApiKey("ADYEN_API_KEY"); // For the live environment, additionally include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $amount = new Amount(); $amount ->setCurrency("EUR") ->setValue(1000); $paymentMethodsRequest = new PaymentMethodsRequest(); $paymentMethodsRequest ->setAmount($amount) ->setMerchantAccount("ADYEN_MERCHANT_ACCOUNT") ->setCountryCode("NL") ->setChannel("Web") ->setShopperLocale("nl-NL"); $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->paymentMethods($paymentMethodsRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v20.0.0 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the live environment, additionally include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) Amount amount = new Amount { Currency = "EUR", Value = 1000 }; PaymentMethodsRequest paymentMethodsRequest = new PaymentMethodsRequest { Amount = amount, MerchantAccount = "ADYEN_MERCHANT_ACCOUNT", CountryCode = "NL", Channel = PaymentMethodsRequest.ChannelEnum.Web, ShopperLocale = "nl-NL" }; // Send the request var service = new PaymentsService(client); var response = service.PaymentMethods(paymentMethodsRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v19.3.0 // Require the parts of the module you want to use const { Client, CheckoutAPI } = require('@adyen/api-library'); // Initialize the client object // For the live environment, additionally include your liveEndpointUrlPrefix. const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Create the request object(s) const paymentMethodsRequest = { merchantAccount: "ADYEN_MERCHANT_ACCOUNT", countryCode: "NL", amount: { currency: "EUR", value: 1000 }, channel: "Web", shopperLocale: "nl-NL" } // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentMethods(paymentMethodsRequest, { idempotencyKey: "UUID" }); ``` #### Go ```go // Adyen Go API Library v12.2.0 import ( "context" "github.com/adyen/adyen-go-api-library/v9/src/common" "github.com/adyen/adyen-go-api-library/v9/src/adyen" "github.com/adyen/adyen-go-api-library/v9/src/checkout" ) // For the live environment, additionally include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) amount := checkout.Amount{ Currency: "EUR", Value: 1000, } paymentMethodsRequest := checkout.PaymentMethodsRequest{ Amount: &amount, MerchantAccount: "ADYEN_MERCHANT_ACCOUNT", CountryCode: common.PtrString("NL"), Channel: common.PtrString("Web"), ShopperLocale: common.PtrString("nl-NL"), } // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentMethodsInput().IdempotencyKey("UUID").PaymentMethodsRequest(paymentMethodsRequest) res, httpRes, err := service.PaymentsApi.PaymentMethods(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v12.7.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the live environment, additionally include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Web", "shopperLocale": "nl-NL" } # Send the request result = adyen.checkout.payments_api.payment_methods(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v9.7.1 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the live environment, additionally include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT', :countryCode => 'NL', :amount => { :currency => 'EUR', :value => 1000 }, :channel => 'Web', :shopperLocale => 'nl-NL' } # Send the request result = adyen.checkout.payments_api.payment_methods(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v19.3.0 // Require the parts of the module you want to use import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // Initialize the client object // For the live environment, additionally include your liveEndpointUrlPrefix. const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Create the request object(s) const amount: Types.checkout.Amount = { currency: "EUR", value: 1000 }; const paymentMethodsRequest: Types.checkout.PaymentMethodsRequest = { amount: amount, merchantAccount: "ADYEN_MERCHANT_ACCOUNT", countryCode: "NL", channel: Types.checkout.PaymentMethodsRequest.ChannelEnum.Web, shopperLocale: "nl-NL" }; // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentMethods(paymentMethodsRequest, { idempotencyKey: "UUID" }); ``` The response includes the list of available `paymentMethods`: **/paymentMethods response** ```json { "paymentMethods":[ { "details":[...], "name":"Cards", "type":"scheme" ... }, { "details":[...], "name":"SEPA Direct Debit", "type":"sepadirectdebit" }, ... ] } ``` Pass the response to your client website. You'll use this in the next step to show which payment methods are available for the shopper. ### Custom list of payment methods When you make a [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) request, the response includes all payment methods that you enabled in your Customer Area that are available for the transaction. To exclude payment methods from the available list of available payment methods for a specific transaction, include one of the following parameters when making your request: * [allowedPaymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods#request-allowedPaymentMethods): Drop-in renders only the payment methods that you specify. * [blockedPaymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods#request-blockedPaymentMethods): Drop-in doesn't render payment methods that you specify. ### Add Drop In ## Add Drop-in to your payments form Client website Next, use Drop-in to show the available payment methods, and to collect payment details from your shopper. Import using the Adyen Web npm package, or embed the Adyen Web script and stylesheet into your HTML file: ### Tab: npm (recommended) We offer two ways of importing with npm: * [Import Drop-in with all payment methods](#import-drop-in-with-all-payment-methods): this method resembles what you are used to before v6. You do not need to import individual payment methods, at the cost of a larger bundle size. * [Import Drop-in with individual payment methods](#import-drop-in-with-individual-payment-methods): this method uses tree shaking to let you import only the payment methods you use, speeding up loading time, at the cost of maintainability (adding payment methods requires developer resources). #### Import Drop-in with all payment methods Install the [Adyen Web Node package](https://www.npmjs.com/package/@adyen/adyen-web): ```bash npm install @adyen/adyen-web --save ``` Import Adyen Web into your application: ```js import { AdyenCheckout, Dropin } from '@adyen/adyen-web/auto'; import '@adyen/adyen-web/styles/adyen.css'; ``` #### Import Drop-in with individual payment methods Install the [Adyen Web Node package](https://www.npmjs.com/package/@adyen/adyen-web): ```bash npm install @adyen/adyen-web --save ``` Import Adyen Web into your application. ```js import { AdyenCheckout, Dropin, Card, GooglePay, PayPal } from '@adyen/adyen-web'; import '@adyen/adyen-web/styles/adyen.css'; ``` ### Tab: Embed script and stylesheet Use the `integrity` attribute so browsers can verify that the script and stylesheet have not been changed unexpectedly. The value of the `integrity` attribute is the [Subresource Integrity (SRI) hash](/online-payments/web-best-practices#implement-subresource-integrity-hashes) which Adyen provides for each version of the Adyen Web JavaScript and CSS files. Get the SRI hashes in the [release notes](/online-payments/release-notes?integration_type=web), under **Updating to this version**. **checkout.html** ```html ```    You can [add your own styling](/online-payments/build-your-integration/sessions-flow?platform=Web\&integration=Drop-in#optional-configuration) by overriding the rules in this CSS file. After you have imported the Adyen Web library, do the following: 1. Create a [Document Object Model (DOM) element](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) on your checkout page and put it where you want Drop-in to render on the page. ```html
``` If you are using JavaScript frameworks such as Vue or React, make sure that you use references instead of selectors and that you do not re-render the DOM element. []() 2. Create a global configuration object with the following parameters and events: | Parameter name | Required | Description | | ------------------------ | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `paymentMethodsResponse` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The full `/paymentMethods` response returned [when you get available payment methods](#get-available-payment-methods). | | `clientKey` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | A public key linked to your API credential, used for [client-side authentication](/development-resources/client-side-authentication). Web Drop-in versions before 3.10.1 use `originKey` instead. Find out how to [migrate from using `originKey` to `clientKey`](/development-resources/client-side-authentication/migrate-from-origin-key-to-client-key). | | `locale` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The shopper's locale. This is used to set the language rendered in the UI. For a list of supported locales, see [Language and localization](/online-payments/build-your-integration/sessions-flow?platform=Web\&integration=Drop-in#optional-configuration). | | `countryCode` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The shopper's country/region. This is used to filter the list of available payment methods to your shopper. Format: the two-letter [ISO-3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. Exception: **QZ** (Kosovo). | | `environment` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Use **test**. When you are ready to accept live payments, change the value to one of our [live environments](/online-payments/drop-in-web#testing-your-integration).  | | `secondaryAmount` | | Shows the payment amount in an additional currency on the **Pay** button. You must do the currency conversion and set the amount. This object has properties:- `currency`: The three-character [ISO currency code](/development-resources/currency-codes). - `value`: The amount of the transaction, in [minor units](/development-resources/currency-codes). - `currencyDisplay`: Sets the [currency formatting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#currencydisplay). Default: **symbol**. | | `showPayButton` | | Shows or hides a **Pay** Button for each payment method. Defaults to **true**. When set to **false**, you must override it in [`paymentMethodsConfiguration` ](/online-payments/build-your-integration/?platform=Web\&integration=Drop-in#configure). The **Pay** button triggers the `onSubmit` event when payment details are valid. If you want to disable the button and then trigger the submit flow on your own, set this to **false** and call the `.submit()` method from your own button implementation. PayPal Smart Payment Buttons doesn't support the `.submit()` method. | | `amount` | | Amount to be displayed on the **Pay** Button. It expects an object with the value and currency properties. For example, `{ value: 1000, currency: 'USD' }`. | | Event name | Required | Description | | --------------------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `onSubmit(state, dropin, actions)` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Create an event handler for this event, which is called when the shopper selects the **Pay** button, and the details are valid. This applies if the [`showPayButton` configuration parameter](#configure) is set to **true**. Makes a POST [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request. You must call `actions.resolve()`, passing `resultCode`, `action`, and `order` objects (if available) from the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, even if the payment is unsuccessful. If the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request from your server fails, or if an unexpected error occurs, call `actions.reject()`. | | `onAdditionalDetails(state, dropin, actions)` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Create an event handler, called when a payment method requires more details, for example for native 3D Secure 2, or native QR code payment methods. Makes a POST [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request. If the [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request from your server is successful, you must call `actions.resolve()`, passing `resultCode`, `action`, and `order` objects (if available) from the API response. You must call it even if the payment is unsuccessful. If the [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request from your server fails, or if an unexpected error occurs, call `actions.reject`. | | `onPaymentCompleted(result, component)` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Create an event handler, called when the payment is completed. | | `onPaymentFailed(result, component)` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Create an event handler, called when the payment failed. A failed payment has result code **Cancelled**, **Error** or **Refused**. | | `onError(error)` | | Create an event handler, called when an error occurs in Drop-in. | | `onChange(state, dropin)` | | Create an event handler, called when the shopper provides the required payment details. | | []()`onActionHandled` | | Create an event handler, called when an action, for example a QR code or 3D Secure 2 authentication screen, is shown to the shopper. The following `action.type` values trigger this callback:- `threeDS` - `qr` - `await`Returns data that contains:- `componentType`: The type of component that shows the action to the shopper. - `actionDescription`: A description of the action shown to the shopper. | **Create a configuration object** ```js const configuration = { clientKey: "YOUR_CLIENT_KEY", environment: "test", amount: { value: 1000, currency: 'EUR' }, locale: 'nl-NL', countryCode: 'NL', // The full /paymentMethods response object from your server. Contains the payment methods configured in your account. paymentMethodsResponse: paymentMethodsResponse, onSubmit: async (state, component, actions) => { try { // Make a POST /payments request from your server. const result = await makePaymentsCall(state.data, countryCode, locale, amount); // If the /payments request from your server fails, or if an unexpected error occurs. if (!result.resultCode) { actions.reject(); return; } const { resultCode, action, order, donationToken } = result; // If the /payments request request form your server is successful, you must call this to resolve whichever of the listed objects are available. // You must call this, even if the result of the payment is unsuccessful. actions.resolve({ resultCode, action, order, donationToken, }); } catch (error) { console.error("onSubmit", error); actions.reject(); } }, onAdditionalDetails: async (state, component, actions) => { try { // Make a POST /payments/details request from your server. const result = await makeDetailsCall(state.data); // If the /payments/details request from your server fails, or if an unexpected error occurs. if (!result.resultCode) { actions.reject(); return; } const { resultCode, action, order, donationToken } = result; // If the /payments/details request request from your server is successful, you must call this to resolve whichever of the listed objects are available. // You must call this, even if the result of the payment is unsuccessful. actions.resolve({ resultCode, action, order, donationToken, }); } catch (error) { console.error("onSubmit", error); actions.reject(); } }, onPaymentCompleted: (result, component) => { console.info(result, component); }, onPaymentFailed: (result, component) => { console.info(result, component); }, onError: (error, component) => { console.error(error.name, error.message, error.stack, component); } ); ``` 3. Create an instance of `AdyenCheckout`, passing the global configuration object you created: ```js const checkout = await AdyenCheckout(configuration); ``` 4. Create and mount an instance of `Dropin`, passing the instance of `AdyenCheckout` you created. You can add [optional Drop-in configuration](#drop-in-configuration) your instance of `Dropin`. How you create it depends on if you import resources for all payment methods or individual payment methods. ### Tab: All payment methods **checkout.js** ```js // Create an instance of Drop-in and mount it to the container you created. const dropin = new Dropin(checkout).mount('#dropin'); ``` ### Tab: Individual payment methods **checkout.js** ```js // Create an instance of Drop-in. const dropin = new Dropin(checkout, { // Include the payment methods that imported. paymentMethodComponents: [Card, PayPal, GooglePay, ApplePay, Ideal], // Mount it to the container you created. }).mount('#dropin'); ``` When the shopper selects the **Pay** button, Drop-in calls the `onSubmit` event, which contains a `state.data`. These are the shopper details that you need to make the payment. 5. Pass the `state.data` to your server. **Sample state from onSubmit event for a card payment** ```js { isValid: true, data: { paymentMethod: { type: "scheme", encryptedCardNumber: "adyenjs_0_1_18$k7s65M5V0KdPxTErhBIPoMPI8HlC..", encryptedExpiryMonth: "adyenjs_0_1_18$p2OZxW2XmwAA8C1Avxm3G9UB6e4..", encryptedExpiryYear: "adyenjs_0_1_18$CkCOLYZsdqpxGjrALWHj3QoGHqe+..", encryptedSecurityCode: "adyenjs_0_1_18$XUyMJyHebrra/TpSda9fha978+.." holderName: "S. Hopper" } } } ``` ### Configuring-Drop-In ### Optional Drop-in configuration You can add the following configuration parameters to the `Dropin` configuration: | Parameter name | Description | | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `openFirstPaymentMethod` | When enabled, Drop-in opens the first payment method automatically on page load. Defaults to **true**. | | `openFirstStoredPaymentMethod` | When enabled, Drop-in opens the payment method with stored card details on page load. This option takes precedence over `openFirstPaymentMethod`. Defaults to **true**. | | `openPaymentMethod.type` | Automatically selects the specified payment method when Drop-in renders. Set the [payment method type](/payment-methods/payment-method-types/) that you want to be automatically selected as the value. | | `showStoredPaymentMethods` | Shows or hides payment methods with stored card details. Defaults to **true**. | | `showRemovePaymentMethodButton` | Allows the shopper to remove a stored payment method. Defaults to **false**. If using this prop, you must also implement the `onDisableStoredPaymentMethod` callback. | | `showPaymentMethods` | Shows or hides regular (not stored) payment methods. Set to **false** if you only want to show payment methods with stored card details. Defaults to **true**. | | `paymentMethodsConfiguration` | Configuration for individual payment methods. The [payment method guides](/payment-methods) have configuration options specific to each payment method. If you include this in the configuration on your instance of `DropIn`, it overrides global payment method configuration on your instance of `AdyenCheckout`. | | `redirectFromTopWhenInIframe` | If your Drop-in is inside of an [iframe element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe), set to **true** if you want redirects to be performed on the top-level window. We recommend that you do not put Component in an iframe. | | `instantPaymentTypes` | Moves payment methods to the top of the list of available payment methods. This is available for [Apple Pay](/payment-methods/apple-pay/web-drop-in#instant-payment-button-configuration) and [Google Pay](/payment-methods/google-pay/web-drop-in#instant-payment-button-configuration). | | `disableFinalAnimation` | When enabled, disables the final animation after a shopper completes the payment (whether successful or failed). This lets you implement your own Defaults to **false**. | | `showRadioButton` | When enabled, payment methods in the Drop-in have a [radio button](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio). Defaults to **false**. | #### Events Use the following events to include additional logic on your checkout page: | Event name | Description | | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `onReady()` | Called when Drop-in is initialized and ready for use. | | `onSelect(component)` | Called when the shopper selects a payment method. | | `onDisableStoredPaymentMethod(storedPaymentMethodId, resolve, reject)` | Called when a shopper removes a stored payment method. To remove the selected payment method, make a **DELETE** `/storedPaymentMethod` request including the `storedPaymentMethodId`. Then call either `resolve()` or `reject()`, depending on the [/storedPaymentMethods/{storedPaymentMethodId}](https://docs.adyen.com/api-explorer/Checkout/latest/delete/storedPaymentMethods/\(storedPaymentMethodId\)) response. | #### Methods Drop-in supports the following methods: | Method name | Description | | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `mount(selector)` | Mounts the Drop-in into the DOM returned by the `selector`. The `selector` must be either a [valid CSS selector string](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector#parameters) or an [HTMLElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement) reference. | | `unmount()` | Unmounts the Drop-in from the DOM. We recommend to unmount in case the payment amount changes after the initial mount. | | `closeActivePaymentMethod()` | Closes a selected payment method, for example if you want to reset the Drop-in. | ### Optional Update Amount (optional) ## Optional: Update the payment amount You must use Checkout API v72 or later for this feature. After you create a session, the order amount can change before the shopper submits the payment. For example: the shopper adds or removes items from their cart, or applies a discount. You can update the session with the new amount so that the shopper pays the correct total. ### Update the session amount Client website Payment server 1. Trigger the `beforeSubmit` callback from your instance of `AdyenCheckout` to make a PATCH `/sessions/{sessionId}` request to update the session from your server, including the follow parameters: | Parameter | Required | Description | | ------------------------------ | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `sessionId` **Path parameter** | ![Required](/user/pages/reuse/image-library/01.icons/required/required.svg?decoding=auto\&fetchpriority=auto) | The ID of the session to update. | | `sessionData` | ![Required](/user/pages/reuse/image-library/01.icons/required/required.svg?decoding=auto\&fetchpriority=auto) | The encoded session data from the original [/sessions](https://docs.adyen.com/api-explorer/Checkout/latest/post/sessions) response. | | `amount.value` | ![Required](/user/pages/reuse/image-library/01.icons/required/required.svg?decoding=auto\&fetchpriority=auto) | The updated amount in [minor units](/development-resources/currency-codes). | | `amount.currency` | ![Required](/user/pages/reuse/image-library/01.icons/required/required.svg?decoding=auto\&fetchpriority=auto) | The three-character [ISO currency code](/development-resources/currency-codes). | | `payable` | | If you know that the amount in this request is the final amount, set to **true**. This indicates that the session is ready for payment. When you set this to true, you can no longer update the session. If you set to **false**, you must make another request to update the session and set to **true** before the shopper can submit the payment. | **Example request to update the session amount** ```bash curl https://checkout-test.adyen.com/v72/sessions/QFQTPCQ8HXSKGK82 \ -X PATCH \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'idempotency-key: YOUR_IDEMPOTENCY_KEY' \ -H 'content-type: application/json' \ -d '{ "sessionData": "Ab02b4c...", "amount": { "value": 10000, "currency": "EUR" }, "payable": true }' ``` After you set `payable` to **true**, you cannot update the session again. Only set this when you confirm the final amount, and the session is ready for payment. The response includes the updated session data. **Example response with updated session data** ```json { "sessionData": "Ab02b4c.." } ``` 2. Add the updated `sessionData` object to the `actions.resolve` method, to pass it to Drop-in. When you make a request to update the server-side session data, you must store and get the updated amount on your server. Do not get the updated amount from the client. **Example of the beforeSubmit callback to update the session** ```ts const checkout = await AdyenCheckout({ beforeSubmit: async (data, component, actions) => { try { // Get the latest session data. const { session } = component.core.session; // Make an PATCH /sessions/{sessionId} request to update the session. const updatedSessionData = await patchSession(session); // Add the updated session data to actions.resolve. actions.resolve({ ...data, sessionData: updatedSessionData }); } catch (error) { actions.reject(); } }, // ...Other configuration properties }); ``` ### Update the amount in Drop-in Client website Update the amount in Drop-in when the payment amount changes (for example, when the shopper adds or removes items from their cart). The amount can be updated multiple times without the need to update the server-side session data every time. The server-side session update is required only before the shopper can submit the payment. #### Show the updated amount to the shopper Client website To show the updated amount in the payment form: From your [instance of `AdyenCheckout`](/online-payments/build-your-integration/sessions-flow/#configure), call the `update` function and pass the new amount. **Example to update the amount in the payment form** ```ts // Create an amount object for the updated amount. const amount = { value: 1000, currency: 'USD' }; // Update the amount in the payment form, specifying not to reinitialize the checkout instance. checkout.update({ amount }, { shouldReinitializeCheckout: false }); ``` ## Make a payment Payment server After the shopper selects the **Pay** button or chooses to pay with a payment method that requires a redirection, you must make a payment request to Adyen. 1. Pass the data from `onSubmit` to your server 2. From your server, make a **POST** [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request including the following parameters: | Parameter name | Required | Description | | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The `currency` of the payment and its `value` in [minor units](/development-resources/currency-codes). | | `reference` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your unique reference for this payment. | | `paymentMethod` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The complete `state.data.paymentMethod` object from the `onSubmit` event from your client app. It includes the payment method details and other required information. | | `paymentMethod.sdkData` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The object that includes information collected by Drop-in to track the user's payment journey, including information like the [checkout attempt identifier](/online-payments/analytics-and-data-tracking#data-we-are-collecting). This is required to use the [Checkout dashboard](/uplift#uplift-dashboards) that lets you analyze your checkout performance. | | `returnUrl` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | URL to where the shopper should be taken back to after a redirection. The URL can contain a maximum of 1024 characters and should include the protocol: `http://` or `https://`. You can also include your own additional query parameters, for example, shopper ID or order reference number. If the URL to return to includes non-ASCII characters, like spaces or special letters, URL encode the value. The URL must not include personally identifiable information (PII), for example name or email address. | | `riskData` | | [Device characteristics and other data](/risk-management/fraud-data-collection) that we use to detect fraudulent payment activity, and mitigate fraud. | | [`applicationInfo`](/development-resources/building-adyen-solutions) | | If you are building an Adyen solution for multiple merchants, include some basic identifying information, so that we can offer you better support. For more information, refer to [Building Adyen solutions](/development-resources/building-adyen-solutions). | | `shopperEmail` | | The shopper's email address. Strongly recommended because this field is used in a number of [risk checks](/risk-management/configure-your-risk-profile/risk-field-reference), and for 3D Secure. | | `shopperIP` | | The shopper's IP address. Strongly recommended because this field is used in a number of [risk checks](/risk-management/configure-your-risk-profile/risk-field-reference). | | `shopperReference` | | Your reference to uniquely identify this shopper. Minimum length: three characters. Do not include personally identifiable information, for example name or email address. Strongly recommended because this field is used in a number of [risk checks](/risk-management/configure-your-risk-profile/risk-field-reference). | For the following cases, you must include additional parameters in your request: * Integrating some payment methods. For more information, go to [payment method integration guides](/payment-methods). * Using our risk management features. For more information, go to [data quality and risk field reference](/risk-management/configure-your-risk-profile/risk-field-reference). * [Native 3D Secure 2 authentication](/online-payments/3d-secure/native-3ds2/android-drop-in#make-a-payment). * [Creating a token](/online-payments/tokenization/create-tokens) to store the shopper's payment details. * [Using a token](/online-payments/tokenization/make-token-payments) to make a recurring payment with stored payment details. * Using [the Adyen Uplift Personalize module](/uplift#uplift-personalize) and accessing the [Checkout dashboard](/uplift#uplift-dashboards). **Example request to make a payment for EUR 10** #### curl ```bash curl https://checkout-test.adyen.com/v72/payments \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "amount": { "currency": "EUR", "value": 1000 }, "reference": "YOUR_ORDER_NUMBER", "paymentMethod":{ "type": "scheme", "encryptedCardNumber": "test_4111111111111111", "encryptedExpiryMonth": "test_03", "encryptedExpiryYear": "test_2030", "encryptedSecurityCode": "test_737" }, "returnUrl": "https://your-company.example.com/checkout?shopperOrder=12xy..", "riskData": { "clientData": "eyJ0cmFuc1N0YXR1cy...I6IlkifQ==" }, "checkoutAttemptId": "7m583f18-b533-4fn0...", "merchantAccount": "ADYEN_MERCHANT_ACCOUNT" }' ``` #### Java ```java // Adyen Java API Library v40.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the LIVE environment, also include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) Amount amount = new Amount() .currency("EUR") .value(1000L); CardDetails cardDetails = new CardDetails() .encryptedCardNumber("test_4111111111111111") .encryptedSecurityCode("test_737") .encryptedExpiryYear("test_2030") .encryptedExpiryMonth("test_03") .type(CardDetails.TypeEnum.SCHEME); RiskData riskData = new RiskData() .clientData("eyJ0cmFuc1N0YXR1cy...I6IlkifQ=="); PaymentRequest paymentRequest = new PaymentRequest() .reference("YOUR_ORDER_NUMBER") .amount(amount) .merchantAccount("ADYEN_MERCHANT_ACCOUNT") .paymentMethod(new CheckoutPaymentMethod(cardDetails)) .checkoutAttemptId("7m583f18-b533-4fn0...") .returnUrl("https://your-company.example.com/checkout?shopperOrder=12xy..") .riskData(riskData); // Send the request PaymentsApi service = new PaymentsApi(client); PaymentResponse response = service.payments(paymentRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("ADYEN_API_KEY"); // For the LIVE environment, also include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $amount = new Amount(); $amount ->setCurrency("EUR") ->setValue(1000); $checkoutPaymentMethod = new CheckoutPaymentMethod(); $checkoutPaymentMethod ->setEncryptedCardNumber("test_4111111111111111") ->setEncryptedSecurityCode("test_737") ->setEncryptedExpiryYear("test_2030") ->setEncryptedExpiryMonth("test_03") ->setType("scheme"); $riskData = new RiskData(); $riskData ->setClientData("eyJ0cmFuc1N0YXR1cy...I6IlkifQ=="); $paymentRequest = new PaymentRequest(); $paymentRequest ->setReference("YOUR_ORDER_NUMBER") ->setAmount($amount) ->setMerchantAccount("ADYEN_MERCHANT_ACCOUNT") ->setPaymentMethod($checkoutPaymentMethod) ->setCheckoutAttemptId("7m583f18-b533-4fn0...") ->setReturnUrl("https://your-company.example.com/checkout?shopperOrder=12xy..") ->setRiskData($riskData); $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->payments($paymentRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v32.1.2 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the LIVE environment, also include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) Amount amount = new Amount { Currency = "EUR", Value = 1000 }; CardDetails cardDetails = new CardDetails { EncryptedCardNumber = "test_4111111111111111", EncryptedSecurityCode = "test_737", EncryptedExpiryYear = "test_2030", EncryptedExpiryMonth = "test_03", Type = CardDetails.TypeEnum.Scheme }; RiskData riskData = new RiskData { ClientData = "eyJ0cmFuc1N0YXR1cy...I6IlkifQ==" }; PaymentRequest paymentRequest = new PaymentRequest { Reference = "YOUR_ORDER_NUMBER", Amount = amount, MerchantAccount = "ADYEN_MERCHANT_ACCOUNT", PaymentMethod = new CheckoutPaymentMethod(cardDetails), CheckoutAttemptId = "7m583f18-b533-4fn0...", ReturnUrl = "https://your-company.example.com/checkout?shopperOrder=12xy..", RiskData = riskData }; // Send the request var service = new PaymentsService(client); var response = service.Payments(paymentRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v29.1.0 const { Client, CheckoutAPI } = require('@adyen/api-library'); // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const paymentRequest = { amount: { currency: "EUR", value: 1000 }, reference: "YOUR_ORDER_NUMBER", paymentMethod: { type: "scheme", encryptedCardNumber: "test_4111111111111111", encryptedExpiryMonth: "test_03", encryptedExpiryYear: "test_2030", encryptedSecurityCode: "test_737" }, returnUrl: "https://your-company.example.com/checkout?shopperOrder=12xy..", riskData: { clientData: "eyJ0cmFuc1N0YXR1cy...I6IlkifQ==" }, checkoutAttemptId: "7m583f18-b533-4fn0...", merchantAccount: "ADYEN_MERCHANT_ACCOUNT" } // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.payments(paymentRequest, { idempotencyKey: "UUID" }); ``` #### Go ```go // Adyen Go API Library v21.0.0 import ( "context" "github.com/adyen/adyen-go-api-library/v21/src/common" "github.com/adyen/adyen-go-api-library/v21/src/adyen" "github.com/adyen/adyen-go-api-library/v21/src/checkout" ) // For the LIVE environment, also include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) amount := checkout.Amount{ Currency: "EUR", Value: 1000, } cardDetails := checkout.CardDetails{ EncryptedCardNumber: common.PtrString("test_4111111111111111"), EncryptedSecurityCode: common.PtrString("test_737"), EncryptedExpiryYear: common.PtrString("test_2030"), EncryptedExpiryMonth: common.PtrString("test_03"), Type: common.PtrString("scheme"), } riskData := checkout.RiskData{ ClientData: common.PtrString("eyJ0cmFuc1N0YXR1cy...I6IlkifQ=="), } paymentRequest := checkout.PaymentRequest{ Reference: "YOUR_ORDER_NUMBER", Amount: amount, MerchantAccount: "ADYEN_MERCHANT_ACCOUNT", PaymentMethod: checkout.CardDetailsAsCheckoutPaymentMethod(&cardDetails), CheckoutAttemptId: common.PtrString("7m583f18-b533-4fn0..."), ReturnUrl: "https://your-company.example.com/checkout?shopperOrder=12xy..", RiskData: &riskData, } // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentsInput().IdempotencyKey("UUID").PaymentRequest(paymentRequest) res, httpRes, err := service.PaymentsApi.Payments(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.6.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "amount": { "currency": "EUR", "value": 1000 }, "reference": "YOUR_ORDER_NUMBER", "paymentMethod": { "type": "scheme", "encryptedCardNumber": "test_4111111111111111", "encryptedExpiryMonth": "test_03", "encryptedExpiryYear": "test_2030", "encryptedSecurityCode": "test_737" }, "returnUrl": "https://your-company.example.com/checkout?shopperOrder=12xy..", "riskData": { "clientData": "eyJ0cmFuc1N0YXR1cy...I6IlkifQ==" }, "checkoutAttemptId": "7m583f18-b533-4fn0...", "merchantAccount": "ADYEN_MERCHANT_ACCOUNT" } # Send the request result = adyen.checkout.payments_api.payments(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v10.4.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :amount => { :currency => 'EUR', :value => 1000 }, :reference => 'YOUR_ORDER_NUMBER', :paymentMethod => { :type => 'scheme', :encryptedCardNumber => 'test_4111111111111111', :encryptedExpiryMonth => 'test_03', :encryptedExpiryYear => 'test_2030', :encryptedSecurityCode => 'test_737' }, :returnUrl => 'https://your-company.example.com/checkout?shopperOrder=12xy..', :riskData => { :clientData => 'eyJ0cmFuc1N0YXR1cy...I6IlkifQ==' }, :checkoutAttemptId => '7m583f18-b533-4fn0...', :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT' } # Send the request result = adyen.checkout.payments_api.payments(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v29.1.0 import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const amount: Types.checkout.Amount = { currency: "EUR", value: 1000 }; const cardDetails: Types.checkout.CardDetails = { encryptedCardNumber: "test_4111111111111111", encryptedSecurityCode: "test_737", encryptedExpiryYear: "test_2030", encryptedExpiryMonth: "test_03", type: Types.checkout.CardDetails.TypeEnum.Scheme }; const riskData: Types.checkout.RiskData = { clientData: "eyJ0cmFuc1N0YXR1cy...I6IlkifQ==" }; const paymentRequest: Types.checkout.PaymentRequest = { reference: "YOUR_ORDER_NUMBER", amount: amount, merchantAccount: "ADYEN_MERCHANT_ACCOUNT", paymentMethod: cardDetails, checkoutAttemptId: "7m583f18-b533-4fn0...", returnUrl: "https://your-company.example.com/checkout?shopperOrder=12xy..", riskData: riskData }; // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.payments(paymentRequest, { idempotencyKey: "UUID" }); ``` []() 3. Your next step depends on if the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response contains an `action` object: * If the response has no `action` object, [get the payment outcome](#get-the-payment-outcome). * If the response contains an `action` object, [handle the additional action](#additional-action). **Example response for iDEAL, a redirect payment method** ```json { "resultCode": "RedirectShopper", "action": { "paymentMethodType": "ideal", "url": "https://checkoutshopper-test.adyen.com/checkoutshopper/checkoutPaymentRedirect?redirectData=X6Xtf...", "method": "GET", "type": "redirect" } } ``` ### Handle Additional Actions ## Handle the additional action Client website Some payment methods require additional action from the shopper. Common examples of additional actions include: * Logging in to a bank's website or app. * Authenticating a payment with 3D Secure 2. * Scanning a QR code. Implement logic to handle all action types, so that your integration can handle different payment methods. To see if an individual payment method requires an additional action, see the corresponding [payment method guide](/payment-methods) for it. To handle the additional action: 1. Pass the `action` object from your server to the `onSubmit` `actions.resolve()` function. 2. Drop-in performs additional actions depending on the value of `action.type`. | Type | `action.type` value | | ----------------------------------------------------------------------- | ------------------- | | [Redirect action](#handle-the-redirect) | **redirect** | | [3D Secure 2 authentication action](#3d-secure-2-authentication-action) | **threeDS2** | | [QR code action](#qr-code-action) | **qrCode** | | [SDK action](#sdk-action) | **sdk** | | [Voucher action](#voucher-action) | **voucher** | | [Await action](#await-action) | **await** | ### Redirect action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type` **redirect**, Drop-in redirects your shopper to another website to complete the payment. 1. When the shopper finishes their payment on the other website, they are returned to your `returnUrl` with an HTTP GET request. The `returnUrl` is appended with a Base64-encoded `redirectResult`. **Example return URL** ```raw GET /?shopperOrder=12xy..&&redirectResult=X6XtfGC3%21Y... HTTP/1.1 Host: www.your-company.example.com/checkout ``` If the shopper fails to return to your website, you do not get the `redirectResult`. Instead, wait for the corresponding [webhook](#update-your-order-management-system) for the outcome of the payment. To process the result: 1. Get the `redirectResult` appended to your return URL. You do not need to decode it. 2. Pass the `redirectResult` to your server. 3. [Send additional payment details](#send-additional-payment-details) to complete the payment flow. **Example JavaScript code snippet to handle redirectResult** ```js function handleRedirectResult() { // 1. Get the redirectResult from your return URL. const urlParams = new URLSearchParams(window.location.search); const redirectResult = urlParams.get('redirectResult'); if (redirectResult) { // 2. Pass the redirectResult to your server. // 3. Your server makes the /payments/details request. Adyen's server processes the encoded redirectResult value. fetch('/api/handle-payment-redirect', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ redirectResult: redirectResult }), }) .then(response => response.json()) .then(data => { // Verify the resultCode from your server's response. if (data && data.resultCode === 'Authorised') { console.log('Payment authorized successfully!'); // Handle successful payment authorization. For example: show a confirmation message or redirect the shopper to a confirmation page. } else { console.log('Payment failed or denied.'); // Handle payment failure. For example: show an error message or redirect the shopper to an error page. } }) .catch(error => { console.error('Error sending redirect result or processing server response:', error); // Handle network errors or issues with server communication. }); } } // Call this function when your page loads. handleRedirectResult(); ``` ### 3D Secure 2 authentication action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **threeDS2**, the payment qualifies for 3D Secure 2 and it goes through the [frictionless or the challenge flow](/online-payments/3d-secure/#authentication-flows). 1. Drop-in handles 3D Secure 2 authentication. If a challenge is required, the shopper performs the authentication challenge to complete the payment. 2. Drop-in calls `onAddtionalDetails`. 3. Pass the `state.data` from `onAdditionalDetails` to your server. 4. [Send additional payment details](#send-additional-payment-details) to complete the payment flow. ### QR code action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **qrCode**, the shopper must scan a QR code to complete the payment. 1. Drop-in shows the QR code to the shopper. 2. The shopper scans the QR code to complete the payment. 3. Drop-in calls `onAddtionalDetails`. 4. Pass the `state.data` from `onAdditionalDetails` to your server. 5. [Send additional payment details](#send-additional-payment-details) to complete the payment flow. ### SDK action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **sdk**, the shopper must use another UI overlay to complete the payment. For example, a payment method requires the shopper to use its specific UI to enter payment details. 2. Drop-in shows a different UI in an overlay. 3. The shopper uses the UI overlay to complete the payment. 4. Drop-in calls `onAddtionalDetails`. 5. Pass the `state.data` from `onAdditionalDetails` to your server. 6. [Send additional payment details](#send-additional-payment-details) to complete the payment flow. ### Voucher action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **voucher**, the shopper must use a voucher to complete the payment. 1. Drop-in shows the voucher to the shopper. 2. The shopper uses the voucher to pay outside of your website. 3. You [get the payment outcome](#get-the-payment-outcome). ### Await action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **await**, the shopper must take an additional action to complete the payment. For example: entering a code into their banking app. 1. Drop-in shows the instructions for the additional action to complete the payment. 2. The shopper does the additional action. 3. Drop-in calls `onAddtionalDetails` or `onError`, depending on the result of the additional action. 4. Pass the `state.data` from `onAdditionalDetails` or `onError` to your server. 5. [Send additional payment details](#send-additional-payment-details) to complete the payment flow. ### Submit Additional Payment Details ## Send additional payment details Payment server If you [handled an additional action](#additional-action), you must send additional payment details. **For redirects**: if the shopper fails to return to your website, you do not get additional payment details to send. Instead, wait for the corresponding [webhook](#update-your-order-management-system) for the outcome of the payment. 1. Pass additional payment details to your server, depending on the action you handled: * If you handled a redirect: pass the `redirectResult`. * If you handled a non-redirect additional action: pass the complete `state.data` object from the `onAdditionalDetails` event. 2. From your server, make a POST [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request including the `redirectResult` or the full `state.data` object, depending on the action you handled. **Example request to send additional payment details** #### curl ```bash curl https://checkout-test.adyen.com/v72/payments/details \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{hint:object passed from your client app}STATE_DATA{/hint}' ``` #### Java ```java // Set your X-API-KEY with the API key from the Customer Area. String xApiKey = "ADYEN_API_KEY"; Client client = new Client(xApiKey,Environment.TEST); Checkout checkout = new Checkout(client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. PaymentsDetailsRequest paymentsDetailsRequest = STATE_DATA; PaymentsResponse paymentsDetailsResponse = checkout.paymentsDetails(paymentsDetailsRequest); ``` #### PHP ```php // Set your X-API-KEY with the API key from the Customer Area. $client = new \Adyen\Client(); $client->setEnvironment(\Adyen\Environment::TEST); $client->setXApiKey("ADYEN_API_KEY"); $service = new \Adyen\Service\Checkout($client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. $params = STATE_DATA; $result = $service->paymentsDetails($params); // Check if further action is needed. if (array_key_exists("action", $result)){ // Pass the action object to your client. // $result["action"] } else { // No further action needed, pass the resultCode to your client. // $result['resultCode'] } ``` #### C\# ```cs // Set your X-API-KEY with the API key from the Customer Area. string apiKey = "ADYEN_API_KEY"; var client = new Client (apiKey, Environment.Test); var checkout = new Checkout(client); // STATE_DATA is an object passed from the client app, deserialized from JSON to a data structure. var paymentsDetailsRequest = STATE_DATA; var paymentsDetailsResponse = checkout.PaymentDetails(paymentsDetailsRequest); ``` #### NodeJS (JavaScript) ```js const {Client, Config, CheckoutAPI} = require('@adyen/api-library'); const config = new Config(); // Set your X-API-KEY with the API key from the Customer Area. config.apiKey = '[ADYEN_API_KEY]'; const client = new Client({ config }); client.setEnvironment("TEST"); const checkout = new CheckoutAPI(client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. checkout.paymentsDetails(STATE_DATA).then(res => res); ``` #### Go ```go import ( "github.com/adyen/adyen-go-api-library/v5/src/checkout" "github.com/adyen/adyen-go-api-library/v5/src/common" "github.com/adyen/adyen-go-api-library/v5/src/adyen" ) // Set your X-API-KEY with the API key from the Customer Area. client := adyen.NewClient(&common.Config{ Environment: common.TestEnv, ApiKey: "[ADYEN_API_KEY]", }) // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. req := STATE_DATA; res, httpRes, err := client.Checkout.PaymentsDetails(&req) ``` #### Python ```py # Set your X-API-KEY with the API key from the Customer Area. adyen = Adyen.Adyen() adyen.payment.client.platform = "test" adyen.client.xapikey = 'ADYEN_API_KEY' # STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. request = STATE_DATA result = adyen.checkout.payments_details(request) # Check if further action is needed. if 'action' in result.message: # Pass the action object to your client. # result.message['action'] else: # No further action needed, pass the resultCode to your client. # result.message['resultCode'] ``` #### Ruby ```ruby require 'adyen-ruby-api-library' # Set your X-API-KEY with the API key from the Customer Area. adyen = Adyen::Client.new adyen.env = :test adyen.api_key = "ADYEN_API_KEY" # STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. request = STATE_DATA response = adyen.checkout.payments.details(request) # Check if further action is needed. if response.body.has_key(:action) # Pass the action object to your client puts response.body[:action] else # No further action needed, pass the resultCode to your client puts response.body[:resultCode] end ``` 3. Pass the [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) response from your server to your client app. **Example response for a successful payment** ```json { "pspReference": "NC6HT9CRT65ZGN82", "resultCode": "Authorised" } ``` **Example response for a refused payment** ```json { "pspReference": "KHQC5N7G84BLNK43", "refusalReason": "Not enough balance", "resultCode": "Refused" } ``` ## Get the payment outcome After Drop-in finishes the payment flow, you can show the shopper the current payment status. Adyen sends a webhook with the outcome of the payment. ### Inform the shopper Client website Use the [`resultCode` ](/online-payments/payment-result-codes)from the `onPaymentCompleted` or `onPaymentFailed` event to show the shopper the [current payment status](/account/payments-lifecycle). This synchronous response doesn't give you the final outcome of the payment. You get the final payment status in a webhook that you use to [update your order management system](#update-your-order-management-system). ### Update your order management system Webhook server You get the outcome of each payment asynchronously, in an **AUTHORISATION** [webhook](/development-resources/webhooks). Use the `merchantReference` from the webhook to match it to your order reference.\ For a successful payment, the event contains `success`: **true**. **Example webhook for a successful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"033899:1111:03/2030", "amount":{ "currency":"EUR", "value":2500 }, "operations":["CANCEL","CAPTURE","REFUND"], "success":"true", "paymentMethod":"mc", "additionalData":{ "expiryDate":"03/2030", "authCode":"033899", "cardBin":"411111", "cardSummary":"1111" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"NC6HT9CRT65ZGN82", "eventDate":"2021-09-13T14:10:22+02:00" } } ] } ``` For an unsuccessful payment, you get `success`: **false**, and the `reason` field has details about why the payment was unsuccessful. **Example webhook for an unsuccessful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"validation 101 Invalid card number", "amount":{ "currency":"EUR", "value":2500 }, "success":"false", "paymentMethod":"unknowncard", "additionalData":{ "expiryDate":"03/2030", "cardBin":"411111", "cardSummary":"1112" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"KHQC5N7G84BLNK43", "eventDate":"2021-09-13T14:14:05+02:00" } } ] } ``` ## Error handling In case you encounter errors in your integration, refer to the following: * [API error codes](/development-resources/error-codes): If you receive a non-HTTP 200 response, use the `errorCode` to troubleshoot and modify your request. * [Payment refusals](/development-resources/refusal-reasons): If you receive an HTTP 200 response with an **Error** or **Refused** `resultCode`, check the refusal reason and, if possible, modify your request. ## Test and go live Before going live, use our list of [test cards and other payment methods](/development-resources/test-cards-and-credentials/test-card-numbers) to test your integration. We recommend testing each payment method that you intend to offer to your shoppers. You can check the status of a test payment in your [Customer Area](https://ca-test.adyen.com/), under **Transactions** > **Payments**. To debug or troubleshoot test payments, you can also use [API logs](/development-resources/logs-resources/api-logs) in your test environment. When you are ready to go live, you need to: 1. [Apply for a live account](/get-started-with-adyen/application-requirements). Review the process to start accepting payments on [Get started with Adyen](/get-started-with-adyen). 2. Assess your [PCI DSS compliance](/development-resources/pci-dss-compliance-guide#online-payments) by submitting the [Self-Assessment Questionnaire-A](https://www.pcisecuritystandards.org/documents/PCI-DSS-v3_2_1-SAQ-A.pdf). 3. [Configure your live account](/online-payments/go-live-checklist).  4. Submit a request to add payment methods in your [live Customer Area](https://ca-live.adyen.com/) . 5. Switch from test to our [live endpoints](/development-resources/live-endpoints#checkout-endpoints). Make sure that all API requests you make for the same payment session use the same live endpoint region. Using different regions for [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) and [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) requests may result in errors, for example, when authenticating with 3D Secure 2. 6. Load Drop-in from one of our live environments and set the `environment` to match your live endpoints: | Endpoint region | Value | | ------------------------- | ------------ | | Europe (EU) live | **live** | | United States (US) live | **live-us** | | Australia (AU) live | **live-au** | | Northeast Asia (NEA) live | **live-nea** | | India (IN) live | **live-in** | ## See also * [Tokenization](/online-payments/tokenization) * [3D Secure](/online-payments/3d-secure) * [PCI DSS compliance guide](/development-resources/pci-dss-compliance-guide) * [Adyen Uplift requirements and recommendations](/uplift/uplift-requirements) ## Next steps [required](/online-payments/modify-payments) [Modify payments](/online-payments/modify-payments) [Find out how to cancel, refund, or capture a payment using our API.](/online-payments/modify-payments) [Add payment methods](/payment-methods#add-payment-methods-to-your-account) [Learn about payment methods and how to add them to your account.](/payment-methods#add-payment-methods-to-your-account) [Tokenization](/online-payments/tokenization) [Save shopper payment details for later payments.](/online-payments/tokenization) [3D Secure authentication](/online-payments/3d-secure) [Comply with regulations such as PSD2 SCA in Europe.](/online-payments/3d-secure) ## Web Components Use our customizable UI components ### Intro Components is our pre-built UI solution for accepting payments on your website. Each component renders a payment method which you can place anywhere on your website. This integration requires you to make API requests to [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods), [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments), and [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) endpoints. Adding new payment methods usually doesn't require more development work. Components supports [cards](/payment-methods/cards/web-drop-in), [wallets](/payment-methods), and [most local payment methods](/payment-methods). ### Version Update ## Introducing Web v6 ### Improvements The Web v6 library introduces the following improvements: * Reduced bundle size through tree shaking * Enhanced design * Enhanced Typescript developer experience * Better alignment of express payment methods * Added support for 6 localizations * Support for Apple Pay Order tracking * Improve AVS checks for Google Pay and Apple Pay To upgrade your existing integration, see [Upgrade to Adyen Web v6](/online-payments/upgrade-your-integration/upgrade-to-web-v6) ### Before You Begin ## Requirements ##### Check out our Node.js + Express tutorial Follow our tutorial to [integrate Drop-in with Node.js and Express](/online-payments/build-your-integration/advanced-flow/web-drop-in-tutorial). Before you begin to integrate, make sure you have followed the [Get started with Adyen guide](/get-started-with-adyen) to: * Get an overview of the steps needed to accept live payments. * Create your test account. After you have created your test account: * [Get your API key](/development-resources/api-credentials#generate-api-key). * [Get your client key](/development-resources/client-side-authentication#get-your-client-key). * [Set up webhooks](/development-resources/webhooks) to know the payment outcome. To make sure that your 3D Secure integration works on Chrome, your cookies need to have the SameSite attribute. For more information, refer to [Chrome SameSite Cookie policy](https://developers.google.com/search/blog/2020/01/get-ready-for-new-samesitenone-secure). ## How it works To handle native 3D Secure 2 authentication: 1. [Get additional shopper details in your payment form](#get-additional-shopper-details). 2. [Make a payment request](#make-a-payment), including additional shopper details. 3. [Handle the 3D Secure 2 action](#handle-the-3d-secure-2-action) to perform the authentication flow. 4. [Submit the authentication result](#submit-authentication-result). 5. [Show the payment result](#show-the-payment-result). ### Install Api Library ## Install an API library Payment server We provide server-side API libraries for several programming languages, available through common package managers, like Gradle and npm, for easier installation and version management. Our API libraries will save you development time, because they: * Use an API version that is up to date. * Have generated models to help you construct requests. * Send the request to Adyen using their built-in HTTP client, so you do not have to create your own. ### Tab: Java ##### Try our example integration ![](/reuse/development-resources/install-api-library/java/advanced/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-java-spring-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/java/advanced/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-java-spring-online-payments). #### Requirements * Java 11 or later. #### Installation You can use [Maven](https://maven.apache.org), adding this dependency to your project's POM. **Add the API library** ```xml com.adyen adyen-java-api-library LATEST_VERSION ``` You can find the latest version on GitHub. Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-java-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```java // Import the required classes. package com.adyen.service; import com.adyen.Client; import com.adyen.service.checkout.PaymentsApi; import com.adyen.model.checkout.Amount; import com.adyen.enums.Environment; import com.adyen.service.exception.ApiException; import java.io.IOException; public class Snippet { public Snippet() throws IOException, ApiException { // Set up the client and service. Client client = new Client("ADYEN_API_KEY", Environment.TEST); } } ``` ### Tab: PHP ##### Try our example integration ![](/reuse/development-resources/install-api-library/php/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-php-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/php/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-php-online-payments). #### Requirements * PHP 7.3 or later. * cURL with SSL support. * The JSON PHP extension. * The list of dependencies from the composer require list. #### Installation You can use [Composer](https://getcomposer.org/). Follow the [installation instructions](https://getcomposer.org/doc/00-intro.md) if you do not already have composer installed. **Install the API library** ```bash composer require adyen/php-api-library ``` In your PHP script, make sure you include the autoloader: **Include the autoloader** ```php require __DIR__ . '/vendor/autoload.php'; ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-php-api-library/releases). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```php use Adyen\Model\Checkout\Amount; use Adyen\Model\Checkout\CreateCheckoutSessionRequest; use Adyen\Service\Checkout\PaymentsApi; // Include your idempotency key when you make an API request. $requestOptions['idempotencyKey'] = "YOUR_IDEMPOTENCY_KEY"; // Set up the client and service. $client = new \Adyen\Client(); $client->setXApiKey('ADYEN_API_KEY'); $client->setEnvironment(\Adyen\Environment::TEST); $service = new PaymentsApi($client); ``` ### Tab: C\# #### Requirements * .NET standard 2.0 or later. * For Terminal API certificate validation, set the application to either of the following: * .NET core 2.1 or later * .NET framework 4.6.1 or later #### Installation You can use [NuGet](https://www.nuget.org/packages/Adyen/): **Install the API library** ```bash PM> Install-Package Adyen -Version LATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-dotnet-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```cs using Adyen; using Adyen.Model.Checkout; using Adyen.Service.Checkout; using Environment = Adyen.Model.Environment; class Program { static void Main() { // Set up the client and service. var config = new Config { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); var checkout = new PaymentsService(client); // Include your idempotency key when you make an API request. var requestOptions = new Adyen.Model.RequestOptions { IdempotencyKey = "YOUR_IDEMPOTENCY_KEY" }; } } ``` ### Tab: NodeJS ##### Try our example integration ![](/reuse/development-resources/install-api-library/node-js/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-node-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/node-js/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-node-online-payments). #### Requirements * Node.js version 18 or later. #### Installation You can use [npm](https://www.npmjs.com/): **Install the API library** ```bash npm install --save @adyen/api-library npm update @adyen/api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-node-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```js // Require the parts of the module you want to use. const { Client, CheckoutAPI, Types} = require("@adyen/api-library"); // Set up the client and service. const client = new Client({ apiKey: "ADYEN_API_KEY", environment: "TEST" }); const checkoutApi = new CheckoutAPI(client); // Include your idempotency key when you make an API request. const requestOptions = { idempotencyKey: "YOUR_IDEMPOTENCY_KEY" }; ``` ### Tab: Go ##### Try our example integration ![](/reuse/development-resources/install-api-library/go/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-golang-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/go/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-golang-online-payments). #### Requirements * Go 1.13 or later. #### Installation You can use [Go modules](https://github.com/golang/go/wiki/Modules): **Install the API library** ```shell go get github.com/adyen/adyen-go-api-library/vLATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-go-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```go package main import ( "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/adyen" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/checkout" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/common" ) // Create a payment object. func main () { client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) service := client.Checkout() ``` ### Tab: Python ##### Try our example integration ![](/reuse/development-resources/install-api-library/python/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-python-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/python/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-python-online-payments). #### Requirements * Python 3.6 or later. * (Optional) Packages: Requests or PycURL #### Installation You can use [pip](https://pip.pypa.io/en/stable/): **Install the API library** ```py pip install Adyen ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-python-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```py import Adyen # Set up the client and service. adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment that the library is used in. ``` ### Tab: Ruby ##### Try our example integration ![](/reuse/development-resources/install-api-library/ruby/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-rails-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/ruby/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-rails-online-payments). #### Requirements * Ruby 2.7 or later. #### Installation You can use [RubyGems](https://rubygems.org/): **Install the API library** ```bash gem install adyen-ruby-api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-ruby-api-library/releases). Run `bundle install` to install dependencies. #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```ruby require 'adyen-ruby-api-library' # Set up the client and service. adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # The environment that the library is used in. ``` ## Get available payment methods Payment server When your shopper is ready to pay, get a list of the available payment methods based on their country, device, and the payment amount. From your server, make a [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) request, specifying: | Parameter name | Required | Description | | ----------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | | The `currency` and `value` of the payment, in [minor units](/development-resources/currency-codes). This is used to filter the list of available payment methods to your shopper. | | `channel` | | The platform of the shopper's device; use **Web**. This is used to filter the list of available payment methods to your shopper. | | `countryCode` | | The shopper's country/region. This is used to filter the list of available payment methods to your shopper. Format: the two-letter [ISO-3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. Exception: **QZ** (Kosovo). | | `shopperLocale` | | By default, the `shopperlocale` is set to **en-US**. To change the language, set this to the shopper's language and country code. You also need to set the same `locale` within your Drop-in configuration. | The following example shows how to get the available payment methods for a shopper in the **Netherlands**, for a payment of **EUR 10**: #### curl ```bash curl https://checkout-test.adyen.com/v72/paymentMethods \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Web", "shopperLocale": "nl-NL" }' ``` #### Java ```java // Adyen Java API Library v28.4.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the live environment, additionally include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) Amount amount = new Amount() .currency("EUR") .value(1000L); PaymentMethodsRequest paymentMethodsRequest = new PaymentMethodsRequest() .amount(amount) .merchantAccount("ADYEN_MERCHANT_ACCOUNT") .countryCode("NL") .channel(PaymentMethodsRequest.ChannelEnum.WEB) .shopperLocale("nl-NL"); // Send the request PaymentsApi service = new PaymentsApi(client); PaymentMethodsResponse response = service.paymentMethods(paymentMethodsRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php // Adyen PHP API Library v20.3.0 use Adyen\Client; use Adyen\Environment; use Adyen\Model\Checkout\Amount; use Adyen\Model\Checkout\PaymentMethodsRequest; use Adyen\Service\Checkout\PaymentsApi; $client = new Client(); $client->setXApiKey("ADYEN_API_KEY"); // For the live environment, additionally include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $amount = new Amount(); $amount ->setCurrency("EUR") ->setValue(1000); $paymentMethodsRequest = new PaymentMethodsRequest(); $paymentMethodsRequest ->setAmount($amount) ->setMerchantAccount("ADYEN_MERCHANT_ACCOUNT") ->setCountryCode("NL") ->setChannel("Web") ->setShopperLocale("nl-NL"); $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->paymentMethods($paymentMethodsRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v20.0.0 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the live environment, additionally include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) Amount amount = new Amount { Currency = "EUR", Value = 1000 }; PaymentMethodsRequest paymentMethodsRequest = new PaymentMethodsRequest { Amount = amount, MerchantAccount = "ADYEN_MERCHANT_ACCOUNT", CountryCode = "NL", Channel = PaymentMethodsRequest.ChannelEnum.Web, ShopperLocale = "nl-NL" }; // Send the request var service = new PaymentsService(client); var response = service.PaymentMethods(paymentMethodsRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v19.3.0 // Require the parts of the module you want to use const { Client, CheckoutAPI } = require('@adyen/api-library'); // Initialize the client object // For the live environment, additionally include your liveEndpointUrlPrefix. const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Create the request object(s) const paymentMethodsRequest = { merchantAccount: "ADYEN_MERCHANT_ACCOUNT", countryCode: "NL", amount: { currency: "EUR", value: 1000 }, channel: "Web", shopperLocale: "nl-NL" } // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentMethods(paymentMethodsRequest, { idempotencyKey: "UUID" }); ``` #### Go ```go // Adyen Go API Library v12.2.0 import ( "context" "github.com/adyen/adyen-go-api-library/v9/src/common" "github.com/adyen/adyen-go-api-library/v9/src/adyen" "github.com/adyen/adyen-go-api-library/v9/src/checkout" ) // For the live environment, additionally include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) amount := checkout.Amount{ Currency: "EUR", Value: 1000, } paymentMethodsRequest := checkout.PaymentMethodsRequest{ Amount: &amount, MerchantAccount: "ADYEN_MERCHANT_ACCOUNT", CountryCode: common.PtrString("NL"), Channel: common.PtrString("Web"), ShopperLocale: common.PtrString("nl-NL"), } // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentMethodsInput().IdempotencyKey("UUID").PaymentMethodsRequest(paymentMethodsRequest) res, httpRes, err := service.PaymentsApi.PaymentMethods(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v12.7.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the live environment, additionally include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Web", "shopperLocale": "nl-NL" } # Send the request result = adyen.checkout.payments_api.payment_methods(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v9.7.1 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the live environment, additionally include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT', :countryCode => 'NL', :amount => { :currency => 'EUR', :value => 1000 }, :channel => 'Web', :shopperLocale => 'nl-NL' } # Send the request result = adyen.checkout.payments_api.payment_methods(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v19.3.0 // Require the parts of the module you want to use import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // Initialize the client object // For the live environment, additionally include your liveEndpointUrlPrefix. const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Create the request object(s) const amount: Types.checkout.Amount = { currency: "EUR", value: 1000 }; const paymentMethodsRequest: Types.checkout.PaymentMethodsRequest = { amount: amount, merchantAccount: "ADYEN_MERCHANT_ACCOUNT", countryCode: "NL", channel: Types.checkout.PaymentMethodsRequest.ChannelEnum.Web, shopperLocale: "nl-NL" }; // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentMethods(paymentMethodsRequest, { idempotencyKey: "UUID" }); ``` The response includes the list of available `paymentMethods`: **/paymentMethods response** ```json { "paymentMethods":[ { "details":[...], "name":"Cards", "type":"scheme" ... }, { "details":[...], "name":"SEPA Direct Debit", "type":"sepadirectdebit" }, ... ] } ``` Pass the response to your client website. You'll use this in the next step to show which payment methods are available for the shopper. ### Custom list of payment methods When you make a [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) request, the response includes all payment methods that you enabled in your Customer Area that are available for the transaction. To exclude payment methods from the available list of available payment methods for a specific transaction, include one of the following parameters when making your request: * [allowedPaymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods#request-allowedPaymentMethods): Drop-in renders only the payment methods that you specify. * [blockedPaymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods#request-blockedPaymentMethods): Drop-in doesn't render payment methods that you specify. ### Add Components ## Add Components to your payments form Client website Next, use the Component to render the payment method, and collect the required payment details from your shopper. Import using the Adyen Web npm package, or embed the Adyen Web script and stylesheet into your HTML file: ### Tab: npm (recommended) Install the [Adyen Web Node package](https://www.npmjs.com/package/@adyen/adyen-web): ```bash npm install @adyen/adyen-web --save ``` Import Adyen Web into your application. ```js import { AdyenCheckout, Card } from '@adyen/adyen-web'; import '@adyen/adyen-web/styles/adyen.css'; ``` ### Tab: Embed script and stylesheet Use the `integrity` attribute so browsers can verify that the script and stylesheet have not been changed unexpectedly. The value of the `integrity` attribute is the [Subresource Integrity (SRI) hash](/online-payments/web-best-practices#implement-subresource-integrity-hashes) which Adyen provides for each version of the Adyen Web JavaScript and CSS files. Get the SRI hashes in the [release notes](/online-payments/release-notes?integration_type=web), under **Updating to this version**. **checkout.html** ```html ```    You can [add your own styling](/online-payments/build-your-integration/sessions-flow?platform=Web\&integration=Drop-in#optional-configuration) by overriding the rules in this CSS file. After you have imported the Adyen Web library, do the following: 1. Create a DOM element on your checkout page, placing it where you want the payment method form to be rendered. ```html
``` If you are using JavaScript frameworks such as Vue or React, make sure that you use references instead of selectors and that you do not re-render the DOM element. 2. []()Create a `configuration` object with the following parameters: | Parameter name | Required | Description | | ------------------------------------------------ | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `paymentMethodsResponse` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The full `/paymentMethods` response returned [when you get available payment methods](#get-available-payment-methods). | | `clientKey` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | A public key linked to your API credential, used for [client-side authentication](/development-resources/client-side-authentication). | | `locale` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The shopper's locale. This is used to set the language rendered in the UI. For a list of supported locales, see [Localization](/online-payments/web-components/localization-components). | | `countryCode` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The shopper's country/region. This is used to filter the list of available payment methods to your shopper. Format: the two-letter [ISO-3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. Exception: **QZ** (Kosovo). | | `environment` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Use **test**. When you are ready to accept live payments, change the value to one of our [live environments](/online-payments/drop-in-web#testing-your-integration).  | | `onSubmit(state, component, actions)` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Create an event handler for this event, which is called when the shopper selects the **Pay** button, and the details are valid. This applies if the [`showPayButton` configuration parameter](#configure) is set to **true**. Makes a POST [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request. You must call `actions.resolve()`, passing `resultCode`, `action`, and `order` objects (if available) from the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, even when the payment is unsuccessful. If the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request from your server fails, or if an unexpected error occurs, call `actions.reject()`. | | `onAdditionalDetails(state, component, actions)` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Create an event handler for this event, used for native 3D Secure 2, and for native QR code payment methods. In the example below, the handler is named `handleOnAdditionalDetails`. Makes a POST [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request. | | `onPaymentCompleted(result, component)` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Create an event handler, called when the payment is completed. | | `onPaymentFailed(result, component)` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Create an event handler, called when the payment failed. A failed payment has result code **Cancelled**, **Error** or **Refused**. | | `onError(error)` | | Create an event handler, called when an error occurs in the Component. | | `onChange(state, component)` | | Create an event handler, called when the shopper provides the required payment details. | | `secondaryAmount` | | Shows the payment amount in an additional currency on the **Pay** button. You must do the currency conversion and set the amount. This object has properties:- `currency`: The three-character [ISO currency code](/development-resources/currency-codes). - `value`: The amount of the transaction, in [minor units](/development-resources/currency-codes). - `currencyDisplay`: Sets the [currency formatting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#currencydisplay). Default: **symbol**. | | `showPayButton` | | Shows or hides a **Pay** Button for each payment method. Defaults to **true**. When set to **false**, you must override it in [`paymentMethodsConfiguration` ](/online-payments/build-your-integration/?platform=Web\&integration=Drop-in#configure). The **Pay** button triggers the `onSubmit` event when payment details are valid. If you want to disable the button and then trigger the submit flow on your own, set this to **false** and call the `.submit()` method from your own button implementation. PayPal Smart Payment Buttons doesn't support the `.submit()` method. | | `amount` | | The `currency` and `value` of the transaction. | | []()`onActionHandled` | | Create an event handler, called when an action, for example a QR code or 3D Secure 2 authentication screen, is shown to the shopper. The following `action.type` values trigger this callback:- `threeDS` - `qr` - `await`Returns data that contains:- `componentType`: The type of component that shows the action to the shopper. - `actionDescription`: A description of the action shown to the shopper. | **Configure the Component** ```js const configuration = { clientKey: "YOUR_CLIENT_KEY", environment: "test", amount: { value: 1000, currency: 'EUR' }, locale: 'nl-NL' countryCode: 'NL' // The full /paymentMethods response object from your server. Contains the payment methods configured in your account. paymentMethodsResponse: paymentMethodsResponse, onSubmit: async (state, component, actions) => { try { // Make a POST /payments request from your server. const result = await makePaymentsCall(state.data, countryCode, locale, amount); // If the /payments request from your server fails, or if an unexpected error occurs. if (!result.resultCode) { actions.reject(); return; } const { resultCode, action, order, donationToken } = result; // If the /payments request request from your server is successful, you must call this to resolve whichever of the listed objects are available. // You must call this, even if the result of the payment is unsuccessful. actions.resolve({ resultCode, action, order, donationToken, }); } catch (error) { console.error("onSubmit", error); actions.reject(); } }, onAdditionalDetails: async (state, component, actions) => { try { // Make a POST /payments/details request from your server. const result = await makeDetailsCall(state.data); // If the /payments/details request from your server fails, or if an unexpected error occurs. if (!result.resultCode) { actions.reject(); return; } const { resultCode, action, order, donationToken } = result; // If the /payments/details request request form your server is successful, you must call this to resolve whichever of the listed objects are available. // You must call this, even if the result of the payment is unsuccessful. actions.resolve({ resultCode, action, order, donationToken, }); } catch (error) { console.error("onSubmit", error); actions.reject(); } }, onPaymentCompleted: (result, component) => { console.info(result, component); }, onPaymentFailed: (result, component) => { console.info(result, component); }, onError: (error, component) => { console.error(error.name, error.message, error.stack, component); } ); ``` 3. Use the `configuration` object to create an instance of `AdyenCheckout`. **Create an instance of AdyenCheckout** ```js const checkout = await AdyenCheckout(configuration); ``` 4. Create and mount an instance of the payment method Component.[]() Some payment method Components require additional configuration. For more information, refer to our [payment method integration guides](/payment-methods). For example, to mount the Card Component using its component name, `card`: **Mount the Component** ```js const card = new Card(checkout).mount('#component-container'); ``` You can also include [optional Card Component configuration](/payment-methods/cards/web-component#component-configuration). When the shopper enters the payment details and selects the **Pay** button, the Component calls the `onSubmit` event. If `state.isValid` is **true**, use the data in `state.data` to make the payment. 5. Pass the `state.data` to your server. **state from onChange event for Card Component** ```js { isValid: true, data: { paymentMethod: { type: "scheme", encryptedCardNumber: "adyenjs_0_1_18$MT6ppy0FAMVMLH...", encryptedExpiryMonth: "adyenjs_0_1_18$MT6ppy0FAMVMLH...", encryptedExpiryYear: "adyenjs_0_1_18$MT6ppy0FAMVMLH...", encryptedSecurityCode: "adyenjs_0_1_18$MT6ppy0FAMVMLH..." } } } ``` #### Methods All Components support the following methods: | Method name | Description | | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `mount(selector)` | Mounts the Component into the DOM returned by the `selector`. The `selector` must be either a [valid CSS selector string](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector#parameters) or an [HTMLElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement) reference. | | `unmount()` | Unmounts the Component from the DOM. We recommend to unmount in case the payment amount changes after the initial mount. | ### Optional Update Amount (optional) ## Optional: Update the payment amount You must use Checkout API v72 or later for this feature. After you create a session, the order amount can change before the shopper submits the payment. For example: the shopper adds or removes items from their cart, or applies a discount. You can update the session with the new amount so that the shopper pays the correct total. ### Update the session amount Client website Payment server 1. Trigger the `beforeSubmit` callback from your instance of `AdyenCheckout` to make a PATCH `/sessions/{sessionId}` request to update the session from your server, including the follow parameters: | Parameter | Required | Description | | ------------------------------ | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `sessionId` **Path parameter** | ![Required](/user/pages/reuse/image-library/01.icons/required/required.svg?decoding=auto\&fetchpriority=auto) | The ID of the session to update. | | `sessionData` | ![Required](/user/pages/reuse/image-library/01.icons/required/required.svg?decoding=auto\&fetchpriority=auto) | The encoded session data from the original [/sessions](https://docs.adyen.com/api-explorer/Checkout/latest/post/sessions) response. | | `amount.value` | ![Required](/user/pages/reuse/image-library/01.icons/required/required.svg?decoding=auto\&fetchpriority=auto) | The updated amount in [minor units](/development-resources/currency-codes). | | `amount.currency` | ![Required](/user/pages/reuse/image-library/01.icons/required/required.svg?decoding=auto\&fetchpriority=auto) | The three-character [ISO currency code](/development-resources/currency-codes). | | `payable` | | If you know that the amount in this request is the final amount, set to **true**. This indicates that the session is ready for payment. When you set this to true, you can no longer update the session. If you set to **false**, you must make another request to update the session and set to **true** before the shopper can submit the payment. | **Example request to update the session amount** ```bash curl https://checkout-test.adyen.com/v72/sessions/QFQTPCQ8HXSKGK82 \ -X PATCH \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'idempotency-key: YOUR_IDEMPOTENCY_KEY' \ -H 'content-type: application/json' \ -d '{ "sessionData": "Ab02b4c...", "amount": { "value": 10000, "currency": "EUR" }, "payable": true }' ``` After you set `payable` to **true**, you cannot update the session again. Only set this when you confirm the final amount, and the session is ready for payment. The response includes the updated session data. **Example response with updated session data** ```json { "sessionData": "Ab02b4c.." } ``` 2. Add the updated `sessionData` object to the `actions.resolve` method, to pass it to the Component. When you make a request to update the server-side session data, you must store and get the updated amount on your server. Do not get the updated amount from the client. **Example of the beforeSubmit callback to update the session** ```ts const checkout = await AdyenCheckout({ beforeSubmit: async (data, component, actions) => { try { // Get the latest session data. const { session } = component.core.session; // Make an PATCH /sessions/{sessionId} request to update the session. const updatedSessionData = await patchSession(session); // Add the updated session data to actions.resolve. actions.resolve({ ...data, sessionData: updatedSessionData }); } catch (error) { actions.reject(); } }, // ...Other configuration properties }); ``` ### Update the amount in the Component Client website Update the amount in the Component when the payment amount changes (for example, when the shopper adds or removes items from their cart). The amount can be updated multiple times without the need to update the server-side session data every time. The server-side session update is required only before the shopper can submit the payment. #### Show the updated amount to the shopper Client website To show the updated amount in the payment form: From your [instance of `AdyenCheckout`](/online-payments/build-your-integration/sessions-flow/#configure), call the `update` function and pass the new amount. **Example to update the amount in the payment form** ```ts // Create an amount object for the updated amount. const amount = { value: 1000, currency: 'USD' }; // Update the amount in the payment form, specifying not to reinitialize the checkout instance. checkout.update({ amount }, { shouldReinitializeCheckout: false }); ``` ## Make a payment Payment server After the shopper selects the **Pay** button or chooses to pay with a payment method that requires a redirection, you must make a payment request to Adyen. 1. Pass the data from `onSubmit` to your server 2. From your server, make a **POST** [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request including the following parameters: | Parameter name | Required | Description | | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The `currency` of the payment and its `value` in [minor units](/development-resources/currency-codes). | | `reference` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your unique reference for this payment. | | `paymentMethod` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The complete `state.data.paymentMethod` object from the `onSubmit` event from your client app. It includes the payment method details and other required information. | | `paymentMethod.sdkData` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The object that includes information collected by the Component to track the user's payment journey, including information like the [checkout attempt identifier](/online-payments/analytics-and-data-tracking#data-we-are-collecting). This is required to use the [Checkout dashboard](/uplift#uplift-dashboards) that lets you analyze your checkout performance. | | `returnUrl` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | URL to where the shopper should be taken back to after a redirection. The URL can contain a maximum of 1024 characters and should include the protocol: `http://` or `https://`. You can also include your own additional query parameters, for example, shopper ID or order reference number. If the URL to return to includes non-ASCII characters, like spaces or special letters, URL encode the value. The URL must not include personally identifiable information (PII), for example name or email address. | | `riskData` | | [Device characteristics and other data](/risk-management/fraud-data-collection) that we use to detect fraudulent payment activity, and mitigate fraud. | | [`applicationInfo`](/development-resources/building-adyen-solutions) | | If you are building an Adyen solution for multiple merchants, include some basic identifying information, so that we can offer you better support. For more information, refer to [Building Adyen solutions](/development-resources/building-adyen-solutions). | | `shopperEmail` | | The shopper's email address. Strongly recommended because this field is used in a number of [risk checks](/risk-management/configure-your-risk-profile/risk-field-reference), and for 3D Secure. | | `shopperIP` | | The shopper's IP address. Strongly recommended because this field is used in a number of [risk checks](/risk-management/configure-your-risk-profile/risk-field-reference). | | `shopperReference` | | Your reference to uniquely identify this shopper. Minimum length: three characters. Do not include personally identifiable information, for example name or email address. Strongly recommended because this field is used in a number of [risk checks](/risk-management/configure-your-risk-profile/risk-field-reference). | For the following cases, you must include additional parameters in your request: * Integrating some payment methods. For more information, go to [payment method integration guides](/payment-methods). * Using our risk management features. For more information, go to [data quality and risk field reference](/risk-management/configure-your-risk-profile/risk-field-reference). * [Creating a token](/online-payments/tokenization/create-tokens) to store the shopper's payment details. * [Using a token](/online-payments/tokenization/make-token-payments) to make a recurring payment with stored payment details. * Using [the Adyen Uplift Personalize module](/uplift#uplift-personalize) and accessing the [Checkout dashboard](/uplift#uplift-dashboards). 3. **Example request to make a payment for EUR 10** #### curl ```bash curl https://checkout-test.adyen.com/v72/payments \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "amount": { "currency": "EUR", "value": 1000 }, "reference": "YOUR_ORDER_NUMBER", "paymentMethod":{ "type": "scheme", "encryptedCardNumber": "test_4111111111111111", "encryptedExpiryMonth": "test_03", "encryptedExpiryYear": "test_2030", "encryptedSecurityCode": "test_737" }, "returnUrl": "https://your-company.example.com/checkout?shopperOrder=12xy..", "riskData": { "clientData": "eyJ0cmFuc1N0YXR1cy...I6IlkifQ==" }, "checkoutAttemptId": "7m583f18-b533-4fn0...", "merchantAccount": "ADYEN_MERCHANT_ACCOUNT" }' ``` #### Java ```java // Adyen Java API Library v40.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the LIVE environment, also include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) Amount amount = new Amount() .currency("EUR") .value(1000L); CardDetails cardDetails = new CardDetails() .encryptedCardNumber("test_4111111111111111") .encryptedSecurityCode("test_737") .encryptedExpiryYear("test_2030") .encryptedExpiryMonth("test_03") .type(CardDetails.TypeEnum.SCHEME); RiskData riskData = new RiskData() .clientData("eyJ0cmFuc1N0YXR1cy...I6IlkifQ=="); PaymentRequest paymentRequest = new PaymentRequest() .reference("YOUR_ORDER_NUMBER") .amount(amount) .merchantAccount("ADYEN_MERCHANT_ACCOUNT") .paymentMethod(new CheckoutPaymentMethod(cardDetails)) .checkoutAttemptId("7m583f18-b533-4fn0...") .returnUrl("https://your-company.example.com/checkout?shopperOrder=12xy..") .riskData(riskData); // Send the request PaymentsApi service = new PaymentsApi(client); PaymentResponse response = service.payments(paymentRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("ADYEN_API_KEY"); // For the LIVE environment, also include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $amount = new Amount(); $amount ->setCurrency("EUR") ->setValue(1000); $checkoutPaymentMethod = new CheckoutPaymentMethod(); $checkoutPaymentMethod ->setEncryptedCardNumber("test_4111111111111111") ->setEncryptedSecurityCode("test_737") ->setEncryptedExpiryYear("test_2030") ->setEncryptedExpiryMonth("test_03") ->setType("scheme"); $riskData = new RiskData(); $riskData ->setClientData("eyJ0cmFuc1N0YXR1cy...I6IlkifQ=="); $paymentRequest = new PaymentRequest(); $paymentRequest ->setReference("YOUR_ORDER_NUMBER") ->setAmount($amount) ->setMerchantAccount("ADYEN_MERCHANT_ACCOUNT") ->setPaymentMethod($checkoutPaymentMethod) ->setCheckoutAttemptId("7m583f18-b533-4fn0...") ->setReturnUrl("https://your-company.example.com/checkout?shopperOrder=12xy..") ->setRiskData($riskData); $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->payments($paymentRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v32.1.2 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the LIVE environment, also include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) Amount amount = new Amount { Currency = "EUR", Value = 1000 }; CardDetails cardDetails = new CardDetails { EncryptedCardNumber = "test_4111111111111111", EncryptedSecurityCode = "test_737", EncryptedExpiryYear = "test_2030", EncryptedExpiryMonth = "test_03", Type = CardDetails.TypeEnum.Scheme }; RiskData riskData = new RiskData { ClientData = "eyJ0cmFuc1N0YXR1cy...I6IlkifQ==" }; PaymentRequest paymentRequest = new PaymentRequest { Reference = "YOUR_ORDER_NUMBER", Amount = amount, MerchantAccount = "ADYEN_MERCHANT_ACCOUNT", PaymentMethod = new CheckoutPaymentMethod(cardDetails), CheckoutAttemptId = "7m583f18-b533-4fn0...", ReturnUrl = "https://your-company.example.com/checkout?shopperOrder=12xy..", RiskData = riskData }; // Send the request var service = new PaymentsService(client); var response = service.Payments(paymentRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v29.1.0 const { Client, CheckoutAPI } = require('@adyen/api-library'); // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const paymentRequest = { amount: { currency: "EUR", value: 1000 }, reference: "YOUR_ORDER_NUMBER", paymentMethod: { type: "scheme", encryptedCardNumber: "test_4111111111111111", encryptedExpiryMonth: "test_03", encryptedExpiryYear: "test_2030", encryptedSecurityCode: "test_737" }, returnUrl: "https://your-company.example.com/checkout?shopperOrder=12xy..", riskData: { clientData: "eyJ0cmFuc1N0YXR1cy...I6IlkifQ==" }, checkoutAttemptId: "7m583f18-b533-4fn0...", merchantAccount: "ADYEN_MERCHANT_ACCOUNT" } // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.payments(paymentRequest, { idempotencyKey: "UUID" }); ``` #### Go ```go // Adyen Go API Library v21.0.0 import ( "context" "github.com/adyen/adyen-go-api-library/v21/src/common" "github.com/adyen/adyen-go-api-library/v21/src/adyen" "github.com/adyen/adyen-go-api-library/v21/src/checkout" ) // For the LIVE environment, also include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) amount := checkout.Amount{ Currency: "EUR", Value: 1000, } cardDetails := checkout.CardDetails{ EncryptedCardNumber: common.PtrString("test_4111111111111111"), EncryptedSecurityCode: common.PtrString("test_737"), EncryptedExpiryYear: common.PtrString("test_2030"), EncryptedExpiryMonth: common.PtrString("test_03"), Type: common.PtrString("scheme"), } riskData := checkout.RiskData{ ClientData: common.PtrString("eyJ0cmFuc1N0YXR1cy...I6IlkifQ=="), } paymentRequest := checkout.PaymentRequest{ Reference: "YOUR_ORDER_NUMBER", Amount: amount, MerchantAccount: "ADYEN_MERCHANT_ACCOUNT", PaymentMethod: checkout.CardDetailsAsCheckoutPaymentMethod(&cardDetails), CheckoutAttemptId: common.PtrString("7m583f18-b533-4fn0..."), ReturnUrl: "https://your-company.example.com/checkout?shopperOrder=12xy..", RiskData: &riskData, } // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentsInput().IdempotencyKey("UUID").PaymentRequest(paymentRequest) res, httpRes, err := service.PaymentsApi.Payments(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.6.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "amount": { "currency": "EUR", "value": 1000 }, "reference": "YOUR_ORDER_NUMBER", "paymentMethod": { "type": "scheme", "encryptedCardNumber": "test_4111111111111111", "encryptedExpiryMonth": "test_03", "encryptedExpiryYear": "test_2030", "encryptedSecurityCode": "test_737" }, "returnUrl": "https://your-company.example.com/checkout?shopperOrder=12xy..", "riskData": { "clientData": "eyJ0cmFuc1N0YXR1cy...I6IlkifQ==" }, "checkoutAttemptId": "7m583f18-b533-4fn0...", "merchantAccount": "ADYEN_MERCHANT_ACCOUNT" } # Send the request result = adyen.checkout.payments_api.payments(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v10.4.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :amount => { :currency => 'EUR', :value => 1000 }, :reference => 'YOUR_ORDER_NUMBER', :paymentMethod => { :type => 'scheme', :encryptedCardNumber => 'test_4111111111111111', :encryptedExpiryMonth => 'test_03', :encryptedExpiryYear => 'test_2030', :encryptedSecurityCode => 'test_737' }, :returnUrl => 'https://your-company.example.com/checkout?shopperOrder=12xy..', :riskData => { :clientData => 'eyJ0cmFuc1N0YXR1cy...I6IlkifQ==' }, :checkoutAttemptId => '7m583f18-b533-4fn0...', :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT' } # Send the request result = adyen.checkout.payments_api.payments(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v29.1.0 import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const amount: Types.checkout.Amount = { currency: "EUR", value: 1000 }; const cardDetails: Types.checkout.CardDetails = { encryptedCardNumber: "test_4111111111111111", encryptedSecurityCode: "test_737", encryptedExpiryYear: "test_2030", encryptedExpiryMonth: "test_03", type: Types.checkout.CardDetails.TypeEnum.Scheme }; const riskData: Types.checkout.RiskData = { clientData: "eyJ0cmFuc1N0YXR1cy...I6IlkifQ==" }; const paymentRequest: Types.checkout.PaymentRequest = { reference: "YOUR_ORDER_NUMBER", amount: amount, merchantAccount: "ADYEN_MERCHANT_ACCOUNT", paymentMethod: cardDetails, checkoutAttemptId: "7m583f18-b533-4fn0...", returnUrl: "https://your-company.example.com/checkout?shopperOrder=12xy..", riskData: riskData }; // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.payments(paymentRequest, { idempotencyKey: "UUID" }); ``` Your next step depends on if the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response contains an `action` object: * If the response has no `action` object, [get the payment outcome](#get-the-payment-outcome). * If the response contains an `action` object, [handle the additional action](#additional-action). **Example response for iDEAL, a redirect payment method** ```json { "resultCode": "RedirectShopper", "action": { "paymentMethodType": "ideal", "url": "https://checkoutshopper-test.adyen.com/checkoutshopper/checkoutPaymentRedirect?redirectData=X6Xtf...", "method": "GET", "type": "redirect" } } ``` ### Handle Additional Actions ## Handle the additional action Client website Some payment methods require additional action from the shopper. Common examples of additional actions include: * Logging in to a bank's website or app. * Authenticating a payment with 3D Secure 2. * Scanning a QR code. Implement logic to handle all action types, so that your integration can handle different payment methods. To see if an individual payment method requires an additional action, see the corresponding [payment method guide](/payment-methods) for it. To handle the additional action: 1. Pass the `action` object from your server to the `onSubmit` `actions.resolve()` function. 2. The Component performs the additional action on the client side. 3. You handle the payment data, depending on the action type (`action.type`). | Type | `action.type` value | | ----------------------------------------------------------------------- | ------------------- | | [Redirect action](#handle-the-redirect) | **redirect** | | [3D Secure 2 authentication action](#3d-secure-2-authentication-action) | **threeDS2** | | [QR code action](#qr-code-action) | **qrCode** | | [SDK action](#sdk-action) | **sdk** | | [Voucher action](#voucher-action) | **voucher** | | [Await action](#await-action) | **await** | ### Redirect action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type` **redirect**, the Component redirects your shopper to another website to complete the payment. 1. When the shopper finishes their payment on the other website, they are returned to your `returnUrl` with an HTTP GET request. The `returnUrl` is appended with a Base64-encoded `redirectResult`. **Example return URL** ```raw GET /?shopperOrder=12xy..&&redirectResult=X6XtfGC3%21Y... HTTP/1.1 Host: www.your-company.example.com/checkout ``` If the shopper fails to return to your website, you do not get the `redirectResult`. Instead, wait for the corresponding [webhook](#update-your-order-management-system) for the outcome of the payment. To process the result: 2. Get the `redirectResult` appended to your return URL. You do not need to decode it. 3. Pass the `redirectResult` to your server. 4. [Send additional payment details](#send-additional-payment-details) to complete the payment flow. **Example JavaScript code snippet to handle redirectResult** ```js function handleRedirectResult() { // 1. Get the redirectResult from your return URL. const urlParams = new URLSearchParams(window.location.search); const redirectResult = urlParams.get('redirectResult'); if (redirectResult) { // 2. Pass the redirectResult to your server. // 3. Your server makes the /payments/details request. Adyen's server processes the encoded redirectResult value. fetch('/api/handle-payment-redirect', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ redirectResult: redirectResult }), }) .then(response => response.json()) .then(data => { // Verify the resultCode from your server's response. if (data && data.resultCode === 'Authorised') { console.log('Payment authorized successfully!'); // Handle successful payment authorization. For example: show a confirmation message or redirect the shopper to a confirmation page. } else { console.log('Payment failed or denied.'); // Handle payment failure. For example: show an error message or redirect the shopper to an error page. } }) .catch(error => { console.error('Error sending redirect result or processing server response:', error); // Handle network errors or issues with server communication. }); } } // Call this function when your page loads. handleRedirectResult(); ``` ### 3D Secure 2 authentication action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **threeDS2**, the payment qualifies for 3D Secure 2 and it goes through the [frictionless or the challenge flow](/online-payments/3d-secure/#authentication-flows). 1. The Component handles 3D Secure 2 authentication. If a challenge is required, the shopper performs the authentication challenge to complete the payment. 2. The Component calls `onAddtionalDetails`. 3. Pass the `state.data` from `onAdditionalDetails` to your server. 4. [Send additional payment details](#send-additional-payment-details) to complete the payment flow. ### QR code action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **qrCode**, the shopper must scan a QR code to complete the payment. 1. The Component shows the QR code to the shopper. 2. The shopper scans the QR code to complete the payment. 3. The Component calls `onAddtionalDetails`. 4. Pass the `state.data` from `onAdditionalDetails` to your server. 5. [Send additional payment details](#send-additional-payment-details) to complete the payment flow. ### SDK action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **sdk**, the shopper must use another UI overlay to complete the payment. For example, a payment method requires the shopper to use its specific UI to enter payment details. 2. The Component shows a different UI in an overlay. 3. The shopper uses the UI overlay to complete the payment. 4. The Component calls `onAddtionalDetails`. 5. Pass the `state.data` from `onAdditionalDetails` to your server. 6. [Send additional payment details](#send-additional-payment-details) to complete the payment flow. ### Voucher action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **voucher**, the shopper must use a voucher to complete the payment. 1. The Component shows the voucher to the shopper. 2. The shopper uses the voucher to pay outside of your website. 3. You [get the payment outcome](#get-the-payment-outcome). ### Await action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **await**, the shopper must take an additional action to complete the payment. For example: entering a code into their banking app. 1. The Component shows the instructions for the additional action to complete the payment. 2. The shopper does the additional action. 3. The Component calls `onAddtionalDetails` or `onError`, depending on the result of the additional action. 4. Pass the `state.data` from `onAdditionalDetails` or `onError` to your server. 5. [Send additional payment details](#send-additional-payment-details) to complete the payment flow. ### Submit Additional Payment Details ## Send additional payment details Payment server If you [handled an additional action](#additional-action), you must send additional payment details. **For redirects**: if the shopper fails to return to your website, you do not get additional payment details to send. Instead, wait for the corresponding [webhook](#update-your-order-management-system) for the outcome of the payment. 1. Pass additional payment details to your server, depending on the action you handled: * If you handled a redirect: pass the `redirectResult`. * If you handled a non-redirect additional action: pass the complete `state.data` object from the `onAdditionalDetails` event. 2. From your server, make a POST [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request including the `redirectResult` or the full `state.data` object, depending on the action you handled. **Example request to send additional payment details** #### curl ```bash curl https://checkout-test.adyen.com/v72/payments/details \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{hint:object passed from your client app}STATE_DATA{/hint}' ``` #### Java ```java // Set your X-API-KEY with the API key from the Customer Area. String xApiKey = "ADYEN_API_KEY"; Client client = new Client(xApiKey,Environment.TEST); Checkout checkout = new Checkout(client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. PaymentsDetailsRequest paymentsDetailsRequest = STATE_DATA; PaymentsResponse paymentsDetailsResponse = checkout.paymentsDetails(paymentsDetailsRequest); ``` #### PHP ```php // Set your X-API-KEY with the API key from the Customer Area. $client = new \Adyen\Client(); $client->setEnvironment(\Adyen\Environment::TEST); $client->setXApiKey("ADYEN_API_KEY"); $service = new \Adyen\Service\Checkout($client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. $params = STATE_DATA; $result = $service->paymentsDetails($params); // Check if further action is needed. if (array_key_exists("action", $result)){ // Pass the action object to your client. // $result["action"] } else { // No further action needed, pass the resultCode to your client. // $result['resultCode'] } ``` #### C\# ```cs // Set your X-API-KEY with the API key from the Customer Area. string apiKey = "ADYEN_API_KEY"; var client = new Client (apiKey, Environment.Test); var checkout = new Checkout(client); // STATE_DATA is an object passed from the client app, deserialized from JSON to a data structure. var paymentsDetailsRequest = STATE_DATA; var paymentsDetailsResponse = checkout.PaymentDetails(paymentsDetailsRequest); ``` #### NodeJS (JavaScript) ```js const {Client, Config, CheckoutAPI} = require('@adyen/api-library'); const config = new Config(); // Set your X-API-KEY with the API key from the Customer Area. config.apiKey = '[ADYEN_API_KEY]'; const client = new Client({ config }); client.setEnvironment("TEST"); const checkout = new CheckoutAPI(client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. checkout.paymentsDetails(STATE_DATA).then(res => res); ``` #### Go ```go import ( "github.com/adyen/adyen-go-api-library/v5/src/checkout" "github.com/adyen/adyen-go-api-library/v5/src/common" "github.com/adyen/adyen-go-api-library/v5/src/adyen" ) // Set your X-API-KEY with the API key from the Customer Area. client := adyen.NewClient(&common.Config{ Environment: common.TestEnv, ApiKey: "[ADYEN_API_KEY]", }) // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. req := STATE_DATA; res, httpRes, err := client.Checkout.PaymentsDetails(&req) ``` #### Python ```py # Set your X-API-KEY with the API key from the Customer Area. adyen = Adyen.Adyen() adyen.payment.client.platform = "test" adyen.client.xapikey = 'ADYEN_API_KEY' # STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. request = STATE_DATA result = adyen.checkout.payments_details(request) # Check if further action is needed. if 'action' in result.message: # Pass the action object to your client. # result.message['action'] else: # No further action needed, pass the resultCode to your client. # result.message['resultCode'] ``` #### Ruby ```ruby require 'adyen-ruby-api-library' # Set your X-API-KEY with the API key from the Customer Area. adyen = Adyen::Client.new adyen.env = :test adyen.api_key = "ADYEN_API_KEY" # STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. request = STATE_DATA response = adyen.checkout.payments.details(request) # Check if further action is needed. if response.body.has_key(:action) # Pass the action object to your client puts response.body[:action] else # No further action needed, pass the resultCode to your client puts response.body[:resultCode] end ``` 3. Pass the [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) response from your server to your client app. **Example response for a successful payment** ```json { "pspReference": "NC6HT9CRT65ZGN82", "resultCode": "Authorised" } ``` **Example response for a refused payment** ```json { "pspReference": "KHQC5N7G84BLNK43", "refusalReason": "Not enough balance", "resultCode": "Refused" } ``` ## Get the payment outcome After the Component finishes the payment flow, you can show the shopper the current payment status. Adyen sends a webhook with the outcome of the payment. ### Inform the shopper Client website Use the [`resultCode`](/online-payments/payment-result-codes) from the `onPaymentCompleted` or `onPaymentFailed` event to show the shopper the [current payment status](/account/payments-lifecycle). This synchronous response doesn't give you the final outcome of the payment. You get the final payment status in a webhook that you use to [update your order management system](#update-your-order-management-system). ### Update your order management system Webhook server You get the outcome of each payment asynchronously, in an **AUTHORISATION** [webhook](/development-resources/webhooks). Use the `merchantReference` from the webhook to match it to your order reference.\ For a successful payment, the event contains `success`: **true**. **Example webhook for a successful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"033899:1111:03/2030", "amount":{ "currency":"EUR", "value":2500 }, "operations":["CANCEL","CAPTURE","REFUND"], "success":"true", "paymentMethod":"mc", "additionalData":{ "expiryDate":"03/2030", "authCode":"033899", "cardBin":"411111", "cardSummary":"1111" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"NC6HT9CRT65ZGN82", "eventDate":"2021-09-13T14:10:22+02:00" } } ] } ``` For an unsuccessful payment, you get `success`: **false**, and the `reason` field has details about why the payment was unsuccessful. **Example webhook for an unsuccessful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"validation 101 Invalid card number", "amount":{ "currency":"EUR", "value":2500 }, "success":"false", "paymentMethod":"unknowncard", "additionalData":{ "expiryDate":"03/2030", "cardBin":"411111", "cardSummary":"1112" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"KHQC5N7G84BLNK43", "eventDate":"2021-09-13T14:14:05+02:00" } } ] } ``` ## Error handling In case you encounter errors in your integration, refer to the following: * [API error codes](/development-resources/error-codes): If you receive a non-HTTP 200 response, use the `errorCode` to troubleshoot and modify your request. * [Payment refusals](/development-resources/refusal-reasons): If you receive an HTTP 200 response with an **Error** or **Refused** `resultCode`, check the refusal reason and, if possible, modify your request. ## Test and go live Before going live, use our list of [test cards and other payment methods](/development-resources/test-cards-and-credentials/test-card-numbers) to test your integration. We recommend testing each payment method that you intend to offer to your shoppers. You can check the status of a test payment in your [Customer Area](https://ca-test.adyen.com/), under **Transactions** > **Payments**. To debug or troubleshoot test payments, you can also use [API logs](/development-resources/logs-resources/api-logs) in your test environment. When you are ready to go live, you need to: 1. [Apply for a live account](/get-started-with-adyen/application-requirements). Review the process to start accepting payments on [Get started with Adyen](/get-started-with-adyen). 2. Assess your [PCI DSS compliance](/development-resources/pci-dss-compliance-guide#online-payments) by submitting the [Self-Assessment Questionnaire-A](https://www.pcisecuritystandards.org/documents/PCI-DSS-v3_2_1-SAQ-A.pdf). 3. [Configure your live account](/online-payments/go-live-checklist).  4. Submit a request to add payment methods in your [live Customer Area](https://ca-live.adyen.com/) . 5. Switch from test to our [live endpoints](/development-resources/live-endpoints#checkout-endpoints). Make sure that all API requests you make for the same payment session use the same live endpoint region. Using different regions for [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) and [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) requests may result in errors, for example, when authenticating with 3D Secure 2. 6. Load Components from one of our live environments and set the `environment` to match your live endpoints: | Endpoint region | Value | | ------------------------- | ------------ | | Europe (EU) live | **live** | | United States (US) live | **live-us** | | Australia (AU) live | **live-au** | | Northeast Asia (NEA) live | **live-nea** | | India (IN) live | **live-in** | ## See also * [Tokenization](/online-payments/tokenization) * [3D Secure](/online-payments/3d-secure) * [PCI DSS compliance guide](/development-resources/pci-dss-compliance-guide) * [Adyen Uplift requirements and recommendations](/uplift/uplift-requirements) ## Next steps [required](/online-payments/modify-payments) [Modify payments](/online-payments/modify-payments) [Find out how to cancel, refund, or capture a payment using our API.](/online-payments/modify-payments) [Add payment methods](/payment-methods#add-payment-methods-to-your-account) [Learn about payment methods and how to add them to your account.](/payment-methods#add-payment-methods-to-your-account) [Tokenization](/online-payments/tokenization) [Save shopper payment details for later payments.](/online-payments/tokenization) [3D Secure authentication](/online-payments/3d-secure) [Comply with regulations such as PSD2 SCA in Europe.](/online-payments/3d-secure) ## Web API only Use Adyen APIs and your own UI ### Intro With an API-only integration, you create your own UI, implement your own client-side logic, and use our API to send and receive payment data. You have full control over the look and feel of your checkout page. To reduce your development time and resources, you can use one of our pre-built UI options (Drop-in/Components) instead. ### Before You Begin ## Requirements Before you build your integration, take into account the following requirements and preparations. | Requirement | Description | | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **[API credential roles](/development-resources/api-credentials/roles/)** | Make sure that you have the following role:- **Checkout webservice role** | | **[Customer Area roles](/account/user-roles)** | Make sure that you have one of the following roles:- **Merchant admin role** - **Manage API credentials** | | **[Webhooks](/development-resources/webhooks)** | Subscribe to the following webhook:- **Standard webhooks** | | **Limitations** | * Your [PCI compliance assesment](/development-resources/pci-dss-compliance-guide?tab=api_only_3_4#online-payments) determines your [integration options for card payments](#collect-card-details). * For 3D Secure 2 authentication for shoppers using Chrome, your [cookies must use the `SameSite` attribute](https://developers.google.com/search/blog/2020/01/get-ready-for-new-samesitenone-secure). | | **Setup steps** | Before you begin:* [Create your Adyen test account](/get-started-with-adyen#test-account) * [Get your API key](/development-resources/api-credentials#generate-api-key). * [Get your client key](/development-resources/client-side-authentication#get-your-client-key). * [Set up webhooks](/development-resources/webhooks). * If you want to process payments using raw card data, contact your Adyen Account Manager to confirm that you are eligible. | ## How it works For an API-only integration, you must implement the following parts: * **Your payment server**: sends the API requests to get available payment methods, make a payment, and send additional payment details. * **Your client**: shows your custom UI where the shopper makes the payment. Passes data to and receives data from your payment server to handle the payment flow and additional actions on your client. * **Your webhook server**: receives webhooks that include the outcome of each payment. ## Integration steps The parts of your integration work together to handle the payment flow: 1. From your server, make an API request to [get a list of payment methods available to the shopper](#get-available-payment-methods). 2. Show the [payment form to collect the shopper's payment details](#collect-shopper-details) in your UI. 3. From your server, [make a payment request](#make-a-payment) with the data that you have collected from the shopper. 4. For some payment methods, you use your client to [handle the additional action](#additional-action) that your shopper must do. For example, you redirect your shopper to another website or show a QR code that the shopper uses to complete the payment. 5. From your server, [send additional payment details](#send-additional-payment-details). 6. [Get the payment outcome](#get-the-payment-outcome). If you are integrating these parts separately, you can start at the corresponding part of this integration guide: [![](/user/pages/reuse/online-payments/how-it-works-parts/servers.svg?decoding=auto\&fetchpriority=auto)](/#install-api-library) [Payment server](/#install-api-library) [Go to the integration steps for your server.](/#install-api-library) [![](/user/pages/reuse/online-payments/how-it-works-parts/browser-developers.svg?decoding=auto\&fetchpriority=auto)](/#collect-shopper-details) [Client website or app](/#collect-shopper-details) [Go to the integration steps for your client.](/#collect-shopper-details) [![](/user/pages/reuse/online-payments/how-it-works-parts/event-code.svg?decoding=auto\&fetchpriority=auto)](/#update-your-order-management-system) [Webhook server](/#update-your-order-management-system) [Go to the integration steps for your webhook server.](/#update-your-order-management-system) ### Install Api Library ## Install an API library Payment server We provide server-side API libraries for several programming languages, available through common package managers, like Gradle and npm, for easier installation and version management. Our API libraries will save you development time, because they: * Use an API version that is up to date. * Have generated models to help you construct requests. * Send the request to Adyen using their built-in HTTP client, so you do not have to create your own. ### Tab: Java ##### Try our example integration ![](/reuse/development-resources/install-api-library/java/advanced/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-java-spring-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/java/advanced/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-java-spring-online-payments). #### Requirements * Java 11 or later. #### Installation You can use [Maven](https://maven.apache.org), adding this dependency to your project's POM. **Add the API library** ```xml com.adyen adyen-java-api-library LATEST_VERSION ``` You can find the latest version on GitHub. Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-java-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```java // Import the required classes. package com.adyen.service; import com.adyen.Client; import com.adyen.service.checkout.PaymentsApi; import com.adyen.model.checkout.Amount; import com.adyen.enums.Environment; import com.adyen.service.exception.ApiException; import java.io.IOException; public class Snippet { public Snippet() throws IOException, ApiException { // Set up the client and service. Client client = new Client("ADYEN_API_KEY", Environment.TEST); } } ``` ### Tab: PHP ##### Try our example integration ![](/reuse/development-resources/install-api-library/php/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-php-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/php/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-php-online-payments). #### Requirements * PHP 7.3 or later. * cURL with SSL support. * The JSON PHP extension. * The list of dependencies from the composer require list. #### Installation You can use [Composer](https://getcomposer.org/). Follow the [installation instructions](https://getcomposer.org/doc/00-intro.md) if you do not already have composer installed. **Install the API library** ```bash composer require adyen/php-api-library ``` In your PHP script, make sure you include the autoloader: **Include the autoloader** ```php require __DIR__ . '/vendor/autoload.php'; ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-php-api-library/releases). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```php use Adyen\Model\Checkout\Amount; use Adyen\Model\Checkout\CreateCheckoutSessionRequest; use Adyen\Service\Checkout\PaymentsApi; // Include your idempotency key when you make an API request. $requestOptions['idempotencyKey'] = "YOUR_IDEMPOTENCY_KEY"; // Set up the client and service. $client = new \Adyen\Client(); $client->setXApiKey('ADYEN_API_KEY'); $client->setEnvironment(\Adyen\Environment::TEST); $service = new PaymentsApi($client); ``` ### Tab: C\# #### Requirements * .NET standard 2.0 or later. * For Terminal API certificate validation, set the application to either of the following: * .NET core 2.1 or later * .NET framework 4.6.1 or later #### Installation You can use [NuGet](https://www.nuget.org/packages/Adyen/): **Install the API library** ```bash PM> Install-Package Adyen -Version LATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-dotnet-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```cs using Adyen; using Adyen.Model.Checkout; using Adyen.Service.Checkout; using Environment = Adyen.Model.Environment; class Program { static void Main() { // Set up the client and service. var config = new Config { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); var checkout = new PaymentsService(client); // Include your idempotency key when you make an API request. var requestOptions = new Adyen.Model.RequestOptions { IdempotencyKey = "YOUR_IDEMPOTENCY_KEY" }; } } ``` ### Tab: NodeJS ##### Try our example integration ![](/reuse/development-resources/install-api-library/node-js/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-node-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/node-js/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-node-online-payments). #### Requirements * Node.js version 18 or later. #### Installation You can use [npm](https://www.npmjs.com/): **Install the API library** ```bash npm install --save @adyen/api-library npm update @adyen/api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-node-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```js // Require the parts of the module you want to use. const { Client, CheckoutAPI, Types} = require("@adyen/api-library"); // Set up the client and service. const client = new Client({ apiKey: "ADYEN_API_KEY", environment: "TEST" }); const checkoutApi = new CheckoutAPI(client); // Include your idempotency key when you make an API request. const requestOptions = { idempotencyKey: "YOUR_IDEMPOTENCY_KEY" }; ``` ### Tab: Go ##### Try our example integration ![](/reuse/development-resources/install-api-library/go/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-golang-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/go/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-golang-online-payments). #### Requirements * Go 1.13 or later. #### Installation You can use [Go modules](https://github.com/golang/go/wiki/Modules): **Install the API library** ```shell go get github.com/adyen/adyen-go-api-library/vLATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-go-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```go package main import ( "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/adyen" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/checkout" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/common" ) // Create a payment object. func main () { client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) service := client.Checkout() ``` ### Tab: Python ##### Try our example integration ![](/reuse/development-resources/install-api-library/python/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-python-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/python/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-python-online-payments). #### Requirements * Python 3.6 or later. * (Optional) Packages: Requests or PycURL #### Installation You can use [pip](https://pip.pypa.io/en/stable/): **Install the API library** ```py pip install Adyen ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-python-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```py import Adyen # Set up the client and service. adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment that the library is used in. ``` ### Tab: Ruby ##### Try our example integration ![](/reuse/development-resources/install-api-library/ruby/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-rails-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/ruby/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-rails-online-payments). #### Requirements * Ruby 2.7 or later. #### Installation You can use [RubyGems](https://rubygems.org/): **Install the API library** ```bash gem install adyen-ruby-api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-ruby-api-library/releases). Run `bundle install` to install dependencies. #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```ruby require 'adyen-ruby-api-library' # Set up the client and service. adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # The environment that the library is used in. ``` ## Get available payment methods Payment server When the shopper goes to your checkout page, get a list of the available payment methods to show the shopper. 1. From your server, make a POST [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/72/post/paymentMethods) request including the following parameters: | Parameter name | Required | Description | | ----------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | | An object with the following parameters:- `currency`: The three-character [ISO currency code](/development-resources/currency-codes). - `value`: The value of the payment in [minor units](/development-resources/currency-codes). | | `channel` | | **Web** | | `countryCode` | | The shopper's country/region. Format: the two-letter [ISO-3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. Exception: **QZ** (Kosovo). | | `shopperLocale` | | Language and country code. This is used to translate the payment methods names in the response. Default value: **en-US**. | The information that you include is used to filter the list of available payment methods. **Example for a shopper in the Netherlands and a payment amount of 10 EUR** #### curl ```bash curl https://checkout-test.adyen.com/v72/paymentMethods \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Web", "shopperLocale": "nl-NL" }' ``` #### Ruby ```rb # Adyen Ruby API Library v11.0.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT', :countryCode => 'NL', :amount => { :currency => 'EUR', :value => 1000 }, :channel => 'Web', :shopperLocale => 'nl-NL' } # Send the request result = adyen.checkout.payments_api.payment_methods(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v30.0.0 import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const amount: Types.checkout.Amount = { currency: "EUR", value: 1000 }; const paymentMethodsRequest: Types.checkout.PaymentMethodsRequest = { amount: amount, merchantAccount: "ADYEN_MERCHANT_ACCOUNT", countryCode: "NL", channel: Types.checkout.PaymentMethodsRequest.ChannelEnum.Web, shopperLocale: "nl-NL" }; // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentMethods(paymentMethodsRequest, { idempotencyKey: "UUID" }); ``` The response includes the list of available payment methods, in the `paymentMethods` object. The payment methods are ordered by popularity in the shopper's country. For each payment method, the response contains: | Parameter name | Description | | -------------- | ------------------------------------------------------------------------------------------------- | | `name` | The name of the payment method that you can show in your payment form. | | `type` | The unique payment method code. You must include this when you [make a payment](#make-a-payment). | **Example response with available payment methods** ```json { "paymentMethods":[ { "name": "Cards", "type": "scheme" }, { "name":"SEPA Direct Debit", "type":"sepadirectdebit" } ] } ``` 2. Pass the list of available payment methods and the required input fields for each payment method to your client. ### Collect Shopper Details ## Build your payment form Client website or app Create your payment form where the shopper enters their information. We recommend that you collect commonly-used [shopper information in your payment form](#information-in-the-payment-form) to process a transactions, depending on your type of business.\ \ Some payment methods require you to collect, or optionally accept, additional information that you include in the payment request. For the additional information you must collect in your payment form for an individual payment method, go to our **API-only** [guide for the individual payment method](/payment-methods). We provide [payment method and issuer logos that you can download](#downloading-logos) and use in your payment form. ### Credit and debit card details Because governing bodies and organizations regulate the handling of credit and debit card information strictly, you must make sure that you are compliant when collecting card details. When a shopper selects to pay with a card, use the integration option that corresponds to your [level of PCI compliance](/development-resources/pci-dss-compliance-guide?tab=api_only_3_4#online-payments): * (Recommended) Adyen's [Custom Card Component](/payment-methods/cards/custom-card-integration) with encryption: our pre-built UI with logic to securely encrypt and handle payment card data. * Your own UI and logic to collect and handle [raw card data](/payment-methods/cards/raw-card-data): before you build an integration that collects raw credit and debit card data, you must [assess your PCI compliance according to the most extensive self-assessment form](/development-resources/pci-dss-compliance-guide?tab=api_only_3_4#online-payments) and contact your Adyen Account Manager to confirm that you are eligible. ### Information in the payment form After collecting information in your payment form, you must add it to corresponding API parameters that you include in the payment request. For example, for commonly-used information: | Field in the payment form | API request parameter | | ---------------------------------- | -------------------------- | | First name | `shopperName.firstName` | | Last name | `shopperName.lastName` | | Email address | `shopperEmail` | | Billing address (multiple fields) | `billingAddress` (object) | | Shipping address (multiple fields) | `deliveryAddress` (object) | | Phone number | `telephoneNumber` | ### Downloading Logos ** ### Downloading logos If you are building your own UI, we provide payment method and issuing bank logos that you can use on your checkout page. The images are available in PNG format with different sizes and screen resolutions and in SVG format. If you cannot find a payment method or issuer logo, contact our [Support Team](https://ca-test.adyen.com/ca/ca/contactUs/support.shtml?form=other). #### Payment method logos Download the images from the links below, specifying: * `img-size`: Specify the size for PNG format. Use the following values: * **small**: Image size 40x26 pixels * **medium**: Image size 77x50 pixels * **large**: Image size 154 x 100 pixels * `suffix`: Specify the image density for PNG format. If not specified, the images will have the same size as the `img-size`. Append any of the following values: * `@2x` * `@3x` * `-ldpi` * `-hdpi` * `-xhdpi` * `-xxhdpi` * `-xxxhdpi` * `pm-type`: The `paymentMethods.type` returned in the `/paymentMethods` response. For example, **googlepay** or **primeiropay\_boleto**. For cards, the values you should use are specified under `brands` with `type`: **scheme**. For example, `mc`, `visa`, and `amex`. To get a generic card logo, set `pm-type` to **card**. Download link for SVG: **Download link for SVG** ```js https://checkoutshopper-live.cdn.adyen.com/checkoutshopper/images/logos/[pm-type].svg ``` Download link for PNG: **Download link for PNG** ```js https://checkoutshopper-live.cdn.adyen.com/checkoutshopper/images/logos/[img-size]/[pm-type][suffix].png ``` Examples:\ \ #### Issuing bank logos Some payment methods such as iDEAL present a list of issuing banks to the shopper. Download the issuing bank logos from the links below, specifying: * `img-size`: Specify the size for PNG format. Use the following values: * **small**: Image size 40x26 pixels * **medium**: Image size 77x50 pixels * **large**: Image size 154 x 100 pixels * `suffix`: Specify the image density for PNG format. If not specified, the images will have the same size as the `img-size`. Append any of the following values: * `@2x` * `@3x` * `-ldpi` * `-hdpi` * `-xhdpi` * `-xxhdpi` * `-xxxhdpi` * `pm-type`: The `paymentMethods.type` in objects with `details.key` **issuer** returned in the `/paymentMethods` response. For example, **ideal**. * `issuerid`: The `details.items.id` referring to the issuing bank. For example, **1121** and **1151** for iDEAL. Download link for SVG: **Download link for SVG** ```js https://checkoutshopper-live.cdn.adyen.com/checkoutshopper/images/logos/[pm-type]/[issuerid].svg ``` Download link for PNG: **Download link for PNG** ```js https://checkoutshopper-live.cdn.adyen.com/checkoutshopper/images/logos/[img-size]/[pm-type]/[issuerid][suffix].png ``` Examples:\ \ ## Make a payment Payment server After the shopper selects the **Pay** button or chooses to pay with a payment method that requires a redirection, you must make a payment request to Adyen. 1. Pass the data from your client to your server. 2. From your server, make a **POST** [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request including the following parameters: | Parameter name | Required | Description | | -------------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | An object with the following parameters:- `currency`: The three-character [ISO currency code](/development-resources/currency-codes). - `value`: The value of the payment in [minor units](/development-resources/currency-codes). | | `reference` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your unique reference for this payment. | | `paymentMethod.type` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The payment method type. From the [`/paymentMethods` response](#get-available-payment-methods), this is the value in `paymentMethod.type`. | | `returnUrl` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The URL where the shopper should return to after a redirection. Format:- Include the protocol: `http://` or `https://`. - Maximum 1024 characters. - If it includes non-ASCII characters, such as spaces or special letters, [URL encode](https://www.w3schools.com/html/html_urlencode.asp) it. - You can include your own additional query parameters, such as a shopper ID or order reference number. The URL must not include personally identifiable information (PII), for example name or email address. | | `applicationInfo` | | If you are a [technology partner, service partner, or system integrator](https://docs.adyen.com/partners/application-information#partnership-type), send information about the application, so that we can offer you more support. | For the following cases, you must include additional parameters in your request: * Integrating some payment methods. For more information, go to [payment method integration guides](/payment-methods). * Using our risk management features. For more information, go to [data quality and risk field reference](/risk-management/configure-your-risk-profile/risk-field-reference). * [Creating a token](/online-payments/tokenization/create-tokens) to store the shopper's payment details. * [Using a token](/online-payments/tokenization/make-token-payments) to make a recurring payment with stored payment details. **Example request to make a payment for EUR 10 with encrypted card details** #### curl ```bash curl https://checkout-test.adyen.com/v72/payments \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "merchantAccount":"ADYEN_MERCHANT_ACCOUNT", "paymentMethod":{ "type": "scheme", "encryptedCardNumber": "test_4111111111111111", "encryptedExpiryMonth": "test_03", "encryptedExpiryYear": "test_2030", "encryptedSecurityCode": "test_737" }, "amount":{ "currency":"EUR", "value":1000 }, "reference":"YOUR_ORDER_NUMBER", "returnUrl":"https://your-company.example.com/checkout?shopperOrder=12xy.." }' ``` #### Java ```java // Adyen Java API Library v39.3.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the LIVE environment, also include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) Amount amount = new Amount() .currency("EUR") .value(1000L); CardDetails cardDetails = new CardDetails() .encryptedCardNumber("test_4111111111111111") .encryptedSecurityCode("test_737") .encryptedExpiryYear("test_2030") .encryptedExpiryMonth("test_03") .type(CardDetails.TypeEnum.SCHEME); PaymentRequest paymentRequest = new PaymentRequest() .reference("YOUR_ORDER_NUMBER") .amount(amount) .merchantAccount("ADYEN_MERCHANT_ACCOUNT") .paymentMethod(new CheckoutPaymentMethod(cardDetails)) .returnUrl("https://your-company.example.com/checkout?shopperOrder=12xy.."); // Send the request PaymentsApi service = new PaymentsApi(client); PaymentResponse response = service.payments(paymentRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("ADYEN_API_KEY"); // For the LIVE environment, also include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $amount = new Amount(); $amount ->setCurrency("EUR") ->setValue(1000); $checkoutPaymentMethod = new CheckoutPaymentMethod(); $checkoutPaymentMethod ->setEncryptedCardNumber("test_4111111111111111") ->setEncryptedSecurityCode("test_737") ->setEncryptedExpiryYear("test_2030") ->setEncryptedExpiryMonth("test_03") ->setType("scheme"); $paymentRequest = new PaymentRequest(); $paymentRequest ->setReference("YOUR_ORDER_NUMBER") ->setAmount($amount) ->setMerchantAccount("ADYEN_MERCHANT_ACCOUNT") ->setPaymentMethod($checkoutPaymentMethod) ->setReturnUrl("https://your-company.example.com/checkout?shopperOrder=12xy.."); $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->payments($paymentRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v32.1.1 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the LIVE environment, also include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) Amount amount = new Amount { Currency = "EUR", Value = 1000 }; CardDetails cardDetails = new CardDetails { EncryptedCardNumber = "test_4111111111111111", EncryptedSecurityCode = "test_737", EncryptedExpiryYear = "test_2030", EncryptedExpiryMonth = "test_03", Type = CardDetails.TypeEnum.Scheme }; PaymentRequest paymentRequest = new PaymentRequest { Reference = "YOUR_ORDER_NUMBER", Amount = amount, MerchantAccount = "ADYEN_MERCHANT_ACCOUNT", PaymentMethod = new CheckoutPaymentMethod(cardDetails), ReturnUrl = "https://your-company.example.com/checkout?shopperOrder=12xy.." }; // Send the request var service = new PaymentsService(client); var response = service.Payments(paymentRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### Go ```go // Adyen Go API Library v21.0.0 import ( "context" "github.com/adyen/adyen-go-api-library/v21/src/common" "github.com/adyen/adyen-go-api-library/v21/src/adyen" "github.com/adyen/adyen-go-api-library/v21/src/checkout" ) // For the LIVE environment, also include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) amount := checkout.Amount{ Currency: "EUR", Value: 1000, } cardDetails := checkout.CardDetails{ EncryptedCardNumber: common.PtrString("test_4111111111111111"), EncryptedSecurityCode: common.PtrString("test_737"), EncryptedExpiryYear: common.PtrString("test_2030"), EncryptedExpiryMonth: common.PtrString("test_03"), Type: common.PtrString("scheme"), } paymentRequest := checkout.PaymentRequest{ Reference: "YOUR_ORDER_NUMBER", Amount: amount, MerchantAccount: "ADYEN_MERCHANT_ACCOUNT", PaymentMethod: checkout.CardDetailsAsCheckoutPaymentMethod(&cardDetails), ReturnUrl: "https://your-company.example.com/checkout?shopperOrder=12xy..", } // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentsInput().IdempotencyKey("UUID").PaymentRequest(paymentRequest) res, httpRes, err := service.PaymentsApi.Payments(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.6.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "paymentMethod": { "type": "scheme", "encryptedCardNumber": "test_4111111111111111", "encryptedExpiryMonth": "test_03", "encryptedExpiryYear": "test_2030", "encryptedSecurityCode": "test_737" }, "amount": { "currency": "EUR", "value": 1000 }, "reference": "YOUR_ORDER_NUMBER", "returnUrl": "https://your-company.example.com/checkout?shopperOrder=12xy.." } # Send the request result = adyen.checkout.payments_api.payments(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v10.4.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT', :paymentMethod => { :type => 'scheme', :encryptedCardNumber => 'test_4111111111111111', :encryptedExpiryMonth => 'test_03', :encryptedExpiryYear => 'test_2030', :encryptedSecurityCode => 'test_737' }, :amount => { :currency => 'EUR', :value => 1000 }, :reference => 'YOUR_ORDER_NUMBER', :returnUrl => 'https://your-company.example.com/checkout?shopperOrder=12xy..' } # Send the request result = adyen.checkout.payments_api.payments(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v29.0.0 import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const amount: Types.checkout.Amount = { currency: "EUR", value: 1000 }; const cardDetails: Types.checkout.CardDetails = { encryptedCardNumber: "test_4111111111111111", encryptedSecurityCode: "test_737", encryptedExpiryYear: "test_2030", encryptedExpiryMonth: "test_03", type: Types.checkout.CardDetails.TypeEnum.Scheme }; const paymentRequest: Types.checkout.PaymentRequest = { reference: "YOUR_ORDER_NUMBER", amount: amount, merchantAccount: "ADYEN_MERCHANT_ACCOUNT", paymentMethod: cardDetails, returnUrl: "https://your-company.example.com/checkout?shopperOrder=12xy.." }; // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.payments(paymentRequest, { idempotencyKey: "UUID" }); ``` []() 3. Your next step depends on if the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response contains an `action` object: * If the response has no `action` object, [get the payment outcome](#get-the-payment-outcome). * If the response contains an `action` object, [handle the additional action](#additional-action). **Example response containing an action object for 3D Secure 2 authentication** ```json { "resultCode" : "IdentifyShopper", "action" : { "token" : "eyJkaXJl...", "paymentMethodType" : "scheme", "paymentData" : "Ab02b4c0...", "type" : "threeDS2", "authorisationToken" : "BQABAQ...", "subtype" : "fingerprint" } } ``` ### Perform Additional Actions ## Handle the additional action Client website or app Some payment methods require additional action from the shopper. Common examples of additional actions include: * Logging in to a bank's website or app. * Authenticating a payment with 3D Secure 2. * Scanning a QR code. Implement logic to handle all action types, so that your integration can handle different payment methods. To see if an individual payment method requires an additional action, see the corresponding [payment method guide](/payment-methods) for it. How you handle the action depends on the action type (`action.type`): | Type | `action.type` value | | ----------------------------------------------------------------------- | ------------------- | | [Redirect action](#handle-the-redirect) | **redirect** | | [3D Secure 2 authentication action](#3d-secure-2-authentication-action) | **threeDS2** | | [QR code action](#qr-code-action) | **qrCode** | | [SDK action](#sdk-action) | **sdk** | | [Voucher action](#voucher-action) | **voucher** | | [Await action](#await-action) | **await** | ### Redirect action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type` **redirect**, redirect the shopper to another site to complete the payment. How you handle the redirect depends on if it is a payment method redirect or a 3D Secure 2 redirect. ### Tab: Payment method redirect **Example /payments response for a payment method redirect** ```json { "action": { "method": "GET", "paymentData": "Ab02b4c0!BQ..", "paymentMethodType": "ideal", "type": "redirect", "url": "https://test.adyen.com/hpp/redirectIdeal.shtml?brandCode=ideal¤cyCode=EUR&issuerId=1121..." } } ``` 1. From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, get the following: | Parameter | Description | | ------------ | ----------------------------------- | | `action.url` | The URL to redirect the shopper to. | 2. Redirect the shopper to the `action.url` with the HTTP GET method, where they finish the payment. **Example to redirect the shopper** ```bash curl https://test.adyen.com/hpp/redirectIdeal.shtml?brandCode=ideal¤cyCode=EUR&issuerId=1121... \ ``` For security reasons, when displaying the redirect in the app, we recommend that you use [SFSafariViewController](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller) for iOS or [Chrome Custom Tabs](https://developer.chrome.com/multidevice/android/customtabs) for Android, instead of WebView objects. Also refer to the [security best practices](https://developer.android.com/topic/security/best-practices#webview) for WebView. 3. When the shopper finishes the payment on the other website, they are returned to your `returnUrl` with the HTTP GET method. The `returnUrl` is appended with a Base64-encoded `redirectResult`. **Redirect result appended to the return URL** ```raw GET /?shopperOrder=12xy..&&redirectResult=X6XtfGC3%21Y... HTTP/1.1 Host: www.your-company.example.com/checkout ``` 4. URL-decode the `redirectResult` value. If a shopper completed the payment but failed to return to your client, you will receive the outcome of the payment in a [webhook event](/development-resources/webhooks). 5. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### Tab: 3D Secure 2 redirect **Example /payments response for a 3D Secure 2 redirect** ```json { "resultCode":"RedirectShopper", "action":{ "data":{ "MD":"OEVudmZVMUlkWjd0MDNwUWs2bmhSdz09...", "PaReq":"eNpVUttygjAQ/RXbDyAXBYRZ00HpTH3wUosPfe...", "TermUrl":"" }, "method":"POST", "paymentData":"Ab02b4c0!BQABAgCJN1wRZuGJmq8dMncmypvknj9s7l5Tj...", "paymentMethodType":"scheme", "type":"redirect", "url":"https://test.adyen.com/hpp/3d/validate.shtml" }, "details":[ { "key":"MD", "type":"text" }, { "key":"PaRes", "type":"text" } ] } ``` 1. From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, get the following from the `action` object: | Parameter | Description | | --------- | ------------------------------------------------------------------------------ | | `url` | The URL to redirect the shopper to. | | `method` | The method to use to redirect the shopper: **POST**. | | `data` | An object with the following data required for authentication:- `MD` - `PaRes` | 2. Redirect the shopper to the `url` with the POST HTTP method, including the following data: | Parameter | Description | | --------- | ------------------------------------------------------------------------------------------------------------------------------------- | | `MD` | From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, the value from `action.data.MD`. | | `PaRes` | From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, the value from `action.data.PaRes`. | **Example of a redirect to a 3D Secure 2 URL** ```bash curl https://checkoutshopper-test.adyen.com/checkoutshopper/threeDS/checkoutRedirect/... \ --data-urlencode 'PaReq=eNpVUttygjAQ/RXbDyAXBYRZ00HpTH3wUosPfe...' \ --data-urlencode 'MD=OEVudmZVMUlkWjd0MDNwUWs2bmhSdz09...' ``` 3. The shopper finishes 3D Secure 2 authentication on an issuer website. In the test environment, this is the page: `https://test.adyen.com/hpp/3d/validate.shtml`, and you perform the authentication using the 3D Secure test credentials: * **Username**: user * **Password**: password 4. The shopper is returned to your `returnUrl` with the same HTTP method. The `returnUrl` is appended with `MD` and `PaRes`. **Example of a 3D Secure 2 redirect back to you with MD and PaRes** ```raw POST / HTTP/1.1 Host: www.your-company.example.com/checkout?shopperOrder=12xy.. Content-Type: application/x-www-form-urlencoded MD=Ab02b4c0%21BQABAgCW5sxB4e%2F%3D%3D..&PaRes=eNrNV0mTo7gS.. ``` 5. URL-decode the `MD` and `PaRes` values. 6. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### 3D Secure 2 authentication action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **threeDS2Fingerprint** or **threeDS2Challenge**, the payment qualifies for 3D Secure 2 and it goes through the [frictionless or the challenge flow](/online-payments/3d-secure/#authentication-flows). Use one of [our 3D Secure 2 solutions](/online-payments/3d-secure) to handle the action. ### QR code action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **qrCode**, the shopper must scan a QR code to complete the payment. **Example /payments response with a QR code action for WeChat Pay desktop** ```json { "resultCode": "Pending", "action": { "paymentData": "Ab02b4c0!BQAB..", "paymentMethodType": "wechatpayQR", "qrCodeData": "weixin://wxpay/bizpayurl?pr=IM7BCOW", "type": "qrCode" } } ``` 1. From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, get the following: | Parameter | Description | | ------------------- | --------------------------------- | | `action.qrCodeData` | Contains the URL for the QR code. | 2. Get the `qrCodeData` from the `action` object. This parameter contains a URL for the QR code. 3. Show the QR code to the shopper. 4. The shopper scans the QR code. 5. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### SDK action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **sdk**, the shopper must use another UI overlay to complete the payment. For example, a payment method requires the shopper to use its specific UI to enter payment details. **Example /payments response with an SDK action for WeChat Pay** ```json { "resultCode": "Pending", "action": { "paymentMethodType": "wechatpaySDK", "type": "sdk", "paymentData": "Ab02b4c0!BQAB..", "sdkData": { "appid": "wx3aed7fe146f6a57a", "noncestr": "cPY0e83ny4hWyf5O", "packageValue": "Sign=WXPay", "partnerid": "205287714", "prepayid": "wx015678064827111da2e4f0b11005864100", "sign": "169FD3F1E193446D90C45573EBDD4020", "timestamp": "1573033086" } }, "details": [ { "key": "resultCode", "type": "text" } ] } ``` 1. From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, get the following from the `action` object: | Parameter | Description | | --------- | --------------------------------------- | | `sdkData` | The data that you must pass to the SDK. | 2. Pass the data from the `sdkData` object to the SDK. 3. The shopper uses the SDK to finish the payment. 4. Get the result from the SDK. 5. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### Voucher action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **voucher**, the shopper must use a voucher to complete the payment. **Voucher action type** ```json { "resultCode": "PresentToShopper", "action": { "expiresAt": "2021-09-04T19:17:00", "initialAmount": { "currency": "IDR", "value": 10000 }, "instructionsUrl": "https://checkoutshopper-test.adyen.com/checkoutshopper/voucherInstructions.shtml?txVariant=doku_mandiri_va", "merchantName": "YOUR_SHOP_NAME", "paymentMethodType": "doku_alfamart", "reference": "8520126030105485", "shopperEmail": "john.smith@adyen.com", "shopperName": "John Smith", "totalAmount": { "currency": "IDR", "value": 10000 }, "paymentData": "Ab02b4c0!BQAB..", "type": "voucher" } } ``` 1. The data included in the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response is different for each voucher payment method. Get the available information from it. For example, for DOKU vouchers, get the following: | Parameter | Description | | ----------------- | ------------------------------------------------------------------------------------------- | | `expiresAt` | The date when the voucher expires. | | `initialAmount` | The payment amount and currency. | | `merchantName` | The name of your shop. | | `instructionsUrl` | The URL where you shopper can get additional information and instructions about how to pay. | 2. Show voucher information to the shopper that your shopper uses to pay outside of your client. 3. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### Await action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **await**, the shopper must take an additional action to complete the payment. For example: entering a code into their banking app. **Example of a /payments response with an await action for a one-time PayTo payment** ```json { "resultCode": "Pending", "action": { "paymentData": "Ab02b4c0!BQAB..", "paymentMethodType": "payto", "type": "await" } } ``` 1. From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, get the following: | Parameter | Description | | -------------------- | ------------------------ | | `action.paymentData` | Additional payment data. | 2. The shopper finishes the additional action for the payment. 3. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### Submit Additional Payment Details ## Send additional payment details Payment server If you [handled an additional action](#additional-action), you must send additional payment details. **For redirects**: if the shopper fails to return to your client, you do not get additional payment details to send. Instead, wait for the corresponding [webhook message](#update-your-order-management-system) for the outcome of the payment. From your server, make a POST [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request. The parameters that you must include depends on the payment method. For the parameters for an individual payment method, go to the **API-only** [page for the individual payment method ](/payment-methods). **Example request to send details from a redirect** #### curl ```bash curl https://checkout-test.adyen.com/v72/payments/details \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "details": { "redirectResult": "eyJ0cmFuc1N0YXR1cyI6IlkifQ==" } }' ``` #### Java ```java // Adyen Java API Library v39.3.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the LIVE environment, also include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) // Send the request PaymentsApi service = new PaymentsApi(client); PaymentDetailsResponse response = service.paymentsDetails(paymentDetailsRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("ADYEN_API_KEY"); // For the LIVE environment, also include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->paymentsDetails($paymentDetailsRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v32.1.1 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the LIVE environment, also include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) // Send the request var service = new PaymentsService(client); var response = service.PaymentsDetails(paymentDetailsRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### Go ```go // Adyen Go API Library v21.0.0 import ( "context" "github.com/adyen/adyen-go-api-library/v21/src/common" "github.com/adyen/adyen-go-api-library/v21/src/adyen" "github.com/adyen/adyen-go-api-library/v21/src/checkout" ) // For the LIVE environment, also include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentsDetailsInput().IdempotencyKey("UUID").PaymentDetailsRequest(paymentDetailsRequest) res, httpRes, err := service.PaymentsApi.PaymentsDetails(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.6.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "details": { "redirectResult": "eyJ0cmFuc1N0YXR1cyI6IlkifQ==" } } # Send the request result = adyen.checkout.payments_api.payments_details(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v10.4.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :details => { :redirectResult => 'eyJ0cmFuc1N0YXR1cyI6IlkifQ==' } } # Send the request result = adyen.checkout.payments_api.payments_details(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v29.0.0 import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentsDetails(paymentDetailsRequest, { idempotencyKey: "UUID" }); ``` The response includes information about the current payment status. **Example response for a successful payment** ```json { "pspReference": "NC6HT9CRT65ZGN82", "resultCode": "Authorised" } ``` **Example response for a refused payment** ```json { "pspReference": "KHQC5N7G84BLNK43", "refusalReason": "Not enough balance", "resultCode": "Refused" } ``` ### Show Payment Result ## Get the payment outcome After the shopper finishes the payment flow, you can show the shopper the current payment status. Adyen sends a webhook with the outcome of the payment. ### Inform the shopper Client website or app Use the [`resultCode` ](/online-payments/payment-result-codes#final-payment-status)to show the shopper the [current payment status](/account/payments-lifecycle). This synchronous response doesn't give you the final outcome of the payment. You get the final payment status in a webhook that you use to [update your order management system](#update-your-order-management-system). ### Update your order management system Webhook server You get the outcome of each payment asynchronously, in an **AUTHORISATION** [webhook](/development-resources/webhooks). Use the `merchantReference` from the webhook to match it to your order reference.\ For a successful payment, the event contains `success`: **true**. **Example webhook for a successful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"033899:1111:03/2030", "amount":{ "currency":"EUR", "value":2500 }, "operations":["CANCEL","CAPTURE","REFUND"], "success":"true", "paymentMethod":"mc", "additionalData":{ "expiryDate":"03/2030", "authCode":"033899", "cardBin":"411111", "cardSummary":"1111" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"NC6HT9CRT65ZGN82", "eventDate":"2021-09-13T14:10:22+02:00" } } ] } ``` For an unsuccessful payment, you get `success`: **false**, and the `reason` field has details about why the payment was unsuccessful. **Example webhook for an unsuccessful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"validation 101 Invalid card number", "amount":{ "currency":"EUR", "value":2500 }, "success":"false", "paymentMethod":"unknowncard", "additionalData":{ "expiryDate":"03/2030", "cardBin":"411111", "cardSummary":"1112" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"KHQC5N7G84BLNK43", "eventDate":"2021-09-13T14:14:05+02:00" } } ] } ``` ## Error handling In case you encounter errors in your integration, refer to the following: * [API error codes](/development-resources/error-codes): If you receive a non-HTTP 200 response, use the `errorCode` to troubleshoot and modify your request. * [Payment refusals](/development-resources/refusal-reasons): If you receive an HTTP 200 response with an **Error** or **Refused** `resultCode`, check the refusal reason and, if possible, modify your request. ## Test and go live Before going live, use our list of [test cards and other payment methods](/development-resources/test-cards-and-credentials/test-card-numbers) to [test your integration](/development-resources/testing). We recommend testing each payment method that you intend to offer to your shoppers. You can check the status of a test payment in your [Customer Area](https://ca-test.adyen.com/), under **Transactions** > **Payments**. To debug or troubleshoot test payments, you can also use [API logs](/development-resources/logs-resources/api-logs) in your test environment. When you are ready to go live, you need to: 1. [Apply for a live account](/get-started-with-adyen/application-requirements). 2. Assess your [PCI DSS compliance](/development-resources/pci-dss-compliance-guide#online-payments) by submitting: * the [Self-Assessment Questionnaire-A](https://www.pcisecuritystandards.org/documents/PCI-DSS-v3_2_1-SAQ-A.pdf), if you are using the Custom Card Component. * the [Self-Assessment Questionnaire-D](https://www.pcisecuritystandards.org/documents/PCI-DSS-v3_2_1-SAQ-D_Merchant.pdf), if you are submitting raw card data. 3. [Configure your live account](/online-payments/go-live-checklist).  4. Submit a request to add payment methods in your [live Customer Area](https://ca-live.adyen.com/) . 5. Switch from test to our [live endpoints](/development-resources/live-endpoints#checkout-endpoints). Make sure that all API requests you make for the same payment session use the same live endpoint region. Using different regions for [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) and [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) requests may result in errors, for example, when authenticating with 3D Secure 2. ### Next Steps [required](/development-resources/webhooks) [Set up notifications](/development-resources/webhooks) [Receive confirmation when a payment is authorised or fails.](/development-resources/webhooks) [required](/payment-methods) [Add payment methods](/payment-methods) [Learn about payment methods and how to add them to your account.](/payment-methods) [Payment modifications](/online-payments/modify-payments) [Find out how to cancel, refund, or capture a payment using our API.](/online-payments/modify-payments) ## iOS Drop-in Use our pre-built UI for accepting payments ### Intro Drop-in is our pre-built UI solution for accepting payments in your app. Drop-in shows all payment methods as a list, in the same block. For the Advanced flow, your server makes API requests to the [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods), [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments), and [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) endpoints. ### Before You Begin ## Requirements Before you begin to integrate, make sure you have followed the [Get started with Adyen guide](/get-started-with-adyen) to: * Get an overview of the steps needed to accept live payments. * Create your test account. After you have created your test account: * [Get your API key](/development-resources/api-credentials#generate-api-key). * [Get your client key](/development-resources/client-side-authentication#get-your-client-key). * [Set up webhooks](/development-resources/webhooks) to know the payment outcome. ### Install the Adyen iOS client-side library Choose how you want to install the Adyen iOS client-side library: ### Tab: Swift Package Manager To install iOS Drop-in using Swift Package Manager, [follow the Apple guide](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app) and specify: * The repository URL as `https://github.com/Adyen/adyen-ios` * The version to be at least **3.8.0** ### Tab: CocoaPods To install iOS Drop-in from CocoaPods: 1. Add `pod 'Adyen'` to your `Podfile`. 2. Run `pod install`. ### Tab: Carthage To install iOS Drop-in from Carthage: 1. Add `github "adyen/adyen-ios"` to your `Cartfile`. 2. Run `carthage update`. 3. Link the framework with your target as described in [Carthage Readme](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application). ### Get your client key You need a [client key](/development-resources/client-side-authentication), a public key linked to your API credential, that the iOS Drop-in uses for client-side authentication. 1. Log in to your [Customer Area](https://ca-test.adyen.com/). 2. Go to **Developers** > **API credentials**, and select the API credential for your integration, for example **ws\@Company.\[YourCompanyAccount]**. 3. Under **Authentication**, select **Generate New Client Key**. 4. Select **Save**. ## How it works For a Drop-in integration, you must implement the following parts: * **Your payment server**: sends the API requests to get available payment methods, make a payment, and send additional payment details. * **Your client app**: shows the Drop-in UI where the shopper makes the payment. Drop-in uses the data from the API responses to handle the payment flow and additional actions on your client app. * **Your webhook server**: receives webhooks that include the outcome of each payment. The parts of your integration work together to complete the payment flow: [![](/user/pages/filters/advanced-flow-integration/ios/4-9-0/drop-in/02.how-it-works/drop-in-flow.jpg)](/user/pages/filters/advanced-flow-integration/ios/4-9-0/drop-in/02.how-it-works/drop-in-flow.jpg) 1. From your server, submit a request to [get a list of payment methods available to the shopper](#get-available-payment-methods). 2. [Create an instance of Drop-in](#add). 3. From your server, [submit a payment request](#make-a-payment) with the data returned by Drop-in. 4. Determine from the response if you need to [perform additional actions on your client app](#additional-action). 5. From your server, [submit additional payment details](#send-additional-payment-details) with the data returned by Drop-in. 6. [Get the payment outcome](#get-the-payment-outcome). If you are integrating these parts separately, you can start at the corresponding part of this integration guide: [![](/user/pages/reuse/online-payments/how-it-works-parts/servers.svg?decoding=auto\&fetchpriority=auto)](/#install-api-library) ###### [Payment server](/#install-api-library) [Go to the integration steps for your server.](/#install-api-library) [Payment server](/#install-api-library) [![](/user/pages/reuse/online-payments/how-it-works-parts/browser-developers.svg?decoding=auto\&fetchpriority=auto)](/#add) ###### [Client app](/#add) [Go to the integration steps for your client app.](/#add) [Client](/#add) [![](/user/pages/reuse/online-payments/how-it-works-parts/event-code.svg?decoding=auto\&fetchpriority=auto)](/#update-your-order-management-system) ###### [Webhook server](/#update-your-order-management-system) [Go to the integration steps for your webhook server.](/#update-your-order-management-system) [Webhook server](/#update-your-order-management-system) ### Install Api Library ## Install an API library Payment server We provide server-side API libraries for several programming languages, available through common package managers, like Gradle and npm, for easier installation and version management. Our API libraries will save you development time, because they: * Use an API version that is up to date. * Have generated models to help you construct requests. * Send the request to Adyen using their built-in HTTP client, so you do not have to create your own. ### Tab: Java ##### Try our example integration ![](/reuse/development-resources/install-api-library/java/advanced/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-java-spring-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/java/advanced/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-java-spring-online-payments). #### Requirements * Java 11 or later. #### Installation You can use [Maven](https://maven.apache.org), adding this dependency to your project's POM. **Add the API library** ```xml com.adyen adyen-java-api-library LATEST_VERSION ``` You can find the latest version on GitHub. Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-java-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```java // Import the required classes. package com.adyen.service; import com.adyen.Client; import com.adyen.service.checkout.PaymentsApi; import com.adyen.model.checkout.Amount; import com.adyen.enums.Environment; import com.adyen.service.exception.ApiException; import java.io.IOException; public class Snippet { public Snippet() throws IOException, ApiException { // Set up the client and service. Client client = new Client("ADYEN_API_KEY", Environment.TEST); } } ``` ### Tab: PHP ##### Try our example integration ![](/reuse/development-resources/install-api-library/php/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-php-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/php/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-php-online-payments). #### Requirements * PHP 7.3 or later. * cURL with SSL support. * The JSON PHP extension. * The list of dependencies from the composer require list. #### Installation You can use [Composer](https://getcomposer.org/). Follow the [installation instructions](https://getcomposer.org/doc/00-intro.md) if you do not already have composer installed. **Install the API library** ```bash composer require adyen/php-api-library ``` In your PHP script, make sure you include the autoloader: **Include the autoloader** ```php require __DIR__ . '/vendor/autoload.php'; ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-php-api-library/releases). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```php use Adyen\Model\Checkout\Amount; use Adyen\Model\Checkout\CreateCheckoutSessionRequest; use Adyen\Service\Checkout\PaymentsApi; // Include your idempotency key when you make an API request. $requestOptions['idempotencyKey'] = "YOUR_IDEMPOTENCY_KEY"; // Set up the client and service. $client = new \Adyen\Client(); $client->setXApiKey('ADYEN_API_KEY'); $client->setEnvironment(\Adyen\Environment::TEST); $service = new PaymentsApi($client); ``` ### Tab: C\# #### Requirements * .NET standard 2.0 or later. * For Terminal API certificate validation, set the application to either of the following: * .NET core 2.1 or later * .NET framework 4.6.1 or later #### Installation You can use [NuGet](https://www.nuget.org/packages/Adyen/): **Install the API library** ```bash PM> Install-Package Adyen -Version LATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-dotnet-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```cs using Adyen; using Adyen.Model.Checkout; using Adyen.Service.Checkout; using Environment = Adyen.Model.Environment; class Program { static void Main() { // Set up the client and service. var config = new Config { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); var checkout = new PaymentsService(client); // Include your idempotency key when you make an API request. var requestOptions = new Adyen.Model.RequestOptions { IdempotencyKey = "YOUR_IDEMPOTENCY_KEY" }; } } ``` ### Tab: NodeJS ##### Try our example integration ![](/reuse/development-resources/install-api-library/node-js/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-node-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/node-js/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-node-online-payments). #### Requirements * Node.js version 18 or later. #### Installation You can use [npm](https://www.npmjs.com/): **Install the API library** ```bash npm install --save @adyen/api-library npm update @adyen/api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-node-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```js // Require the parts of the module you want to use. const { Client, CheckoutAPI, Types} = require("@adyen/api-library"); // Set up the client and service. const client = new Client({ apiKey: "ADYEN_API_KEY", environment: "TEST" }); const checkoutApi = new CheckoutAPI(client); // Include your idempotency key when you make an API request. const requestOptions = { idempotencyKey: "YOUR_IDEMPOTENCY_KEY" }; ``` ### Tab: Go ##### Try our example integration ![](/reuse/development-resources/install-api-library/go/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-golang-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/go/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-golang-online-payments). #### Requirements * Go 1.13 or later. #### Installation You can use [Go modules](https://github.com/golang/go/wiki/Modules): **Install the API library** ```shell go get github.com/adyen/adyen-go-api-library/vLATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-go-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```go package main import ( "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/adyen" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/checkout" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/common" ) // Create a payment object. func main () { client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) service := client.Checkout() ``` ### Tab: Python ##### Try our example integration ![](/reuse/development-resources/install-api-library/python/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-python-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/python/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-python-online-payments). #### Requirements * Python 3.6 or later. * (Optional) Packages: Requests or PycURL #### Installation You can use [pip](https://pip.pypa.io/en/stable/): **Install the API library** ```py pip install Adyen ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-python-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```py import Adyen # Set up the client and service. adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment that the library is used in. ``` ### Tab: Ruby ##### Try our example integration ![](/reuse/development-resources/install-api-library/ruby/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-rails-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/ruby/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-rails-online-payments). #### Requirements * Ruby 2.7 or later. #### Installation You can use [RubyGems](https://rubygems.org/): **Install the API library** ```bash gem install adyen-ruby-api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-ruby-api-library/releases). Run `bundle install` to install dependencies. #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```ruby require 'adyen-ruby-api-library' # Set up the client and service. adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # The environment that the library is used in. ``` ## Get available payment methods Payment server When your shopper is ready to pay, get a list of the available payment methods based on their country, device, and the payment amount. From your server, make a POST [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) request, providing the following parameters. While most parameters are optional, we recommend that you include them because Adyen uses these to tailor the list of payment methods for your shopper. We use the optional parameters to tailor the list of available payment methods to your shopper. | Parameter name | Required | Description | | ----------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | | The `currency` of the payment and its `value` in [minor units](/development-resources/currency-codes). | | `channel` | | The platform where the payment is taking place. Use **iOS**. Adyen returns only the payment methods available for iOS. | | `countryCode` | | The shopper's country/region. Adyen returns only the payment methods available in this country. Format: the two-letter [ISO-3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. Exception: **QZ** (Kosovo). | | `shopperLocale` | | By default, the `shopperlocale` is set to **en-US**. To change the language, set this to the shopper's language and country code. You also need to set the same `ShopperLocale` within your Drop-in configuration. | The following example shows how to get the available payment methods for a shopper in the **Netherlands**, for a payment of **EUR 10**: #### curl ```bash curl https://checkout-test.adyen.com/v72/paymentMethods \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Android", "shopperLocale": "nl-NL" }' ``` #### Java ```java // Adyen Java API Library v27.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the live environment, additionally include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) Amount amount = new Amount() .currency("EUR") .value(1000L); PaymentMethodsRequest paymentMethodsRequest = new PaymentMethodsRequest() .amount(amount) .merchantAccount("ADYEN_MERCHANT_ACCOUNT") .countryCode("NL") .channel(PaymentMethodsRequest.ChannelEnum.IOS) .shopperLocale("nl-NL"); // Send the request PaymentsApi service = new PaymentsApi(client); PaymentMethodsResponse response = service.paymentMethods(paymentMethodsRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("ADYEN_API_KEY"); // For the LIVE environment, also include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->paymentMethods($paymentMethodsRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v32.1.1 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the LIVE environment, also include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) // Send the request var service = new PaymentsService(client); var response = service.PaymentMethods(paymentMethodsRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v29.0.0 const { Client, CheckoutAPI } = require('@adyen/api-library'); // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const paymentMethodsRequest = { merchantAccount: "ADYEN_MERCHANT_ACCOUNT", countryCode: "NL", amount: { currency: "EUR", value: 1000 }, channel: "Android", shopperLocale: "nl-NL" } // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentMethods(paymentMethodsRequest, { idempotencyKey: "UUID" }); ``` #### Go ```go // Adyen Go API Library v10.4.0 import ( "context" "github.com/adyen/adyen-go-api-library/v9/src/common" "github.com/adyen/adyen-go-api-library/v9/src/adyen" "github.com/adyen/adyen-go-api-library/v9/src/checkout" ) // For the live environment, additionally include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) amount := checkout.Amount{ Currency: "EUR", Value: 1000, } paymentMethodsRequest := checkout.PaymentMethodsRequest{ Amount: &amount, MerchantAccount: "ADYEN_MERCHANT_ACCOUNT", CountryCode: common.PtrString("NL"), Channel: common.PtrString("iOS"), ShopperLocale: common.PtrString("nl-NL"), } // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentMethodsInput().IdempotencyKey("UUID").PaymentMethodsRequest(paymentMethodsRequest) res, httpRes, err := service.PaymentsApi.PaymentMethods(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.6.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Android", "shopperLocale": "nl-NL" } # Send the request result = adyen.checkout.payments_api.payment_methods(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v10.4.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT', :countryCode => 'NL', :amount => { :currency => 'EUR', :value => 1000 }, :channel => 'Android', :shopperLocale => 'nl-NL' } # Send the request result = adyen.checkout.payments_api.payment_methods(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v29.0.0 import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentMethods(paymentMethodsRequest, { idempotencyKey: "UUID" }); ``` The response includes the list of available `paymentMethods`: **/paymentMethods response** ```json { "paymentMethods":[ { "details":[...], "name":"Cards", "type":"scheme" ... }, { "details":[...], "name":"SEPA Direct Debit", "type":"sepadirectdebit" }, ... ] } ``` Pass the response to your client app. You will use this in the next step to present which payment methods are available to the shopper. ### Add Drop In ## Add Drop-in to your payment form Client app Next, use Drop-in to show the available payment methods and to collect payment details from your shopper. 1. Decode the [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) response with the `PaymentMethods` structure. **Decode the /paymentMethods response** ```swift let paymentMethods = try JSONDecoder().decode(PaymentMethods.self, from: paymentMethodsResponse) ``` 2. Create an instance of `APIContext` that contains to following: | | Description | | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | [Client key](/development-resources/client-side-authentication#get-your-client-key) | Authenticates requests from your payment environment. | | Environment setting | The [environment value](#test-and-go-live) that matches the endpoint that your server uses. Use **Environment.test** for your test environment. | **Create the APIContext** ```swift // Set the client key and environment in an instance of APIContext. let apiContext = APIContext(clientKey: clientKey, environment: Environment.test) // Set the environment to a live one when going live. ``` 3. Create an instance of `AdyenContext` that contains the following: | | Description | | ------------------- | -------------------------------------------------------- | | API context | Your instance of `APIContext`. | | Payment information | A `Payment` object with the payment amount and currency. | **Create the AdyenContext** ```swift // Create the amount with the value in minor units and the currency code. let amount = Amount(value: 1000, currencyCode: "EUR") // Create the payment object with the amount and country code. let payment = Payment(amount: amount, countryCode: "NL") // Create an instance of AdyenContext, passing the instance of APIContext, and payment object. let adyenContext = AdyenContext(apiContext: apiContext, payment:payment) ``` 4. Create a Drop-in configuration object (`DropInComponent.Configuration`). You can add the following:[]() | Type of configuration | Description | | ---------------------------- | --------------------------------------------------------------------------------------------------------- | | Payment method configuration | Some [payment methods](/payment-methods) require additional configuration or have optional configuration. | | Optional configuration | You can add [optional configuration](#optional-configuration) for Drop-in. | The following example shows an optional configuration for cards. **Configure Drop-in** ```js let dropInConfiguration = DropInComponent.Configuration() // Some payment methods have additional required or optional configuration. // For example, an optional configuration to show the cardholder name field for cards. dropInConfiguration.card.showsHolderNameField = true ``` 5. Initialize Drop-in ([ `DropInComponent` ](https://adyen.github.io/adyen-ios/5.0.0/documentation/adyen/)).[]() | Parameter name | Required | Description | | ----------------------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | `paymentMethods` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The full, decoded [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) response. | | `context` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The `AdyenContext` that you created. | | `paymentMethodsConfiguration` | For some [payment methods](/payment-methods). | Configuration for specific payment methods. | **Initialize Drop-in** ```swift let dropInComponent = DropInComponent(paymentMethods: paymentMethods, context: adyenContext, configuration: dropInConfiguration) // Keep the instance of Drop-in so that it doesn't get destroyed after the function is executed. self.dropInComponent = dropInComponent // Set self as the delegate. dropInComponent.delegate = self // If you support gift cards, set self as the partial payment delegate. dropInComponent.partialPaymentDelegate = self ``` 6. After the shopper selects a payment method and provides payment details, Drop-in invokes the `didSubmit` method. Get the contents of `data.paymentMethod` and pass this to your server. ```swift func didSubmit(_ data: PaymentComponentData, for paymentMethod: PaymentMethod, from component: DropInComponent) ``` If an error occurs on the app, Drop-in invokes the `didFail` method. Dismiss Drop-in's view controller and display an error message. ```swift func didFail(with error: Error, from component: DropInComponent) ``` If the shopper decides not to continue with the selected payment method, Drop-in invokes the `didCancel` method. You can use `didCancel` to track the state of the payment. ```swift func didCancel(component: PaymentComponent, from dropInComponent: DropInComponent) ``` For more information on iOS Drop-in classes, see our [reference documentation](https://adyen.github.io/adyen-ios/5.0.0/documentation/adyen/) page. ## Make a payment Payment server When the shopper selects the **Pay** button or chooses to pay with a payment method that requires a redirection, you must make a payment request to Adyen. 1. Pass the full data from `didSubmit` to your server. 2. From your server, make a POST [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request including the following: | Parameter name | Required | Description | | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The `currency` of the payment and its `value` in [minor units](/development-resources/currency-codes). | | `reference` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your unique reference for this payment. | | `paymentMethod` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The complete `data.paymentMethod` object from the `didSubmit` method from your client app. It includes the payment method details and other required information. | | `paymentMethod.sdkData` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The object that includes information collected by Drop-in to track the user's payment journey, including information like the [checkout attempt identifier](/online-payments/analytics-and-data-tracking#data-we-are-collecting). This is required to use the [Checkout dashboard](/uplift#uplift-dashboards) that lets you analyze your checkout performance. | | `returnUrl` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The URL the shopper should be taken back to after a redirection. Use the custom URL for your app, for example, `my-app://adyen`, to take the shopper back to your app after they complete the payment outside of your app. For more information on setting a custom URL scheme, read the [Apple Developer documentation](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app). The URL can contain a maximum of 1024 characters. You can also include your own additional query parameters, for example, shopper ID or order reference number. | | [`applicationInfo`](/development-resources/building-adyen-solutions) | | If you are building an Adyen solution for multiple merchants, include some basic identifying information, so that we can offer you better support. For more information, refer to [Building Adyen solutions](/development-resources/building-adyen-solutions). | For the following cases, you must include additional parameters in your request: * Integrating some payment methods. For more information, go to [payment method integration guides](/payment-methods). * Using our risk management features. For more information, see [Required risk fields](/risk-management/configure-manual-risk/required-risk-field-reference). * [Native 3D Secure 2 authentication](/online-payments/3d-secure/native-3ds2/android-drop-in#make-a-payment). * [Creating a token](/online-payments/tokenization/create-tokens) to store the shopper's payment details. * [Using a token](/online-payments/tokenization/make-token-payments) to make a recurring payment with stored payment details. 3. **Example request to make a payment for EUR 10** #### curl ```bash curl https://checkout-test.adyen.com/v72/payments \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "amount":{ "currency":"EUR", "value":1000 }, "reference":"YOUR_ORDER_NUMBER", "paymentMethod":{hint:paymentMethod field of an object passed from your client app}STATE_DATA{/hint}, "returnUrl":"my-app://adyen", "merchantAccount":"ADYEN_MERCHANT_ACCOUNT" }' ``` #### Java ```java // Set your ADYEN_API_KEY with the API key from the Customer Area. Client client = new Client(System.getenv("ADYEN_API_KEY"), Environment.TEST); PaymentsApi checkout = new PaymentsApi(client); PaymentRequest paymentRequest = new PaymentRequest(); paymentRequest.setMerchantAccount(System.getenv("MERCHANT_ACCOUNT")); // STATE_DATA is the paymentMethod field of an object passed from your client. String STATE_DATA = "{\n" + " \"type\": \"scheme\",\n" + " \"number\":\"4111111111111111\",\n" + " \"cvc\":\"737\",\n" + " \"expiryMonth\":\"10\",\n" + " \"expiryYear\":\"2020\",\n" + " \"holderName\":\"John Smith\"\n" + "}\n"; // Deserialize the payment method from STATE_DATA. paymentRequest.setPaymentMethod(CheckoutPaymentMethod.fromJson(STATE_DATA)); Amount amount = new Amount(); amount.setCurrency("EUR"); amount.setValue(1000L); paymentRequest.setAmount(amount); paymentRequest.setReference("YOUR_ORDER_NUMBER"); paymentRequest.setReturnUrl("my-app://adyen"); // Add your idempotency key. RequestOptions requestOptions = new RequestOptions(); requestOptions.setIdempotencyKey("YOUR_IDEMPOTENCY_KEY"); PaymentResponse response = checkout.payments(paymentRequest, requestOptions); ``` #### PHP ```php // Set ADYEN_API_KEY with the API key from the Customer Area. $client = new \Adyen\Client(); $client->setEnvironment(\Adyen\Environment::TEST); $client->setXApiKey("ADYEN_API_KEY"); $service = new \Adyen\Service\Checkout($client); // STATE_DATA is the paymentMethod field of an object passed from your client app, deserialized from JSON to a data structure. $paymentMethod = STATE_DATA;; $params = array( "paymentMethod" => $paymentMethod, "amount" => array( "currency" => "EUR", "value" => 1000 ), "reference" => "YOUR_ORDER_NUMBER", "returnUrl" => "my-app://adyen", "merchantAccount" => "ADYEN_MERCHANT_ACCOUNT" ); $result = $service->payments($params); // Check if further action is needed if (array_key_exists("action", $result)){ // Pass the action object to your client. // $result["action"] } else { // No further action needed, pass the resultCode to your client. // $result['resultCode'] } ``` #### C\# ```cs // Set ADYEN_API_KEY with the API key from the Customer Area. string apiKey = "ADYEN_API_KEY"; var client = new Client (apiKey, Environment.Test); var checkout = new Checkout(client); var amount = new Adyen.Model.Checkout.Amount("EUR", 1000); var paymentsRequest = new Adyen.Model.Checkout.PaymentRequest { // STATE_DATA is the paymentMethod field of an object passed from your client app, deserialized from JSON to a data structure. PaymentMethod = STATE_DATA, Amount = amount, Reference = "YOUR_ORDER_NUMBER", ReturnUrl = @"my-app://adyen", }; var paymentResponse = checkout.Payments(paymentsRequest); ``` #### NodeJS (JavaScript) ```js const {Client, Config, CheckoutAPI} = require('@adyen/api-library'); const config = new Config(); // Set ADYEN_API_KEY with the API key from the Customer Area. config.apiKey = 'ADYEN_API_KEY'; config.merchantAccount = 'ADYEN_MERCHANT_ACCOUNT'; const client = new Client({ config }); client.setEnvironment("TEST"); const checkout = new CheckoutAPI(client); checkout.payments({ merchantAccount: config.merchantAccount, // STATE_DATA is the paymentMethod field of an object passed from the your client app, deserialized from JSON to a data structure. paymentMethod: STATE_DATA, amount: { currency: "EUR", value: 1000, }, reference: "YOUR_ORDER_NUMBER", returnUrl: "my-app://adyen" }).then(res => res); ``` #### Go ```go import ( "github.com/adyen/adyen-go-api-library/v5/src/checkout" "github.com/adyen/adyen-go-api-library/v5/src/common" "github.com/adyen/adyen-go-api-library/v5/src/adyen" ) // Set ADYEN_API_KEY with the API key from the Customer Area. client := adyen.NewClient(&common.Config{ Environment: common.TestEnv, ApiKey: "ADYEN_API_KEY", }) // STATE_DATA is the paymentMethod field of an object passed from your client app, deserialized from JSON to a data structure. paymentMethod := STATE_DATA res, httpRes, err := client.Checkout.Payments(&checkout.PaymentRequest{ PaymentMethod: paymentMethod, Amount: checkout.Amount{ Value: 1000, Currency: "EUR", }, Reference: "YOUR_ORDER_NUMBER", ReturnUrl: "my-app://adyen", MerchantAccount: "ADYEN_MERCHANT_ACCOUNT", }) ``` #### Python ```py # Set ADYEN_API_KEY with the API key from the Customer Area. adyen = Adyen.Adyen() adyen.payment.client.platform = "test" adyen.client.xapikey = 'ADYEN_API_KEY' # STATE_DATA is the paymentMethod field of an object passed from your client app, deserialized from JSON to a data structure. paymentMethod = STATE_DATA result = adyen.checkout.payments({ 'paymentMethod': paymentMethod, 'amount': { 'value': 1000, 'currency': 'EUR' }, 'reference': 'YOUR_ORDER_NUMBER', 'returnUrl': 'my-app://adyen', 'merchantAccount': 'ADYEN_MERCHANT_ACCOUNT' }) # Check if further action is needed if 'action' in result.message: # Pass the action object to your client. # result.message['action'] else: # No further action needed, pass the resultCode to your client. # result.message['resultCode'] ``` #### Ruby ```ruby require 'adyen-ruby-api-library' # Set ADYEN_API_KEY with the API key from the Customer Area. adyen = Adyen::Client.new adyen.env = :test adyen.api_key = "ADYEN_API_KEY" # STATE_DATA is the paymentMethod field of an object passed from the front end or client app, deserialized from JSON to a data structure. paymentMethod = STATE_DATA response = adyen.checkout.payments({ :paymentMethod => paymentMethod, :amount => { :currency => 'EUR', :value => 1000 }, :reference => 'YOUR_ORDER_NUMBER', :returnUrl => 'my-app://adyen', :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT' }) # Check if further action is needed. if response.body.has_key(:action) # Pass the action object to your client app. # response.body[:action] else # No further action needed, pass the resultCode object to your client app. # response.body[:resultCode] ``` Your next step depends on if the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response contains an `action` object: * If the response has no `action` object, [get the payment outcome](#get-the-payment-outcome). * If the response contains an `action` object, [handle the additional action](#additional-action). **Example response containing an action object for 3D Secure 2 authentication** ```json { "resultCode" : "IdentifyShopper", "action" : { "token" : "eyJkaXJl...", "paymentMethodType" : "scheme", "paymentData" : "Ab02b4c0...", "type" : "threeDS2", "authorisationToken" : "BQABAQ...", "subtype" : "fingerprint" } } ``` ### Perform Additional Actions ## Handle the additional action Client app Some payment methods require additional action from the shopper. Common examples of additional actions include: * Logging in to a bank's website or app. * Authenticating a payment with 3D Secure 2. * Scanning a QR code. To handle the action: 1. Pass the full `action` object from your server to your client app. 2. Call [`dropInComponent.handle(action)` ](https://adyen.github.io/adyen-ios/5.0.0/documentation/adyen/)to trigger Drop-in to handle the additional action. **Use Drop-in to handle the additional action** ```swift let action = try JSONDecoder().decode(Action.self, from: actionData) dropInComponent.handle(action) ``` 3. Drop-in performs the additional action in your app. 4. You handle the payment data, depending on the value of `action.type`. | Type | `action.type` value | | ----------------------------------------------------------------------- | ------------------- | | [Redirect action](#handle-the-redirect) | **redirect** | | [3D Secure 2 authentication action](#3d-secure-2-authentication-action) | **threeDS2** | | [QR code action](#qr-code-action) | **qrCode** | | [SDK action](#sdk-action) | **sdk** | | [Voucher action](#voucher-action) | **voucher** | | [Await action](#await-action) | **await** | ### Redirect action []() When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type` **redirect**, Drop-in redirects your shopper to another website to complete the payment. 1. When the shopper returns to your app, inform Drop-in. To do this, implement the following in your `UIApplicationDelegate`: ```swift func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool { RedirectComponent.applicationDidOpen(from: url) return true } ``` 2. After Drop-in completes the additional action, Drop-in invokes the `didProvide` method. **didProvide with action data** ```swift func didProvide(_ data: ActionComponentData, from component: ActionComponent, in dropInComponent: AnyDropInComponent) ``` If an error occurs in the app, Drop-in invokes the `didFail` method. Dismiss Drop-in's view controller and display an error message. **didFail with action error** ```swift func didFail(with error: Error, from component: ActionComponent, in dropInComponent: AnyDropInComponent) ``` 3. Get the `data` from the `didProvide` method. 4. [Dismiss Drop-in](#dismiss) immediately or after the following step. 5. Pass the contents of `data` to your server. 6. [Send additional payment details](#send-additional-payment-details). If the shopper fails to return to your app, you do not get the additional data to send. Instead, wait for the corresponding [webhook](#update-your-order-management-system) for the outcome of the payment. ### 3D Secure 2 authentication action When the response includes `action.type`: **threeDS2**, the payment qualifies for 3D Secure 2 and it goes through the frictionless or the challenge flow. 1. Drop-in handles 3D Secure 2 authentication. If a challenge is required, the shopper performs the authentication challenge to complete the payment. 2. After Drop-in completes the additional action, it invokes the `didProvide` method. **didProvide with action data** ```swift func didProvide(_ data: ActionComponentData, from component: ActionComponent, in dropInComponent: AnyDropInComponent) ``` If an error occurs in the app, Drop-in invokes the `didFail` method. Dismiss Drop-in's view controller and display an error message. **didFail with action error** ```swift func didFail(with error: Error, from component: ActionComponent, in dropInComponent: AnyDropInComponent) ``` 3. Get the `data` from the `didProvide` method. 4. [Dismiss `dropInComponent`](#dismiss) now or after the following step. 5. Pass the contents of `data` to your server. 6. [Send additional payment details](#send-additional-payment-details). ### QR code action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **qrCode**, the shopper must scan a QR code to complete the payment. 1. `AdyenActionComponent` uses `presentationDelegate` to show the UI for QR code payment. 2. Drop-in polls the payment status and, if completed, calls the `didProvide` method. **didProvide with action data** ```swift func didProvide(_ data: ActionComponentData, from component: ActionComponent, in dropInComponent: AnyDropInComponent) ``` If an error occurs in the app, Drop-in invokes the `didFail` method. Dismiss Drop-in's view controller and display an error message. **didFail with action error** ```swift func didFail(with error: Error, from component: ActionComponent, in dropInComponent: AnyDropInComponent) ``` 3. Get the `data` from the `didProvide` method. 4. [Dismiss `dropInComponent`](#dismiss) now or after the following step. 5. Pass the contents of `data` to your server. 6. [Send additional payment details](#send-additional-payment-details). ### SDK action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **sdk**, the shopper must use the payment method's app to complete the payment. 1. `AdyenActionComponent` triggers the app switch from your app to the payment method's app, if installed in the shopper's device. 2. When the shopper returns to your app, Drop-in invokes the `didProvide` method. **didProvide with action data** ```swift func didProvide(_ data: ActionComponentData, from component: ActionComponent, in dropInComponent: AnyDropInComponent) ``` If an error occurs in the app, Drop-in invokes the `didFail` method. Dismiss Drop-in's view controller and display an error message. **didFail with action error** ```swift func didFail(with error: Error, from component: ActionComponent, in dropInComponent: AnyDropInComponent) ``` 3. Get the `data` from the `didProvide` method. 4. [Dismiss `dropInComponent`](#dismiss) now or after the following step. 5. Pass the contents of `data` to your server. 6. [Send additional payment details](#send-additional-payment-details). ### Voucher action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **voucher**, the shopper must use a voucher to complete the payment. 1. `AdyenActionComponent` uses `presentationDelegate` to show the UI for the voucher. 2. The shopper shares, saves the voucher as an image or, in some cases, adds the voucher to Apple Wallet. 3. When the shopper completes the flow, Drop-in invokes the `didComplete` method. **didProvide with action data** ```swift func didProvide(_ data: ActionComponentData, from component: ActionComponent, in dropInComponent: AnyDropInComponent) ``` If an error occurs in the app, Drop-in invokes the `didFail` method. Dismiss Drop-in's view controller and display an error message. **didFail with action error** ```swift func didFail(with error: Error, from component: ActionComponent, in dropInComponent: AnyDropInComponent) ``` 4. [Dismiss `dropInComponent`](#dismiss). The payment flow in your app is complete. After the shopper pays, or the voucher expires, your webhook server gets the [webhook to update the payment status](#update-your-order-management-system). ### Await action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **await**, the shopper must take an additional action to complete the payment. 1. `AdyenActionComponent` uses `presentationDelegate` to show the await UI. The shopper continues payment process outside of your app. 2. Drop-in polls the payment status and, if completed, calls the `didProvide` the `didProvide` method from the `ActionComponentDelegate`. **didProvide with action data** ```swift func didProvide(_ data: ActionComponentData, from component: ActionComponent, in dropInComponent: AnyDropInComponent) ``` If an error occurs in the app, Drop-in invokes the `didFail` method. Dismiss Drop-in's view controller and display an error message. **didFail with action error** ```swift func didFail(with error: Error, from component: ActionComponent, in dropInComponent: AnyDropInComponent) ``` 3. Get the `data` from the `didProvide` method. 4. [Dismiss `dropInComponent`](#dismiss) now or after the following step. 5. Pass the contents of `data` to your server. 6. [Send additional payment details](#send-additional-payment-details). ### Submit Additional Details ## Send additional payment details Payment server If you [handled an additional action](#additional-action), you must send additional payment details. **For redirects**: if the shopper fails to return to your app, you do not get additional payment details to send. Instead, wait for the corresponding [webhook](#update-your-order-management-system) for the outcome of the payment. 1. Pass the full `data` object from the `didProvide` method to your server. 2. From your server, make a POST [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request including the full `data` object. **Example request to send additional payment details** #### curl ```bash curl https://checkout-test.adyen.com/v72/payments/details \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{hint:object passed from your client app}STATE_DATA{/hint}' ``` #### Java ```java // Set your X-API-KEY with the API key from the Customer Area. String xApiKey = "ADYEN_API_KEY"; Client client = new Client(xApiKey,Environment.TEST); Checkout checkout = new Checkout(client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. PaymentsDetailsRequest paymentsDetailsRequest = STATE_DATA; PaymentsResponse paymentsDetailsResponse = checkout.paymentsDetails(paymentsDetailsRequest); ``` #### PHP ```php // Set your X-API-KEY with the API key from the Customer Area. $client = new \Adyen\Client(); $client->setEnvironment(\Adyen\Environment::TEST); $client->setXApiKey("ADYEN_API_KEY"); $service = new \Adyen\Service\Checkout($client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. $params = STATE_DATA; $result = $service->paymentsDetails($params); // Check if further action is needed. if (array_key_exists("action", $result)){ // Pass the action object to your client. // $result["action"] } else { // No further action needed, pass the resultCode to your client. // $result['resultCode'] } ``` #### C\# ```cs // Set your X-API-KEY with the API key from the Customer Area. string apiKey = "ADYEN_API_KEY"; var client = new Client (apiKey, Environment.Test); var checkout = new Checkout(client); // STATE_DATA is an object passed from the client app, deserialized from JSON to a data structure. var paymentsDetailsRequest = STATE_DATA; var paymentsDetailsResponse = checkout.PaymentDetails(paymentsDetailsRequest); ``` #### NodeJS (JavaScript) ```js const {Client, Config, CheckoutAPI} = require('@adyen/api-library'); const config = new Config(); // Set your X-API-KEY with the API key from the Customer Area. config.apiKey = '[ADYEN_API_KEY]'; const client = new Client({ config }); client.setEnvironment("TEST"); const checkout = new CheckoutAPI(client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. checkout.paymentsDetails(STATE_DATA).then(res => res); ``` #### Go ```go import ( "github.com/adyen/adyen-go-api-library/v5/src/checkout" "github.com/adyen/adyen-go-api-library/v5/src/common" "github.com/adyen/adyen-go-api-library/v5/src/adyen" ) // Set your X-API-KEY with the API key from the Customer Area. client := adyen.NewClient(&common.Config{ Environment: common.TestEnv, ApiKey: "[ADYEN_API_KEY]", }) // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. req := STATE_DATA; res, httpRes, err := client.Checkout.PaymentsDetails(&req) ``` #### Python ```py # Set your X-API-KEY with the API key from the Customer Area. adyen = Adyen.Adyen() adyen.payment.client.platform = "test" adyen.client.xapikey = 'ADYEN_API_KEY' # STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. request = STATE_DATA result = adyen.checkout.payments_details(request) # Check if further action is needed. if 'action' in result.message: # Pass the action object to your client. # result.message['action'] else: # No further action needed, pass the resultCode to your client. # result.message['resultCode'] ``` #### Ruby ```ruby require 'adyen-ruby-api-library' # Set your X-API-KEY with the API key from the Customer Area. adyen = Adyen::Client.new adyen.env = :test adyen.api_key = "ADYEN_API_KEY" # STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. request = STATE_DATA response = adyen.checkout.payments.details(request) # Check if further action is needed. if response.body.has_key(:action) # Pass the action object to your client puts response.body[:action] else # No further action needed, pass the resultCode to your client puts response.body[:resultCode] end ``` 3. Pass the [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) response from your server to your client app. **Example response for a successful payment** ```json { "pspReference": "NC6HT9CRT65ZGN82", "resultCode": "Authorised" } ``` **Example response for a refused payment** ```json { "pspReference": "KHQC5N7G84BLNK43", "refusalReason": "Not enough balance", "resultCode": "Refused" } ``` ### Dismiss-Dropin ## Dismiss Drop-in Client app After you make a [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request to submit the payment data or a [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request to send additional details, dismiss Drop-in to finalize the payment flow. Call `finalizeIfNeeded` and do the following, depending on what the Drop-in handled: | | What to do | | ----------- | ----------------------------------------------------------------------- | | Result code | If no further steps are required from the application, dismiss Drop-in. | | Error | Dismiss Drop-in, and show an error message. | Implement the following in your `dropInComponent` object: **Implement finalizeIfNeeded to dismiss Drop-in** ```js dropInComponent?.finalizeIfNeeded(with: isSuccessful) { [weak self] in guard let self else { return } myCheckoutViewController.dismiss(animated: true) { [weak self] in // Continue the flow. } } ``` ### Show Payment Result ## Get the payment outcome After Drop-in finishes the payment flow, you can show the shopper the current payment status. Adyen sends a webhook with the outcome of the payment. ### Inform the shopper Client app Use the [`resultCode` ](/online-payments/payment-result-codes#final-payment-status)to show the shopper the [current payment status](/account/payments-lifecycle). This synchronous response doesn't give you the final outcome of the payment. You get the final payment status in a webhook that you use to [update your order management system](#update-your-order-management-system). ### Update your order management system Webhook server You get the outcome of each payment asynchronously, in an **AUTHORISATION** [webhook](/development-resources/webhooks). Use the `merchantReference` from the webhook to match it to your order reference.\ For a successful payment, the event contains `success`: **true**. **Example webhook for a successful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"033899:1111:03/2030", "amount":{ "currency":"EUR", "value":2500 }, "operations":["CANCEL","CAPTURE","REFUND"], "success":"true", "paymentMethod":"mc", "additionalData":{ "expiryDate":"03/2030", "authCode":"033899", "cardBin":"411111", "cardSummary":"1111" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"NC6HT9CRT65ZGN82", "eventDate":"2021-09-13T14:10:22+02:00" } } ] } ``` For an unsuccessful payment, you get `success`: **false**, and the `reason` field has details about why the payment was unsuccessful. **Example webhook for an unsuccessful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"validation 101 Invalid card number", "amount":{ "currency":"EUR", "value":2500 }, "success":"false", "paymentMethod":"unknowncard", "additionalData":{ "expiryDate":"03/2030", "cardBin":"411111", "cardSummary":"1112" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"KHQC5N7G84BLNK43", "eventDate":"2021-09-13T14:14:05+02:00" } } ] } ``` ## Test and go live Before going live, use our list of [test cards and other payment methods](/development-resources/test-cards-and-credentials/test-card-numbers) to test your integration. We recommend testing each payment method that you intend to offer to your shoppers. You can check the status of a test payment in your [Customer Area](https://ca-test.adyen.com/), under **Transactions** > **Payments**. To debug or troubleshoot test payments, you can also use [API logs](/development-resources/logs-resources/api-logs) in your test environment. When you are ready to go live, you need to: 1. [Apply for a live account](/get-started-with-adyen/application-requirements).   2. Assess your [PCI DSS compliance](/development-resources/pci-dss-compliance-guide#mobile-in-app-online-payments-integration), and submit the [Self-Assessment Questionnaire-A](https://www.pcisecuritystandards.org/documents/PCI-DSS-v3_2_1-SAQ-A.pdf). 3. [Configure your live account](/online-payments/go-live-checklist). 4. Switch from test to our [live endpoints](/development-resources/live-endpoints#checkout-endpoints). Make sure that all API requests you make for the same payment session use the same live endpoint region. Using different regions for [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) and [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) requests may result in errors, for example, when authenticating with 3D Secure 2. 5. Load Drop-in from one of our live environments and set the [`dropInComponent.environment` ](https://adyen.github.io/adyen-ios/5.0.0/documentation/adyen/)to match your live endpoints: | Endpoint region | `environment` value | | --------------- | -------------------- | | Europe | **liveEurope** | | Australia | **liveAustralia** | | US | **liveUnitedStates** | | Northeast Asia | **liveNea** | ## Error handling In case you encounter errors in your integration, refer to the following: * [API error codes](/development-resources/error-codes): If you receive a non-HTTP 200 response, use the `errorCode` to troubleshoot and modify your request. * [Payment refusals](/development-resources/refusal-reasons): If you receive an HTTP 200 response with an **Error** or **Refused** `resultCode`, check the refusal reason and, if possible, modify your request. ## Optional configuration Client app You can set additional configuration on the [Drop-in configuration](#configure). | Parameter name | Description | | ------------------------ | -------------------------------------------------------------------------------------- | | `shopperInformation` | Prefilled shopper information. | | `localizationParameters` | [Localization](#localization) parameters, like custom placeholders in other languages. | | `style` | Custom styling of the UI. | ### Localization iOS Drop-in supports the languages listed [here](https://github.com/Adyen/adyen-ios/tree/master/Adyen/Assets). To customize a localization, add a new `localizable.strings` file for the language that you need. You can also override [existing strings](https://github.com/Adyen/adyen-ios/blob/master/Adyen/Assets/en-US.lproj/Localizable.strings) by using the same keys. For example, to override the cardholder name field title, set the following on your `localizable.strings` file: ```swift "adyen.card.nameItem.title" = "Your cardholder name"; ``` To find localized strings, the library first checks your custom `localizable.strings` file, and then the default Adyen file. You can use `LocalizationParameters` to customize the localization file name, bundle, or the separator for translation strings. For example, if you store translations in `MyLocalizable.strings` files in the shared bundle `CommonBundle`: ```swift let localizationParameters = LocalizationParameters(bundle: commonBundle, tableName: "MyLocalizable") dropInComponent.localizationParameters = localizationParameters ``` ## See also * [Adyen iOS Reference](https://adyen.github.io/adyen-ios/5.0.0/documentation/adyen/) * [Adyen iOS on GitHub](https://github.com/Adyen/adyen-ios) * [Tokenization](/online-payments/tokenization) ## Next steps [required](/development-resources/webhooks) [Set up notifications](/development-resources/webhooks) [Receive confirmation when a payment is authorised or fails.](/development-resources/webhooks) [Add payment methods](/payment-methods#add-payment-methods-to-your-account) [Learn about payment methods and how to add them to your account.](/payment-methods#add-payment-methods-to-your-account) [Payment modifications](/online-payments/modify-payments) [Find out how to cancel, refund, or capture a payment using our API.](/online-payments/modify-payments) [3D Secure authentication](/online-payments/3d-secure) [Comply with regulations such as PSD2 SCA in Europe.](/online-payments/3d-secure) ## iOS Components Use our customizable UI components ### Intro Components are our pre-built UI solution for accepting payments in your app. Each Component renders a payment method you can render anywhere in your app. For the Advanced flow, your server makes API requests to the [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods), [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments), and [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) endpoints. ### Before You Begin ## Requirements Before you begin to integrate, make sure you have followed the [Get started with Adyen guide](/get-started-with-adyen) to: * Get an overview of the steps needed to accept live payments. * Create your test account. After you have created your test account: * [Get your API key](/development-resources/api-credentials#generate-api-key). * [Get your client key](/development-resources/client-side-authentication#get-your-client-key). * [Set up webhooks](/development-resources/webhooks) to know the payment outcome. ### Install the Adyen iOS client-side library Choose how you want to install the Adyen iOS client-side library: ### Tab: Swift Package Manager To install iOS Components using Swift Package Manager, [follow the Apple guide](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app) and specify: * The repository URL as `https://github.com/Adyen/adyen-ios` * The version to be at least **3.8.0** ### Tab: CocoaPods To install iOS Components from CocoaPods: 1. Add `pod 'Adyen'` to your `Podfile`. 2. Run `pod install`. ### Tab: Carthage To install iOS Components from Carthage: 1. Add `github "adyen/adyen-ios"` to your `Cartfile`. 2. Run `carthage update`. 3. Link the framework with your target as described in [Carthage Readme](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application). ### Get your client key You need a [client key](/development-resources/client-side-authentication), a public key linked to your API credential, that the iOS Components use for client-side authentication. 1. Log in to your [Customer Area](https://ca-test.adyen.com/). 2. Go to **Developers** > **API credentials**, and select the API credential for your integration, for example **ws\@Company.\[YourCompanyAccount]**. 3. Under **Authentication**, select **Generate New Client Key**. 4. Select **Save**. ## How it works For a Components integration, you must implement the following parts: * **Your payment server**: sends the API requests to get available payment methods, make a payment, and send additional payment details. * **Your client app**: shows the the Component UI where the shopper makes the payment. The Component uses the data from the API responses to handle the payment flow and additional actions on your client app. * **Your webhook server**: receives webhooks that include the outcome of each payment. The parts of your integration work together to complete the payment flow: 1. From your server, submit a request to [get a list of payment methods available to the shopper](#get-available-payment-methods). 2. [Add Components](#add) to your payments form. 3. From your server, [submit a payment request](#make-a-payment) with the data returned by the Component. 4. Determine from the response if you need to perform additional actions on your client app, such as to [redirect the shopper](#additional-action). 5. From your server, [verify the payment result](#send-additional-payment-details). 6. [Get the payment outcome](#get-the-payment-outcome). If you are integrating these parts separately, you can start at the corresponding part of this integration guide: [![](/user/pages/reuse/online-payments/how-it-works-parts/servers.svg?decoding=auto\&fetchpriority=auto)](/#install-api-library) [Payment server](/#install-api-library) [Go to the integration steps for your server.](/#install-api-library) [![](/user/pages/reuse/online-payments/how-it-works-parts/browser-developers.svg?decoding=auto\&fetchpriority=auto)](/#add) [Client app](/#add) [Go to the integration steps for your client app.](/#add) [![](/user/pages/reuse/online-payments/how-it-works-parts/event-code.svg?decoding=auto\&fetchpriority=auto)](/#update-your-order-management-system) [Webhook server](/#update-your-order-management-system) [Go to the integration steps for your webhook server.](/#update-your-order-management-system) ### Install Api Library ## Install an API library Payment server We provide server-side API libraries for several programming languages, available through common package managers, like Gradle and npm, for easier installation and version management. Our API libraries will save you development time, because they: * Use an API version that is up to date. * Have generated models to help you construct requests. * Send the request to Adyen using their built-in HTTP client, so you do not have to create your own. ### Tab: Java ##### Try our example integration ![](/reuse/development-resources/install-api-library/java/advanced/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-java-spring-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/java/advanced/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-java-spring-online-payments). #### Requirements * Java 11 or later. #### Installation You can use [Maven](https://maven.apache.org), adding this dependency to your project's POM. **Add the API library** ```xml com.adyen adyen-java-api-library LATEST_VERSION ``` You can find the latest version on GitHub. Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-java-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```java // Import the required classes. package com.adyen.service; import com.adyen.Client; import com.adyen.service.checkout.PaymentsApi; import com.adyen.model.checkout.Amount; import com.adyen.enums.Environment; import com.adyen.service.exception.ApiException; import java.io.IOException; public class Snippet { public Snippet() throws IOException, ApiException { // Set up the client and service. Client client = new Client("ADYEN_API_KEY", Environment.TEST); } } ``` ### Tab: PHP ##### Try our example integration ![](/reuse/development-resources/install-api-library/php/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-php-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/php/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-php-online-payments). #### Requirements * PHP 7.3 or later. * cURL with SSL support. * The JSON PHP extension. * The list of dependencies from the composer require list. #### Installation You can use [Composer](https://getcomposer.org/). Follow the [installation instructions](https://getcomposer.org/doc/00-intro.md) if you do not already have composer installed. **Install the API library** ```bash composer require adyen/php-api-library ``` In your PHP script, make sure you include the autoloader: **Include the autoloader** ```php require __DIR__ . '/vendor/autoload.php'; ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-php-api-library/releases). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```php use Adyen\Model\Checkout\Amount; use Adyen\Model\Checkout\CreateCheckoutSessionRequest; use Adyen\Service\Checkout\PaymentsApi; // Include your idempotency key when you make an API request. $requestOptions['idempotencyKey'] = "YOUR_IDEMPOTENCY_KEY"; // Set up the client and service. $client = new \Adyen\Client(); $client->setXApiKey('ADYEN_API_KEY'); $client->setEnvironment(\Adyen\Environment::TEST); $service = new PaymentsApi($client); ``` ### Tab: C\# #### Requirements * .NET standard 2.0 or later. * For Terminal API certificate validation, set the application to either of the following: * .NET core 2.1 or later * .NET framework 4.6.1 or later #### Installation You can use [NuGet](https://www.nuget.org/packages/Adyen/): **Install the API library** ```bash PM> Install-Package Adyen -Version LATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-dotnet-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```cs using Adyen; using Adyen.Model.Checkout; using Adyen.Service.Checkout; using Environment = Adyen.Model.Environment; class Program { static void Main() { // Set up the client and service. var config = new Config { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); var checkout = new PaymentsService(client); // Include your idempotency key when you make an API request. var requestOptions = new Adyen.Model.RequestOptions { IdempotencyKey = "YOUR_IDEMPOTENCY_KEY" }; } } ``` ### Tab: NodeJS ##### Try our example integration ![](/reuse/development-resources/install-api-library/node-js/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-node-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/node-js/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-node-online-payments). #### Requirements * Node.js version 18 or later. #### Installation You can use [npm](https://www.npmjs.com/): **Install the API library** ```bash npm install --save @adyen/api-library npm update @adyen/api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-node-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```js // Require the parts of the module you want to use. const { Client, CheckoutAPI, Types} = require("@adyen/api-library"); // Set up the client and service. const client = new Client({ apiKey: "ADYEN_API_KEY", environment: "TEST" }); const checkoutApi = new CheckoutAPI(client); // Include your idempotency key when you make an API request. const requestOptions = { idempotencyKey: "YOUR_IDEMPOTENCY_KEY" }; ``` ### Tab: Go ##### Try our example integration ![](/reuse/development-resources/install-api-library/go/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-golang-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/go/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-golang-online-payments). #### Requirements * Go 1.13 or later. #### Installation You can use [Go modules](https://github.com/golang/go/wiki/Modules): **Install the API library** ```shell go get github.com/adyen/adyen-go-api-library/vLATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-go-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```go package main import ( "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/adyen" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/checkout" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/common" ) // Create a payment object. func main () { client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) service := client.Checkout() ``` ### Tab: Python ##### Try our example integration ![](/reuse/development-resources/install-api-library/python/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-python-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/python/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-python-online-payments). #### Requirements * Python 3.6 or later. * (Optional) Packages: Requests or PycURL #### Installation You can use [pip](https://pip.pypa.io/en/stable/): **Install the API library** ```py pip install Adyen ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-python-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```py import Adyen # Set up the client and service. adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment that the library is used in. ``` ### Tab: Ruby ##### Try our example integration ![](/reuse/development-resources/install-api-library/ruby/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-rails-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/ruby/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-rails-online-payments). #### Requirements * Ruby 2.7 or later. #### Installation You can use [RubyGems](https://rubygems.org/): **Install the API library** ```bash gem install adyen-ruby-api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-ruby-api-library/releases). Run `bundle install` to install dependencies. #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```ruby require 'adyen-ruby-api-library' # Set up the client and service. adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # The environment that the library is used in. ``` ## Get available payment methods Payment server When your shopper is ready to pay, get a list of the available payment methods based on their country, device, and the payment amount. From your server, make a POST [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) request, providing the following parameters. While most parameters are optional, we recommend that you include them because Adyen uses these to tailor the list of payment methods for your shopper. We use the optional parameters to tailor the list of available payment methods to your shopper. | Parameter name | Required | Description | | ----------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | | The `currency` of the payment and its `value` in [minor units](/development-resources/currency-codes). | | `channel` | | The platform where the payment is taking place. Use **iOS**. Adyen returns only the payment methods available for iOS. | | `countryCode` | | The shopper's country/region. Adyen returns only the payment methods available in this country. Format: the two-letter [ISO-3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. Exception: **QZ** (Kosovo). | | `shopperLocale` | | Language and country code. By default, the shopper locale is set to **en-US**. If this is provided, the payment method names are translated to the specified language. | The following example shows how to get the available payment methods for a shopper in the **Netherlands**, for a payment of **EUR 10**: #### curl ```bash curl https://checkout-test.adyen.com/v72/paymentMethods \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Android", "shopperLocale": "nl-NL" }' ``` #### Java ```java // Adyen Java API Library v27.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the live environment, additionally include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) Amount amount = new Amount() .currency("EUR") .value(1000L); PaymentMethodsRequest paymentMethodsRequest = new PaymentMethodsRequest() .amount(amount) .merchantAccount("ADYEN_MERCHANT_ACCOUNT") .countryCode("NL") .channel(PaymentMethodsRequest.ChannelEnum.IOS) .shopperLocale("nl-NL"); // Send the request PaymentsApi service = new PaymentsApi(client); PaymentMethodsResponse response = service.paymentMethods(paymentMethodsRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("ADYEN_API_KEY"); // For the LIVE environment, also include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->paymentMethods($paymentMethodsRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v32.1.1 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the LIVE environment, also include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) // Send the request var service = new PaymentsService(client); var response = service.PaymentMethods(paymentMethodsRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v29.0.0 const { Client, CheckoutAPI } = require('@adyen/api-library'); // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const paymentMethodsRequest = { merchantAccount: "ADYEN_MERCHANT_ACCOUNT", countryCode: "NL", amount: { currency: "EUR", value: 1000 }, channel: "Android", shopperLocale: "nl-NL" } // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentMethods(paymentMethodsRequest, { idempotencyKey: "UUID" }); ``` #### Go ```go // Adyen Go API Library v10.4.0 import ( "context" "github.com/adyen/adyen-go-api-library/v9/src/common" "github.com/adyen/adyen-go-api-library/v9/src/adyen" "github.com/adyen/adyen-go-api-library/v9/src/checkout" ) // For the live environment, additionally include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) amount := checkout.Amount{ Currency: "EUR", Value: 1000, } paymentMethodsRequest := checkout.PaymentMethodsRequest{ Amount: &amount, MerchantAccount: "ADYEN_MERCHANT_ACCOUNT", CountryCode: common.PtrString("NL"), Channel: common.PtrString("iOS"), ShopperLocale: common.PtrString("nl-NL"), } // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentMethodsInput().IdempotencyKey("UUID").PaymentMethodsRequest(paymentMethodsRequest) res, httpRes, err := service.PaymentsApi.PaymentMethods(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.6.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Android", "shopperLocale": "nl-NL" } # Send the request result = adyen.checkout.payments_api.payment_methods(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v10.4.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT', :countryCode => 'NL', :amount => { :currency => 'EUR', :value => 1000 }, :channel => 'Android', :shopperLocale => 'nl-NL' } # Send the request result = adyen.checkout.payments_api.payment_methods(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v29.0.0 import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentMethods(paymentMethodsRequest, { idempotencyKey: "UUID" }); ``` The response includes the list of available `paymentMethods`: **/paymentMethods response** ```json { "paymentMethods":[ { "details":[...], "name":"Cards", "type":"scheme" ... }, { "details":[...], "name":"SEPA Direct Debit", "type":"sepadirectdebit" }, ... ] } ``` Pass the response to your client app. You then use this in the next step to present which payment methods are available to the shopper. ### Add Components ## Add Components to your payment form Client app Use the Component to collect payment details from your shopper. 1. Decode the [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) response with the `PaymentMethods` structure. Find the payment method object for the Component that you want to instantiate. For example, for a card payment, you need to find the `CardPaymentMethod` object. **Decode the payment methods response** ```swift let paymentMethods = try JSONDecoder().decode(PaymentMethods.self, from: paymentMethodsResponse) ``` Get the payment method from the payment methods object. For example, the card payment method: **Get the payment method** ```swift let cardPaymentMethod = paymentMethods.paymentMethod(ofType: CardPaymentMethod.self) ``` 2) Create an instance of `APIContext` that contains to following: | | Description | | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | [Client key](/development-resources/client-side-authentication#get-your-client-key) | Authenticates requests from your payment environment. | | Environment setting | The [environment value](#test-and-go-live) that matches the endpoint that your server uses. Use **Environment.test** for your test environment. | **Create the APIContext** ```swift // Set the client key and environment in an instance of APIContext. let apiContext = APIContext(clientKey: clientKey, environment: Environment.test) // Set the environment to a live one when going live. ``` 3. Create an instance of `AdyenContext` that contains the following: | | Description | | ------------------- | -------------------------------------------------------- | | API context | Your instance of `APIContext`. | | Payment information | A `Payment` object with the payment amount and currency. | **Create the AdyenContext** ```swift // Create the amount with the value in minor units and the currency code. let amount = Amount(value: 1000, currencyCode: "EUR") // Create the payment object with the amount and country code. let payment = Payment(amount: amount, countryCode: "NL") // Create an instance of AdyenContext, passing the instance of APIContext, and payment object. let adyenContext = AdyenContext(apiContext: apiContext, payment: payment) ``` 4) Create a configuration object. You can add the following:[]() | Type of configuration | Description | | ---------------------------- | --------------------------------------------------------------------------------------------------------- | | Payment method configuration | Some [payment methods](/payment-methods) require additional configuration or have optional configuration. | | Optional configuration | You can add [optional configuration](#optional-configuration) to each component. | The following example shows creating a configuration object for the Card Component. **Configure the Component** ```swift let cardConfiguration = CardComponent.Configuration() // Some payment methods have additional required or optional configuration. // For example, an optional configuration to show the cardholder name field for cards. cardConfiguration.showsHolderNameField = true ``` 5. Initialize the Component class.[]() | Parameter name | Required | Description | | --------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | `paymentMethod` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The full, decoded [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) response. | | `context` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The `AdyenContext` that you created. | | `configuration` | | The configuration object that you created. | The following example shows initializing an instance of [`CardComponent` ](https://adyen.github.io/adyen-ios/5.0.0/documentation/adyen/cardcomponent). **Initialize the Component** ```swift let cardComponent = CardComponent(paymentMethod: cardPaymentMethod, context: adyenContext, configuration: cardConfiguration) // Keep the instance of the Component so that it doesn't get destroyed after the function is executed. self.cardComponent = cardComponent // Set self as the delegate. cardComponent.delegate = self ``` 6. Get the contents of `data.paymentMethod` and pass this to your server. Dismiss the Component immediately, or wait until you have submitted the details to your server. **didSubmit with payment method data** ```swift func didSubmit(_ data: PaymentComponentData, from component: PaymentComponent) ``` In case an error occurs on the app, the Component invokes the `didFail` method from the `PaymentComponentDelegate`. Dismiss the Component's view controller and display an error message. **didFail with an error** ```swift func didFail(with error: Error, from component: PaymentComponent) ``` ## Make a payment Payment server When the shopper selects the **Pay** button or chooses to pay with a payment method that requires a redirection, you must make a payment request to Adyen. 1. Pass the full data from `didSubmit` to your server. 2. From your server, make a POST [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request including the following: | Parameter name | Required | Description | | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The `currency` of the payment and its `value` in [minor units](/development-resources/currency-codes). | | `reference` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your unique reference for this payment. | | `paymentMethod` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The complete `data.paymentMethod` object from the `didSubmit` method from your client app. It includes the payment method details and other required information. | | `paymentMethod.sdkData` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The object that includes information collected by the Component to track the user's payment journey, including information like the [checkout attempt identifier](/online-payments/analytics-and-data-tracking#data-we-are-collecting). This is required to use the [Checkout dashboard](/uplift#uplift-dashboards) that lets you analyze your checkout performance. | | `returnUrl` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The URL the shopper should be taken back to after a redirection. Use the custom URL for your app, for example, `my-app://adyen`, to take the shopper back to your app after they complete the payment outside of your app. For more information on setting a custom URL scheme, read the [Apple Developer documentation](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app). The URL can contain a maximum of 1024 characters. You can also include your own additional query parameters, for example, shopper ID or order reference number. | | [`applicationInfo`](/development-resources/building-adyen-solutions) | | If you are building an Adyen solution for multiple merchants, include some basic identifying information, so that we can offer you better support. For more information, refer to [Building Adyen solutions](/development-resources/building-adyen-solutions). | For the following cases, you must include additional parameters in your request: * Integrating some payment methods. For more information, go to [payment method integration guides](/payment-methods). * Using our risk management features. For more information, see [Required risk fields](/risk-management/configure-manual-risk/required-risk-field-reference). * [Native 3D Secure 2 authentication](/online-payments/3d-secure/native-3ds2/android-drop-in#make-a-payment). * [Creating a token](/online-payments/tokenization/create-tokens) to store the shopper's payment details. * [Using a token](/online-payments/tokenization/make-token-payments) to make a recurring payment with stored payment details. 3. **Example request to make a payment for EUR 10** #### curl ```bash curl https://checkout-test.adyen.com/v72/payments \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "amount":{ "currency":"EUR", "value":1000 }, "reference":"YOUR_ORDER_NUMBER", "paymentMethod":{hint:paymentMethod field of an object passed from your client app}STATE_DATA{/hint}, "returnUrl":"my-app://adyen", "merchantAccount":"ADYEN_MERCHANT_ACCOUNT" }' ``` #### Java ```java // Set your ADYEN_API_KEY with the API key from the Customer Area. Client client = new Client(System.getenv("ADYEN_API_KEY"), Environment.TEST); PaymentsApi checkout = new PaymentsApi(client); PaymentRequest paymentRequest = new PaymentRequest(); paymentRequest.setMerchantAccount(System.getenv("MERCHANT_ACCOUNT")); // STATE_DATA is the paymentMethod field of an object passed from your client. String STATE_DATA = "{\n" + " \"type\": \"scheme\",\n" + " \"number\":\"4111111111111111\",\n" + " \"cvc\":\"737\",\n" + " \"expiryMonth\":\"10\",\n" + " \"expiryYear\":\"2020\",\n" + " \"holderName\":\"John Smith\"\n" + "}\n"; // Deserialize the payment method from STATE_DATA. paymentRequest.setPaymentMethod(CheckoutPaymentMethod.fromJson(STATE_DATA)); Amount amount = new Amount(); amount.setCurrency("EUR"); amount.setValue(1000L); paymentRequest.setAmount(amount); paymentRequest.setReference("YOUR_ORDER_NUMBER"); paymentRequest.setReturnUrl("my-app://adyen"); // Add your idempotency key. RequestOptions requestOptions = new RequestOptions(); requestOptions.setIdempotencyKey("YOUR_IDEMPOTENCY_KEY"); PaymentResponse response = checkout.payments(paymentRequest, requestOptions); ``` #### PHP ```php // Set ADYEN_API_KEY with the API key from the Customer Area. $client = new \Adyen\Client(); $client->setEnvironment(\Adyen\Environment::TEST); $client->setXApiKey("ADYEN_API_KEY"); $service = new \Adyen\Service\Checkout($client); // STATE_DATA is the paymentMethod field of an object passed from your client app, deserialized from JSON to a data structure. $paymentMethod = STATE_DATA;; $params = array( "paymentMethod" => $paymentMethod, "amount" => array( "currency" => "EUR", "value" => 1000 ), "reference" => "YOUR_ORDER_NUMBER", "returnUrl" => "my-app://adyen", "merchantAccount" => "ADYEN_MERCHANT_ACCOUNT" ); $result = $service->payments($params); // Check if further action is needed if (array_key_exists("action", $result)){ // Pass the action object to your client. // $result["action"] } else { // No further action needed, pass the resultCode to your client. // $result['resultCode'] } ``` #### C\# ```cs // Set ADYEN_API_KEY with the API key from the Customer Area. string apiKey = "ADYEN_API_KEY"; var client = new Client (apiKey, Environment.Test); var checkout = new Checkout(client); var amount = new Adyen.Model.Checkout.Amount("EUR", 1000); var paymentsRequest = new Adyen.Model.Checkout.PaymentRequest { // STATE_DATA is the paymentMethod field of an object passed from your client app, deserialized from JSON to a data structure. PaymentMethod = STATE_DATA, Amount = amount, Reference = "YOUR_ORDER_NUMBER", ReturnUrl = @"my-app://adyen", }; var paymentResponse = checkout.Payments(paymentsRequest); ``` #### NodeJS (JavaScript) ```js const {Client, Config, CheckoutAPI} = require('@adyen/api-library'); const config = new Config(); // Set ADYEN_API_KEY with the API key from the Customer Area. config.apiKey = 'ADYEN_API_KEY'; config.merchantAccount = 'ADYEN_MERCHANT_ACCOUNT'; const client = new Client({ config }); client.setEnvironment("TEST"); const checkout = new CheckoutAPI(client); checkout.payments({ merchantAccount: config.merchantAccount, // STATE_DATA is the paymentMethod field of an object passed from the your client app, deserialized from JSON to a data structure. paymentMethod: STATE_DATA, amount: { currency: "EUR", value: 1000, }, reference: "YOUR_ORDER_NUMBER", returnUrl: "my-app://adyen" }).then(res => res); ``` #### Go ```go import ( "github.com/adyen/adyen-go-api-library/v5/src/checkout" "github.com/adyen/adyen-go-api-library/v5/src/common" "github.com/adyen/adyen-go-api-library/v5/src/adyen" ) // Set ADYEN_API_KEY with the API key from the Customer Area. client := adyen.NewClient(&common.Config{ Environment: common.TestEnv, ApiKey: "ADYEN_API_KEY", }) // STATE_DATA is the paymentMethod field of an object passed from your client app, deserialized from JSON to a data structure. paymentMethod := STATE_DATA res, httpRes, err := client.Checkout.Payments(&checkout.PaymentRequest{ PaymentMethod: paymentMethod, Amount: checkout.Amount{ Value: 1000, Currency: "EUR", }, Reference: "YOUR_ORDER_NUMBER", ReturnUrl: "my-app://adyen", MerchantAccount: "ADYEN_MERCHANT_ACCOUNT", }) ``` #### Python ```py # Set ADYEN_API_KEY with the API key from the Customer Area. adyen = Adyen.Adyen() adyen.payment.client.platform = "test" adyen.client.xapikey = 'ADYEN_API_KEY' # STATE_DATA is the paymentMethod field of an object passed from your client app, deserialized from JSON to a data structure. paymentMethod = STATE_DATA result = adyen.checkout.payments({ 'paymentMethod': paymentMethod, 'amount': { 'value': 1000, 'currency': 'EUR' }, 'reference': 'YOUR_ORDER_NUMBER', 'returnUrl': 'my-app://adyen', 'merchantAccount': 'ADYEN_MERCHANT_ACCOUNT' }) # Check if further action is needed if 'action' in result.message: # Pass the action object to your client. # result.message['action'] else: # No further action needed, pass the resultCode to your client. # result.message['resultCode'] ``` #### Ruby ```ruby require 'adyen-ruby-api-library' # Set ADYEN_API_KEY with the API key from the Customer Area. adyen = Adyen::Client.new adyen.env = :test adyen.api_key = "ADYEN_API_KEY" # STATE_DATA is the paymentMethod field of an object passed from the front end or client app, deserialized from JSON to a data structure. paymentMethod = STATE_DATA response = adyen.checkout.payments({ :paymentMethod => paymentMethod, :amount => { :currency => 'EUR', :value => 1000 }, :reference => 'YOUR_ORDER_NUMBER', :returnUrl => 'my-app://adyen', :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT' }) # Check if further action is needed. if response.body.has_key(:action) # Pass the action object to your client app. # response.body[:action] else # No further action needed, pass the resultCode object to your client app. # response.body[:resultCode] ``` Your next step depends on if the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response contains an `action` object: * If the response has no `action` object, [get the payment outcome](#get-the-payment-outcome). * If the response contains an `action` object, [handle the additional action](#additional-action). **Example response containing an action object for 3D Secure 2 authentication** ```json { "resultCode" : "IdentifyShopper", "action" : { "token" : "eyJkaXJl...", "paymentMethodType" : "scheme", "paymentData" : "Ab02b4c0...", "type" : "threeDS2", "authorisationToken" : "BQABAQ...", "subtype" : "fingerprint" } } ``` ### Perform Additional Actions ## Handle the additional action Client app Some payment methods require additional action from the shopper. Common examples of additional actions include: * Logging in to a bank's website or app. * Authenticating a payment with 3D Secure 2. * Scanning a QR code. Use [`AdyenActionComponent` ](https://adyen.github.io/adyen-ios/5.0.0/documentation/adyen/)and the `action` object from the API response to handle the action. 1. Pass the full `action` object from your server to your client app. 2. Create and persist instance of `AdyenActionComponent`. **AdyenActionComponent** ```swift internal lazy var actionComponent: AdyenActionComponent = { let component = AdyenActionComponent(apiContext: apiContext) component.delegate = self component.presentationDelegate = self return component }() ``` 3. Use it to handle the action. **Handle the action** ```swift let action = try JSONDecoder().decode(Action.self, from: actionData) actionComponent.handle(action) ``` 4. `AdyenActionComponent` performs the additional action in your app. 5. You handle the payment data, depending on the value of `action.type`. | Type | `action.type` value | | ----------------------------------------------------------------------- | ------------------- | | [Redirect action](#handle-the-redirect) | **redirect** | | [3D Secure 2 authentication action](#3d-secure-2-authentication-action) | **threeDS2** | | [QR code action](#qr-code-action) | **qrCode** | | [SDK action](#sdk-action) | **sdk** | | [Voucher action](#voucher-action) | **voucher** | | [Await action](#await-action) | **await** | ### Redirect action []() When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type` **redirect**, the Component redirects your shopper to another website to complete the payment. 1. When the shopper returns to your app, inform `AdyenActionComponent`. To do this, implement the following in your `UIApplicationDelegate`: ```swift func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool { RedirectComponent.applicationDidOpen(from: url) return true } ``` 2. After the Redirect Component (under the hood of `AdyenActionComponent`) completes the additional action, the Component invokes the `didProvide` method from the `ActionComponentDelegate`. **didProvide with action data** ```swift func didProvide(_ data: ActionComponentData, from component: ActionComponent) ``` If an error occurs in the app, the Component invokes the `didFail` method from the `ActionComponentDelegate`. Dismiss the Component's view controller and show an error message in your app. **didFail with action error** ```swift func didFail(with error: Error, from component: ActionComponent) ``` 3. Get the `data` from the `didProvide` method. 4. [Dismiss the Component](#dismiss) immediately or after the following step. 5. Pass the contents of `data` to your server. 6. [Send additional payment details](#send-additional-payment-details). If the shopper fails to return to your app, you do not get the additional data to send. Instead, wait for the corresponding [webhook](#update-your-order-management-system) for the outcome of the payment. ### 3D Secure 2 authentication action When the response includes `action.type`: **threeDS2**, the payment qualifies for 3D Secure 2 and it goes through the frictionless or the challenge flow. 1. The Component handles 3D Secure 2 authentication. If a challenge is required, the shopper performs the authentication challenge to complete the payment. 2. After the Component completes the additional action, it invokes the `didProvide` method from the `ActionComponentDelegate`. **didProvide with action data** ```swift func didProvide(_ data: ActionComponentData, from component: ActionComponent) ``` If an error occurs in the app, the Component invokes the `didFail` method from the `ActionComponentDelegate`. Dismiss the Component's view controller and show an error message in your app. **didFail with action error** ```swift func didFail(with error: Error, from component: ActionComponent) ``` 3. Get the `data` from the `didProvide` method. 4. [Dismiss current component](#dismiss) now or after the following step. 5. Pass the contents of `data` to your server. 6. [Send additional payment details](#send-additional-payment-details). ### QR code action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **qrCode**, the shopper must scan a QR code to complete the payment. 1. `AdyenActionComponent` uses `presentationDelegate` to show the UI for QR code payment. 2. The Component polls the payment status and, if completed, calls the `didProvide` method from the `ActionComponentDelegate`. **didProvide with action data** ```swift func didProvide(_ data: ActionComponentData, from component: ActionComponent) ``` If an error occurs in the app, the Component invokes the `didFail` method from the `ActionComponentDelegate`. Dismiss the Component's view controller and show an error message in your app. **didFail with action error** ```swift func didFail(with error: Error, from component: ActionComponent) ``` 3. Get the `data` from the `didProvide` method. 4. [Dismiss current component](#dismiss) now or after the following step. 5. Pass the contents of `data` to your server. 6. [Send additional payment details](#send-additional-payment-details). ### SDK action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **sdk**, the shopper must use the payment method's app to complete the payment. 1. `AdyenActionComponent` triggers the app switch from your app to the payment method's app, if installed in the shopper's device. 2. When the shopper returns to your app, the Component invokes the `didProvide` method from the `ActionComponentDelegate`. **didProvide with action data** ```swift func didProvide(_ data: ActionComponentData, from component: ActionComponent) ``` If an error occurs in the app, the Component invokes the `didFail` method from the `ActionComponentDelegate`. Dismiss the Component's view controller and show an error message in your app. **didFail with action error** ```swift func didFail(with error: Error, from component: ActionComponent) ``` 3. Get the `data` from the `didProvide` method. 4. [Dismiss current component](#dismiss) now or after the following step. 5. Pass the contents of `data` to your server. 6. [Send additional payment details](#send-additional-payment-details). ### Voucher action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **voucher**, the shopper must use a voucher to complete the payment. 1. `AdyenActionComponent` uses `presentationDelegate` to show the UI for the voucher. 2. The shopper shares, saves the voucher as an image or, in some cases, adds the voucher to Apple Wallet. 3. When the shopper completes the flow, the Component invokes the `didComplete` method from the `ActionComponentDelegate`. **didProvide with action data** ```swift func didProvide(_ data: ActionComponentData, from component: ActionComponent) ``` If an error occurs in the app, the Component invokes the `didFail` method from the `ActionComponentDelegate`. Dismiss the Component's view controller and show an error message in your app. **didFail with action error** ```swift func didFail(with error: Error, from component: ActionComponent) ``` 4. [Dismiss current component](#dismiss). The payment flow in your app is complete. After the shopper pays, or the voucher expires, your webhook server gets the [webhook to update the payment status](#update-your-order-management-system). ### Await action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **await**, the shopper must take an additional action to complete the payment. 1. `AdyenActionComponent` uses `presentationDelegate` to show the await UI. The shopper continues payment process outside of your app. 2. The Component polls the payment status and, if completed, calls the `didProvide` the `didProvide` method from the `ActionComponentDelegate`. **didProvide with action data** ```swift func didProvide(_ data: ActionComponentData, from component: ActionComponent) ``` If an error occurs in the app, the Component invokes the `didFail` method from the `ActionComponentDelegate`. Dismiss the Component's view controller and show an error message in your app. **didFail with action error** ```swift func didFail(with error: Error, from component: ActionComponent) ``` 3. Get the `data` from the `didProvide` method. 4. [Dismiss current component](#dismiss) now or after the following step. 5. Pass the contents of `data` to your server. 6. [Send additional payment details](#send-additional-payment-details). ### Submit Additional Details ## Send additional payment details Payment server If you [handled an additional action](#additional-action), you must send additional payment details. **For redirects**: if the shopper fails to return to your app, you do not get additional payment details to send. Instead, wait for the corresponding [webhook](#update-your-order-management-system) for the outcome of the payment. 1. Pass the full `data` object from the `didProvide` method to your server. 2. From your server, make a POST [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request including the full `data` object. **Example request to send additional payment details** #### curl ```bash curl https://checkout-test.adyen.com/v72/payments/details \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{hint:object passed from your client app}STATE_DATA{/hint}' ``` #### Java ```java // Set your X-API-KEY with the API key from the Customer Area. String xApiKey = "ADYEN_API_KEY"; Client client = new Client(xApiKey,Environment.TEST); Checkout checkout = new Checkout(client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. PaymentsDetailsRequest paymentsDetailsRequest = STATE_DATA; PaymentsResponse paymentsDetailsResponse = checkout.paymentsDetails(paymentsDetailsRequest); ``` #### PHP ```php // Set your X-API-KEY with the API key from the Customer Area. $client = new \Adyen\Client(); $client->setEnvironment(\Adyen\Environment::TEST); $client->setXApiKey("ADYEN_API_KEY"); $service = new \Adyen\Service\Checkout($client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. $params = STATE_DATA; $result = $service->paymentsDetails($params); // Check if further action is needed. if (array_key_exists("action", $result)){ // Pass the action object to your client. // $result["action"] } else { // No further action needed, pass the resultCode to your client. // $result['resultCode'] } ``` #### C\# ```cs // Set your X-API-KEY with the API key from the Customer Area. string apiKey = "ADYEN_API_KEY"; var client = new Client (apiKey, Environment.Test); var checkout = new Checkout(client); // STATE_DATA is an object passed from the client app, deserialized from JSON to a data structure. var paymentsDetailsRequest = STATE_DATA; var paymentsDetailsResponse = checkout.PaymentDetails(paymentsDetailsRequest); ``` #### NodeJS (JavaScript) ```js const {Client, Config, CheckoutAPI} = require('@adyen/api-library'); const config = new Config(); // Set your X-API-KEY with the API key from the Customer Area. config.apiKey = '[ADYEN_API_KEY]'; const client = new Client({ config }); client.setEnvironment("TEST"); const checkout = new CheckoutAPI(client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. checkout.paymentsDetails(STATE_DATA).then(res => res); ``` #### Go ```go import ( "github.com/adyen/adyen-go-api-library/v5/src/checkout" "github.com/adyen/adyen-go-api-library/v5/src/common" "github.com/adyen/adyen-go-api-library/v5/src/adyen" ) // Set your X-API-KEY with the API key from the Customer Area. client := adyen.NewClient(&common.Config{ Environment: common.TestEnv, ApiKey: "[ADYEN_API_KEY]", }) // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. req := STATE_DATA; res, httpRes, err := client.Checkout.PaymentsDetails(&req) ``` #### Python ```py # Set your X-API-KEY with the API key from the Customer Area. adyen = Adyen.Adyen() adyen.payment.client.platform = "test" adyen.client.xapikey = 'ADYEN_API_KEY' # STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. request = STATE_DATA result = adyen.checkout.payments_details(request) # Check if further action is needed. if 'action' in result.message: # Pass the action object to your client. # result.message['action'] else: # No further action needed, pass the resultCode to your client. # result.message['resultCode'] ``` #### Ruby ```ruby require 'adyen-ruby-api-library' # Set your X-API-KEY with the API key from the Customer Area. adyen = Adyen::Client.new adyen.env = :test adyen.api_key = "ADYEN_API_KEY" # STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. request = STATE_DATA response = adyen.checkout.payments.details(request) # Check if further action is needed. if response.body.has_key(:action) # Pass the action object to your client puts response.body[:action] else # No further action needed, pass the resultCode to your client puts response.body[:resultCode] end ``` 3. Pass the [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) response from your server to your client app. **Example response for a successful payment** ```json { "pspReference": "NC6HT9CRT65ZGN82", "resultCode": "Authorised" } ``` **Example response for a refused payment** ```json { "pspReference": "KHQC5N7G84BLNK43", "refusalReason": "Not enough balance", "resultCode": "Refused" } ``` ### Dismiss-Component ## Dismiss the Component Client app After you make a [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request to submit the payment data or a [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request to send additional details, dismiss the Component to finalize the payment flow. Call `finalizeIfNeeded` and do the following, depending on what the Component handled: | | What to do | | ----------- | ----------------------------------------------------------------------------- | | Result code | If no further steps are required from the application, dismiss the Component. | | Error | Dismiss the Component, and show an error message. | Implement the following in your `currentComponent` object: **Implement finalizeIfNeeded to dismiss the Component** ```js currentComponent?.finalizeIfNeeded(with: isSuccessful) { [weak self] in guard let self else { return } myCheckoutViewController.dismiss(animated: true) { [weak self] in // Continue the flow. } } ``` ### Show Payment Result ## Get the payment outcome After the Component finishes the payment flow, you can show the shopper the current payment status. Adyen sends a webhook with the outcome of the payment. ### Inform the shopper Client app Use the [`resultCode`](/online-payments/payment-result-codes#final-payment-status) to show the shopper the [current payment status](/account/payments-lifecycle). This synchronous response doesn't give you the final outcome of the payment. You get the final payment status in a webhook that you use to [update your order management system](#update-your-order-management-system). ### Update your order management system Webhook server You get the outcome of each payment asynchronously, in an **AUTHORISATION** [webhook](/development-resources/webhooks). Use the `merchantReference` from the webhook to match it to your order reference.\ For a successful payment, the event contains `success`: **true**. **Example webhook for a successful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"033899:1111:03/2030", "amount":{ "currency":"EUR", "value":2500 }, "operations":["CANCEL","CAPTURE","REFUND"], "success":"true", "paymentMethod":"mc", "additionalData":{ "expiryDate":"03/2030", "authCode":"033899", "cardBin":"411111", "cardSummary":"1111" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"NC6HT9CRT65ZGN82", "eventDate":"2021-09-13T14:10:22+02:00" } } ] } ``` For an unsuccessful payment, you get `success`: **false**, and the `reason` field has details about why the payment was unsuccessful. **Example webhook for an unsuccessful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"validation 101 Invalid card number", "amount":{ "currency":"EUR", "value":2500 }, "success":"false", "paymentMethod":"unknowncard", "additionalData":{ "expiryDate":"03/2030", "cardBin":"411111", "cardSummary":"1112" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"KHQC5N7G84BLNK43", "eventDate":"2021-09-13T14:14:05+02:00" } } ] } ``` ## Test and go live Before going live, use our list of [test cards and other payment methods](/development-resources/test-cards-and-credentials/test-card-numbers) to test your integration. We recommend testing each payment method that you intend to offer to your shoppers. You can check the status of a test payment in your [Customer Area](https://ca-test.adyen.com/), under **Transactions** > **Payments**. To debug or troubleshoot test payments, you can also use [API logs](/development-resources/logs-resources/api-logs) in your test environment. When you are ready to go live, you need to: 1. [Apply for a live account](/get-started-with-adyen/application-requirements).   2. Assess your [PCI DSS compliance](/development-resources/pci-dss-compliance-guide#mobile-in-app-online-payments-integration), and submit the [Self-Assessment Questionnaire-A](https://www.pcisecuritystandards.org/documents/PCI-DSS-v3_2_1-SAQ-A.pdf). 3. [Configure your live account](/online-payments/go-live-checklist). 4. Switch from test to our [live endpoints](/development-resources/live-endpoints#checkout-endpoints). Make sure that all API requests you make for the same payment session use the same live endpoint region. Using different regions for [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) and [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) requests may result in errors, for example, when authenticating with 3D Secure 2. 5. Load the Components from one of our live environments and set the Component's [`environment` ](https://adyen.github.io/adyen-ios/5.0.0/documentation/adyen/)to match your live endpoints: | Endpoint region | `environment` value | | --------------- | -------------------- | | Europe | **liveEurope** | | Australia | **liveAustralia** | | US | **liveUnitedStates** | | Northeast Asia | **liveNea** | ## Error handling In case you encounter errors in your integration, refer to the following: * [API error codes](/development-resources/error-codes): If you receive a non-HTTP 200 response, use the `errorCode` to troubleshoot and modify your request. * [Payment refusals](/development-resources/refusal-reasons): If you receive an HTTP 200 response with an **Error** or **Refused** `resultCode`, check the refusal reason and, if possible, modify your request. ## Optional configuration Client app You can set additional configuration on the [Component configuration](#configure). | Parameter name | Description | | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | | `showsSubmitButton` | Set to **false** to hide the default pay button, so that you can [implement a custom button](#custom-pay-button) instead. Default: **true**. | | `shopperInformation` | Prefilled shopper information. | | `localizationParameters` | [Localization](#localization) parameters, like custom placeholders in other languages. | | `style` | Custom styling of the UI. | The following example shows how to set optional configuration parameters on the Card Component. **Set optional configuration parameters** ```js // Create a configuration object for the Component. let cardComponentConfiguration = CardComponent.Configuration() // Optional: create a configuration object for styling. let style = FormComponentStyle() // Set the background color. style.backgroundColor = .darkGray // Set the style on the configuration object. cardComponentConfiguration.style = style ``` ### Implement a custom pay button To implement a custom pay button, hide the default one and use the included functions to validate and submit payment data. This is not supported for [Apple Pay](/filters/advanced-flow-integration/ios/5-14-0/components/optional-configuration/payment-methods/apple-pay) and [BACS Direct Debit](/payment-methods/bacs). 1. When you [create the configuration object](#configure), set `showsSubmitButton` to **false**. 2. [Initialize](#initialize) the Component. 3. You can optionally show a confirmation page to the shopper, where payment data is validated. 4. Create and show your custom button. You can use the following functions. | Function | Required | Description | | ------------ | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | `validate()` | | Validates the payment data. | | `submit()` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Makes a [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request to submit the payment data. | The following example shows the Card Component with a custom pay button. **Card Component with a custom pay button** ```swift class CardPaymentViewController: UIViewController { // The instance of CardComponent for handling card payments. var cardComponent: CardComponent? // The function to configure and initialize an instance of CardComponent. func setupCardComponent() { // 1. Hide the default submit button in the CardComponent configuration. var cardComponentConfiguration = CardComponent.Configuration(showsSubmitButton: false) // 2. Decode the payment method response and get the card payment method. let paymentMethods = try JSONDecoder().decode(PaymentMethods.self, from: paymentMethodsResponse) let paymentMethod = paymentMethods.paymentMethod(ofType: CardPaymentMethod.self) else { // If no valid payment method is found, exit setup. return } // 3. Initialize the CardComponent with the payment method, context, and configuration. cardComponent = CardComponent(paymentMethod: paymentMethod, context: adyenContext, configuration: cardComponentConfiguration) // 4. Set the delegate to handle CardComponent callbacks. self.cardComponent = cardComponent cardComponent.delegate = self } override func viewDidLoad() { super.viewDidLoad() // 5. Create your custom button for starting the payment. let customSubmitButton = UIButton(frame: .zero) customSubmitButton.setTitle("Pay Now", for: .normal) customSubmitButton.backgroundColor = .systemBlue customSubmitButton.layer.cornerRadius = 8 customSubmitButton.addTarget(self, action: #selector(startPayment), for: .touchUpInside) // 6. Configure and initialize an instance of CardComponent. setupCardComponent() // 7. If the instance of CardComponent successfully initialized, add its view to the view hierarchy. if let cardView = cardComponent?.viewController.view { view.addSubview(cardView) // Optional: set constraints or position cardView. } // 8. Add your custom pay button to the view hierarchy. view.addSubview(customSubmitButton) // 9. Optional: set constraints or change the position of your custom submit button. // 10. Optional: configure additional UI elements or the layout. view.backgroundColor = .white } // The action that is triggered when the shopper selects your custom button. @objc func startPayment() { // 11. Validate the payment details that the shopper entered. if cardComponent?.validate() == true { // 12. If validation is successful, submit the payment. cardComponent?.submit() } else { // 13. If validation is unsuccessful, handle validation errors. For example, show an error message to the user. print("Validation failed. Please check your card details.") } } } ``` ### Localization iOS Components support the languages listed [here](https://github.com/Adyen/adyen-ios/tree/master/Adyen/Assets). To customize a localization, add a new `localizable.strings` file for the language that you need. You can also override [existing strings](https://github.com/Adyen/adyen-ios/blob/master/Adyen/Assets/en-US.lproj/Localizable.strings) by using the same keys. For example, to override the cardholder name field title, set the following on your `localizable.strings` file: ```swift "adyen.card.nameItem.title" = "Your cardholder name"; ``` For more information on iOS Components classes, see our [reference documentation](https://adyen.github.io/adyen-ios/5.0.0/documentation/adyen/) page. To find localized strings, the library first checks your custom `localizable.strings` file, and then the default Adyen file. You can use `LocalizationParameters` to customize the localization file name, bundle, or the separator for translation strings. For example, if you store translations in `MyLocalizable.strings` files in the shared bundle `CommonBundle`: ```swift let localizationParameters = LocalizationParameters(bundle: commonBundle, tableName: "MyLocalizable") cardComponentConfiguration.localizationParameters = localizationParameters ``` ## See also * [Adyen iOS Reference](https://adyen.github.io/adyen-ios/5.0.0/documentation/adyen/) * [Adyen iOS on GitHub](https://github.com/Adyen/adyen-ios) * [Tokenization](/online-payments/tokenization) ## Next steps [required](/development-resources/webhooks) [Set up notifications](/development-resources/webhooks) [Receive confirmation when a payment is authorised or fails.](/development-resources/webhooks) [Add payment methods](/payment-methods#add-payment-methods-to-your-account) [Learn about payment methods and how to add them to your account.](/payment-methods#add-payment-methods-to-your-account) [Payment modifications](/online-payments/modify-payments) [Find out how to cancel, refund, or capture a payment using our API.](/online-payments/modify-payments) [3D Secure authentication](/online-payments/3d-secure) [Comply with regulations such as PSD2 SCA in Europe.](/online-payments/3d-secure) ## iOS API only Use Adyen APIs and your own UI ### Intro With an API-only integration, you create your own UI, implement your own client-side logic, and use our API to send and receive payment data. You have full control over the look and feel of your checkout page. To reduce your development time and resources, you can use one of our pre-built UI options (Drop-in/Components) instead. ### Before You Begin ## Requirements Before you build your integration, take into account the following requirements and preparations. | Requirement | Description | | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **[API credential roles](/development-resources/api-credentials/roles/)** | Make sure that you have the following role:- **Checkout webservice role** | | **[Customer Area roles](/account/user-roles)** | Make sure that you have one of the following roles:- **Merchant admin role** - **Manage API credentials** | | **[Webhooks](/development-resources/webhooks)** | Subscribe to the following webhook:- **Standard webhooks** | | **Limitations** | * Your [PCI compliance assesment](/development-resources/pci-dss-compliance-guide?tab=api_only_3_4#online-payments) determines your [integration options for card payments](#collect-card-details). * For 3D Secure 2 authentication for shoppers using Chrome, your [cookies must use the `SameSite` attribute](https://developers.google.com/search/blog/2020/01/get-ready-for-new-samesitenone-secure). | | **Setup steps** | Before you begin:* [Create your Adyen test account](/get-started-with-adyen#test-account) * [Get your API key](/development-resources/api-credentials#generate-api-key). * [Get your client key](/development-resources/client-side-authentication#get-your-client-key). * [Set up webhooks](/development-resources/webhooks). * If you want to process payments using raw card data, contact your Adyen Account Manager to confirm that you are eligible. | ## How it works For an API-only integration, you must implement the following parts: * **Your payment server**: sends the API requests to get available payment methods, make a payment, and send additional payment details. * **Your client**: shows your custom UI where the shopper makes the payment. Passes data to and receives data from your payment server to handle the payment flow and additional actions on your client. * **Your webhook server**: receives webhooks that include the outcome of each payment. ## Integration steps The parts of your integration work together to handle the payment flow: 1. From your server, make an API request to [get a list of payment methods available to the shopper](#get-available-payment-methods). 2. Show the [payment form to collect the shopper's payment details](#collect-shopper-details) in your UI. 3. From your server, [make a payment request](#make-a-payment) with the data that you have collected from the shopper. 4. For some payment methods, you use your client to [handle the additional action](#additional-action) that your shopper must do. For example, you redirect your shopper to another website or show a QR code that the shopper uses to complete the payment. 5. From your server, [send additional payment details](#send-additional-payment-details). 6. [Get the payment outcome](#get-the-payment-outcome). If you are integrating these parts separately, you can start at the corresponding part of this integration guide: [![](/user/pages/reuse/online-payments/how-it-works-parts/servers.svg?decoding=auto\&fetchpriority=auto)](/#install-api-library) [Payment server](/#install-api-library) [Go to the integration steps for your server.](/#install-api-library) [![](/user/pages/reuse/online-payments/how-it-works-parts/browser-developers.svg?decoding=auto\&fetchpriority=auto)](/#collect-shopper-details) [Client website or app](/#collect-shopper-details) [Go to the integration steps for your client.](/#collect-shopper-details) [![](/user/pages/reuse/online-payments/how-it-works-parts/event-code.svg?decoding=auto\&fetchpriority=auto)](/#update-your-order-management-system) [Webhook server](/#update-your-order-management-system) [Go to the integration steps for your webhook server.](/#update-your-order-management-system) ### Install Api Library ## Install an API library Payment server We provide server-side API libraries for several programming languages, available through common package managers, like Gradle and npm, for easier installation and version management. Our API libraries will save you development time, because they: * Use an API version that is up to date. * Have generated models to help you construct requests. * Send the request to Adyen using their built-in HTTP client, so you do not have to create your own. ### Tab: Java ##### Try our example integration ![](/reuse/development-resources/install-api-library/java/advanced/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-java-spring-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/java/advanced/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-java-spring-online-payments). #### Requirements * Java 11 or later. #### Installation You can use [Maven](https://maven.apache.org), adding this dependency to your project's POM. **Add the API library** ```xml com.adyen adyen-java-api-library LATEST_VERSION ``` You can find the latest version on GitHub. Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-java-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```java // Import the required classes. package com.adyen.service; import com.adyen.Client; import com.adyen.service.checkout.PaymentsApi; import com.adyen.model.checkout.Amount; import com.adyen.enums.Environment; import com.adyen.service.exception.ApiException; import java.io.IOException; public class Snippet { public Snippet() throws IOException, ApiException { // Set up the client and service. Client client = new Client("ADYEN_API_KEY", Environment.TEST); } } ``` ### Tab: PHP ##### Try our example integration ![](/reuse/development-resources/install-api-library/php/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-php-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/php/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-php-online-payments). #### Requirements * PHP 7.3 or later. * cURL with SSL support. * The JSON PHP extension. * The list of dependencies from the composer require list. #### Installation You can use [Composer](https://getcomposer.org/). Follow the [installation instructions](https://getcomposer.org/doc/00-intro.md) if you do not already have composer installed. **Install the API library** ```bash composer require adyen/php-api-library ``` In your PHP script, make sure you include the autoloader: **Include the autoloader** ```php require __DIR__ . '/vendor/autoload.php'; ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-php-api-library/releases). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```php use Adyen\Model\Checkout\Amount; use Adyen\Model\Checkout\CreateCheckoutSessionRequest; use Adyen\Service\Checkout\PaymentsApi; // Include your idempotency key when you make an API request. $requestOptions['idempotencyKey'] = "YOUR_IDEMPOTENCY_KEY"; // Set up the client and service. $client = new \Adyen\Client(); $client->setXApiKey('ADYEN_API_KEY'); $client->setEnvironment(\Adyen\Environment::TEST); $service = new PaymentsApi($client); ``` ### Tab: C\# #### Requirements * .NET standard 2.0 or later. * For Terminal API certificate validation, set the application to either of the following: * .NET core 2.1 or later * .NET framework 4.6.1 or later #### Installation You can use [NuGet](https://www.nuget.org/packages/Adyen/): **Install the API library** ```bash PM> Install-Package Adyen -Version LATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-dotnet-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```cs using Adyen; using Adyen.Model.Checkout; using Adyen.Service.Checkout; using Environment = Adyen.Model.Environment; class Program { static void Main() { // Set up the client and service. var config = new Config { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); var checkout = new PaymentsService(client); // Include your idempotency key when you make an API request. var requestOptions = new Adyen.Model.RequestOptions { IdempotencyKey = "YOUR_IDEMPOTENCY_KEY" }; } } ``` ### Tab: NodeJS ##### Try our example integration ![](/reuse/development-resources/install-api-library/node-js/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-node-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/node-js/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-node-online-payments). #### Requirements * Node.js version 18 or later. #### Installation You can use [npm](https://www.npmjs.com/): **Install the API library** ```bash npm install --save @adyen/api-library npm update @adyen/api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-node-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```js // Require the parts of the module you want to use. const { Client, CheckoutAPI, Types} = require("@adyen/api-library"); // Set up the client and service. const client = new Client({ apiKey: "ADYEN_API_KEY", environment: "TEST" }); const checkoutApi = new CheckoutAPI(client); // Include your idempotency key when you make an API request. const requestOptions = { idempotencyKey: "YOUR_IDEMPOTENCY_KEY" }; ``` ### Tab: Go ##### Try our example integration ![](/reuse/development-resources/install-api-library/go/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-golang-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/go/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-golang-online-payments). #### Requirements * Go 1.13 or later. #### Installation You can use [Go modules](https://github.com/golang/go/wiki/Modules): **Install the API library** ```shell go get github.com/adyen/adyen-go-api-library/vLATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-go-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```go package main import ( "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/adyen" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/checkout" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/common" ) // Create a payment object. func main () { client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) service := client.Checkout() ``` ### Tab: Python ##### Try our example integration ![](/reuse/development-resources/install-api-library/python/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-python-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/python/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-python-online-payments). #### Requirements * Python 3.6 or later. * (Optional) Packages: Requests or PycURL #### Installation You can use [pip](https://pip.pypa.io/en/stable/): **Install the API library** ```py pip install Adyen ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-python-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```py import Adyen # Set up the client and service. adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment that the library is used in. ``` ### Tab: Ruby ##### Try our example integration ![](/reuse/development-resources/install-api-library/ruby/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-rails-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/ruby/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-rails-online-payments). #### Requirements * Ruby 2.7 or later. #### Installation You can use [RubyGems](https://rubygems.org/): **Install the API library** ```bash gem install adyen-ruby-api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-ruby-api-library/releases). Run `bundle install` to install dependencies. #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```ruby require 'adyen-ruby-api-library' # Set up the client and service. adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # The environment that the library is used in. ``` ## Get available payment methods Payment server When the shopper goes to your checkout page, get a list of the available payment methods to show the shopper. 1. From your server, make a POST [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/72/post/paymentMethods) request including the following parameters: | Parameter name | Required | Description | | ----------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | | An object with the following parameters:- `currency`: The three-character [ISO currency code](/development-resources/currency-codes). - `value`: The value of the payment in [minor units](/development-resources/currency-codes). | | `channel` | | **iOS** | | `countryCode` | | The shopper's country/region. Format: the two-letter [ISO-3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. Exception: **QZ** (Kosovo). | | `shopperLocale` | | Language and country code. This is used to translate the payment methods names in the response. Default value: **en-US**. | The information that you include is used to filter the list of available payment methods. **Example for a shopper in the Netherlands and a payment amount of 10 EUR** ```bash curl https://checkout-test.adyen.com/v72/paymentMethods \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "iOS", "shopperLocale": "nl-NL" }' ``` The response includes the list of available payment methods, in the `paymentMethods` object. The payment methods are ordered by popularity in the shopper's country. For each payment method, the response contains: | Parameter name | Description | | -------------- | ------------------------------------------------------------------------------------------------- | | `name` | The name of the payment method that you can show in your payment form. | | `type` | The unique payment method code. You must include this when you [make a payment](#make-a-payment). | **Example response with available payment methods** ```json { "paymentMethods":[ { "name": "Cards", "type": "scheme" }, { "name":"SEPA Direct Debit", "type":"sepadirectdebit" } ] } ``` 2. Pass the list of available payment methods and the required input fields for each payment method to your client. ### Collect Shopper Details ## Build your payment form Client website or app Create your payment form where the shopper enters their information. We recommend that you collect commonly-used [shopper information in your payment form](#information-in-the-payment-form) to process a transactions, depending on your type of business.\ \ Some payment methods require you to collect, or optionally accept, additional information that you include in the payment request. For the additional information you must collect in your payment form for an individual payment method, go to our **API-only** [guide for the individual payment method](/payment-methods). We provide [payment method and issuer logos that you can download](#downloading-logos) and use in your payment form. ### Credit and debit card details Because governing bodies and organizations regulate the handling of credit and debit card information strictly, you must make sure that you are compliant when collecting card details. When a shopper selects to pay with a card, use the integration option that corresponds to your [level of PCI compliance](/development-resources/pci-dss-compliance-guide?tab=api_only_3_4#online-payments): * (Recommended) Adyen's [Custom Card Component](/payment-methods/cards/custom-card-integration) with encryption: our pre-built UI with logic to securely encrypt and handle payment card data. * Your own UI and logic to collect and handle [raw card data](/payment-methods/cards/raw-card-data): before you build an integration that collects raw credit and debit card data, you must [assess your PCI compliance according to the most extensive self-assessment form](/development-resources/pci-dss-compliance-guide?tab=api_only_3_4#online-payments) and contact your Adyen Account Manager to confirm that you are eligible. ### Information in the payment form After collecting information in your payment form, you must add it to corresponding API parameters that you include in the payment request. For example, for commonly-used information: | Field in the payment form | API request parameter | | ---------------------------------- | -------------------------- | | First name | `shopperName.firstName` | | Last name | `shopperName.lastName` | | Email address | `shopperEmail` | | Billing address (multiple fields) | `billingAddress` (object) | | Shipping address (multiple fields) | `deliveryAddress` (object) | | Phone number | `telephoneNumber` | ### Downloading Logos ** ### Downloading logos If you are building your own UI, we provide payment method and issuing bank logos that you can use on your checkout page. The images are available in PNG format with different sizes and screen resolutions and in SVG format. If you cannot find a payment method or issuer logo, contact our [Support Team](https://ca-test.adyen.com/ca/ca/contactUs/support.shtml?form=other). #### Payment method logos Download the images from the links below, specifying: * `img-size`: Specify the size for PNG format. Use the following values: * **small**: Image size 40x26 pixels * **medium**: Image size 77x50 pixels * **large**: Image size 154 x 100 pixels * `suffix`: Specify the image density for PNG format. If not specified, the images will have the same size as the `img-size`. Append any of the following values: * `@2x` * `@3x` * `-ldpi` * `-hdpi` * `-xhdpi` * `-xxhdpi` * `-xxxhdpi` * `pm-type`: The `paymentMethods.type` returned in the `/paymentMethods` response. For example, **googlepay** or **primeiropay\_boleto**. For cards, the values you should use are specified under `brands` with `type`: **scheme**. For example, `mc`, `visa`, and `amex`. To get a generic card logo, set `pm-type` to **card**. Download link for SVG: **Download link for SVG** ```js https://checkoutshopper-live.cdn.adyen.com/checkoutshopper/images/logos/[pm-type].svg ``` Download link for PNG: **Download link for PNG** ```js https://checkoutshopper-live.cdn.adyen.com/checkoutshopper/images/logos/[img-size]/[pm-type][suffix].png ``` Examples:\ \ #### Issuing bank logos Some payment methods such as iDEAL present a list of issuing banks to the shopper. Download the issuing bank logos from the links below, specifying: * `img-size`: Specify the size for PNG format. Use the following values: * **small**: Image size 40x26 pixels * **medium**: Image size 77x50 pixels * **large**: Image size 154 x 100 pixels * `suffix`: Specify the image density for PNG format. If not specified, the images will have the same size as the `img-size`. Append any of the following values: * `@2x` * `@3x` * `-ldpi` * `-hdpi` * `-xhdpi` * `-xxhdpi` * `-xxxhdpi` * `pm-type`: The `paymentMethods.type` in objects with `details.key` **issuer** returned in the `/paymentMethods` response. For example, **ideal**. * `issuerid`: The `details.items.id` referring to the issuing bank. For example, **1121** and **1151** for iDEAL. Download link for SVG: **Download link for SVG** ```js https://checkoutshopper-live.cdn.adyen.com/checkoutshopper/images/logos/[pm-type]/[issuerid].svg ``` Download link for PNG: **Download link for PNG** ```js https://checkoutshopper-live.cdn.adyen.com/checkoutshopper/images/logos/[img-size]/[pm-type]/[issuerid][suffix].png ``` Examples:\ \ ## Make a payment Payment server After the shopper selects the **Pay** button or chooses to pay with a payment method that requires a redirection, you must make a payment request to Adyen. 1. Pass the data from your client to your server. 2. From your server, make a **POST** [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request including the following parameters: | Parameter name | Required | Description | | -------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | An object with the following parameters:- `currency`: The three-character [ISO currency code](/development-resources/currency-codes). - `value`: The value of the payment in [minor units](/development-resources/currency-codes). | | `reference` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your unique reference for this payment. | | `paymentMethod.type` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The payment method type. From the [`/paymentMethods` response](#get-available-payment-methods), this is the value in `paymentMethod.type`. | | `returnUrl` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The URL where the shopper should return to after a redirection. Use the [custom URL scheme](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app) for your app. Example: `com.mydomain.adyencheckout://` Format:- Maximum 1024 characters. - If it includes non-ASCII characters, such as spaces or special letters, [URL encode](https://www.w3schools.com/html/html_urlencode.asp) it. - You can include your own additional query parameters, such as a shopper ID or order reference number. The URL must not include personally identifiable information (PII), for example name or email address. | | `applicationInfo` | | If you are a [technology partner, service partner, or system integrator](https://docs.adyen.com/partners/application-information#partnership-type), send information about the application, so that we can offer you more support. | For the following cases, you must include additional parameters in your request: * Integrating some payment methods. For more information, go to [payment method integration guides](/payment-methods). * Using our risk management features. For more information, go to [data quality and risk field reference](/risk-management/configure-your-risk-profile/risk-field-reference). * [Creating a token](/online-payments/tokenization/create-tokens) to store the shopper's payment details. * [Using a token](/online-payments/tokenization/make-token-payments) to make a recurring payment with stored payment details. **Example request to make a payment for EUR 10 with encrypted card details** ```bash curl https://checkout-test.adyen.com/v72/payments \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "merchantAccount":"ADYEN_MERCHANT_ACCOUNT", "paymentMethod":{ "type": "scheme", "encryptedCardNumber": "test_4111111111111111", "encryptedExpiryMonth": "test_03", "encryptedExpiryYear": "test_2030", "encryptedSecurityCode": "test_737" }, "amount":{ "currency":"EUR", "value":1000 }, "reference":"YOUR_ORDER_NUMBER", "returnUrl":"com.mydomain.adyencheckout://" }' ``` []() 3. Your next step depends on if the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response contains an `action` object: * If the response has no `action` object, [get the payment outcome](#get-the-payment-outcome). * If the response contains an `action` object, [handle the additional action](#additional-action). **Example response containing an action object for 3D Secure 2 authentication** ```json { "resultCode" : "IdentifyShopper", "action" : { "token" : "eyJkaXJl...", "paymentMethodType" : "scheme", "paymentData" : "Ab02b4c0...", "type" : "threeDS2", "authorisationToken" : "BQABAQ...", "subtype" : "fingerprint" } } ``` ### Perform Additional Actions ## Handle the additional action Client website or app Some payment methods require additional action from the shopper. Common examples of additional actions include: * Logging in to a bank's website or app. * Authenticating a payment with 3D Secure 2. * Scanning a QR code. Implement logic to handle all action types, so that your integration can handle different payment methods. To see if an individual payment method requires an additional action, see the corresponding [payment method guide](/payment-methods) for it. How you handle the action depends on the action type (`action.type`): | Type | `action.type` value | | ----------------------------------------------------------------------- | ------------------- | | [Redirect action](#handle-the-redirect) | **redirect** | | [3D Secure 2 authentication action](#3d-secure-2-authentication-action) | **threeDS2** | | [QR code action](#qr-code-action) | **qrCode** | | [SDK action](#sdk-action) | **sdk** | | [Voucher action](#voucher-action) | **voucher** | | [Await action](#await-action) | **await** | ### Redirect action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type` **redirect**, redirect the shopper to another site to complete the payment. How you handle the redirect depends on if it is a payment method redirect or a 3D Secure 2 redirect. ### Tab: Payment method redirect **Example /payments response for a payment method redirect** ```json { "action": { "method": "GET", "paymentData": "Ab02b4c0!BQ..", "paymentMethodType": "ideal", "type": "redirect", "url": "https://test.adyen.com/hpp/redirectIdeal.shtml?brandCode=ideal¤cyCode=EUR&issuerId=1121..." } } ``` 1. From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, get the following: | Parameter | Description | | ------------ | ----------------------------------- | | `action.url` | The URL to redirect the shopper to. | 2. Redirect the shopper to the `action.url` with the HTTP GET method, where they finish the payment. **Example to redirect the shopper** ```bash curl https://test.adyen.com/hpp/redirectIdeal.shtml?brandCode=ideal¤cyCode=EUR&issuerId=1121... \ ``` 3. When the shopper finishes the payment on the other website, they are returned to your `returnUrl` with the HTTP GET method. The `returnUrl` is appended with a Base64-encoded `redirectResult`. **Redirect result appended to the return URL** ```raw GET /?shopperOrder=12xy..&&redirectResult=X6XtfGC3%21Y... HTTP/1.1 Host: www.your-company.example.com/checkout ``` 4. URL-decode the `redirectResult` value. If a shopper completed the payment but failed to return to your client, you will receive the outcome of the payment in a [webhook event](/development-resources/webhooks). 5. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### Tab: 3D Secure 2 redirect **Example /payments response for a 3D Secure 2 redirect** ```json { "resultCode":"RedirectShopper", "action":{ "data":{ "MD":"OEVudmZVMUlkWjd0MDNwUWs2bmhSdz09...", "PaReq":"eNpVUttygjAQ/RXbDyAXBYRZ00HpTH3wUosPfe...", "TermUrl":"" }, "method":"POST", "paymentData":"Ab02b4c0!BQABAgCJN1wRZuGJmq8dMncmypvknj9s7l5Tj...", "paymentMethodType":"scheme", "type":"redirect", "url":"https://test.adyen.com/hpp/3d/validate.shtml" }, "details":[ { "key":"MD", "type":"text" }, { "key":"PaRes", "type":"text" } ] } ``` 1. From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, get the following from the `action` object: | Parameter | Description | | --------- | ------------------------------------------------------------------------------ | | `url` | The URL to redirect the shopper to. | | `method` | The method to use to redirect the shopper: **POST**. | | `data` | An object with the following data required for authentication:- `MD` - `PaRes` | 2. Redirect the shopper to the `url` with the POST HTTP method, including the following data: | Parameter | Description | | --------- | ------------------------------------------------------------------------------------------------------------------------------------- | | `MD` | From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, the value from `action.data.MD`. | | `PaRes` | From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, the value from `action.data.PaRes`. | **Example of a redirect to a 3D Secure 2 URL** ```bash curl https://checkoutshopper-test.adyen.com/checkoutshopper/threeDS/checkoutRedirect/... \ --data-urlencode 'PaReq=eNpVUttygjAQ/RXbDyAXBYRZ00HpTH3wUosPfe...' \ --data-urlencode 'MD=OEVudmZVMUlkWjd0MDNwUWs2bmhSdz09...' ``` 3. The shopper finishes 3D Secure 2 authentication on an issuer website. In the test environment, this is the page: `https://test.adyen.com/hpp/3d/validate.shtml`, and you perform the authentication using the 3D Secure test credentials: * **Username**: user * **Password**: password 4. The shopper is returned to your `returnUrl` with the same HTTP method. The `returnUrl` is appended with `MD` and `PaRes`. **Example of a 3D Secure 2 redirect back to you with MD and PaRes** ```raw POST / HTTP/1.1 Host: www.your-company.example.com/checkout?shopperOrder=12xy.. Content-Type: application/x-www-form-urlencoded MD=Ab02b4c0%21BQABAgCW5sxB4e%2F%3D%3D..&PaRes=eNrNV0mTo7gS.. ``` 5. URL-decode the `MD` and `PaRes` values. 6. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### 3D Secure 2 authentication action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **threeDS2Fingerprint** or **threeDS2Challenge**, the payment qualifies for 3D Secure 2 and it goes through the [frictionless or the challenge flow](/online-payments/3d-secure/#authentication-flows). Use one of [our 3D Secure 2 solutions](/online-payments/3d-secure) to handle the action. ### QR code action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **qrCode**, the shopper must scan a QR code to complete the payment. **Example /payments response with a QR code action for WeChat Pay desktop** ```json { "resultCode": "Pending", "action": { "paymentData": "Ab02b4c0!BQAB..", "paymentMethodType": "wechatpayQR", "qrCodeData": "weixin://wxpay/bizpayurl?pr=IM7BCOW", "type": "qrCode" } } ``` 1. From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, get the following: | Parameter | Description | | ------------------- | --------------------------------- | | `action.qrCodeData` | Contains the URL for the QR code. | 2. Get the `qrCodeData` from the `action` object. This parameter contains a URL for the QR code. 3. Show the QR code to the shopper. 4. The shopper scans the QR code. 5. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### SDK action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **sdk**, the shopper must use another UI overlay to complete the payment. For example, a payment method requires the shopper to use its specific UI to enter payment details. **Example /payments response with an SDK action for WeChat Pay** ```json { "resultCode": "Pending", "action": { "paymentMethodType": "wechatpaySDK", "type": "sdk", "paymentData": "Ab02b4c0!BQAB..", "sdkData": { "appid": "wx3aed7fe146f6a57a", "noncestr": "cPY0e83ny4hWyf5O", "packageValue": "Sign=WXPay", "partnerid": "205287714", "prepayid": "wx015678064827111da2e4f0b11005864100", "sign": "169FD3F1E193446D90C45573EBDD4020", "timestamp": "1573033086" } }, "details": [ { "key": "resultCode", "type": "text" } ] } ``` 1. From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, get the following from the `action` object: | Parameter | Description | | --------- | --------------------------------------- | | `sdkData` | The data that you must pass to the SDK. | 2. Pass the data from the `sdkData` object to the SDK. 3. The shopper uses the SDK to finish the payment. 4. Get the result from the SDK. 5. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### Voucher action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **voucher**, the shopper must use a voucher to complete the payment. **Voucher action type** ```json { "resultCode": "PresentToShopper", "action": { "expiresAt": "2021-09-04T19:17:00", "initialAmount": { "currency": "IDR", "value": 10000 }, "instructionsUrl": "https://checkoutshopper-test.adyen.com/checkoutshopper/voucherInstructions.shtml?txVariant=doku_mandiri_va", "merchantName": "YOUR_SHOP_NAME", "paymentMethodType": "doku_alfamart", "reference": "8520126030105485", "shopperEmail": "john.smith@adyen.com", "shopperName": "John Smith", "totalAmount": { "currency": "IDR", "value": 10000 }, "paymentData": "Ab02b4c0!BQAB..", "type": "voucher" } } ``` 1. The data included in the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response is different for each voucher payment method. Get the available information from it. For example, for DOKU vouchers, get the following: | Parameter | Description | | ----------------- | ------------------------------------------------------------------------------------------- | | `expiresAt` | The date when the voucher expires. | | `initialAmount` | The payment amount and currency. | | `merchantName` | The name of your shop. | | `instructionsUrl` | The URL where you shopper can get additional information and instructions about how to pay. | 2. Show voucher information to the shopper that your shopper uses to pay outside of your client. 3. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### Await action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **await**, the shopper must take an additional action to complete the payment. For example: entering a code into their banking app. **Example of a /payments response with an await action for a one-time PayTo payment** ```json { "resultCode": "Pending", "action": { "paymentData": "Ab02b4c0!BQAB..", "paymentMethodType": "payto", "type": "await" } } ``` 1. From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, get the following: | Parameter | Description | | -------------------- | ------------------------ | | `action.paymentData` | Additional payment data. | 2. The shopper finishes the additional action for the payment. 3. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### Submit Additional Payment Details ## Send additional payment details Payment server If you [handled an additional action](#additional-action), you must send additional payment details. **For redirects**: if the shopper fails to return to your client, you do not get additional payment details to send. Instead, wait for the corresponding [webhook message](#update-your-order-management-system) for the outcome of the payment. From your server, make a POST [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request. The parameters that you must include depends on the payment method. For the parameters for an individual payment method, go to the **API-only** [page for the individual payment method ](/payment-methods). **Example request to send details from a redirect** #### curl ```bash curl https://checkout-test.adyen.com/v72/payments/details \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "details": { "redirectResult": "eyJ0cmFuc1N0YXR1cyI6IlkifQ==" } }' ``` #### Java ```java // Adyen Java API Library v39.3.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the LIVE environment, also include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) // Send the request PaymentsApi service = new PaymentsApi(client); PaymentDetailsResponse response = service.paymentsDetails(paymentDetailsRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("ADYEN_API_KEY"); // For the LIVE environment, also include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->paymentsDetails($paymentDetailsRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v32.1.1 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the LIVE environment, also include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) // Send the request var service = new PaymentsService(client); var response = service.PaymentsDetails(paymentDetailsRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### Go ```go // Adyen Go API Library v21.0.0 import ( "context" "github.com/adyen/adyen-go-api-library/v21/src/common" "github.com/adyen/adyen-go-api-library/v21/src/adyen" "github.com/adyen/adyen-go-api-library/v21/src/checkout" ) // For the LIVE environment, also include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentsDetailsInput().IdempotencyKey("UUID").PaymentDetailsRequest(paymentDetailsRequest) res, httpRes, err := service.PaymentsApi.PaymentsDetails(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.6.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "details": { "redirectResult": "eyJ0cmFuc1N0YXR1cyI6IlkifQ==" } } # Send the request result = adyen.checkout.payments_api.payments_details(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v10.4.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :details => { :redirectResult => 'eyJ0cmFuc1N0YXR1cyI6IlkifQ==' } } # Send the request result = adyen.checkout.payments_api.payments_details(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v29.0.0 import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentsDetails(paymentDetailsRequest, { idempotencyKey: "UUID" }); ``` The response includes information about the current payment status. **Example response for a successful payment** ```json { "pspReference": "NC6HT9CRT65ZGN82", "resultCode": "Authorised" } ``` **Example response for a refused payment** ```json { "pspReference": "KHQC5N7G84BLNK43", "refusalReason": "Not enough balance", "resultCode": "Refused" } ``` ### Show Payment Result ## Get the payment outcome After the shopper finishes the payment flow, you can show the shopper the current payment status. Adyen sends a webhook with the outcome of the payment. ### Inform the shopper Client website or app Use the [`resultCode` ](/online-payments/payment-result-codes#final-payment-status)to show the shopper the [current payment status](/account/payments-lifecycle). This synchronous response doesn't give you the final outcome of the payment. You get the final payment status in a webhook that you use to [update your order management system](#update-your-order-management-system). ### Update your order management system Webhook server You get the outcome of each payment asynchronously, in an **AUTHORISATION** [webhook](/development-resources/webhooks). Use the `merchantReference` from the webhook to match it to your order reference.\ For a successful payment, the event contains `success`: **true**. **Example webhook for a successful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"033899:1111:03/2030", "amount":{ "currency":"EUR", "value":2500 }, "operations":["CANCEL","CAPTURE","REFUND"], "success":"true", "paymentMethod":"mc", "additionalData":{ "expiryDate":"03/2030", "authCode":"033899", "cardBin":"411111", "cardSummary":"1111" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"NC6HT9CRT65ZGN82", "eventDate":"2021-09-13T14:10:22+02:00" } } ] } ``` For an unsuccessful payment, you get `success`: **false**, and the `reason` field has details about why the payment was unsuccessful. **Example webhook for an unsuccessful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"validation 101 Invalid card number", "amount":{ "currency":"EUR", "value":2500 }, "success":"false", "paymentMethod":"unknowncard", "additionalData":{ "expiryDate":"03/2030", "cardBin":"411111", "cardSummary":"1112" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"KHQC5N7G84BLNK43", "eventDate":"2021-09-13T14:14:05+02:00" } } ] } ``` ## Error handling In case you encounter errors in your integration, refer to the following: * [API error codes](/development-resources/error-codes): If you receive a non-HTTP 200 response, use the `errorCode` to troubleshoot and modify your request. * [Payment refusals](/development-resources/refusal-reasons): If you receive an HTTP 200 response with an **Error** or **Refused** `resultCode`, check the refusal reason and, if possible, modify your request. ## Test and go live Before going live, use our list of [test cards and other payment methods](/development-resources/test-cards-and-credentials/test-card-numbers) to [test your integration](/development-resources/testing). We recommend testing each payment method that you intend to offer to your shoppers. You can check the status of a test payment in your [Customer Area](https://ca-test.adyen.com/), under **Transactions** > **Payments**. To debug or troubleshoot test payments, you can also use [API logs](/development-resources/logs-resources/api-logs) in your test environment. When you are ready to go live, you need to: 1. [Apply for a live account](/get-started-with-adyen/application-requirements). 2. Assess your [PCI DSS compliance](/development-resources/pci-dss-compliance-guide#online-payments) by submitting: * the [Self-Assessment Questionnaire-A](https://www.pcisecuritystandards.org/documents/PCI-DSS-v3_2_1-SAQ-A.pdf), if you are using the Custom Card Component. * the [Self-Assessment Questionnaire-D](https://www.pcisecuritystandards.org/documents/PCI-DSS-v3_2_1-SAQ-D_Merchant.pdf), if you are submitting raw card data. 3. [Configure your live account](/online-payments/go-live-checklist).  4. Submit a request to add payment methods in your [live Customer Area](https://ca-live.adyen.com/) . 5. Switch from test to our [live endpoints](/development-resources/live-endpoints#checkout-endpoints). Make sure that all API requests you make for the same payment session use the same live endpoint region. Using different regions for [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) and [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) requests may result in errors, for example, when authenticating with 3D Secure 2. ### Next Steps [required](/development-resources/webhooks) [Set up notifications](/development-resources/webhooks) [Receive confirmation when a payment is authorised or fails.](/development-resources/webhooks) [required](/payment-methods) [Add payment methods](/payment-methods) [Learn about payment methods and how to add them to your account.](/payment-methods) [Payment modifications](/online-payments/modify-payments) [Find out how to cancel, refund, or capture a payment using our API.](/online-payments/modify-payments) ## Android Drop-in Use our pre-built UI for accepting payments ### Before You Begin ## Requirements Before you begin to integrate, make sure you have followed the [Get started with Adyen guide](/get-started-with-adyen) to: * Get an overview of the steps needed to accept live payments. * Create your test account. After you have created your test account: * [Get your API key](/development-resources/api-credentials#generate-api-key). * [Get your client key](/development-resources/client-side-authentication#get-your-client-key). * [Set up webhooks](/development-resources/webhooks) to know the payment outcome. ## How it works Our [Android Drop-in](/online-payments/build-your-integration/sessions-flow?platform=Android\&integration=Drop-in) renders the available cards in your payment form, and securely collects any sensitive card information, so it doesn't touch your server. Drop-in also handles the 3D Secure 2 device fingerprinting and challenge flows, including the data exchange between your front end and the issuer's Access Control Server (ACS). When adding 3D Secure 2 authentication to your integration, you also need to: 1. [Configure Drop-in](#configure-drop-in) to collect the cardholder name. 2. Provide additional parameters [when making a payment request](#make-a-payment). 3. [Submit authentication results](#submit-additional-3d-secure-2-authentication-details) if you receive an `action` object in response to your API request. 4. If the payment was routed to the 3D Secure 2 redirect flow, handle the redirect. ### Install Api Library ## Install an API library Payment server We provide server-side API libraries for several programming languages, available through common package managers, like Gradle and npm, for easier installation and version management. Our API libraries will save you development time, because they: * Use an API version that is up to date. * Have generated models to help you construct requests. * Send the request to Adyen using their built-in HTTP client, so you do not have to create your own. ### Tab: Java ##### Try our example integration ![](/reuse/development-resources/install-api-library/java/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-java-spring-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/java/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-java-spring-online-payments). #### Requirements * Java 11 or later. #### Installation You can use [Maven](https://maven.apache.org), adding this dependency to your project's POM. **Add the API library** ```xml com.adyen adyen-java-api-library LATEST_VERSION ``` You can find the latest version on GitHub. Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-java-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```java // Import the required classes. package com.adyen.service; import com.adyen.Client; import com.adyen.service.checkout.PaymentsApi; import com.adyen.model.checkout.Amount; import com.adyen.model.checkout.CreateCheckoutSessionRequest; import com.adyen.model.checkout.CreateCheckoutSessionResponse; import com.adyen.enums.Environment; import com.adyen.service.exception.ApiException; import java.io.IOException; public class Snippet { public Snippet() throws IOException, ApiException { // Set up the client and service. Client client = new Client("ADYEN_API_KEY", Environment.TEST); } } ``` ### Tab: PHP ##### Try our example integration ![](/reuse/development-resources/install-api-library/php/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-php-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/php/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-php-online-payments). #### Requirements * PHP 7.3 or later. * cURL with SSL support. * The JSON PHP extension. * The list of dependencies from the composer require list. #### Installation You can use [Composer](https://getcomposer.org/). Follow the [installation instructions](https://getcomposer.org/doc/00-intro.md) if you do not already have composer installed. **Install the API library** ```bash composer require adyen/php-api-library ``` In your PHP script, make sure you include the autoloader: **Include the autoloader** ```php require __DIR__ . '/vendor/autoload.php'; ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-php-api-library/releases). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```php use Adyen\Model\Checkout\Amount; use Adyen\Model\Checkout\CreateCheckoutSessionRequest; use Adyen\Service\Checkout\PaymentsApi; // Include your idempotency key when you make an API request. $requestOptions['idempotencyKey'] = "YOUR_IDEMPOTENCY_KEY"; // Set up the client and service. $client = new \Adyen\Client(); $client->setXApiKey('ADYEN_API_KEY'); $client->setEnvironment(\Adyen\Environment::TEST); $service = new PaymentsApi($client); ``` ### Tab: C\# #### Requirements * .NET standard 2.0 or later. * For Terminal API certificate validation, set the application to either of the following: * .NET core 2.1 or later * .NET framework 4.6.1 or later #### Installation You can use [NuGet](https://www.nuget.org/packages/Adyen/): **Install the API library** ```bash PM> Install-Package Adyen -Version LATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-dotnet-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```cs using Adyen; using Adyen.Model.Checkout; using Adyen.Service.Checkout; using Environment = Adyen.Model.Environment; class Program { static void Main() { // Set up the client and service. var config = new Config { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); var checkout = new PaymentsService(client); // Include your idempotency key when you make an API request. var requestOptions = new Adyen.Model.RequestOptions { IdempotencyKey = "YOUR_IDEMPOTENCY_KEY" }; } } ``` ### Tab: NodeJS ##### Try our example integration ![](/reuse/development-resources/install-api-library/node-js/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-node-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/node-js/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-node-online-payments). #### Requirements * Node.js version 18 or later. #### Installation You can use [npm](https://www.npmjs.com/): **Install the API library** ```bash npm install --save @adyen/api-library npm update @adyen/api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-node-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```js // Require the parts of the module you want to use. const { Client, CheckoutAPI, Types} = require("@adyen/api-library"); // Set up the client and service. const client = new Client({ apiKey: "ADYEN_API_KEY", environment: "TEST" }); const checkoutApi = new CheckoutAPI(client); // Include your idempotency key when you make an API request. const requestOptions = { idempotencyKey: "YOUR_IDEMPOTENCY_KEY" }; ``` ### Tab: Go ##### Try our example integration ![](/reuse/development-resources/install-api-library/go/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-golang-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/go/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-golang-online-payments). #### Requirements * Go 1.13 or later. #### Installation You can use [Go modules](https://github.com/golang/go/wiki/Modules): **Install the API library** ```shell go get github.com/adyen/adyen-go-api-library/vLATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-go-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```go package main import ( "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/adyen" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/checkout" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/common" ) // Create a payment object. func main () { client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) service := client.Checkout() ``` ### Tab: Python ##### Try our example integration ![](/reuse/development-resources/install-api-library/python/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-python-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/python/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-python-online-payments). #### Requirements * Python 3.6 or later. * (Optional) Packages: Requests or PycURL #### Installation You can use [pip](https://pip.pypa.io/en/stable/): **Install the API library** ```py pip install Adyen ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-python-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```py import Adyen # Set up the client and service. adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment that the library is used in. ``` ### Tab: Ruby ##### Try our example integration ![](/reuse/development-resources/install-api-library/ruby/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-rails-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/ruby/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-rails-online-payments). #### Requirements * Ruby 2.7 or later. #### Installation You can use [RubyGems](https://rubygems.org/): **Install the API library** ```bash gem install adyen-ruby-api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-ruby-api-library/releases). Run `bundle install` to install dependencies. #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```ruby require 'adyen-ruby-api-library' # Set up the client and service. adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # The environment that the library is used in. ``` ### Get Payment Methods ## Get available payment methods Payment server When the shopper is ready to pay, get a list of the available payment methods based on their country, device, and the payment amount. 1. From your server, make a POST [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) request, including: We recommend that you include all the optional parameters to get the most accurate list of available payment methods. | Parameter name | Required | Description | | ----------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | | The `currency` and `value` of the payment, in [minor units](/development-resources/currency-codes). | | `channel` | | Use **Android**. Adyen returns only the payment methods available for Android. | | `countryCode` | | The shopper's country/region. Adyen returns only the payment methods available in this country. Format: the two-letter [ISO-3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. Exception: **QZ** (Kosovo). | | `shopperLocale` | | By default, the `shopperlocale` is set to **en-US**. To change the language, set this to the shopper's language and country code. You also need to set the same `ShopperLocale` within your Drop-in configuration. | For example, to get available payment methods for a shopper in the Netherlands, for a payment of **10** EUR: #### curl ```bash curl https://checkout-test.adyen.com/v72/paymentMethods \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Android", "shopperLocale": "nl-NL" }' ``` #### Java ```java // Adyen Java API Library v27.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the live environment, additionally include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) Amount amount = new Amount() .currency("EUR") .value(1000L); PaymentMethodsRequest paymentMethodsRequest = new PaymentMethodsRequest() .amount(amount) .merchantAccount("ADYEN_MERCHANT_ACCOUNT") .countryCode("NL") .channel(PaymentMethodsRequest.ChannelEnum.IOS) .shopperLocale("nl-NL"); // Send the request PaymentsApi service = new PaymentsApi(client); PaymentMethodsResponse response = service.paymentMethods(paymentMethodsRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("ADYEN_API_KEY"); // For the LIVE environment, also include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->paymentMethods($paymentMethodsRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v32.1.1 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the LIVE environment, also include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) // Send the request var service = new PaymentsService(client); var response = service.PaymentMethods(paymentMethodsRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v29.0.0 const { Client, CheckoutAPI } = require('@adyen/api-library'); // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const paymentMethodsRequest = { merchantAccount: "ADYEN_MERCHANT_ACCOUNT", countryCode: "NL", amount: { currency: "EUR", value: 1000 }, channel: "Android", shopperLocale: "nl-NL" } // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentMethods(paymentMethodsRequest, { idempotencyKey: "UUID" }); ``` #### Go ```go // Adyen Go API Library v10.4.0 import ( "context" "github.com/adyen/adyen-go-api-library/v9/src/common" "github.com/adyen/adyen-go-api-library/v9/src/adyen" "github.com/adyen/adyen-go-api-library/v9/src/checkout" ) // For the live environment, additionally include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) amount := checkout.Amount{ Currency: "EUR", Value: 1000, } paymentMethodsRequest := checkout.PaymentMethodsRequest{ Amount: &amount, MerchantAccount: "ADYEN_MERCHANT_ACCOUNT", CountryCode: common.PtrString("NL"), Channel: common.PtrString("iOS"), ShopperLocale: common.PtrString("nl-NL"), } // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentMethodsInput().IdempotencyKey("UUID").PaymentMethodsRequest(paymentMethodsRequest) res, httpRes, err := service.PaymentsApi.PaymentMethods(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.6.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Android", "shopperLocale": "nl-NL" } # Send the request result = adyen.checkout.payments_api.payment_methods(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v10.4.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT', :countryCode => 'NL', :amount => { :currency => 'EUR', :value => 1000 }, :channel => 'Android', :shopperLocale => 'nl-NL' } # Send the request result = adyen.checkout.payments_api.payment_methods(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v29.0.0 import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentMethods(paymentMethodsRequest, { idempotencyKey: "UUID" }); ``` The response includes the list of available `paymentMethods`: **/paymentMethods response** ```json { "paymentMethods":[ { "details":[...], "name":"Cards", "type":"scheme" ... }, { "details":[...], "name":"SEPA Direct Debit", "type":"sepadirectdebit" }, ... ] } ``` 2. Deserialize the response to a `PaymentMethodsApiResponse`: **Deserialize the response** ```java val paymentMethodsApiResponse = PaymentMethodsApiResponse.SERIALIZER.deserialize(paymentMethodsResponse) ``` 3. Pass the `PaymentMethodsApiResponse` object to your client app to [launch and show Drop-in](#launch-and-show). ### Configure Drop In ## Set up Drop-in Client app ### 1: Import the library The default implementation is with Jetpack Compose, but you can import the library without Jetpack Compose instead. Import the compatibility module in your `build.gradle` file: ### Tab: With Jetpack Compose **Import the module with Compose** ```groovy implementation "com.adyen.checkout:drop-in-compose:YOUR_VERSION" ``` ### Tab: Without Jetpack Compose **Import the module without Compose** ```groovy implementation "com.adyen.checkout:drop-in:YOUR_VERSION" ``` ### Create Configuration Object ### 2: Create the configuration object Create the configuration object to pass when you launch and show Drop-in. 1. Set the following properties in the configuration object:[]() | Property | Required | Description | | --------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | | `amount` | If you want to show the amount on the **Pay** button. | The currency and value of the payment amount shown on the **Pay** button. | | `environment` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Use `Environment.TEST` for testing. When going live, use one of our live environments. | | `clientKey` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your client key. | | `shopperLocale` | | The shopper's locale. By default, this is the device's locale. | 2. Add additional configuration to this object. Some [payment methods](/payment-methods) require additional configuration, and you can add optional configuration for Drop-in. For example, to configure for a payment of 10 EUR: **Example configuration** ```kotlin // Create the amount object. val amount = Amount( currency = "EUR", value = 1000, // Value in minor units. ) // Create a configuration object val checkoutConfiguration = CheckoutConfiguration( environment = environment, clientKey = clientKey, shopperLocale = shopperLocale, // Optional amount = amount, // Optional: set this to show the amount on the Pay button. ) { // Optional: add Drop-in configuration. dropIn { setEnableRemovingStoredPaymentMethods(true) } // Optional: add or change default configuration for the card payment method. card { setHolderNameRequired(true) setShopperReference("...") } // Optional: add or change default configuration for 3D Secure 2. adyen3DS2 { setThreeDSRequestorAppURL("...") } } ``` 3. Extend the `DropInService` class so that you can interact with Drop-in. 4. Implement methods to pass data between your client app and your server. You must also handle the `DropInServiceResult` which includes the result of the API requests from your server. For example: **Example DropInService implementation** ```kotlin class YourDropInService : DropInService() { // The handler to make a /payments request. override fun onSubmit(state: PaymentComponentState<*>) { val paymentComponentJson = PaymentComponentData.SERIALIZER.serialize(state.data) // Your server makes a /payments request, including `paymentComponentJson`. // This is used in 4: Make a payment. // Create the `DropInServiceResult` based on the /payments response. // You must switch to a background thread before making an API request. For example, `launch(Dispatchers.IO)` if using coroutines. // If the payment finished, handle the result. sendResult(DropInServiceResult.Finished("YOUR_RESULT")) // If additional action is needed, handle the action. val action = Action.SERIALIZER.deserialize(actionJSONObject) sendResult(DropInServiceResult.Action(action)) } // Handler to make a /payments/details request to send additional payment details. override fun onAdditionalDetails(actionComponentData: ActionComponentData) { val actionComponentJson = ActionComponentData.SERIALIZER.serialize(actionComponentData) // Your server makes a /payments/details request, including `actionComponentJson`. // This is used in Step 5: Submit additional payment details. // Create the `DropInServiceResult` based on the /payments/details response. sendResult(DropInServiceResult.Finished("YOUR_RESULT")) } } ``` Drop-in uses the `DropInServiceResult` to complete or dismiss the payment and determine if you need to handle additional actions. Additional actions include redirecting the shopper to another app or performing 3D Secure 2 authentication. 5. Add your `DropInService` to your manifest file. For example: ```xml ``` ### Launch and show Drop-in ### Tab: With Jetpack Compose 1. Implement `DropInCallback` to get the final result. **Implement DropInCallback** ```kotlin override fun onDropInResult(dropInResult: DropInResult?) { when (dropInResult) { // The payment finishes with a result. is DropInResult.Finished -> handleResult(dropInResult.result) // The shopper dismisses Drop-in. is DropInResult.CancelledByUser -> // Drop-in encounters an error. is DropInResult.Error -> handleError(dropInResult.reason) // Drop-in encounters an unexpected state. null -> } } ``` 2. Create the Drop-in launcher and call `DropIn.startPayment`, passing: | Parameter | Description | | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | `dropInLauncher` | The Drop-in launcher you created. | | `paymentMethodsApiResponse` | The [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) response that you deserialized. | | `checkoutConfiguration` | The Drop-in configuration that you created. | | `YourDropInService::class.java` (Example) | The `DropInService` that you created. | For example: **Start Drop-in** ```kotlin import com.adyen.checkout.dropin.compose.startPayment import com.adyen.checkout.dropin.compose.rememberLauncherForDropInResult @Composable private fun ComposableDropIn() { val dropInLauncher = rememberLauncherForDropInResult(dropInCallback) DropIn.startPayment(dropInLauncher, paymentMethodsApiResponse, checkoutConfiguration, YourDropInService::class.java) } ``` ### Tab: Without Jetpack Compose 1. Register your `Activity` or `Fragment` with the Activity Result API by calling `DropIn.registerForDropInResult`. **Register your Activity or Fragment** ```kotlin // Declare this as a field in your Activity or Fragment. private val dropInLauncher = DropIn.registerForDropInResult(this, dropInCallback) ``` 2. Implement `DropInCallback` to get the final result. **Implement DropInCallback** ```kotlin override fun onDropInResult(dropInResult: DropInResult?) { when (dropInResult) { // The payment finishes with a result. is DropInResult.Finished -> handleResult(dropInResult.result) // The shopper dismisses Drop-in. is DropInResult.CancelledByUser -> // Drop-in encounters an error. is DropInResult.Error -> handleError(dropInResult.reason) // Drop-in encounters an unexpected state. null -> } } ``` 3. Deserialize the [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) response to a `PaymentMethodsApiResponse` object: **Deserialize the API response** ```kotlin val paymentMethodsApiResponse = PaymentMethodsApiResponse.SERIALIZER.deserialize(paymentMethodsResponseJSON) ``` 4. Call `DropIn.startPayment`, passing: | Parameter | Description | | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | `context` | Your context. | | `dropInLauncher` | The Drop-in launcher you declared in your `Activity` or `Fragment`. | | `paymentMethodsApiResponse` | The [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) response that you deserialized. | | `checkoutConfiguration` | The checkout configuration that you created. | | `YourDropInService::class.java` (Example) | The `DropInService` that you created. | For example: **Launch Drop-in** ```kotlin DropIn.startPayment( context, dropInLauncher, paymentMethodsApiResponse, checkoutConfiguration, YourDropInService::class.java, ) ``` Your app shows Drop-in, and your shopper can choose a payment method. ## Make a payment Payment server When the shopper enters their payment details and selects the **Pay** button, the `onSubmit` method in your `DropInService` class is called, passing the `paymentComponentJson` object. 1. Pass the `paymentComponentJson` object to your server. 2. From your server, make a **POST** [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request including the following: | Parameter name | Required | Description | | ------------------------------------------------------ | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The `currency` and `value` of the payment, in [minor units](/development-resources/currency-codes). | | `reference` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your unique reference for this payment. | | `paymentMethod` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The complete `paymentComponentData.paymentMethod` object from your client app that includes the payment method details and other required information. | | `paymentMethod.sdkData` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The object that includes information collected by Drop-in to track the user's payment journey, including information like the [checkout attempt identifier](/online-payments/analytics-and-data-tracking#data-we-are-collecting). This is required to use the [Checkout dashboard](/uplift#uplift-dashboards) that lets you analyze your checkout performance. | | `returnUrl` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | In case of a redirection, this is the URL to where your shopper is redirected after they complete the payment. Maximum length: 1024 characters. Get this URL from Drop-in in the `RedirectComponent.getReturnUrl(context)`. | | [`applicationInfo`](/partners/application-information) | | If you are building an Adyen solution for multiple merchants, include some [basic identifying information](/partners/application-information), so that we can offer you better support. | You must include additional parameters in your payment request to: * Integrate some payment methods. For more information, go to [payment method integration guides](/payment-methods). * Using our risk management features. For more information, go to [Required risk fields](/risk-management/configure-manual-risk/required-risk-field-reference). * Use [native 3D Secure 2 authentication](/online-payments/3d-secure/native-3ds2/android-drop-in#make-a-payment). * [Tokenize your shopper's payment details](/payment-methods/cards/android-drop-in#create-a-token) or [make recurring payments](/payment-methods/cards/android-drop-in#make-a-payment-with-a-token). 3. For example, to make a payment request for **EUR 10**: #### curl ```bash curl https://checkout-test.adyen.com/v72/payments \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "amount":{ "currency":"EUR", "value":1000 }, "reference":"YOUR_ORDER_NUMBER", "paymentMethod":{hint:paymentMethod field of an object passed from your client app}STATE_DATA{/hint}, "returnUrl":"adyencheckout://your.package.name", "merchantAccount":"ADYEN_MERCHANT_ACCOUNT" }' ``` #### Java ```java // Adyen Java API Library v39.3.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the LIVE environment, also include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) Amount amount = new Amount() .currency("EUR") .value(1000L); PaymentRequest paymentRequest = new PaymentRequest() .reference("YOUR_ORDER_NUMBER") .amount(amount) .merchantAccount("ADYEN_MERCHANT_ACCOUNT") .returnUrl("adyencheckout://your.package.name"); // Send the request PaymentsApi service = new PaymentsApi(client); PaymentResponse response = service.payments(paymentRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("ADYEN_API_KEY"); // For the LIVE environment, also include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $amount = new Amount(); $amount ->setCurrency("EUR") ->setValue(1000); $paymentRequest = new PaymentRequest(); $paymentRequest ->setReference("YOUR_ORDER_NUMBER") ->setAmount($amount) ->setMerchantAccount("ADYEN_MERCHANT_ACCOUNT") ->setReturnUrl("adyencheckout://your.package.name"); $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->payments($paymentRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v32.1.1 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the LIVE environment, also include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) Amount amount = new Amount { Currency = "EUR", Value = 1000 }; PaymentRequest paymentRequest = new PaymentRequest { Reference = "YOUR_ORDER_NUMBER", Amount = amount, MerchantAccount = "ADYEN_MERCHANT_ACCOUNT", ReturnUrl = "adyencheckout://your.package.name" }; // Send the request var service = new PaymentsService(client); var response = service.Payments(paymentRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v29.0.0 const { Client, CheckoutAPI } = require('@adyen/api-library'); // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const paymentRequest = { amount: { currency: "EUR", value: 1000 }, reference: "YOUR_ORDER_NUMBER", paymentMethod: "STATE_DATA", returnUrl: "adyencheckout://your.package.name", merchantAccount: "ADYEN_MERCHANT_ACCOUNT" } // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.payments(paymentRequest, { idempotencyKey: "UUID" }); ``` #### Go ```go // Adyen Go API Library v21.0.0 import ( "context" "github.com/adyen/adyen-go-api-library/v21/src/common" "github.com/adyen/adyen-go-api-library/v21/src/adyen" "github.com/adyen/adyen-go-api-library/v21/src/checkout" ) // For the LIVE environment, also include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) amount := checkout.Amount{ Currency: "EUR", Value: 1000, } paymentRequest := checkout.PaymentRequest{ Reference: "YOUR_ORDER_NUMBER", Amount: amount, MerchantAccount: "ADYEN_MERCHANT_ACCOUNT", ReturnUrl: "adyencheckout://your.package.name", } // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentsInput().IdempotencyKey("UUID").PaymentRequest(paymentRequest) res, httpRes, err := service.PaymentsApi.Payments(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.6.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "amount": { "currency": "EUR", "value": 1000 }, "reference": "YOUR_ORDER_NUMBER", "paymentMethod": "STATE_DATA", "returnUrl": "adyencheckout://your.package.name", "merchantAccount": "ADYEN_MERCHANT_ACCOUNT" } # Send the request result = adyen.checkout.payments_api.payments(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v10.4.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :amount => { :currency => 'EUR', :value => 1000 }, :reference => 'YOUR_ORDER_NUMBER', :paymentMethod => 'STATE_DATA', :returnUrl => 'adyencheckout://your.package.name', :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT' } # Send the request result = adyen.checkout.payments_api.payments(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v29.0.0 import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const amount: Types.checkout.Amount = { currency: "EUR", value: 1000 }; const paymentRequest: Types.checkout.PaymentRequest = { reference: "YOUR_ORDER_NUMBER", amount: amount, merchantAccount: "ADYEN_MERCHANT_ACCOUNT", returnUrl: "adyencheckout://your.package.name" }; // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.payments(paymentRequest, { idempotencyKey: "UUID" }); ``` Your next step depends on if the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response contains an `action` object: * If the response has no `action` object, [get the payment outcome](#get-the-payment-outcome). * If the response contains an `action` object, [handle the additional action](#additional-action). **Example response containing an action object for 3D Secure 2 authentication** ```json { "resultCode" : "IdentifyShopper", "action" : { "token" : "eyJkaXJl...", "paymentMethodType" : "scheme", "paymentData" : "Ab02b4c0...", "type" : "threeDS2", "authorisationToken" : "BQABAQ...", "subtype" : "fingerprint" } } ``` ### Error handling If the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request fails, return `DropInServiceResult.Error` to your client app, including the `action` object. ### Handle Additional Action ## Handle the additional action Client app Some payment methods require additional action from the shopper. Common examples of additional actions include: * Logging in to a bank's website or app. * Authenticating a payment with 3D Secure 2. * Scanning a QR code. Implement logic to handle all action types, so that your integration can handle different payment methods. To see if an individual payment method requires an additional action, see the corresponding [payment method guide](/payment-methods) for it. Deserialize the `action` object it and pass it to Drop-in. 1. Pass the full `action` object from your server to Drop-in. 2. Use `ActionResponse.SERIALIZER` to deserialize the `action` object. 3. Return it as `DropInServiceResult.Action` to Drop-in. 4. Drop-in handles the additional action on the client side. 5. You handle the payment data, depending on the type of action (`action.type`). | Type | `action.type` value | | ----------------------------------------------------------------------- | ------------------- | | [Redirect action](#handle-the-redirect) | **redirect** | | [3D Secure 2 authentication action](#3d-secure-2-authentication-action) | **threeDS2** | | [QR code action](#qr-code-action) | **qrCode** | | [SDK action](#sdk-action) | **sdk** | | [Voucher action](#voucher-action) | **voucher** | | [Await action](#await-action) | **await** | ### Redirect action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type` **redirect**, Drop-in redirects your shopper to another website to complete the payment. 1. When the shopper returns to your app, Drop-in calls the `onAdditionalDetails` method in your `DropInService` class. 2. From `onAdditionalDetails`, get the `actionComponentJson` object.\` 3. Pass the `actionComponentJson` object from your client app to your server. 4. [Send additional payment details](#send-additional-payment-details). If the shopper fails to return to your app, you do not get the additional data to send. Instead, wait for the corresponding [webhook](#update-your-order-management-system) for the outcome of the payment. ### 3D Secure 2 authentication action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **threeDS2**, the payment qualifies for 3D Secure 2 and it goes through the [frictionless or the challenge flow](/online-payments/3d-secure/#authentication-flows). 1. Drop-in handles 3D Secure 2 authentication. If a challenge is required, the shopper performs the authentication challenge to complete the payment. 2. Drop-in calls the `onAdditionalDetails` method in your `DropInService` class. 3. From `onAdditionalDetails`, get the `actionComponentJson` object. 4. Pass the `actionComponentJson` object from your client app to your server. 5. [Send additional payment details](#send-additional-payment-details). ### QR code action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **qrCode**, the shopper must use a QR code to complete the payment. 1. Drop-in shows the QR code to the shopper. 2. When the shopper uses the QR code to complete the payment, Drop-in calls the `onAdditionalDetails` method in your `DropInService` class. 3. From `onAdditionalDetails`, get the `actionComponentJson` object. 4. Pass the `actionComponentJson` object from your client app to your server. 5. [Send additional payment details](#send-additional-payment-details). ### SDK action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **sdk**, the shopper must use another UI overlay to complete the payment. For example, a payment method requires the shopper to use its specific UI to enter payment details. 1. Drop-in shows a different UI in an overlay. 2. The shopper uses the UI overlay to complete the payment. 3. Drop-in calls the `onAdditionalDetails` method in your `DropInService` class. 4. From `onAdditionalDetails`, get the `actionComponentJson` object. 5. Pass the `actionComponentJson` object from your client app to your server. 6. [Send additional payment details](#send-additional-payment-details). ### Voucher action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **voucher**, the shopper must use a voucher to complete the payment. 1. Drop-in shows the voucher to the shopper. 2. When the shopper completes the additional action with the voucher (for example: saving it to their digital wallet or forwarding it to their email), Drop-in calls the `onAdditionalDetails` method in your `DropInService` class. 3. From `onAdditionalDetails`, get the `actionComponentJson` object. 4. Pass the `actionComponentJson` object from your client app to your server. 5. [Send additional payment details](#send-additional-payment-details). ### Await action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **await**, the shopper must take an additional action to complete the payment. For example: entering a code into their banking app. 1. Drop-in shows the instructions for the additional action to complete the payment. 2. The shopper does the additional action. 3. Drop-in calls the `onAdditionalDetails` method in your `DropInService` class. 4. From `onAdditionalDetails`, get the `actionComponentJson` object. 5. Pass the `actionComponentJson` object from your client app to your server. 6. [Send additional payment details](#send-additional-payment-details). ### Send Additional Details ## Send additional payment details Payment server If you [handled an additional action](#additional-action), you must send additional payment details to Adyen. 1. Pass the full `actionComponentJson` object to your server. 2. From your server, make a **POST** [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request including the full data from the `actionComponentJson` object. #### curl ```bash curl https://checkout-test.adyen.com/v72/payments/details \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{hint:object passed from your client app}STATE_DATA{/hint}' ``` #### Java ```java // Set your X-API-KEY with the API key from the Customer Area. String xApiKey = "ADYEN_API_KEY"; Client client = new Client(xApiKey,Environment.TEST); Checkout checkout = new Checkout(client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. PaymentsDetailsRequest paymentsDetailsRequest = STATE_DATA; PaymentsResponse paymentsDetailsResponse = checkout.paymentsDetails(paymentsDetailsRequest); ``` #### PHP ```php // Set your X-API-KEY with the API key from the Customer Area. $client = new \Adyen\Client(); $client->setEnvironment(\Adyen\Environment::TEST); $client->setXApiKey("ADYEN_API_KEY"); $service = new \Adyen\Service\Checkout($client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. $params = STATE_DATA; $result = $service->paymentsDetails($params); // Check if further action is needed. if (array_key_exists("action", $result)){ // Pass the action object to your client. // $result["action"] } else { // No further action needed, pass the resultCode to your client. // $result['resultCode'] } ``` #### C\# ```cs // Set your X-API-KEY with the API key from the Customer Area. string apiKey = "ADYEN_API_KEY"; var client = new Client (apiKey, Environment.Test); var checkout = new Checkout(client); // STATE_DATA is an object passed from the client app, deserialized from JSON to a data structure. var paymentsDetailsRequest = STATE_DATA; var paymentsDetailsResponse = checkout.PaymentDetails(paymentsDetailsRequest); ``` #### NodeJS (JavaScript) ```js const {Client, Config, CheckoutAPI} = require('@adyen/api-library'); const config = new Config(); // Set your X-API-KEY with the API key from the Customer Area. config.apiKey = '[ADYEN_API_KEY]'; const client = new Client({ config }); client.setEnvironment("TEST"); const checkout = new CheckoutAPI(client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. checkout.paymentsDetails(STATE_DATA).then(res => res); ``` #### Go ```go import ( "github.com/adyen/adyen-go-api-library/v5/src/checkout" "github.com/adyen/adyen-go-api-library/v5/src/common" "github.com/adyen/adyen-go-api-library/v5/src/adyen" ) // Set your X-API-KEY with the API key from the Customer Area. client := adyen.NewClient(&common.Config{ Environment: common.TestEnv, ApiKey: "[ADYEN_API_KEY]", }) // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. req := STATE_DATA; res, httpRes, err := client.Checkout.PaymentsDetails(&req) ``` #### Python ```py # Set your X-API-KEY with the API key from the Customer Area. adyen = Adyen.Adyen() adyen.payment.client.platform = "test" adyen.client.xapikey = 'ADYEN_API_KEY' # STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. request = STATE_DATA result = adyen.checkout.payments_details(request) # Check if further action is needed. if 'action' in result.message: # Pass the action object to your client. # result.message['action'] else: # No further action needed, pass the resultCode to your client. # result.message['resultCode'] ``` #### Ruby ```ruby require 'adyen-ruby-api-library' # Set your X-API-KEY with the API key from the Customer Area. adyen = Adyen::Client.new adyen.env = :test adyen.api_key = "ADYEN_API_KEY" # STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. request = STATE_DATA response = adyen.checkout.payments.details(request) # Check if further action is needed. if response.body.has_key(:action) # Pass the action object to your client puts response.body[:action] else # No further action needed, pass the resultCode to your client puts response.body[:resultCode] end ``` 3. Pass the [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) response from your server to your client app. **Example response for a successful payment** ```json { "pspReference": "NC6HT9CRT65ZGN82", "resultCode": "Authorised" } ``` **Example response for a refused payment** ```json { "pspReference": "KHQC5N7G84BLNK43", "refusalReason": "Not enough balance", "resultCode": "Refused" } ``` ### Get Payment Outcome ## Get the payment outcome After Drop-in finishes the payment flow, you can show the shopper the current payment status. Adyen sends a webhook with the outcome of the payment. ### Inform the shopper Client app Use the [`resultCode` ](/online-payments/payment-result-codes#final-payment-status)to show the shopper the [current payment status](/account/payments-lifecycle). This synchronous response doesn't give you the final outcome of the payment. You get the final payment status in a webhook that you use to [update your order management system](#update-your-order-management-system). ### Update your order management system Webhook server You get the outcome of each payment asynchronously, in a webhook with `eventCode`: **AUTHORISATION**. Use this to update your order management system.\ For a successful payment, the event contains `success`: **true**. **Example webhook for a successful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"033899:1111:03/2030", "amount":{ "currency":"EUR", "value":2500 }, "operations":["CANCEL","CAPTURE","REFUND"], "success":"true", "paymentMethod":"mc", "additionalData":{ "expiryDate":"03/2030", "authCode":"033899", "cardBin":"411111", "cardSummary":"1111" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"NC6HT9CRT65ZGN82", "eventDate":"2021-09-13T14:10:22+02:00" } } ] } ``` For an unsuccessful payment, you get `success`: **false**, and the `reason` field has details about why the payment was unsuccessful. **Example webhook for an unsuccessful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"validation 101 Invalid card number", "amount":{ "currency":"EUR", "value":2500 }, "success":"false", "paymentMethod":"unknowncard", "additionalData":{ "expiryDate":"03/2030", "cardBin":"411111", "cardSummary":"1112" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"KHQC5N7G84BLNK43", "eventDate":"2021-09-13T14:14:05+02:00" } } ] } ``` ## Test and go live Before going live, use our list of [test cards and other payment methods](/development-resources/test-cards-and-credentials/test-card-numbers) to [test your integration](/development-resources/testing). Use the [Adyen Android test cards app](/development-resources/test-cards-and-credentials/test-card-numbers#android-test-cards-app) to access, copy, and autofill card details from within your Android device. We recommend testing each payment method that you intend to offer to your shoppers. You can check the status of a test payment in your [Customer Area](https://ca-test.adyen.com/), under **Payments** > **Payment list**. To debug or troubleshoot test payments, you can also use [API logs](/development-resources/logs-resources/api-logs) in your test environment. When you are ready to go live, you need to: 1. [Apply for a live account](/get-started-with-adyen/application-requirements). Review the process to start accepting payments on [Get started with Adyen](/get-started-with-adyen). 2. Assess your [PCI DSS compliance](/development-resources/pci-dss-compliance-guide#online-payments) by submitting the [Self-Assessment Questionnaire-A](https://www.pcisecuritystandards.org/documents/PCI-DSS-v3_2_1-SAQ-A.pdf). 3. [Configure your live account](/online-payments/go-live-checklist).  4. Submit a request to add payment methods in your [live Customer Area](https://ca-live.adyen.com/) . 5. Switch from test to our [live endpoints](/development-resources/live-endpoints#checkout-endpoints). Make sure that all API requests you make for the same payment session use the same live endpoint region. Using different regions for [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) and [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) requests may result in errors, for example, when authenticating with 3D Secure 2. 6. Load from one of our live environments and set the `environment` to match your live endpoints: | Endpoint region | Value | | ------------------------- | ------------------ | | Europe (EU) live | **EUROPE** | | United States (US) live | **UNITED\_STATES** | | Australia (AU) live | **AUSTRALIA** | | Northeast Asia (NEA) live | **NEA** | | India (IN) live | **INDIA** | ## Next steps [required](/online-payments/modify-payments) [Modify payments](/online-payments/modify-payments) [Find out how to cancel, refund, or capture a payment using our API.](/online-payments/modify-payments) [Add payment methods](/payment-methods/add-payment-methods) [Learn about payment methods and how to add them to your account.](/payment-methods/add-payment-methods) [Tokenization](/online-payments/tokenization) [Save shopper payment details for later payments.](/online-payments/tokenization) [3D Secure authentication](/online-payments/3d-secure) [Comply with regulations such as PSD2 SCA in Europe.](/online-payments/3d-secure) ## Android Components Use our customizable UI components ## How it works Our 3D Secure 2 Component handles the 3D Secure 2 device fingerprinting and challenge flows, including the data exchange between your front end and the issuer's Access Control Server (ACS). When adding native 3D Secure 2 authentication to your integration: 1. [Collect the cardholder name in your payment form](#collect-additional-parameters). 2. Provide additional parameters [when making a payment request](#make-a-payment). 3. [Use the Action Component to perform the authentication flow](#use-the-action-component). 4. If the payment was routed to the 3D Secure 2 redirect flow, [handle the redirect](#handle-a-redirect). ### Before You Begin ## Requirements Before you begin to integrate, make sure you have followed the [Get started with Adyen guide](/get-started-with-adyen) to: * Get an overview of the steps needed to accept live payments. * Create your test account. After you have created your test account: * [Get your API key](/development-resources/api-credentials#generate-api-key). * [Get your client key](/development-resources/client-side-authentication#get-your-client-key). * [Set up webhooks](/development-resources/webhooks) to know the payment outcome. ### Install Api Library ## Install an API library Payment server We provide server-side API libraries for several programming languages, available through common package managers, like Gradle and npm, for easier installation and version management. Our API libraries will save you development time, because they: * Use an API version that is up to date. * Have generated models to help you construct requests. * Send the request to Adyen using their built-in HTTP client, so you do not have to create your own. ### Tab: Java ##### Try our example integration ![](/reuse/development-resources/install-api-library/java/advanced/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-java-spring-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/java/advanced/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-java-spring-online-payments). #### Requirements * Java 11 or later. #### Installation You can use [Maven](https://maven.apache.org), adding this dependency to your project's POM. **Add the API library** ```xml com.adyen adyen-java-api-library LATEST_VERSION ``` You can find the latest version on GitHub. Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-java-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```java // Import the required classes. package com.adyen.service; import com.adyen.Client; import com.adyen.service.checkout.PaymentsApi; import com.adyen.model.checkout.Amount; import com.adyen.enums.Environment; import com.adyen.service.exception.ApiException; import java.io.IOException; public class Snippet { public Snippet() throws IOException, ApiException { // Set up the client and service. Client client = new Client("ADYEN_API_KEY", Environment.TEST); } } ``` ### Tab: PHP ##### Try our example integration ![](/reuse/development-resources/install-api-library/php/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-php-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/php/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-php-online-payments). #### Requirements * PHP 7.3 or later. * cURL with SSL support. * The JSON PHP extension. * The list of dependencies from the composer require list. #### Installation You can use [Composer](https://getcomposer.org/). Follow the [installation instructions](https://getcomposer.org/doc/00-intro.md) if you do not already have composer installed. **Install the API library** ```bash composer require adyen/php-api-library ``` In your PHP script, make sure you include the autoloader: **Include the autoloader** ```php require __DIR__ . '/vendor/autoload.php'; ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-php-api-library/releases). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```php use Adyen\Model\Checkout\Amount; use Adyen\Model\Checkout\CreateCheckoutSessionRequest; use Adyen\Service\Checkout\PaymentsApi; // Include your idempotency key when you make an API request. $requestOptions['idempotencyKey'] = "YOUR_IDEMPOTENCY_KEY"; // Set up the client and service. $client = new \Adyen\Client(); $client->setXApiKey('ADYEN_API_KEY'); $client->setEnvironment(\Adyen\Environment::TEST); $service = new PaymentsApi($client); ``` ### Tab: C\# #### Requirements * .NET standard 2.0 or later. * For Terminal API certificate validation, set the application to either of the following: * .NET core 2.1 or later * .NET framework 4.6.1 or later #### Installation You can use [NuGet](https://www.nuget.org/packages/Adyen/): **Install the API library** ```bash PM> Install-Package Adyen -Version LATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-dotnet-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```cs using Adyen; using Adyen.Model.Checkout; using Adyen.Service.Checkout; using Environment = Adyen.Model.Environment; class Program { static void Main() { // Set up the client and service. var config = new Config { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); var checkout = new PaymentsService(client); // Include your idempotency key when you make an API request. var requestOptions = new Adyen.Model.RequestOptions { IdempotencyKey = "YOUR_IDEMPOTENCY_KEY" }; } } ``` ### Tab: NodeJS ##### Try our example integration ![](/reuse/development-resources/install-api-library/node-js/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-node-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/node-js/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-node-online-payments). #### Requirements * Node.js version 18 or later. #### Installation You can use [npm](https://www.npmjs.com/): **Install the API library** ```bash npm install --save @adyen/api-library npm update @adyen/api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-node-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```js // Require the parts of the module you want to use. const { Client, CheckoutAPI, Types} = require("@adyen/api-library"); // Set up the client and service. const client = new Client({ apiKey: "ADYEN_API_KEY", environment: "TEST" }); const checkoutApi = new CheckoutAPI(client); // Include your idempotency key when you make an API request. const requestOptions = { idempotencyKey: "YOUR_IDEMPOTENCY_KEY" }; ``` ### Tab: Go ##### Try our example integration ![](/reuse/development-resources/install-api-library/go/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-golang-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/go/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-golang-online-payments). #### Requirements * Go 1.13 or later. #### Installation You can use [Go modules](https://github.com/golang/go/wiki/Modules): **Install the API library** ```shell go get github.com/adyen/adyen-go-api-library/vLATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-go-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```go package main import ( "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/adyen" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/checkout" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/common" ) // Create a payment object. func main () { client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) service := client.Checkout() ``` ### Tab: Python ##### Try our example integration ![](/reuse/development-resources/install-api-library/python/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-python-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/python/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-python-online-payments). #### Requirements * Python 3.6 or later. * (Optional) Packages: Requests or PycURL #### Installation You can use [pip](https://pip.pypa.io/en/stable/): **Install the API library** ```py pip install Adyen ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-python-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```py import Adyen # Set up the client and service. adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment that the library is used in. ``` ### Tab: Ruby ##### Try our example integration ![](/reuse/development-resources/install-api-library/ruby/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-rails-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/ruby/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-rails-online-payments). #### Requirements * Ruby 2.7 or later. #### Installation You can use [RubyGems](https://rubygems.org/): **Install the API library** ```bash gem install adyen-ruby-api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-ruby-api-library/releases). Run `bundle install` to install dependencies. #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```ruby require 'adyen-ruby-api-library' # Set up the client and service. adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # The environment that the library is used in. ``` ### Get Payment Methods ## Get available payment methods Payment server When the shopper is ready to pay, get a list of the available payment methods based on their country, device, and the payment amount. From your server, make a POST [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) request, including: We recommend that you include all the optional parameters to get the most accurate list of available payment methods. | Parameter name | Required | Description | | ----------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | | The `currency` and `value` of the payment, in [minor units](/development-resources/currency-codes). | | `channel` | | Use **Android**. Adyen returns only the payment methods available for Android. | | `countryCode` | | The shopper's country/region. Adyen returns only the payment methods available in this country. Format: the two-letter [ISO-3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. Exception: **QZ** (Kosovo). | | `shopperLocale` | | By default, the `shopperlocale` is set to **en-US**. To change the language, set this to the shopper's language and country code. You also need to set the same `ShopperLocale` within your Checkout configuration. | For example, to get available payment methods for a shopper in the Netherlands, for a payment of **10** EUR: #### curl ```bash curl https://checkout-test.adyen.com/v72/paymentMethods \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Android", "shopperLocale": "nl-NL" }' ``` #### Java ```java // Adyen Java API Library v27.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the live environment, additionally include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) Amount amount = new Amount() .currency("EUR") .value(1000L); PaymentMethodsRequest paymentMethodsRequest = new PaymentMethodsRequest() .amount(amount) .merchantAccount("ADYEN_MERCHANT_ACCOUNT") .countryCode("NL") .channel(PaymentMethodsRequest.ChannelEnum.IOS) .shopperLocale("nl-NL"); // Send the request PaymentsApi service = new PaymentsApi(client); PaymentMethodsResponse response = service.paymentMethods(paymentMethodsRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("ADYEN_API_KEY"); // For the LIVE environment, also include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->paymentMethods($paymentMethodsRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v32.1.1 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the LIVE environment, also include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) // Send the request var service = new PaymentsService(client); var response = service.PaymentMethods(paymentMethodsRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v29.0.0 const { Client, CheckoutAPI } = require('@adyen/api-library'); // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const paymentMethodsRequest = { merchantAccount: "ADYEN_MERCHANT_ACCOUNT", countryCode: "NL", amount: { currency: "EUR", value: 1000 }, channel: "Android", shopperLocale: "nl-NL" } // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentMethods(paymentMethodsRequest, { idempotencyKey: "UUID" }); ``` #### Go ```go // Adyen Go API Library v10.4.0 import ( "context" "github.com/adyen/adyen-go-api-library/v9/src/common" "github.com/adyen/adyen-go-api-library/v9/src/adyen" "github.com/adyen/adyen-go-api-library/v9/src/checkout" ) // For the live environment, additionally include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) amount := checkout.Amount{ Currency: "EUR", Value: 1000, } paymentMethodsRequest := checkout.PaymentMethodsRequest{ Amount: &amount, MerchantAccount: "ADYEN_MERCHANT_ACCOUNT", CountryCode: common.PtrString("NL"), Channel: common.PtrString("iOS"), ShopperLocale: common.PtrString("nl-NL"), } // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentMethodsInput().IdempotencyKey("UUID").PaymentMethodsRequest(paymentMethodsRequest) res, httpRes, err := service.PaymentsApi.PaymentMethods(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.6.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Android", "shopperLocale": "nl-NL" } # Send the request result = adyen.checkout.payments_api.payment_methods(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v10.4.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT', :countryCode => 'NL', :amount => { :currency => 'EUR', :value => 1000 }, :channel => 'Android', :shopperLocale => 'nl-NL' } # Send the request result = adyen.checkout.payments_api.payment_methods(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v29.0.0 import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentMethods(paymentMethodsRequest, { idempotencyKey: "UUID" }); ``` The response includes the list of available `paymentMethods`: **/paymentMethods response** ```json { "paymentMethods":[ { "details":[...], "name":"Cards", "type":"scheme" ... }, { "details":[...], "name":"SEPA Direct Debit", "type":"sepadirectdebit" }, ... ] } ``` You must pass the response to your client app to [launch and show Components](#launch-and-show-components). ### Configure Drop In ## Set up Components Client app ### 1: Import the library The default implementation is with Jetpack Compose, but you can import the library without Jetpack Compose instead. Import the compatibility module in your `build.gradle` file. For example, to import the Card Component: ### Tab: With Jetpack Compose **Import the module with Compose** ```groovy implementation "com.adyen.checkout:card:YOUR_VERSION" implementation "com.adyen.checkout:components-compose:YOUR_VERSION" ``` ### Tab: Without Jetpack Compose **Import the module without Compose** ```groovy implementation "com.adyen.checkout:card:YOUR_VERSION" ``` You can find the module to import for each payment method on the corresponding [payment method](/payment-methods/) page. ### Create Configuration Object ### 2: Create the configuration object 1. Set the following properties in the configuration object: | Property | Required | Description | | --------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | | `amount` | If you want to show the amount on the **Pay** button. | The currency and value of the payment amount shown on the **Pay** button. | | `environment` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Use `Environment.TEST` for testing. When going live, use one of our live environments. | | `clientKey` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your client key. | | `shopperLocale` | | The shopper's locale. By default, this is the device's locale. | 2. Include other configurations for the Component. For example, to configure the card Component: **Configure the card Component** ```kotlin // Create the amount object. val amount = Amount( currency = "EUR", value = 1000, ) // Create a configuration object val checkoutConfiguration = CheckoutConfiguration( environment = environment, clientKey = clientKey, shopperLocale = shopperLocale, // optional amount = amount, // optional ) { // Optional: configuration for the card payment method. card { setHolderNameRequired(true) setShopperReference("...") } } ``` 3. Implement methods in `ComponentCallback` to pass data between your client app and your server. | Method | Description | | --------------------- | -------------------------------------------------------------------------------------------------------------- | | `onSubmit` | Make a [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request. | | `onAdditionalDetails` | Make a [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request. | | `onError` | Handle an error if the Component encounters one. | For example, for the card Component: **Implement methods for the card Component** ```kotlin // Handler to make a /payments request. override fun onSubmit(state: CardComponentState) { val paymentComponentJson = PaymentComponentData.SERIALIZER.serialize(state.data) // Your server makes /payments request, including paymentComponentJson. // This is used in Step 4: Make a payment. // If additional action is required, handle the action. val action = Action.SERIALIZER.deserialize(actionJSONObject) cardComponent.handleAction(action, activity) } // Handler to make a /payments/details request to send additional payment details. override fun onAdditionalDetails(actionComponentData: ActionComponentData) { val actionComponentJson = ActionComponentData.SERIALIZER.serialize(actionComponentData) // Your server makes a /payments/details request, including actionComponentJson. // This is used in Step 5: Submit additional payment details. } // The Component encounters an error. override fun onError(componentError: ComponentError) { // Handle the error. } ``` ### Launch And Show Drop In ### Launch and show the Component Client app ### Tab: With Jetpack Compose 1. Deserialize the [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) response to a `PaymentMethodsApiResponse` object: **Serialize the API response** ```kotlin val paymentMethodsApiResponse = PaymentMethodsApiResponse.SERIALIZER.deserialize(paymentMethodsResponseJSON) ``` 2. Create the Component and attach it to a view. For example: **Create the Component** ```kotlin import com.adyen.checkout.components.compose.get // Create the payment method object from the /paymentMethods response. val paymentMethod = paymentMethodsApiResponse?.paymentMethods.orEmpty().firstOrNull { it.type == PaymentMethodTypes.SCHEME } @Composable private fun ComposableCardComponent() { // Keep a reference to this Component in case you need to access it later. val cardComponent = CardComponent.PROVIDER.get( paymentMethod = paymentMethod, configuration = checkoutConfiguration, componentCallback = callback, // This key is required to ensure a new Component gets created for each different screen or payment session. // Generate a new value for this key every time you need to reset the Component. key = "UNIQUE_KEY_PER_COMPONENT", ) // This is your composable, a wrapper around our xml view. AdyenComponent( component = cardComponent, modifier = YOUR_MODIFIER, ) } ``` ### Tab: Without Jetpack Compose 1. Add `AdyenComponentView` to your layout `.xml` file. For example: **Add AdyenComponentView** ```xml ``` 2. Deserialize the [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) response to a `PaymentMethodsApiResponse` object: **Serialize the API response** ```kotlin val paymentMethodsApiResponse = PaymentMethodsApiResponse.SERIALIZER.deserialize(paymentMethodsResponseJSON) ``` 3. Launch the Component by calling `PROVIDER.get` from your Component class, passing: | Parameter | Description | | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | `activity` or `fragment` (Example) | Your `Activity` or `Fragment`. | | `paymentMethod` | The payment method from your [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) response. | | `checkoutConfiguration` | The checkout configuration that you created. | | `componentCallback` | The callback for the functions you implemented. | **Create the Component** ```kotlin // Create the payment method object from the /paymentMethods response. val paymentMethod = paymentMethodsApiResponse?.paymentMethods.orEmpty().firstOrNull { it.type == PaymentMethodTypes.SCHEME } val cardComponent = CardComponent.PROVIDER.get( activity, // Your activity or fragment. paymentMethod, checkoutConfiguration, componentCallback, ) ``` 4. Attach your Component to your `Activity` or `Fragment`. For example to attach your Component to your view with the identifier `cardView`: **Attach your Component to your view** ```kotlin binding.cardView.attach(cardComponent, activity) // Your activity or fragment. ``` Your app shows the Component. ## Make a payment Payment server When the shopper enters their payment details and selects the **Pay** button, the `onSubmit` method in your `ComponentCallback` class is called, passing the `paymentComponentJson` object. 1. Pass the `paymentComponentJson` object to your server. 2. From your server, make a **POST** [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request including the following | Parameter name | Required | Description | | ------------------------------------------------------ | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The `currency` and `value` of the payment, in [minor units](/development-resources/currency-codes). | | `reference` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your unique reference for this payment. | | `paymentMethod` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The complete `paymentComponentData.paymentMethod` object from your client app that includes the payment method details and other required information. | | `paymentMethod.sdkData` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The object that includes information collected by the Component to track the user's payment journey, including information like the [checkout attempt identifier](/online-payments/analytics-and-data-tracking#data-we-are-collecting). This is required to use the [Checkout dashboard](/uplift#uplift-dashboards) that lets you analyze your checkout performance. | | `returnUrl` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | In case of a redirection, this is the URL to where your shopper is redirected after they complete the payment. Maximum length: 1024 characters. Get this URL from the `RedirectComponent.getReturnUrl(context)`. | | [`applicationInfo`](/partners/application-information) | | If you are building an Adyen solution for multiple merchants, include some [basic identifying information](/partners/application-information), so that we can offer you better support. | For the following cases, you must include additional parameters in your request: * Integrating some payment methods. For more information, refer to our [payment method integration guides](/payment-methods). * Using our risk management features. For more information, see [Required risk fields](/risk-management/configure-manual-risk/required-risk-field-reference). * [Native 3D Secure 2 authentication](/online-payments/3d-secure/native-3ds2/android-drop-in#make-a-payment). * [Creating a token](/online-payments/tokenization/create-tokens) to store the shopper's payment details. * [Using a token](/online-payments/tokenization/make-token-payments) to make a recurring payment with stored payment details. 3. **Example request to make a payment for EUR 10** #### curl ```bash curl https://checkout-test.adyen.com/v72/payments \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "amount":{ "currency":"EUR", "value":1000 }, "reference":"YOUR_ORDER_NUMBER", "paymentMethod":{hint:paymentMethod field of an object passed from your client app}STATE_DATA{/hint}, "returnUrl":"adyencheckout://your.package.name", "merchantAccount":"ADYEN_MERCHANT_ACCOUNT" }' ``` #### Java ```java // Adyen Java API Library v39.3.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the LIVE environment, also include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) Amount amount = new Amount() .currency("EUR") .value(1000L); PaymentRequest paymentRequest = new PaymentRequest() .reference("YOUR_ORDER_NUMBER") .amount(amount) .merchantAccount("ADYEN_MERCHANT_ACCOUNT") .returnUrl("adyencheckout://your.package.name"); // Send the request PaymentsApi service = new PaymentsApi(client); PaymentResponse response = service.payments(paymentRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("ADYEN_API_KEY"); // For the LIVE environment, also include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $amount = new Amount(); $amount ->setCurrency("EUR") ->setValue(1000); $paymentRequest = new PaymentRequest(); $paymentRequest ->setReference("YOUR_ORDER_NUMBER") ->setAmount($amount) ->setMerchantAccount("ADYEN_MERCHANT_ACCOUNT") ->setReturnUrl("adyencheckout://your.package.name"); $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->payments($paymentRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v32.1.1 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the LIVE environment, also include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) Amount amount = new Amount { Currency = "EUR", Value = 1000 }; PaymentRequest paymentRequest = new PaymentRequest { Reference = "YOUR_ORDER_NUMBER", Amount = amount, MerchantAccount = "ADYEN_MERCHANT_ACCOUNT", ReturnUrl = "adyencheckout://your.package.name" }; // Send the request var service = new PaymentsService(client); var response = service.Payments(paymentRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v29.0.0 const { Client, CheckoutAPI } = require('@adyen/api-library'); // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const paymentRequest = { amount: { currency: "EUR", value: 1000 }, reference: "YOUR_ORDER_NUMBER", paymentMethod: "STATE_DATA", returnUrl: "adyencheckout://your.package.name", merchantAccount: "ADYEN_MERCHANT_ACCOUNT" } // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.payments(paymentRequest, { idempotencyKey: "UUID" }); ``` #### Go ```go // Adyen Go API Library v21.0.0 import ( "context" "github.com/adyen/adyen-go-api-library/v21/src/common" "github.com/adyen/adyen-go-api-library/v21/src/adyen" "github.com/adyen/adyen-go-api-library/v21/src/checkout" ) // For the LIVE environment, also include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) amount := checkout.Amount{ Currency: "EUR", Value: 1000, } paymentRequest := checkout.PaymentRequest{ Reference: "YOUR_ORDER_NUMBER", Amount: amount, MerchantAccount: "ADYEN_MERCHANT_ACCOUNT", ReturnUrl: "adyencheckout://your.package.name", } // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentsInput().IdempotencyKey("UUID").PaymentRequest(paymentRequest) res, httpRes, err := service.PaymentsApi.Payments(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.6.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "amount": { "currency": "EUR", "value": 1000 }, "reference": "YOUR_ORDER_NUMBER", "paymentMethod": "STATE_DATA", "returnUrl": "adyencheckout://your.package.name", "merchantAccount": "ADYEN_MERCHANT_ACCOUNT" } # Send the request result = adyen.checkout.payments_api.payments(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v10.4.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :amount => { :currency => 'EUR', :value => 1000 }, :reference => 'YOUR_ORDER_NUMBER', :paymentMethod => 'STATE_DATA', :returnUrl => 'adyencheckout://your.package.name', :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT' } # Send the request result = adyen.checkout.payments_api.payments(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v29.0.0 import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const amount: Types.checkout.Amount = { currency: "EUR", value: 1000 }; const paymentRequest: Types.checkout.PaymentRequest = { reference: "YOUR_ORDER_NUMBER", amount: amount, merchantAccount: "ADYEN_MERCHANT_ACCOUNT", returnUrl: "adyencheckout://your.package.name" }; // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.payments(paymentRequest, { idempotencyKey: "UUID" }); ``` Your next step depends on if the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response contains an `action` object: * If the response has no `action` object, [get the payment outcome](#get-the-payment-outcome). * If the response contains an `action` object, [handle the additional action](#additional-action). **Example response containing an action object for 3D Secure 2 authentication** ```json { "resultCode" : "IdentifyShopper", "action" : { "token" : "eyJkaXJl...", "paymentMethodType" : "scheme", "paymentData" : "Ab02b4c0...", "type" : "threeDS2", "authorisationToken" : "BQABAQ...", "subtype" : "fingerprint" } } ``` ### Error handling If the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request fails, show the error to the shopper in your client UI. ### Handle Additional Action ## Handle the additional action Client app Some payment methods require additional action from the shopper. Common examples of additional actions include: * Logging in to a bank's website or app. * Authenticating a payment with 3D Secure 2. * Scanning a QR code. Implement logic to handle all action types, so that your integration can handle different payment methods. To see if an individual payment method requires an additional action, see the corresponding [payment method guide](/payment-methods) for it. When you get the `action` object in the response, do the following: 1. Pass the full `action` object from your server to the Component. 2. Use `ActionResponse.SERIALIZER` to serialize the `action` object. 3. Return the serialized object to The Component. 4. The Component handles the additional action on the client side. 5. You handle the payment data, depending on the type of action (`action.type`). | Type | `action.type` value | | ----------------------------------------------------------------------- | ------------------- | | [Redirect action](#handle-the-redirect) | **redirect** | | [3D Secure 2 authentication action](#3d-secure-2-authentication-action) | **threeDS2** | | [QR code action](#qr-code-action) | **qrCode** | | [SDK action](#sdk-action) | **sdk** | | [Voucher action](#voucher-action) | **voucher** | | [Await action](#await-action) | **await** | ### Redirect action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **redirect**, the Component redirects your shopper to another website or app to complete the payment. 1. Add an `IntentFilter` to your `Activity` that handles redirects. **Add handling for redirects** ```xml ``` The `android:host` value is your package name at build time. This must match the `returnUrl` from the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request.\ To get your `returnUrl` from the Component, you can use the `RedirectComponent.getReturnUrl(context)` function. 2. Pass the full `action` object from your server to the Component. 3. The Component redirects the shopper to another website or app. 4. The shopper returns to your app. 5. From your `Activity`, get the result of the redirect. 6. Pass the `Intent` to the the Component. Depending on your activity's launch mode, you get the intent in either `onCreate` or `onNewIntent`. **Handle the intent** ```java private fun handleIntent(intent: Intent?) { if (intent.data?.toString().orEmpty().startsWith(RedirectComponent.REDIRECT_RESULT_SCHEME)) { cardComponent?.handleIntent(intent) } } ``` 7. The Component notifies you through the `ComponentCallback.onAdditionalDetails` method with the `actionComponentData` object from `intent.data`. 8. Pass the `actionComponentData` object from your client app to your server. 9. [Send additional payment details](#send-additional-payment-details). If the shopper fails to return to your app, you do not get the additional data to send. Instead, wait for the corresponding [webhook](#update-your-order-management-system) for the outcome of the payment. ### 3D Secure 2 authentication action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **threeDS2**, the payment qualifies for 3D Secure 2 and it goes through the [frictionless or the challenge flow](/online-payments/3d-secure/#authentication-flows). 1. The Component handles 3D Secure 2 authentication. If a challenge is required, the shopper performs the authentication challenge to complete the payment. 2. The Component calls the `onAdditionalDetails` method in your `ComponentCallback` class. 3. From `onAdditionalDetails`, get the `actionComponentJson` object. 4. Pass the `actionComponentJson` object from your client app to your server. 5. [Send additional payment details](#send-additional-payment-details). ### QR code action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **qrCode**, the shopper must use a QR code to complete the payment. 1. The Component shows the QR code to the shopper. 2. When the shopper uses the QR code to complete the payment, the Component calls the `onAdditionalDetails` method in your `ComponentCallback` class. 3. From `onAdditionalDetails`, get the `actionComponentJson` object. 4. Pass the `actionComponentJson` object from your client app to your server. 5. [Send additional payment details](#send-additional-payment-details). ### SDK action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **sdk**, the shopper must use another UI overlay to complete the payment. For example, a payment method requires the shopper to use its specific UI to enter payment details. 1. The Component shows a different UI in an overlay. 2. The shopper uses the UI overlay to complete the payment. 3. The Component calls the `onAdditionalDetails` method in your `ComponentCallback` class. 4. From `onAdditionalDetails`, get the `actionComponentJson` object. 5. Pass the `actionComponentJson` object from your client app to your server. 6. [Send additional payment details](#send-additional-payment-details). ### Voucher action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **voucher**, the shopper must use a voucher to complete the payment. 1. The Component shows the voucher to the shopper. 2. When the shopper completes the additional action with the voucher (for example: saving it to their digital wallet or forwarding it to their email), The Component calls the `onAdditionalDetails` method in your `ComponentCallback` class. 3. From `onAdditionalDetails`, get the `actionComponentJson` object. 4. Pass the `actionComponentJson` object from your client app to your server. 5. [Send additional payment details](#send-additional-payment-details). ### Await action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **await**, the shopper must take an additional action to complete the payment. For example: entering a code into their banking app. 1. The Component shows the instructions for the additional action to complete the payment. 2. The shopper does the additional action. 3. The Component calls the `onAdditionalDetails` method in your `ComponentCallback` class. 4. From `onAdditionalDetails`, get the `actionComponentJson` object. 5. Pass the `actionComponentJson` object from your client app to your server. 6. [Send additional payment details](#send-additional-payment-details). ### Send Additional Details ## Send additional payment details Payment server If you [handled an additional action](#additional-action), you must send additional payment details to Adyen. 1. Pass the full `actionComponentJson` object to your server. 2. From your server, make a **POST** [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request including the full data from the `actionComponentJson` object. #### curl ```bash curl https://checkout-test.adyen.com/v72/payments/details \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{hint:object passed from your client app}STATE_DATA{/hint}' ``` #### Java ```java // Set your X-API-KEY with the API key from the Customer Area. String xApiKey = "ADYEN_API_KEY"; Client client = new Client(xApiKey,Environment.TEST); Checkout checkout = new Checkout(client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. PaymentsDetailsRequest paymentsDetailsRequest = STATE_DATA; PaymentsResponse paymentsDetailsResponse = checkout.paymentsDetails(paymentsDetailsRequest); ``` #### PHP ```php // Set your X-API-KEY with the API key from the Customer Area. $client = new \Adyen\Client(); $client->setEnvironment(\Adyen\Environment::TEST); $client->setXApiKey("ADYEN_API_KEY"); $service = new \Adyen\Service\Checkout($client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. $params = STATE_DATA; $result = $service->paymentsDetails($params); // Check if further action is needed. if (array_key_exists("action", $result)){ // Pass the action object to your client. // $result["action"] } else { // No further action needed, pass the resultCode to your client. // $result['resultCode'] } ``` #### C\# ```cs // Set your X-API-KEY with the API key from the Customer Area. string apiKey = "ADYEN_API_KEY"; var client = new Client (apiKey, Environment.Test); var checkout = new Checkout(client); // STATE_DATA is an object passed from the client app, deserialized from JSON to a data structure. var paymentsDetailsRequest = STATE_DATA; var paymentsDetailsResponse = checkout.PaymentDetails(paymentsDetailsRequest); ``` #### NodeJS (JavaScript) ```js const {Client, Config, CheckoutAPI} = require('@adyen/api-library'); const config = new Config(); // Set your X-API-KEY with the API key from the Customer Area. config.apiKey = '[ADYEN_API_KEY]'; const client = new Client({ config }); client.setEnvironment("TEST"); const checkout = new CheckoutAPI(client); // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. checkout.paymentsDetails(STATE_DATA).then(res => res); ``` #### Go ```go import ( "github.com/adyen/adyen-go-api-library/v5/src/checkout" "github.com/adyen/adyen-go-api-library/v5/src/common" "github.com/adyen/adyen-go-api-library/v5/src/adyen" ) // Set your X-API-KEY with the API key from the Customer Area. client := adyen.NewClient(&common.Config{ Environment: common.TestEnv, ApiKey: "[ADYEN_API_KEY]", }) // STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. req := STATE_DATA; res, httpRes, err := client.Checkout.PaymentsDetails(&req) ``` #### Python ```py # Set your X-API-KEY with the API key from the Customer Area. adyen = Adyen.Adyen() adyen.payment.client.platform = "test" adyen.client.xapikey = 'ADYEN_API_KEY' # STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. request = STATE_DATA result = adyen.checkout.payments_details(request) # Check if further action is needed. if 'action' in result.message: # Pass the action object to your client. # result.message['action'] else: # No further action needed, pass the resultCode to your client. # result.message['resultCode'] ``` #### Ruby ```ruby require 'adyen-ruby-api-library' # Set your X-API-KEY with the API key from the Customer Area. adyen = Adyen::Client.new adyen.env = :test adyen.api_key = "ADYEN_API_KEY" # STATE_DATA is an object passed from your client app, deserialized from JSON to a data structure. request = STATE_DATA response = adyen.checkout.payments.details(request) # Check if further action is needed. if response.body.has_key(:action) # Pass the action object to your client puts response.body[:action] else # No further action needed, pass the resultCode to your client puts response.body[:resultCode] end ``` 3. Pass the [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) response from your server to your client app. **Example response for a successful payment** ```json { "pspReference": "NC6HT9CRT65ZGN82", "resultCode": "Authorised" } ``` **Example response for a refused payment** ```json { "pspReference": "KHQC5N7G84BLNK43", "refusalReason": "Not enough balance", "resultCode": "Refused" } ``` ### Get Payment Outcome ## Get the payment outcome After the Component finishes the payment flow, you can show the shopper the current payment status. Adyen sends a webhook with the outcome of the payment. ### Inform the shopper Client app Use the [`resultCode` ](/online-payments/payment-result-codes#final-payment-status)to show the shopper the [current payment status](/account/payments-lifecycle). This synchronous response doesn't give you the final outcome of the payment. You get the final payment status in a webhook that you use to [update your order management system](#update-your-order-management-system). ### Update your order management system Webhook server You get the outcome of each payment asynchronously, in an **AUTHORISATION** [webhook](/development-resources/webhooks). Use the `merchantReference` from the webhook to match it to your order reference.\ For a successful payment, the event contains `success`: **true**. **Example webhook for a successful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"033899:1111:03/2030", "amount":{ "currency":"EUR", "value":2500 }, "operations":["CANCEL","CAPTURE","REFUND"], "success":"true", "paymentMethod":"mc", "additionalData":{ "expiryDate":"03/2030", "authCode":"033899", "cardBin":"411111", "cardSummary":"1111" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"NC6HT9CRT65ZGN82", "eventDate":"2021-09-13T14:10:22+02:00" } } ] } ``` For an unsuccessful payment, you get `success`: **false**, and the `reason` field has details about why the payment was unsuccessful. **Example webhook for an unsuccessful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"validation 101 Invalid card number", "amount":{ "currency":"EUR", "value":2500 }, "success":"false", "paymentMethod":"unknowncard", "additionalData":{ "expiryDate":"03/2030", "cardBin":"411111", "cardSummary":"1112" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"KHQC5N7G84BLNK43", "eventDate":"2021-09-13T14:14:05+02:00" } } ] } ``` ## Test and go live Before going live, use our list of [test cards and other payment methods](/development-resources/test-cards-and-credentials/test-card-numbers) to [test your integration](/development-resources/testing). Use the [Adyen Android test cards app](/development-resources/test-cards-and-credentials/test-card-numbers#android-test-cards-app) to access, copy, and autofill card details from within your Android device. We recommend testing each payment method that you intend to offer to your shoppers. You can check the status of a test payment in your [Customer Area](https://ca-test.adyen.com/), under **Payments** > **Payment list**. To debug or troubleshoot test payments, you can also use [API logs](/development-resources/logs-resources/api-logs) in your test environment. When you are ready to go live, you need to: 1. [Apply for a live account](/get-started-with-adyen/application-requirements). Review the process to start accepting payments on [Get started with Adyen](/get-started-with-adyen). 2. Assess your [PCI DSS compliance](/development-resources/pci-dss-compliance-guide#online-payments) by submitting the [Self-Assessment Questionnaire-A](https://www.pcisecuritystandards.org/documents/PCI-DSS-v3_2_1-SAQ-A.pdf). 3. [Configure your live account](/online-payments/go-live-checklist).  4. Submit a request to add payment methods in your [live Customer Area](https://ca-live.adyen.com/) . 5. Switch from test to our [live endpoints](/development-resources/live-endpoints#checkout-endpoints). Make sure that all API requests you make for the same payment session use the same live endpoint region. Using different regions for [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) and [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) requests may result in errors, for example, when authenticating with 3D Secure 2. 6. Load from one of our live environments and set the `environment` to match your live endpoints: | Endpoint region | Value | | ------------------------- | ------------------ | | Europe (EU) live | **EUROPE** | | United States (US) live | **UNITED\_STATES** | | Australia (AU) live | **AUSTRALIA** | | Northeast Asia (NEA) live | **NEA** | | India (IN) live | **INDIA** | ## Next steps [required](/online-payments/modify-payments) [Modify payments](/online-payments/modify-payments) [Find out how to cancel, refund, or capture a payment using our API.](/online-payments/modify-payments) [Add payment methods](/payment-methods/add-payment-methods) [Learn about payment methods and how to add them to your account.](/payment-methods/add-payment-methods) [Tokenization](/online-payments/tokenization) [Save shopper payment details for later payments.](/online-payments/tokenization) [3D Secure authentication](/online-payments/3d-secure) [Comply with regulations such as PSD2 SCA in Europe.](/online-payments/3d-secure) ## Android API only Use Adyen APIs and your own UI ### Intro With an API-only integration, you create your own UI, implement your own client-side logic, and use our API to send and receive payment data. You have full control over the look and feel of your checkout page. To reduce your development time and resources, you can use one of our pre-built UI options (Drop-in/Components) instead. ### Before You Begin ## Requirements Before you build your integration, take into account the following requirements and preparations. | Requirement | Description | | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **[API credential roles](/development-resources/api-credentials/roles/)** | Make sure that you have the following role:- **Checkout webservice role** | | **[Customer Area roles](/account/user-roles)** | Make sure that you have one of the following roles:- **Merchant admin role** - **Manage API credentials** | | **[Webhooks](/development-resources/webhooks)** | Subscribe to the following webhook:- **Standard webhooks** | | **Limitations** | * Your [PCI compliance assesment](/development-resources/pci-dss-compliance-guide?tab=api_only_3_4#online-payments) determines your [integration options for card payments](#collect-card-details). * For 3D Secure 2 authentication for shoppers using Chrome, your [cookies must use the `SameSite` attribute](https://developers.google.com/search/blog/2020/01/get-ready-for-new-samesitenone-secure). | | **Setup steps** | Before you begin:* [Create your Adyen test account](/get-started-with-adyen#test-account) * [Get your API key](/development-resources/api-credentials#generate-api-key). * [Get your client key](/development-resources/client-side-authentication#get-your-client-key). * [Set up webhooks](/development-resources/webhooks). * If you want to process payments using raw card data, contact your Adyen Account Manager to confirm that you are eligible. | ## How it works For an API-only integration, you must implement the following parts: * **Your payment server**: sends the API requests to get available payment methods, make a payment, and send additional payment details. * **Your client**: shows your custom UI where the shopper makes the payment. Passes data to and receives data from your payment server to handle the payment flow and additional actions on your client. * **Your webhook server**: receives webhooks that include the outcome of each payment. ## Integration steps The parts of your integration work together to handle the payment flow: 1. From your server, make an API request to [get a list of payment methods available to the shopper](#get-available-payment-methods). 2. Show the [payment form to collect the shopper's payment details](#collect-shopper-details) in your UI. 3. From your server, [make a payment request](#make-a-payment) with the data that you have collected from the shopper. 4. For some payment methods, you use your client to [handle the additional action](#additional-action) that your shopper must do. For example, you redirect your shopper to another website or show a QR code that the shopper uses to complete the payment. 5. From your server, [send additional payment details](#send-additional-payment-details). 6. [Get the payment outcome](#get-the-payment-outcome). If you are integrating these parts separately, you can start at the corresponding part of this integration guide: [![](/user/pages/reuse/online-payments/how-it-works-parts/servers.svg?decoding=auto\&fetchpriority=auto)](/#install-api-library) [Payment server](/#install-api-library) [Go to the integration steps for your server.](/#install-api-library) [![](/user/pages/reuse/online-payments/how-it-works-parts/browser-developers.svg?decoding=auto\&fetchpriority=auto)](/#collect-shopper-details) [Client website or app](/#collect-shopper-details) [Go to the integration steps for your client.](/#collect-shopper-details) [![](/user/pages/reuse/online-payments/how-it-works-parts/event-code.svg?decoding=auto\&fetchpriority=auto)](/#update-your-order-management-system) [Webhook server](/#update-your-order-management-system) [Go to the integration steps for your webhook server.](/#update-your-order-management-system) ### Install Api Library ## Install an API library Payment server We provide server-side API libraries for several programming languages, available through common package managers, like Gradle and npm, for easier installation and version management. Our API libraries will save you development time, because they: * Use an API version that is up to date. * Have generated models to help you construct requests. * Send the request to Adyen using their built-in HTTP client, so you do not have to create your own. ### Tab: Java ##### Try our example integration ![](/reuse/development-resources/install-api-library/java/advanced/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-java-spring-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/java/advanced/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-java-spring-online-payments). #### Requirements * Java 11 or later. #### Installation You can use [Maven](https://maven.apache.org), adding this dependency to your project's POM. **Add the API library** ```xml com.adyen adyen-java-api-library LATEST_VERSION ``` You can find the latest version on GitHub. Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-java-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```java // Import the required classes. package com.adyen.service; import com.adyen.Client; import com.adyen.service.checkout.PaymentsApi; import com.adyen.model.checkout.Amount; import com.adyen.enums.Environment; import com.adyen.service.exception.ApiException; import java.io.IOException; public class Snippet { public Snippet() throws IOException, ApiException { // Set up the client and service. Client client = new Client("ADYEN_API_KEY", Environment.TEST); } } ``` ### Tab: PHP ##### Try our example integration ![](/reuse/development-resources/install-api-library/php/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-php-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/php/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-php-online-payments). #### Requirements * PHP 7.3 or later. * cURL with SSL support. * The JSON PHP extension. * The list of dependencies from the composer require list. #### Installation You can use [Composer](https://getcomposer.org/). Follow the [installation instructions](https://getcomposer.org/doc/00-intro.md) if you do not already have composer installed. **Install the API library** ```bash composer require adyen/php-api-library ``` In your PHP script, make sure you include the autoloader: **Include the autoloader** ```php require __DIR__ . '/vendor/autoload.php'; ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-php-api-library/releases). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```php use Adyen\Model\Checkout\Amount; use Adyen\Model\Checkout\CreateCheckoutSessionRequest; use Adyen\Service\Checkout\PaymentsApi; // Include your idempotency key when you make an API request. $requestOptions['idempotencyKey'] = "YOUR_IDEMPOTENCY_KEY"; // Set up the client and service. $client = new \Adyen\Client(); $client->setXApiKey('ADYEN_API_KEY'); $client->setEnvironment(\Adyen\Environment::TEST); $service = new PaymentsApi($client); ``` ### Tab: C\# #### Requirements * .NET standard 2.0 or later. * For Terminal API certificate validation, set the application to either of the following: * .NET core 2.1 or later * .NET framework 4.6.1 or later #### Installation You can use [NuGet](https://www.nuget.org/packages/Adyen/): **Install the API library** ```bash PM> Install-Package Adyen -Version LATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-dotnet-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```cs using Adyen; using Adyen.Model.Checkout; using Adyen.Service.Checkout; using Environment = Adyen.Model.Environment; class Program { static void Main() { // Set up the client and service. var config = new Config { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); var checkout = new PaymentsService(client); // Include your idempotency key when you make an API request. var requestOptions = new Adyen.Model.RequestOptions { IdempotencyKey = "YOUR_IDEMPOTENCY_KEY" }; } } ``` ### Tab: NodeJS ##### Try our example integration ![](/reuse/development-resources/install-api-library/node-js/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-node-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/node-js/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-node-online-payments). #### Requirements * Node.js version 18 or later. #### Installation You can use [npm](https://www.npmjs.com/): **Install the API library** ```bash npm install --save @adyen/api-library npm update @adyen/api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-node-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```js // Require the parts of the module you want to use. const { Client, CheckoutAPI, Types} = require("@adyen/api-library"); // Set up the client and service. const client = new Client({ apiKey: "ADYEN_API_KEY", environment: "TEST" }); const checkoutApi = new CheckoutAPI(client); // Include your idempotency key when you make an API request. const requestOptions = { idempotencyKey: "YOUR_IDEMPOTENCY_KEY" }; ``` ### Tab: Go ##### Try our example integration ![](/reuse/development-resources/install-api-library/go/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-golang-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/go/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-golang-online-payments). #### Requirements * Go 1.13 or later. #### Installation You can use [Go modules](https://github.com/golang/go/wiki/Modules): **Install the API library** ```shell go get github.com/adyen/adyen-go-api-library/vLATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-go-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```go package main import ( "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/adyen" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/checkout" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/common" ) // Create a payment object. func main () { client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) service := client.Checkout() ``` ### Tab: Python ##### Try our example integration ![](/reuse/development-resources/install-api-library/python/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-python-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/python/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-python-online-payments). #### Requirements * Python 3.6 or later. * (Optional) Packages: Requests or PycURL #### Installation You can use [pip](https://pip.pypa.io/en/stable/): **Install the API library** ```py pip install Adyen ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-python-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```py import Adyen # Set up the client and service. adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment that the library is used in. ``` ### Tab: Ruby ##### Try our example integration ![](/reuse/development-resources/install-api-library/ruby/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-rails-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/ruby/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-rails-online-payments). #### Requirements * Ruby 2.7 or later. #### Installation You can use [RubyGems](https://rubygems.org/): **Install the API library** ```bash gem install adyen-ruby-api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-ruby-api-library/releases). Run `bundle install` to install dependencies. #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```ruby require 'adyen-ruby-api-library' # Set up the client and service. adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # The environment that the library is used in. ``` ## Get available payment methods Payment server When the shopper goes to your checkout page, get a list of the available payment methods to show the shopper. 1. From your server, make a POST [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/71/post/paymentMethods) request including the following parameters: | Parameter name | Required | Description | | ----------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | | An object with the following parameters:- `currency`: The three-character [ISO currency code](/development-resources/currency-codes). - `value`: The value of the payment in [minor units](/development-resources/currency-codes). | | `channel` | | **Android** | | `countryCode` | | The shopper's country/region. Format: the two-letter [ISO-3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. Exception: **QZ** (Kosovo). | | `shopperLocale` | | Language and country code. This is used to translate the payment methods names in the response. Default value: **en-US**. | The information that you include is used to filter the list of available payment methods. **Example for a shopper in the Netherlands and a payment amount of 10 EUR** ```bash curl https://checkout-test.adyen.com/v72/paymentMethods \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Android", "shopperLocale": "nl-NL" }' ``` The response includes the list of available payment methods, in the `paymentMethods` object. The payment methods are ordered by popularity in the shopper's country. For each payment method, the response contains: | Parameter name | Description | | -------------- | ------------------------------------------------------------------------------------------------- | | `name` | The name of the payment method that you can show in your payment form. | | `type` | The unique payment method code. You must include this when you [make a payment](#make-a-payment). | **Example response with available payment methods** ```json { "paymentMethods":[ { "name": "Cards", "type": "scheme" }, { "name":"SEPA Direct Debit", "type":"sepadirectdebit" } ] } ``` 2. Pass the list of available payment methods and the required input fields for each payment method to your client. ### Collect Shopper Details ## Build your payment form Client website or app Create your payment form where the shopper enters their information. We recommend that you collect commonly-used [shopper information in your payment form](#information-in-the-payment-form) to process a transactions, depending on your type of business.\ \ Some payment methods require you to collect, or optionally accept, additional information that you include in the payment request. For the additional information you must collect in your payment form for an individual payment method, go to our **API-only** [guide for the individual payment method](/payment-methods). We provide [payment method and issuer logos that you can download](#downloading-logos) and use in your payment form. ### Credit and debit card details Because governing bodies and organizations regulate the handling of credit and debit card information strictly, you must make sure that you are compliant when collecting card details. When a shopper selects to pay with a card, use the integration option that corresponds to your [level of PCI compliance](/development-resources/pci-dss-compliance-guide?tab=api_only_3_4#online-payments): * (Recommended) Adyen's [Custom Card Component](/payment-methods/cards/custom-card-integration) with encryption: our pre-built UI with logic to securely encrypt and handle payment card data. * Your own UI and logic to collect and handle [raw card data](/payment-methods/cards/raw-card-data): before you build an integration that collects raw credit and debit card data, you must [assess your PCI compliance according to the most extensive self-assessment form](/development-resources/pci-dss-compliance-guide?tab=api_only_3_4#online-payments) and contact your Adyen Account Manager to confirm that you are eligible. ### Information in the payment form After collecting information in your payment form, you must add it to corresponding API parameters that you include in the payment request. For example, for commonly-used information: | Field in the payment form | API request parameter | | ---------------------------------- | -------------------------- | | First name | `shopperName.firstName` | | Last name | `shopperName.lastName` | | Email address | `shopperEmail` | | Billing address (multiple fields) | `billingAddress` (object) | | Shipping address (multiple fields) | `deliveryAddress` (object) | | Phone number | `telephoneNumber` | ### Downloading Logos ** ### Downloading logos If you are building your own UI, we provide payment method and issuing bank logos that you can use on your checkout page. The images are available in PNG format with different sizes and screen resolutions and in SVG format. If you cannot find a payment method or issuer logo, contact our [Support Team](https://ca-test.adyen.com/ca/ca/contactUs/support.shtml?form=other). #### Payment method logos Download the images from the links below, specifying: * `img-size`: Specify the size for PNG format. Use the following values: * **small**: Image size 40x26 pixels * **medium**: Image size 77x50 pixels * **large**: Image size 154 x 100 pixels * `suffix`: Specify the image density for PNG format. If not specified, the images will have the same size as the `img-size`. Append any of the following values: * `@2x` * `@3x` * `-ldpi` * `-hdpi` * `-xhdpi` * `-xxhdpi` * `-xxxhdpi` * `pm-type`: The `paymentMethods.type` returned in the `/paymentMethods` response. For example, **googlepay** or **primeiropay\_boleto**. For cards, the values you should use are specified under `brands` with `type`: **scheme**. For example, `mc`, `visa`, and `amex`. To get a generic card logo, set `pm-type` to **card**. Download link for SVG: **Download link for SVG** ```js https://checkoutshopper-live.cdn.adyen.com/checkoutshopper/images/logos/[pm-type].svg ``` Download link for PNG: **Download link for PNG** ```js https://checkoutshopper-live.cdn.adyen.com/checkoutshopper/images/logos/[img-size]/[pm-type][suffix].png ``` Examples:\ \ #### Issuing bank logos Some payment methods such as iDEAL present a list of issuing banks to the shopper. Download the issuing bank logos from the links below, specifying: * `img-size`: Specify the size for PNG format. Use the following values: * **small**: Image size 40x26 pixels * **medium**: Image size 77x50 pixels * **large**: Image size 154 x 100 pixels * `suffix`: Specify the image density for PNG format. If not specified, the images will have the same size as the `img-size`. Append any of the following values: * `@2x` * `@3x` * `-ldpi` * `-hdpi` * `-xhdpi` * `-xxhdpi` * `-xxxhdpi` * `pm-type`: The `paymentMethods.type` in objects with `details.key` **issuer** returned in the `/paymentMethods` response. For example, **ideal**. * `issuerid`: The `details.items.id` referring to the issuing bank. For example, **1121** and **1151** for iDEAL. Download link for SVG: **Download link for SVG** ```js https://checkoutshopper-live.cdn.adyen.com/checkoutshopper/images/logos/[pm-type]/[issuerid].svg ``` Download link for PNG: **Download link for PNG** ```js https://checkoutshopper-live.cdn.adyen.com/checkoutshopper/images/logos/[img-size]/[pm-type]/[issuerid][suffix].png ``` Examples:\ \ ## Make a payment Payment server After the shopper selects the **Pay** button or chooses to pay with a payment method that requires a redirection, you must make a payment request to Adyen. 1. Pass the data from your client to your server. 2. From your server, make a **POST** [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request including the following parameters: | Parameter name | Required | Description | | -------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | An object with the following parameters:- `currency`: The three-character [ISO currency code](/development-resources/currency-codes). - `value`: The value of the payment in [minor units](/development-resources/currency-codes). | | `reference` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your unique reference for this payment. | | `paymentMethod.type` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The payment method type. From the [`/paymentMethods` response](#get-available-payment-methods), this is the value in `paymentMethod.type`. | | `returnUrl` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The URL where the shopper should return to after a redirection. Use the combination of:- `adyencheckout://` scheme - Your package name - A path.Example: `adyencheckout://com.adyen.adyen_checkout_example/adyenPayment` Format:- Maximum 1024 characters. - If it includes non-ASCII characters, such as spaces or special letters, [URL encode](https://www.w3schools.com/html/html_urlencode.asp) it. - You can include your own additional query parameters, such as a shopper ID or order reference number. The URL must not include personally identifiable information (PII), for example name or email address. | | `applicationInfo` | | If you are a [technology partner, service partner, or system integrator](https://docs.adyen.com/partners/application-information#partnership-type), send information about the application, so that we can offer you more support. | For the following cases, you must include additional parameters in your request: * Integrating some payment methods. For more information, go to [payment method integration guides](/payment-methods). * Using our risk management features. For more information, go to [data quality and risk field reference](/risk-management/configure-your-risk-profile/risk-field-reference). * [Creating a token](/online-payments/tokenization/create-tokens) to store the shopper's payment details. * [Using a token](/online-payments/tokenization/make-token-payments) to make a recurring payment with stored payment details. **Example request to make a payment for EUR 10 with encrypted card details** ```bash curl https://checkout-test.adyen.com/v72/payments \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "merchantAccount":"ADYEN_MERCHANT_ACCOUNT", "paymentMethod":{ "type": "scheme", "encryptedCardNumber": "test_4111111111111111", "encryptedExpiryMonth": "test_03", "encryptedExpiryYear": "test_2030", "encryptedSecurityCode": "test_737" }, "amount":{ "currency":"EUR", "value":1000 }, "reference":"YOUR_ORDER_NUMBER", "returnUrl":"adyencheckout://com.adyen.adyen_checkout_example/adyenPayment" }' ``` []() 3. Your next step depends on if the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response contains an `action` object: * If the response has no `action` object, [get the payment outcome](#get-the-payment-outcome). * If the response contains an `action` object, [handle the additional action](#additional-action). **Example response containing an action object for 3D Secure 2 authentication** ```json { "resultCode" : "IdentifyShopper", "action" : { "token" : "eyJkaXJl...", "paymentMethodType" : "scheme", "paymentData" : "Ab02b4c0...", "type" : "threeDS2", "authorisationToken" : "BQABAQ...", "subtype" : "fingerprint" } } ``` ### Perform Additional Actions ## Handle the additional action Client website or app Some payment methods require additional action from the shopper. Common examples of additional actions include: * Logging in to a bank's website or app. * Authenticating a payment with 3D Secure 2. * Scanning a QR code. Implement logic to handle all action types, so that your integration can handle different payment methods. To see if an individual payment method requires an additional action, see the corresponding [payment method guide](/payment-methods) for it. How you handle the action depends on the action type (`action.type`): | Type | `action.type` value | | ----------------------------------------------------------------------- | ------------------- | | [Redirect action](#handle-the-redirect) | **redirect** | | [3D Secure 2 authentication action](#3d-secure-2-authentication-action) | **threeDS2** | | [QR code action](#qr-code-action) | **qrCode** | | [SDK action](#sdk-action) | **sdk** | | [Voucher action](#voucher-action) | **voucher** | | [Await action](#await-action) | **await** | ### Redirect action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type` **redirect**, redirect the shopper to another site to complete the payment. How you handle the redirect depends on if it is a payment method redirect or a 3D Secure 2 redirect. ### Tab: Payment method redirect **Example /payments response for a payment method redirect** ```json { "action": { "method": "GET", "paymentData": "Ab02b4c0!BQ..", "paymentMethodType": "ideal", "type": "redirect", "url": "https://test.adyen.com/hpp/redirectIdeal.shtml?brandCode=ideal¤cyCode=EUR&issuerId=1121..." } } ``` 1. From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, get the following: | Parameter | Description | | ------------ | ----------------------------------- | | `action.url` | The URL to redirect the shopper to. | 2. Redirect the shopper to the `action.url` with the HTTP GET method, where they finish the payment. **Example to redirect the shopper** ```bash curl https://test.adyen.com/hpp/redirectIdeal.shtml?brandCode=ideal¤cyCode=EUR&issuerId=1121... \ ``` 3. When the shopper finishes the payment on the other website, they are returned to your `returnUrl` with the HTTP GET method. The `returnUrl` is appended with a Base64-encoded `redirectResult`. **Redirect result appended to the return URL** ```raw GET /?shopperOrder=12xy..&&redirectResult=X6XtfGC3%21Y... HTTP/1.1 Host: www.your-company.example.com/checkout ``` 4. URL-decode the `redirectResult` value. If a shopper completed the payment but failed to return to your client, you will receive the outcome of the payment in a [webhook event](/development-resources/webhooks). 5. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### Tab: 3D Secure 2 redirect **Example /payments response for a 3D Secure 2 redirect** ```json { "resultCode":"RedirectShopper", "action":{ "data":{ "MD":"OEVudmZVMUlkWjd0MDNwUWs2bmhSdz09...", "PaReq":"eNpVUttygjAQ/RXbDyAXBYRZ00HpTH3wUosPfe...", "TermUrl":"" }, "method":"POST", "paymentData":"Ab02b4c0!BQABAgCJN1wRZuGJmq8dMncmypvknj9s7l5Tj...", "paymentMethodType":"scheme", "type":"redirect", "url":"https://test.adyen.com/hpp/3d/validate.shtml" }, "details":[ { "key":"MD", "type":"text" }, { "key":"PaRes", "type":"text" } ] } ``` 1. From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, get the following from the `action` object: | Parameter | Description | | --------- | ------------------------------------------------------------------------------ | | `url` | The URL to redirect the shopper to. | | `method` | The method to use to redirect the shopper: **POST**. | | `data` | An object with the following data required for authentication:- `MD` - `PaRes` | 2. Redirect the shopper to the `url` with the POST HTTP method, including the following data: | Parameter | Description | | --------- | ------------------------------------------------------------------------------------------------------------------------------------- | | `MD` | From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, the value from `action.data.MD`. | | `PaRes` | From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, the value from `action.data.PaRes`. | **Example of a redirect to a 3D Secure 2 URL** ```bash curl https://checkoutshopper-test.adyen.com/checkoutshopper/threeDS/checkoutRedirect/... \ --data-urlencode 'PaReq=eNpVUttygjAQ/RXbDyAXBYRZ00HpTH3wUosPfe...' \ --data-urlencode 'MD=OEVudmZVMUlkWjd0MDNwUWs2bmhSdz09...' ``` 3. The shopper finishes 3D Secure 2 authentication on an issuer website. In the test environment, this is the page: `https://test.adyen.com/hpp/3d/validate.shtml`, and you perform the authentication using the 3D Secure test credentials: * **Username**: user * **Password**: password 4. The shopper is returned to your `returnUrl` with the same HTTP method. The `returnUrl` is appended with `MD` and `PaRes`. **Example of a 3D Secure 2 redirect back to you with MD and PaRes** ```raw POST / HTTP/1.1 Host: www.your-company.example.com/checkout?shopperOrder=12xy.. Content-Type: application/x-www-form-urlencoded MD=Ab02b4c0%21BQABAgCW5sxB4e%2F%3D%3D..&PaRes=eNrNV0mTo7gS.. ``` 5. URL-decode the `MD` and `PaRes` values. 6. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### 3D Secure 2 authentication action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **threeDS2Fingerprint** or **threeDS2Challenge**, the payment qualifies for 3D Secure 2 and it goes through the [frictionless or the challenge flow](/online-payments/3d-secure/#authentication-flows). Use one of [our 3D Secure 2 solutions](/online-payments/3d-secure) to handle the action. ### QR code action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **qrCode**, the shopper must scan a QR code to complete the payment. **Example /payments response with a QR code action for WeChat Pay desktop** ```json { "resultCode": "Pending", "action": { "paymentData": "Ab02b4c0!BQAB..", "paymentMethodType": "wechatpayQR", "qrCodeData": "weixin://wxpay/bizpayurl?pr=IM7BCOW", "type": "qrCode" } } ``` 1. From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, get the following: | Parameter | Description | | ------------------- | --------------------------------- | | `action.qrCodeData` | Contains the URL for the QR code. | 2. Get the `qrCodeData` from the `action` object. This parameter contains a URL for the QR code. 3. Show the QR code to the shopper. 4. The shopper scans the QR code. 5. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### SDK action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **sdk**, the shopper must use another UI overlay to complete the payment. For example, a payment method requires the shopper to use its specific UI to enter payment details. **Example /payments response with an SDK action for WeChat Pay** ```json { "resultCode": "Pending", "action": { "paymentMethodType": "wechatpaySDK", "type": "sdk", "paymentData": "Ab02b4c0!BQAB..", "sdkData": { "appid": "wx3aed7fe146f6a57a", "noncestr": "cPY0e83ny4hWyf5O", "packageValue": "Sign=WXPay", "partnerid": "205287714", "prepayid": "wx015678064827111da2e4f0b11005864100", "sign": "169FD3F1E193446D90C45573EBDD4020", "timestamp": "1573033086" } }, "details": [ { "key": "resultCode", "type": "text" } ] } ``` 1. From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, get the following from the `action` object: | Parameter | Description | | --------- | --------------------------------------- | | `sdkData` | The data that you must pass to the SDK. | 2. Pass the data from the `sdkData` object to the SDK. 3. The shopper uses the SDK to finish the payment. 4. Get the result from the SDK. 5. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### Voucher action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **voucher**, the shopper must use a voucher to complete the payment. **Voucher action type** ```json { "resultCode": "PresentToShopper", "action": { "expiresAt": "2021-09-04T19:17:00", "initialAmount": { "currency": "IDR", "value": 10000 }, "instructionsUrl": "https://checkoutshopper-test.adyen.com/checkoutshopper/voucherInstructions.shtml?txVariant=doku_mandiri_va", "merchantName": "YOUR_SHOP_NAME", "paymentMethodType": "doku_alfamart", "reference": "8520126030105485", "shopperEmail": "john.smith@adyen.com", "shopperName": "John Smith", "totalAmount": { "currency": "IDR", "value": 10000 }, "paymentData": "Ab02b4c0!BQAB..", "type": "voucher" } } ``` 1. The data included in the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response is different for each voucher payment method. Get the available information from it. For example, for DOKU vouchers, get the following: | Parameter | Description | | ----------------- | ------------------------------------------------------------------------------------------- | | `expiresAt` | The date when the voucher expires. | | `initialAmount` | The payment amount and currency. | | `merchantName` | The name of your shop. | | `instructionsUrl` | The URL where you shopper can get additional information and instructions about how to pay. | 2. Show voucher information to the shopper that your shopper uses to pay outside of your client. 3. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### Await action When the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response includes `action.type`: **await**, the shopper must take an additional action to complete the payment. For example: entering a code into their banking app. **Example of a /payments response with an await action for a one-time PayTo payment** ```json { "resultCode": "Pending", "action": { "paymentData": "Ab02b4c0!BQAB..", "paymentMethodType": "payto", "type": "await" } } ``` 1. From the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, get the following: | Parameter | Description | | -------------------- | ------------------------ | | `action.paymentData` | Additional payment data. | 2. The shopper finishes the additional action for the payment. 3. [Send additional payment details](#send-additional-payment-details) to finish the payment flow. ### Submit Additional Payment Details ## Send additional payment details Payment server If you [handled an additional action](#additional-action), you must send additional payment details. **For redirects**: if the shopper fails to return to your client, you do not get additional payment details to send. Instead, wait for the corresponding [webhook message](#update-your-order-management-system) for the outcome of the payment. From your server, make a POST [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request. The parameters that you must include depends on the payment method. For the parameters for an individual payment method, go to the **API-only** [page for the individual payment method ](/payment-methods). **Example request to send details from a redirect** #### curl ```bash curl https://checkout-test.adyen.com/v72/payments/details \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "details": { "redirectResult": "eyJ0cmFuc1N0YXR1cyI6IlkifQ==" } }' ``` #### Java ```java // Adyen Java API Library v39.3.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the LIVE environment, also include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) // Send the request PaymentsApi service = new PaymentsApi(client); PaymentDetailsResponse response = service.paymentsDetails(paymentDetailsRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("ADYEN_API_KEY"); // For the LIVE environment, also include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->paymentsDetails($paymentDetailsRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v32.1.1 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the LIVE environment, also include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) // Send the request var service = new PaymentsService(client); var response = service.PaymentsDetails(paymentDetailsRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### Go ```go // Adyen Go API Library v21.0.0 import ( "context" "github.com/adyen/adyen-go-api-library/v21/src/common" "github.com/adyen/adyen-go-api-library/v21/src/adyen" "github.com/adyen/adyen-go-api-library/v21/src/checkout" ) // For the LIVE environment, also include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentsDetailsInput().IdempotencyKey("UUID").PaymentDetailsRequest(paymentDetailsRequest) res, httpRes, err := service.PaymentsApi.PaymentsDetails(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.6.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "details": { "redirectResult": "eyJ0cmFuc1N0YXR1cyI6IlkifQ==" } } # Send the request result = adyen.checkout.payments_api.payments_details(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v10.4.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :details => { :redirectResult => 'eyJ0cmFuc1N0YXR1cyI6IlkifQ==' } } # Send the request result = adyen.checkout.payments_api.payments_details(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v29.0.0 import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentsDetails(paymentDetailsRequest, { idempotencyKey: "UUID" }); ``` The response includes information about the current payment status. **Example response for a successful payment** ```json { "pspReference": "NC6HT9CRT65ZGN82", "resultCode": "Authorised" } ``` **Example response for a refused payment** ```json { "pspReference": "KHQC5N7G84BLNK43", "refusalReason": "Not enough balance", "resultCode": "Refused" } ``` ### Show Payment Result ## Get the payment outcome After the shopper finishes the payment flow, you can show the shopper the current payment status. Adyen sends a webhook with the outcome of the payment. ### Inform the shopper Client website or app Use the [`resultCode` ](/online-payments/payment-result-codes#final-payment-status)to show the shopper the [current payment status](/account/payments-lifecycle). This synchronous response doesn't give you the final outcome of the payment. You get the final payment status in a webhook that you use to [update your order management system](#update-your-order-management-system). ### Update your order management system Webhook server You get the outcome of each payment asynchronously, in an **AUTHORISATION** [webhook](/development-resources/webhooks). Use the `merchantReference` from the webhook to match it to your order reference.\ For a successful payment, the event contains `success`: **true**. **Example webhook for a successful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"033899:1111:03/2030", "amount":{ "currency":"EUR", "value":2500 }, "operations":["CANCEL","CAPTURE","REFUND"], "success":"true", "paymentMethod":"mc", "additionalData":{ "expiryDate":"03/2030", "authCode":"033899", "cardBin":"411111", "cardSummary":"1111" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"NC6HT9CRT65ZGN82", "eventDate":"2021-09-13T14:10:22+02:00" } } ] } ``` For an unsuccessful payment, you get `success`: **false**, and the `reason` field has details about why the payment was unsuccessful. **Example webhook for an unsuccessful payment** ```json { "live": "false", "notificationItems":[ { "NotificationRequestItem":{ "eventCode":"AUTHORISATION", "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT", "reason":"validation 101 Invalid card number", "amount":{ "currency":"EUR", "value":2500 }, "success":"false", "paymentMethod":"unknowncard", "additionalData":{ "expiryDate":"03/2030", "cardBin":"411111", "cardSummary":"1112" }, "merchantReference":"YOUR_REFERENCE", "pspReference":"KHQC5N7G84BLNK43", "eventDate":"2021-09-13T14:14:05+02:00" } } ] } ``` ## Error handling In case you encounter errors in your integration, refer to the following: * [API error codes](/development-resources/error-codes): If you receive a non-HTTP 200 response, use the `errorCode` to troubleshoot and modify your request. * [Payment refusals](/development-resources/refusal-reasons): If you receive an HTTP 200 response with an **Error** or **Refused** `resultCode`, check the refusal reason and, if possible, modify your request. ## Test and go live Before going live, use our list of [test cards and other payment methods](/development-resources/test-cards-and-credentials/test-card-numbers) to [test your integration](/development-resources/testing). We recommend testing each payment method that you intend to offer to your shoppers. You can check the status of a test payment in your [Customer Area](https://ca-test.adyen.com/), under **Transactions** > **Payments**. To debug or troubleshoot test payments, you can also use [API logs](/development-resources/logs-resources/api-logs) in your test environment. When you are ready to go live, you need to: 1. [Apply for a live account](/get-started-with-adyen/application-requirements). 2. Assess your [PCI DSS compliance](/development-resources/pci-dss-compliance-guide#online-payments) by submitting: * the [Self-Assessment Questionnaire-A](https://www.pcisecuritystandards.org/documents/PCI-DSS-v3_2_1-SAQ-A.pdf), if you are using the Custom Card Component. * the [Self-Assessment Questionnaire-D](https://www.pcisecuritystandards.org/documents/PCI-DSS-v3_2_1-SAQ-D_Merchant.pdf), if you are submitting raw card data. 3. [Configure your live account](/online-payments/go-live-checklist).  4. Submit a request to add payment methods in your [live Customer Area](https://ca-live.adyen.com/) . 5. Switch from test to our [live endpoints](/development-resources/live-endpoints#checkout-endpoints). Make sure that all API requests you make for the same payment session use the same live endpoint region. Using different regions for [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) and [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) requests may result in errors, for example, when authenticating with 3D Secure 2. ### Next Steps [required](/development-resources/webhooks) [Set up notifications](/development-resources/webhooks) [Receive confirmation when a payment is authorised or fails.](/development-resources/webhooks) [required](/payment-methods) [Add payment methods](/payment-methods) [Learn about payment methods and how to add them to your account.](/payment-methods) [Payment modifications](/online-payments/modify-payments) [Find out how to cancel, refund, or capture a payment using our API.](/online-payments/modify-payments) ## React Native Drop-in Use our pre-built UI for accepting payments ### Intro Drop-in is our pre-built UI solution for accepting payments in your app. Drop-in shows all payment methods as a list, in the same block. Your server makes API requests to the [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods), [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments), and [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) endpoints. ### Before You Begin ## Requirements Before you begin to integrate, make sure you have followed the [Get started with Adyen guide](/get-started-with-adyen) to: * Get an overview of the steps needed to accept live payments. * Create your test account. After you have created your test account: * [Get your API key](/development-resources/api-credentials#generate-api-key). * [Get your client key](/development-resources/client-side-authentication#get-your-client-key). * [Set up webhooks](/development-resources/webhooks) to know the payment outcome. ## How it works For a Drop-in integration, you must implement the following parts: * **Your payment server**: sends the API requests to get available payment methods, make a payment, and send additional payment details. * **Your client app**: shows the Drop-in UI where the shopper makes the payment. Drop-in uses the data from the API responses to handle the payment flow and additional actions on your client app. * **Your webhook server**: receives webhooks that include the outcome of each payment. If you are integrating these parts separately, you can start at the corresponding part of this integration guide: [![](/user/pages/reuse/online-payments/how-it-works-parts/servers.svg?decoding=auto\&fetchpriority=auto)](/#install-api-library) [Payment server](/#install-api-library) [Go to the integration steps for your server.](/#install-api-library) [![](/user/pages/reuse/online-payments/how-it-works-parts/browser-developers.svg?decoding=auto\&fetchpriority=auto)](/#add) [Client app](/#add) [Go to the integration steps for your client app.](/#add) [![](/user/pages/reuse/online-payments/how-it-works-parts/event-code.svg?decoding=auto\&fetchpriority=auto)](/#update-your-order-management-system) [Webhook server](/#update-your-order-management-system) [Go to the integration steps for your webhook server.](/#update-your-order-management-system) The parts of your integration work together to complete the payment flow: 1. The shopper goes to the checkout page. 2. Your server uses the shopper's country and currency information from your client to get available payment methods. 3. Drop-in shows the available payment methods, collects the shopper's payment details, handles additional actions, and shows the payment result to the shopper. 4. Your webhook server receives the notification containing the payment outcome. ![](/user/pages/filters/advanced-flow-integration/react-native/1-0-0/02.how-it-works/drop-in-flow.jpg) ### Install Api Library ## Install an API library Payment server We provide server-side API libraries for several programming languages, available through common package managers, like Gradle and npm, for easier installation and version management. Our API libraries will save you development time, because they: * Use an API version that is up to date. * Have generated models to help you construct requests. * Send the request to Adyen using their built-in HTTP client, so you do not have to create your own. ### Tab: Java ##### Try our example integration ![](/reuse/development-resources/install-api-library/java/advanced/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-java-spring-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/java/advanced/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-java-spring-online-payments). #### Requirements * Java 11 or later. #### Installation You can use [Maven](https://maven.apache.org), adding this dependency to your project's POM. **Add the API library** ```xml com.adyen adyen-java-api-library LATEST_VERSION ``` You can find the latest version on GitHub. Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-java-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```java // Import the required classes. package com.adyen.service; import com.adyen.Client; import com.adyen.service.checkout.PaymentsApi; import com.adyen.model.checkout.Amount; import com.adyen.enums.Environment; import com.adyen.service.exception.ApiException; import java.io.IOException; public class Snippet { public Snippet() throws IOException, ApiException { // Set up the client and service. Client client = new Client("ADYEN_API_KEY", Environment.TEST); } } ``` ### Tab: PHP ##### Try our example integration ![](/reuse/development-resources/install-api-library/php/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-php-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/php/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-php-online-payments). #### Requirements * PHP 7.3 or later. * cURL with SSL support. * The JSON PHP extension. * The list of dependencies from the composer require list. #### Installation You can use [Composer](https://getcomposer.org/). Follow the [installation instructions](https://getcomposer.org/doc/00-intro.md) if you do not already have composer installed. **Install the API library** ```bash composer require adyen/php-api-library ``` In your PHP script, make sure you include the autoloader: **Include the autoloader** ```php require __DIR__ . '/vendor/autoload.php'; ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-php-api-library/releases). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```php use Adyen\Model\Checkout\Amount; use Adyen\Model\Checkout\CreateCheckoutSessionRequest; use Adyen\Service\Checkout\PaymentsApi; // Include your idempotency key when you make an API request. $requestOptions['idempotencyKey'] = "YOUR_IDEMPOTENCY_KEY"; // Set up the client and service. $client = new \Adyen\Client(); $client->setXApiKey('ADYEN_API_KEY'); $client->setEnvironment(\Adyen\Environment::TEST); $service = new PaymentsApi($client); ``` ### Tab: C\# #### Requirements * .NET standard 2.0 or later. * For Terminal API certificate validation, set the application to either of the following: * .NET core 2.1 or later * .NET framework 4.6.1 or later #### Installation You can use [NuGet](https://www.nuget.org/packages/Adyen/): **Install the API library** ```bash PM> Install-Package Adyen -Version LATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-dotnet-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```cs using Adyen; using Adyen.Model.Checkout; using Adyen.Service.Checkout; using Environment = Adyen.Model.Environment; class Program { static void Main() { // Set up the client and service. var config = new Config { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); var checkout = new PaymentsService(client); // Include your idempotency key when you make an API request. var requestOptions = new Adyen.Model.RequestOptions { IdempotencyKey = "YOUR_IDEMPOTENCY_KEY" }; } } ``` ### Tab: NodeJS ##### Try our example integration ![](/reuse/development-resources/install-api-library/node-js/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-node-online-payments#checkout-example).\ ![](/reuse/development-resources/install-api-library/node-js/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-node-online-payments). #### Requirements * Node.js version 18 or later. #### Installation You can use [npm](https://www.npmjs.com/): **Install the API library** ```bash npm install --save @adyen/api-library npm update @adyen/api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-node-api-library/releases). #### Setting up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```js // Require the parts of the module you want to use. const { Client, CheckoutAPI, Types} = require("@adyen/api-library"); // Set up the client and service. const client = new Client({ apiKey: "ADYEN_API_KEY", environment: "TEST" }); const checkoutApi = new CheckoutAPI(client); // Include your idempotency key when you make an API request. const requestOptions = { idempotencyKey: "YOUR_IDEMPOTENCY_KEY" }; ``` ### Tab: Go ##### Try our example integration ![](/reuse/development-resources/install-api-library/go/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-golang-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/go/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-golang-online-payments). #### Requirements * Go 1.13 or later. #### Installation You can use [Go modules](https://github.com/golang/go/wiki/Modules): **Install the API library** ```shell go get github.com/adyen/adyen-go-api-library/vLATEST_VERSION ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-go-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```go package main import ( "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/adyen" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/checkout" "github.com/adyen/adyen-go-api-library/vLATEST_VERSION/src/common" ) // Create a payment object. func main () { client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) service := client.Checkout() ``` ### Tab: Python ##### Try our example integration ![](/reuse/development-resources/install-api-library/python/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-python-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/python/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-python-online-payments). #### Requirements * Python 3.6 or later. * (Optional) Packages: Requests or PycURL #### Installation You can use [pip](https://pip.pypa.io/en/stable/): **Install the API library** ```py pip install Adyen ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-python-api-library). #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```py import Adyen # Set up the client and service. adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment that the library is used in. ``` ### Tab: Ruby ##### Try our example integration ![](/reuse/development-resources/install-api-library/ruby/gitpod-icon.png)  [Run it in Gitpod](https://github.com/adyen-examples/adyen-rails-online-payments#run-this-integration-in-seconds-using-gitpod).\ ![](/reuse/development-resources/install-api-library/ruby/github-icon.png)  [Clone the repository](https://github.com/adyen-examples/adyen-rails-online-payments). #### Requirements * Ruby 2.7 or later. #### Installation You can use [RubyGems](https://rubygems.org/): **Install the API library** ```bash gem install adyen-ruby-api-library ``` Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-ruby-api-library/releases). Run `bundle install` to install dependencies. #### Set up the client Create a singleton resource that you use for the API requests to Adyen: **Set up your client** ```ruby require 'adyen-ruby-api-library' # Set up the client and service. adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # The environment that the library is used in. ``` ## Get available payment methods Payment server When your shopper is ready to pay, get a list of the available payment methods based on their country, device, and the payment amount. From your server, make a POST [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) request, providing the following parameters. While most parameters are optional, we recommend that you include them because Adyen uses these to tailor the list of payment methods for your shopper. We use the optional parameters to tailor the list of available payment methods to your shopper. | Parameter name | Required | Description | | ----------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchantAccount` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Your merchant account name. | | `amount` | | The `currency` of the payment and its `value` in [minor units](/development-resources/currency-codes). | | `channel` | | The platform where the payment is taking place. For example, when you set this to **iOS**, Adyen returns only the payment methods available for iOS. | | `countryCode` | | The shopper's country/region. Adyen returns only the payment methods available in this country. Format: the two-letter [ISO-3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. Exception: **QZ** (Kosovo). | | `shopperLocale` | | By default, the `shopperlocale` is set to **en-US**. To change the language, set this to the shopper's language and country code. The front end also uses this locale. | For example, to get the available payment methods for a shopper in the **Netherlands**, for a payment of **EUR 10**: #### curl ```bash curl https://checkout-test.adyen.com/v72/paymentMethods \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Android", "shopperLocale": "nl-NL" }' ``` #### Java ```java // Adyen Java API Library v27.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the live environment, additionally include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) Amount amount = new Amount() .currency("EUR") .value(1000L); PaymentMethodsRequest paymentMethodsRequest = new PaymentMethodsRequest() .amount(amount) .merchantAccount("ADYEN_MERCHANT_ACCOUNT") .countryCode("NL") .channel(PaymentMethodsRequest.ChannelEnum.IOS) .shopperLocale("nl-NL"); // Send the request PaymentsApi service = new PaymentsApi(client); PaymentMethodsResponse response = service.paymentMethods(paymentMethodsRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("ADYEN_API_KEY"); // For the LIVE environment, also include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->paymentMethods($paymentMethodsRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v32.1.1 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the LIVE environment, also include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) // Send the request var service = new PaymentsService(client); var response = service.PaymentMethods(paymentMethodsRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v29.0.0 const { Client, CheckoutAPI } = require('@adyen/api-library'); // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const paymentMethodsRequest = { merchantAccount: "ADYEN_MERCHANT_ACCOUNT", countryCode: "NL", amount: { currency: "EUR", value: 1000 }, channel: "Android", shopperLocale: "nl-NL" } // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentMethods(paymentMethodsRequest, { idempotencyKey: "UUID" }); ``` #### Go ```go // Adyen Go API Library v10.4.0 import ( "context" "github.com/adyen/adyen-go-api-library/v9/src/common" "github.com/adyen/adyen-go-api-library/v9/src/adyen" "github.com/adyen/adyen-go-api-library/v9/src/checkout" ) // For the live environment, additionally include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) amount := checkout.Amount{ Currency: "EUR", Value: 1000, } paymentMethodsRequest := checkout.PaymentMethodsRequest{ Amount: &amount, MerchantAccount: "ADYEN_MERCHANT_ACCOUNT", CountryCode: common.PtrString("NL"), Channel: common.PtrString("iOS"), ShopperLocale: common.PtrString("nl-NL"), } // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentMethodsInput().IdempotencyKey("UUID").PaymentMethodsRequest(paymentMethodsRequest) res, httpRes, err := service.PaymentsApi.PaymentMethods(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.6.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "countryCode": "NL", "amount": { "currency": "EUR", "value": 1000 }, "channel": "Android", "shopperLocale": "nl-NL" } # Send the request result = adyen.checkout.payments_api.payment_methods(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v10.4.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT', :countryCode => 'NL', :amount => { :currency => 'EUR', :value => 1000 }, :channel => 'Android', :shopperLocale => 'nl-NL' } # Send the request result = adyen.checkout.payments_api.payment_methods(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v29.0.0 import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.paymentMethods(paymentMethodsRequest, { idempotencyKey: "UUID" }); ``` The response includes the list of available `paymentMethods`: **/paymentMethods response** ```json { "paymentMethods":[ { "details":[...], "name":"Cards", "type":"scheme" ... }, { "details":[...], "name":"SEPA Direct Debit", "type":"sepadirectdebit" }, ... ] } ``` Pass the response to your client app. Use this in the next step to show available payment methods to the shopper. ### Add Adyen To Your App ## Add Adyen Drop-in to your app Client app ### 1. Add Adyen React Native to your project **Add Adyen React Native** ```js $ yarn add @adyen/react-native ``` ### 2. Install ### Tab: iOS 1. Run `pod install`. 2. In your `AppDelegate.m` file, add a return URL handler for handling redirects from other apps. For example: **iOS return URL handler** ```js import { ... - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { return [ADYRedirectComponent applicationDidOpenURL:url]; } ``` If you use `RCTLinkingManager` or other ways of deep linking, use `ADYRedirectComponent.applicationDidOpenURL` first: **Return URL handler with deep linking** ```js import { ... - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { return [ADYRedirectComponent applicationDidOpenURL:url] || [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options]; } ``` If you want to [support universal links in your app](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app), add the following return URL handler instead: **Return handler with universal link support** ```js import { ... - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray> * _Nullable))restorationHandler { if ([[userActivity activityType] isEqualToString:NSUserActivityTypeBrowsingWeb]) { NSURL *url = [userActivity webpageURL]; if (![url isEqual:[NSNull null]] && [ADYRedirectComponent applicationDidOpenURL:url]) { return YES; } } BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler]; return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result; } ``` If your `Podfile` has `use_frameworks!`, import the redirect component using underscores (**\_**) instead of hyphens(**-**): ```js #import ``` ### Tab: Android 1. Provide your checkout [activity](https://developer.android.com/guide/components/activities/intro-activities) to `AdyenCheckout`. **Provide checkout activity to AdyenCheckout** ```kotlin @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AdyenCheckout.setLauncherActivity(this); } ``` 2. To enable standalone redirect components, return the URL handler to your Checkout activity `onNewIntent`. **Return URL handler to onNewIntent** ```kotlin @Override public void onNewIntent(Intent intent) { super.onNewIntent(intent); AdyenCheckout.handle(intent); } ``` ### Tab: Expo The library is not compatible with ExpoGo and is only available with the Expo managed workflow. 1. Add the Adyen React Native plugin to your `app.json`. **Add Adyen React Native** ```js { "expo": { "plugins": ["@adyen/react-native"] } } ``` ### Create A Configuration Object ### 3. Create a configuration object Create a configuration object with the following properties: | Parameter | Required | Description | | | ------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - | | `environment` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Use **test**. When you're ready to accept live payments, change the value to one of our [live environments](/online-payments/react-native/drop-in#test-and-go-live). | | | `clientKey` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | A public key linked to your API credential, used for [client-side authentication](/development-resources/client-side-authentication). | | | `returnUrl` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | For iOS, this is the URL to your app, where the shopper should return, after a redirection. Maximum of 1024 characters. For more information on setting a custom URL scheme for your app, read the [Apple Developer documentation](https://developer.apple.com/documentation/uikit/inter-process_communication/allowing_apps_and_websites_to_link_to_your_content/defining_a_custom_url_scheme_for_your_app). For Android, this value is automatically overridden by `AdyenCheckout`. | | | `countryCode` | If you want to show the amount on the **Pay** button. | The shopper's country/region. Format: the two-letter [ISO-3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. Exception: **QZ** (Kosovo). | | | `amount` | If you want to show the amount on the **Pay** button. | The `currency` and `value` of the payment, in [minor units](/development-resources/currency-codes). | | For example:[]() **Create a configuration object** ```js const configuration = { // When you're ready to accept live payments, change the value to one of our live environments. environment: 'test', clientKey: 'YOUR_CLIENT_KEY', // For iOS, this is the URL to your app. For Android, this is automatically overridden by AdyenCheckout. returnUrl: 'your-app://', // Must be included to show the amount on the Pay button. countryCode: 'NL', amount: { currency: 'EUR', value: 1000 } }; ``` To add configuration for specific payment methods, add these in a payment method specific configuration object. For example, for Apple Pay: **Add configuration for Apple Pay** ```js const configuration: Configuration = { environment: 'test', // When you're ready to accept real payments, change the value to a suitable live environment. clientKey: 'YOUR_CLIENT_KEY', returnUrl: 'your-app://', countryCode: 'NL', amount: { currency: 'EUR', value: 1000 }, applepay: { merchantID: 'APPLE_PAY_MERCHANT_ID', merchantName: 'APPLE_PAY_MERCHANT_NAME' } }; ``` #### Optional configuration Optionally, you can configure the following properties for Drop-in. | Parameter | Description | | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `showPreselectedStoredPaymentMethod` | When enabled, shows the preselected stored payment method view. Defaults to **true**. | | `skipListWhenSinglePaymentMethod` | Set to **true** to skip showing the payment methods list when only one non-instant payment method is available. Defaults to **false**. | | `title` Only for iOS | Set a custom title for the pre-selected stored payment view. By default, the app's name is used. | | `showRemovePaymentMethodButton` | Allows the shopper to remove a stored payment method. Defaults to **false**. When enabled, you must also implement the `onDisableStoredPaymentMethod` callback. | | `onDisableStoredPaymentMethod(storedPaymentMethod, resolve, reject) => {}` | Called when a shopper removes a stored payment method. To remove the selected payment method, make a **DELETE** `storedPaymentMethods` request using the `storedPaymentMethodId`. Then call either `resolve()` or `reject()`, depending on the [/storedPaymentMethods/{storedPaymentMethodId}](https://docs.adyen.com/api-explorer/Checkout/latest/delete/storedPaymentMethods/\(storedPaymentMethodId\)) response. | For example: **Add optional configuration for Drop-in** ```js const configuration: Configuration = { environment: 'test', // When you're ready to accept real payments, change the value to a suitable live environment. clientKey: '{YOUR_CLIENT_KEY}', returnUrl: 'your-app://', countryCode: 'NL', amount: { currency: 'EUR', value: 1000 }, dropin: { skipListWhenSinglePaymentMethod: true, showPreselectedStoredPaymentMethod: false } }; ``` ### Initialize ### 4. Initialize Drop-in 1. Configure `AdyenCheckout`, setting the following: | Parameter | Description | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `config` | Your [configuration object](#configure). | | `paymentMethods` | The full response from the [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) endpoint. | | `onSubmit` | Callback that uses `data` to make a [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request when the shopper selects the **Pay** button and the payment details are valid. | | `onAdditionalDetails` | Callback that uses `data` to make a [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request when a payment requires additional details, for example to authenticate with 3D Secure or to pay using a QR code. | | `onError` | Callback that handles errors. | In your `onSubmit`, `onAdditionalDetails`, and `onError` callbacks, you must call `component.hide(result)` to dismiss the payment UI when the API request is completed and the payment result is known. 2. Set `AdyenCheckout` as the [context](https://reactjs.org/docs/context.html) for your [`View` ](https://reactnative.dev/docs/view). For example: **Configure AdyenCheckout** ```js // Import AdyenCheckout. import { AdyenCheckout } from '@adyen/react-native'; import { useCallback } from 'react'; const submitHandler = useCallback( (data, component, extra) => { // Make a /payments request. // When this callback is executed, you must call `component.hide(true | false)` to dismiss the payment UI. }, [...], ); const errorHandler = useCallback( (error, component) => { // Handle errors or termination by shopper. // When this callback is executed, you must call `component.hide(false)` to dismiss the payment UI. }, [...], ); const additionalDetailsHandler = useCallback( (data, component) => { // Make a /payments/details request. // When this callback is executed, you must call `component.hide(true | false)` to dismiss the payment UI. }, [...], ); ``` 3. Create a way, like a button, for `AdyenCheckout` to call the `start` function. **Create a way to start Drop-in** ```js // Import useAdyenCheckout. import { useAdyenCheckout } from '@adyen/react-native'; // Set your View to use AdyenCheckout as the context. const YourCheckoutView = () => { const { start } = useAdyenCheckout(); return ( // Create a way, like a checkout button, that starts Drop-in.