Search

Are you looking for test card numbers?

Would you like to contact support?

API only

Learn how you can use our APIs and then build your own UI.

Use our APIs and build your own payments form if you want full control over the look and feel of your checkout page. If you'd rather not build your own payments form and would like to use our available UI solutions for popular payment methods, see Drop-in or Components.

To start your online payments integration, you need to implement API calls from your server and then build your client-side implementation:

  1. From your server, submit a request to get a list of payment methods available to the shopper.
  2. Present the list of available payment methods to the shopper.
  3. Collect your shopper's payment details.
  4. From your server, submit a payment request with the data you have collected from the shopper.
  5. Determine from the response if you need to perform additional actions on your front end, such as to redirect the shopper.
  6. From your server, verify the payment result.
  7. Present the payment result to the shopper.

Before you begin

Before you start integrating with our online payments API, make sure that you have performed the following steps:

  1. Sign up for an Adyen test account at https://www.adyen.com/signup
  2. Get your API Key. Save a copy as you need it for API calls you make to the Adyen payments platform.
  3. Install one of our Libraries to connect with the Adyen APIs.
  4. If you're building for multiple merchants, provide some basic information so that we can offer you better support.

For more information on these steps, refer to Get started with Adyen.

Step 1: Get available payment methods and determine the required fields

First, you need to get a list of payment methods available to your shopper:

  1. Make a POST /paymentMethods request, providing:

    • merchantAccount: Your merchant account name. 
    • countryCode: The shopper's country.
    • amount: The currency and value of the payment. 
    • channel: The platform of the shopper's device. Specify either Android, iOS, or Web.

    We use the countryCodeamount, and channel to tailor the list of payment methods to your shopper.

    curl https://checkout-test.adyen.com/v49/paymentMethods \
    -H "x-API-key: YOUR_X-API-KEY" \
    -H "content-type: application/json" \
    -d '{
      "merchantAccount": "YOUR_MERCHANT_ACCOUNT",
      "countryCode": "NL",
      "amount": {
        "currency": "EUR",
        "value": 1000
      },
      "channel": "Web"
    }'
    # Set your X-API-KEY with the API key from the Customer Area.
    adyen = Adyen::Client.new
    adyen.api_key = "YOUR_X-API-KEY"
    
    response = adyen.checkout.payment_methods({
      :merchantAccount => 'YOUR_MERCHANT_ACCOUNT',
      :countryCode => 'NL',
      :amount => {
        :currency => 'EUR',
        :value => 1000
      },
      :channel => 'Web'
    })
    // Set your X-API-KEY with the API key from the Customer Area.
    Client client = new Client(xApiKey,Environment.TEST);
    
    Checkout checkout = new Checkout(client);
    PaymentMethodsRequest paymentMethodsRequest = new PaymentMethodsRequest();
    paymentMethodsRequest.setMerchantAccount("YOUR_MERCHANT_ACCOUNT");
    paymentMethodsRequest.setCountryCode("NL");
    Amount amount = new Amount();
    amount.setCurrency("EUR");
    amount.setValue(1000L);
    paymentMethodsRequest.setAmount(amount);
    paymentMethodsRequest.setChannel(PaymentMethodsRequest.ChannelEnum.WEB);
    PaymentMethodsResponse response = checkout.paymentMethods(paymentMethodsRequest);
    // Set your X-API-KEY with the API key from the Customer Area.
    $client = new \Adyen\Client();
    $client->setXApiKey("YOUR_X-API-KEY");
    $service = new \Adyen\Service\Checkout($client);
    
    $params = array(
      "merchantAccount" => "YOUR_MERCHANT_ACCOUNT",
      "countryCode" => "NL",
      "amount" => array(
        "currency" => "EUR",
        "value" => 1000
      ),
      "channel" => "Web"
    );
    $result = $service->paymentMethods($params);
    #Set your X-API-KEY with the API key from the Customer Area.
    adyen = Adyen.Adyen()
    adyen.client.xapikey = 'YOUR_X-API-KEY'
    
    result = adyen.checkout.payment_methods({
      'merchantAccount': 'YOUR_MERCHANT_ACCOUNT',
      'countryCode': 'NL',
      'amount': {
        'value': 1000,
        'currency': 'EUR'
      },
      'channel': 'Web',
    })
    // Set your X-API-KEY with the API key from the Customer Area.
    var client = new Client ("YOUR-X-API-KEY", Environment.Test);
    var checkout = new Checkout(client);
    var amount = new Model.Checkout.Amount("EUR", 1000);
    var paymentMethodsRequest = new Model.Checkout.PaymentMethodsRequest(MerchantAccount: "YOUR_MERCHANT_ACCOUNT")
    {
       CountryCode = "NL",
       Amount = amount,
       Channel = "Web"
    };

    A list of available paymentMethods is returned in the response, including:

    • name: Name of the payment method, which you can display to your shopper in your payments form. 
    • type: Unique payment method code. Pass this back to indicate the shopper's chosen payment method when you make the payment.
    • details: An array that contains the required fields for each payment method.
    {
      "paymentMethods":[
        {
          "details": [
            {
              "key": "number",
              "type": "text"
            },
            {
              "key": "expiryMonth",
              "type": "text"
            },
            {
              "key": "expiryYear",
              "type": "text"
            },
            {
              "key": "cvc",
              "type": "text"
            },
            {
              "key": "holderName",
              "optional": true,
              "type": "text"
            }
          ],
          "name": "Credit Card",
          "type": "scheme"
        },
        {
          "details":[
            {
              "key":"sepa.ownerName",
              "type":"text"
            },
            {
              "key":"sepa.ibanNumber",
              "type":"text"
            }
          ],
          "name":"SEPA Direct Debit",
          "type":"sepadirectdebit"
        },
        {    ...
        }
      ]
    }
  2. Use the details array of each payment method to determine what you need to collect from the shopper. If a payment method does not have a details array, you do not need to collect any shopper details in your form. This usually means that the shopper must be redirected to another site to complete the payment.

    • key: Shopper detail you need to collect using your payments form.
    • type: Input type for collecting the payment detail from the shopper:

      Type Description
      emailAddress Email address.
      radio Radio buttons displaying the options specified within the items array.
      select A list displaying the options specified within the items array. Present each name in this array to the shopper.
      tel Telephone number.
      text Generic string. For "type": "scheme", if you are PCI Level 1 or 2 certified you can alternatively collect and submit raw card data. See Collecting raw card data for more information. Otherwise, you need to generate encrypted card data using our Custom card fields.

Pass the name values to your front end and proceed to the next step to show your shoppers the available payment methods.

Step 2: Present the list of available payment methods to your shopper

Use the name values from the /paymentMethods response to show the payment methods available to your shopper.

We also provide payment method and issuer logos that you can use on your payment form. See Downloading logos for details.

Next, render the input fields to get the required payment details from your shopper.

Step 3: Collect shopper details

After your shopper selects a payment method, use the details array from the /paymentMethods response to render your input fields. If the shopper selects a payment method without a details array, proceed to step 4 to make the payment.

For your payment form, you can build either:

  • A hard-coded payment form: After making a /paymentMethods call in step 1 to determine the payment details you need to collect, you build a static form that collects them from the shopper.

    A hard-coded form is quicker to implement, but the payment details you need to collect from a shopper can change. You should regularly poll the /paymentMethods endpoint to check for any updates to required payment details. We recommend this approach if you're only working with a small number of payment methods or countries.

  • Or a dynamically generated payment form: For each transaction, you make a /paymentMethods call in step 1 to determine the payment details you need to collect. Then use the response to generate a form that collects them from the shopper.

    This takes more time to implement, but ensures that the required payment details you collect from the shopper are up-to-date.

If the shopper selects to pay with a Card payment method, proceed to Collecting your shopper's card payment details.

From the details array, use details.type to determine the data type of the information that you need to collect. For example, when the shopper chooses to pay with name SEPA Direct Debit:

{
  "paymentMethods":[
    {
      ...
    },
    {
      "details":[
        {
          "key":"sepa.ownerName",
          "type":"text"
        },
        {
          "key":"sepa.ibanNumber",
          "type":"text"
        }
      ],
      "name":"SEPA Direct Debit",
      "type":"sepadirectdebit"
    }
  ]
}

The details.type property indicates that you need text fields to collect the following details.key fields:

  • sepa.ownerName: Name on the shopper's bank account.
  • sepa.ibanNumber: IBAN number of this account.

Next, pass the data you have collected from your shopper and the payment method type to your server and proceed to step 4 to submit a payment request.

For example:

{
 "type": "sepadirectdebit",
 "sepa.ownerName": "A Schneider",
 "sepa.ibanNumber": "NL13TEST0123456789"
}

Collecting your shopper's card details

If the shopper selects to pay with a Card payment method, you have the following options for collecting card details:

  • If you are PCI Level 1 or 2 certified, you can collect your shopper's raw card data.
  • Otherwise, you need to collect and encrypt your shopper's card data with our Custom card fields component before making a payment request.

    If you are currently using a standalone Secured Fields, we recommend you upgrade to the Components. Older standalone version will still be supported, but new functionality will only be released on Secured Fields Component.

After you have collected your shopper's raw card details or you have received the encrypted details from the Secured Fields component, pass the data along with type: scheme to your server and proceed to step 4 to submit a payment request.

  {
      "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...",
      "holderName" : "S. Hopper"
  }

Step 4: Make a payment

After you've collected payment details from the shopper on your front end, submit a payment request from your server:

  1. Make a POST /payments request specifying the parameters described below, along with other parameters that might be required for your integration.

    For example, you need to include additional fields if you are implementing 3D Secure 2 native or 3D Secure redirect authentication.

    • amount
    • reference: Your unique reference for this payment.
    • paymentMethod: The shopper payment details you have collected from the previous step and the payment method type.
    • returnUrl: URL to where the shopper should be taken back to after a redirection. This is used for payment methods that require redirection to issuer's site, such as iDEAL, or in a 3D Secure authentication flow.
    curl https://checkout-test.adyen.com/v49/payments \
    -H "x-API-key: YOUR_X-API-KEY" \
    -H "content-type: application/json" \
    -d '{
      "amount":{
        "currency":"EUR",
        "value":1000
      },
      "reference":"YOUR_ORDER_NUMBER",
      "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...",
        "holderName" : "S. Hopper"
      },
      "returnUrl":"https://your-company.com/checkout/",
      "merchantAccount":"YOUR_MERCHANT_ACCOUNT"
    }'
    # Set your X-API-KEY with the API key from the Customer Area.
    adyen = Adyen::Client.new
    adyen.api_key = "YOUR_X-API-KEY"
     
    response = adyen.checkout.payments({
      :amount => {
        :currency => "EUR",
        :value => 1000
      },
      :reference => "YOUR_ORDER_NUMBER",
      :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..."
      },
      :returnUrl => "https://your-company.com/checkout/",
      :merchantAccount => "YOUR_MERCHANT_ACCOUNT"
    })
    // Set your X-API-KEY with the API key from the Customer Area.
    Client client = new Client(xApiKey,Environment.TEST);
     
    Checkout checkout = new Checkout(client);
    PaymentsRequest paymentsRequest = new PaymentsRequest();
    paymentsRequest.setMerchantAccount("YOUR_MERCHANT_ACCOUNT");
    Amount amount = new Amount();
    amount.setCurrency("EUR");
    amount.setValue(15000L);
    paymentsRequest.setAmount(amount);
    String encryptedCardNumber = "adyenjs_0_1_18$...encryptedCardNumber";
    String encryptedExpiryMonth = "adyenjs_0_1_18$...encryptedExpiryMonth";
    String encryptedExpiryYear = "adyenjs_0_1_18$...encryptedExpiryYear";
    String encryptedSecurityCode = "adyenjs_0_1_18$...encryptedSecurityCode";
    paymentsRequest.setReference("Your order number");
    paymentsRequest.addEncryptedCardData(encryptedCardNumber,encryptedExpiryMonth, encryptedExpiryYear, encryptedSecurityCode, "John Smith");
    paymentsRequest.setReturnUrl("https://your-company.com/...");
    PaymentsResponse paymentsResponse = checkout.payments(paymentsRequest);
    // Set your X-API-KEY with the API key from the Customer Area.
    $client = new \Adyen\Client();
    $client->setXApiKey("YOUR_X-API-KEY");
    $service = new \Adyen\Service\Checkout($client);
    
    $params = array(
      "amount" => array(
        "currency" => "EUR",
        "value" => 1000
      ),
      "reference" => "YOUR_ORDER_NUMBER",
      "paymentMethod" => array(
        "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..."
      ),
      "returnUrl" => "https://your-company.com/checkout/",
      "merchantAccount" => "YOUR_MERCHANT_ACCOUNT"
    );
    $result = $service->payments($params);
    #Set your X-API-KEY with the API key from the Customer Area.
    adyen = Adyen.Adyen()
    adyen.client.xapikey = 'YOUR_X-API-KEY'
    
    result = adyen.checkout.payments({
       'amount': {
          'value': 1000,
          'currency': 'EUR'
       },
       'reference': 'YOUR_ORDER_NUMBER',
       '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...'
       },
       'returnUrl': 'https://your-company.com/...',
       'merchantAccount': 'YOUR_MERCHANT_ACCOUNT'
    })
    // Set your X-API-KEY with the API key from the Customer Area.
    var client = new Client ("YOUR_X-API-KEY", Environment.Test);
    var checkout = new Checkout(client);
    
    var amount = new Model.Checkout.Amount("EUR", 1000);
    var details = new Model.Checkout.DefaultPaymentMethodDetails{
      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..."
    };
    var paymentsRequest = new Model.Checkout.PaymentRequest
    {
      Reference = "YOUR_ORDER_NUMBER",
      Amount = amount,
      ReturnUrl = @"https://your-company.com/...",
      MerchantAccount = "YOUR_MERCHANT_ACCOUNT",
      PaymentMethod = details
    };
    
    var paymentResponse = checkout.Payments(paymentsRequest);

Response

Depending on the payment result, you'll receive a response containing:

  • resultCode: If the payment has been successfully completed, you will get an Authorised result code. For other possible resultCode values and the actions that you need to take, see Result codes.
  • action: Supported from API version 49 and later. If you get this object in the response, this means that you need to perform additional action on your front end to complete the payment.
  • pspReference: Our unique identifier for the transaction.
  • refusalReason: Returned with resultCode Error or Refused. See refusal reasons for possible values.

    {
       "additionalData": {
           "sepadirectdebit.sequenceType": "OneOff",
           "sepadirectdebit.dateOfSignature": "2019-06-04",
           "sepadirectdebit.mandateId": "851559658348924K",
           "merchantReference": "TEST"
       },
       "pspReference": "851559658348924K",
       "resultCode": "Received"
    }
    {
      "resultCode": "RedirectShopper",
      "action": {
          "method": "POST",
          "paymentData": "Ab02b4c0!BQABAgCW5sxB4e/==",
          "paymentMethodType": "scheme",
          "type": "redirect",
          "url": "https://test.adyen.com/hpp/3d/validate.shtml",
          "data": {
            "PaReq": "eNpVUslygkAQ/RXjB8yCgEi1kyJSq..",
            "TermUrl": "https://your-company.com/...",
            "MD": "ejJydDdDeExyVUFrTEFaMTlITCt_..."
          }
      },
      "details": [
          {
              "key": "MD",
              "type": "text"
          },
          {
              "key": "PaRes",
              "type": "text"
          }
      ],
      "paymentData": "Ab02b4c0!BQABAgCW5sxB4e/=="
    }
  1. The next steps depend on if you received an action object in the response.
    • If you received an action object, you need to perform both step 5 and step 6.
    • If you did not get an action object, proceed to step 7 to present the payment result to your shopper.

Step 5: Perform additional front end actions

If your server received an action object in the /payments response, you need to perform an additional action in your front end. Refer to the specific payment method page to know how you should handle the front end action.

In the example from the previous step, you need to perform action.type: redirect for 3D Secure 1. To complete the 3D Secure 1 authentication, you need to:

  1. Use the url in the /payments response to make an HTTP POST. Append this with the fields you received in the action.data object.

    curl https://test.adyen.com/hpp/3d/validate.shtml \
    --data-urlencode 'PaReq=eNpVUslygkAQ/RXjB8yCgEi1kyJSq..' \
    --data-urlencode 'TermUrl=https://your-company.com/...' \
    --data-urlencode 'MD=ejJydDdDeExyVUFrTEFaMTlITCt_...'
  2. After the shopper has successfully completed 3D Secure verification, the card issuer will redirect them back to your website via an HTTP POST. This will be appended with MD and PaRes variables. Pass both values to your server.

Step 6: Submit additional payment details

If you performed an additional action on your front end in step 5, you need to submit the results to your server.

  1. From your server, make a POST /payments/details request. Refer to the specific payment method page to know the fields that you need to submit.

    For the same 3D Secure 1 example, you need to make a /payments/details request specifying:

    • paymentData: Value you received in the /payments response.
    • MD: Value you received when the shopper was redirected back to your website.
    • PaRes: Value you received when the shopper was redirected back to your website.

      curl https://checkout-test.adyen.com/v49/payments/details \
      -H "x-API-key: YOUR_X-API-KEY" \
      -H "content-type: application/json" \
      -d '{
           "paymentData":Ab02b4c0!BQABAgCW5sxB4e/==",
           "details":{
              "MD":"ejJydDdDeExyVUFrTEFaMTlITCt_...",
              "PaRes":"eNpVUttygjAQ/RXrB5PKQ31Qa..."
           }
      }'
      # Set your X-API-KEY with the API key from the Customer Area.
      adyen = Adyen::Client.new
      adyen.api_key = "YOUR_X-API-KEY"
      
      response = adyen.checkout.payments.details({
        :details => {
          :payload => "sdfsdfsdf..."
        }
      })
      // Set your X-API-KEY with the API key from the Customer Area.
      Client client = new Client(xApiKey,Environment.TEST);
      
      Checkout checkout = new Checkout(client);
      PaymentDetailsRequest paymentDetailsRequest = new PaymentDetailsRequest();
      HashMap<String, String> details = new HashMap<>();
      details.put("payload", "sdfsdfsdf...");
      paymentsDetailsRequest.setDetails(details);
      PaymentsResponse paymentsResponse = checkout.paymentDetails(PaymentDetailsRequest);
      // Set your X-API-KEY with the API key from the Customer Area.
      $client = new \Adyen\Client();
      $client->setXApiKey("YOUR_X-API-KEY");
      $service = new \Adyen\Service\Checkout($client);
      
      $params = array(
        "details" => array(
          "payload" => "sdfsdfsdf..."
        )
      );
      $result = $service->paymentDetails($params);
      #Set your X-API-KEY with the API key from the Customer Area.
      adyen = Adyen.Adyen()
      adyen.client.xapikey = 'YOUR_X-API-KEY'
      
      result = adyen.checkout.payments_details({
         'details': {
            'payload': 'sdfsdfsdf...'
         }
      })
      // Set your X-API-KEY with the API key from the Customer Area.
      var client = new Client ("YOUR_X-API-KEY", Environment.Test);
      var checkout = new Checkout(client);
      
      var details = new Dictionary<string, string>
      {
        { "payload", "Ab02b4c0..." }
      };
      var paymentsDetailsRequest = new Model.Checkout.PaymentsDetailsRequest(Details: details);
      var paymentResponse = checkout.PaymentDetails(paymentsDetailsRequest);

    If the payment was successful you receive:

    • pspReference: Our unique identifier for the transaction.
    • resultCode: Authorised.
  2. The next steps depend on if you received an action object in the response.
    • If you received an action object, perform both step 5 and step 6 again.
    • If you did not get an action object, proceed to the next step to present the payment result to your shopper.

Step 7: Present payment result

If you do not receive an action object from your last API request, this means that the payment has been completed.

Use the resultCode from the response to present the payment result to your shopper. For example:

  • If you get an Authorised result code, inform the shopper that the payment has been successfully completed.
  • If you get an Error or Refused result code, inform the shopper that the payment failed.
  • If you get a Pending or Received resultCode, inform the shopper that you've received their order, and are waiting for the payment to be processed. To receive payment status updates, set up your notification webhooks.

Check out the specific payment method page for the possible result codes that you might receive, or see this list of Result codes for recommended messages that you can present to your shopper.

Notification webhooks

Although in most cases the resultCode you received from the /payments or /payments/details endpoints already indicate the payment result, notifications are the only way to know about the outcome of a payment in cases where:

  • The resultCode is Pending or Received.
  • The shopper completed the payment but failed to return to your website or app.

Make sure that you set up your notification webhooks so you can receive payment status updates.

After we know the outcome of a payment, we will send you a notification containing:

  • eventCode: AUTHORISATION
  • success: Indicates the outcome of the payment. Possible values:

    • true: The payment was successful.
    • false: The payment failed.

Refer to Notification request item to see all the information returned in a notification.

Testing and going live

Before going live, use our list of test cards and other payment methods 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, under TransactionsPayments.

When you've completed testing, there are some additional steps you need to complete before you can accept live payments from shoppers. Refer to Getting started with Adyen for more information. 

When you're ready to move to production, you'll have to switch from test to our live endpoints. See Live endpoints for more information.

Next steps