Search

Are you looking for test card numbers?

Would you like to contact support?

Creating tokens

Save a shopper's payment method with Adyen.

Tokens with Adyen are based on the concept of a shopper who can have one or more tokenized payment methods.

To create a token for a shopper's payment method, you need to submit a payment request with a shopperReference, your own unique id for the shopper. The token is created only after a successful payment authorization. This ensures that the payment details the shopper provided is linked to an active, chargeable account.

You use the same endpoint when you make a payment request for the first transaction in a subscription or contract, or to store a shopper's card details for future transactions. If the payment is successful, we return the recurringDetailReference in the response. You will use both the shopperReference and the associated recurringDetailReference when you make future payments.

Depending on your business case, you can also submit a zero-auth card payment request with a zero amount to tokenize card payment details.

For card payments, our Drop-in and Components solutions also support showing a checkbox to offer your shoppers the option to store their card details for future use.

You can store maximum of 100 payment details associated with the same shopperReference.

Showing the option to save and tokenize card details

For card payments, you can show a checkbox to store your shopper's card details with the following integrations:

  • Our Drop-in solution for Web and iOS.
  • Our pre-built Card Component for Web and iOS.

Alternatively, you can also build your own UI to show the checkbox.

Web Drop-in

Set enableStoreDetails to true in your Drop-in configuration.

const dropin = checkout
.create('dropin', {
  paymentMethodsConfiguration: {
    card: {
      enableStoreDetails: true,
    }
  }
  // Other configuration here
.mount('#dropin');

Follow the same procedure for collecting your shopper's card details and their preference for storing their card details. After Drop-in returns the state.data, pass this to your server and proceed to submit a payment request.

iOS Drop-in

Set showsStorePaymentMethodField to true in your Drop-in configuration. This configuration option is available from Adyen iOS 3.1.1 and later.

let configuration = DropInComponent.PaymentMethodsConfiguration()
configuration.card.publicKey = "..." // Your public key, retrieved from the Customer Area.
configuration.card.showsStorePaymentMethodField = true

Follow the same procedure for collecting your shopper's card details and their preference for storing their card details. After Drop-in returns data.paymentMethod, pass this to your server and proceed to submit a payment request.

Web Card Component

Set enableStoreDetails to true when instantiating your Web Card Component:

const card = checkout.create("card", {
    enableStoreDetails: true
}).mount("#card");

Follow the same procedure for collecting your shopper's card details and their preference for storing their card details. After Component returns the state.data, pass this to your server and proceed to submit a payment request.

iOS Card Component

Include the showsStorePaymentMethodField in your Drop-in configuration. This configuration option is available from Adyen iOS 3.1.1 and later.

let cardComponent = CardComponent(paymentMethod: cardPaymentMethod,
 publicKey: "YOUR_PUBLIC_KEY")
 cardComponent.showsStorePaymentMethodField = true
 cardComponent.delegate = self
 cardComponent.environment = .test
 present(cardComponent.viewController, animated: true)

Follow the same procedure for collecting your shopper's card details and their preference for storing their card details. After the Component returns data.paymentMethod, pass this to your server and proceed to submit a payment request.

Making a payment and tokenizing payment details

When you make the payment request for the first transaction in a subscription or contract, or to store a shopper's card details for future transactions, you use the same /payments endpoint. Make sure that you provide the applicable parameters to set the right recurring transaction type.

  1. From your server, make a POST /payments request and include the following values:

    • shopperReference: Your unique identifier for the shopper.
    • shopperInteraction: Set this to the applicable value for your business model. See shopper interaction.
    • recurringProcessingModel: Set this to the applicable value for your business model. See recurring processing model.
    • paymentMethod: Object that contains the shopper's payment details. If you are tokenizing card details, this object also includes the indicator that the shopper agreed to store card details.

      If you are using Drop-in or Card Component, pass the data returned in the events and send it in this object. For example, send the data.paymentMethod from your iOS Drop-in and Card Component or state.data from your Web Drop-in and Card Component.

      If you are tokenizing card details, you can also collect the following values with your own UI:

      • amount: Contains the currency and value of the transaction.
      • paymentMethod.type: Set this to scheme.
      • encryptedCardNumber: The encrypted card number.
      • encryptedExpiryMonth: The encrypted card expiry month.
      • encryptedExpiryYear: The encrypted card expiry year.
      • encryptedSecurityCode: The encrypted card verification code.
      • holderName: The card holder's name. Required for 3D Secure authentication.
      • storeDetails: Set this to true if the shopper agreed to store their card details for future payments on your site or app.

    In some business cases, the shopper may not purchase anything on the first transaction. Examples are subscription models where the first month is free or when shoppers are just storing their card details for future use. For these business cases, you can use zero-auth transactions. Specify the amount.value to 0 to validate the card details.

    If you are implementing 3D Secure for PSD2 SCA compliance, issuing banks might require SCA for zero-auth transactions. Contact our Support Team to enable 3D Secure for zero-auth transactions.

    Sample request for storing a shopper's card details for future payments

    curl https://checkout-test.adyen.com/v46/payments \
    -H "X-API-key: [Your API Key here]" \
    -H "Content-Type: application/json" \
    -d '{
       "amount":{
          "value":0,
          "currency":"USD"
       },
       "paymentMethod":{
          "type":"scheme",
          "number":"4111111111111111",
          "expiryMonth":"10",
          "expiryYear":"2020",
          "cvc":"737",
          "holderName":"John Smith",
          "storeDetails":true
       },
       "reference":"YOUR_ORDER_NUMBER",
       "merchantAccount":"YOUR_MERCHANT_ACCOUNT",
       "shopperReference":"YOUR_UNIQUE_SHOPPER_ID_IOfW3k9G2PvXFu2j",
       "returnUrl":"https://your-company.com/..."
    }'
    # 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 => "USD",
        :value => 0
      },
      :reference => "YOUR_ORDER_NUMBER",
      :paymentMethod => {
        :type => "scheme",
        :number => "4111111111111111",
        :expiryMonth => "10",
        :expiryYear => "2020",
        :cvc => "737",
        :storeDetails => true
      },
      :shopperReference => "YOUR_UNIQUE_SHOPPER_ID_IOfW3k9G2PvXFu2j",
      :returnUrl => "https://your-company.com/...",
      :merchantAccount => "YOUR_MERCHANT_ACCOUNT"
    })
    // Set your X-API-KEY with the API key from the Customer Area.
    Config config = new Config();
    config.setApiKey("Your X-API-KEY"));
    Client client = new Client(config);
     
    Checkout checkout = new Checkout(client);
    PaymentsRequest paymentsRequest = new PaymentsRequest();
    Amount amount = new Amount();
    amount.setCurrency("USD");
    amount.setValue(0L);
    paymentsRequest.setAmount(amount);
    paymentsRequest.setReference("YOUR_ORDER_NUMBER");
    paymentsRequest.setPaymentMethod(new HashMap<String, String>());
    paymentsRequest.putPaymentMethodItem("type","scheme");
    paymentsRequest.putPaymentMethodItem("number", "4111111111111111");
    paymentsRequest.putPaymentMethodItem("expiryMonth", "10");
    paymentsRequest.putPaymentMethodItem("expiryYear", "2020");
    paymentsRequest.putPaymentMethodItem("cvc", "737");
    paymentsRequest.putPaymentMethodItem("storeDetails", "true");
    paymentsRequest.setShopperReference("YOUR_UNIQUE_SHOPPER_ID_IOfW3k9G2PvXFu2j");
    paymentsRequest.setReturnUrl("https://your-company.com/...");
    paymentsRequest.setMerchantAccount("YOUR_MERCHANT_ACCOUNT");
    PaymentsResponse response = 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" => "USD",
        "value" => 0
      ),
      "reference" => "Your order number",
      "paymentMethod" => array(
        "type" => "scheme",
        "number" => "4111111111111111",
        "expiryMonth" => "10",
        "expiryYear" => "2020",
        "cvc" => "737",
        "holderName" => "John Smith",
        "storeDetails" => true
      ),
      "returnUrl" => "https://your-company.com/checkout/",
      "merchantAccount" => "YOUR_MERCHANT_ACCOUNT",
      "reference" => "YOUR_ORDER_NUMBER",
      "shopperReference" => "YOUR_UNIQUE_SHOPPER_ID_IOfW3k9G2PvXFu2j",
      "returnUrl" => "https://your-company.com/..."
    );
    $result = $service->payments($params);

    Sample request for a first transaction for a subscription

    curl https://checkout-test.adyen.com/v49/payments \
    -H "X-API-key: [Your API Key here]" \
    -H "Content-Type: application/json" \
    -d '{
       "amount":{
          "value":0,
          "currency":"USD"
       },
       "paymentMethod":{
          "type":"scheme",
          "number":"4111111111111111",
          "expiryMonth":"10",
          "expiryYear":"2020",
          "cvc":"737",
          "holderName":"John Smith",
       },
       "reference":"YOUR_ORDER_NUMBER",
       "shopperInteraction": "Ecommerce",
       "recurringProcessingModel": "Subscription",
       "merchantAccount":"YOUR_MERCHANT_ACCOUNT",
       "shopperReference":"YOUR_UNIQUE_SHOPPER_ID_IOfW3k9G2PvXFu2j",
       "returnUrl":"https://your-company.com/..."
    }'
    # 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 => "USD",
        :value => 0
      },
      :reference => "YOUR_ORDER_NUMBER",
      :paymentMethod => {
        :type => "scheme",
        :number => "4111111111111111",
        :expiryMonth => "10",
        :expiryYear => "2020",
        :cvc => "737",
        :storeDetails => true
      },
      :shopperReference => "YOUR_UNIQUE_SHOPPER_ID_IOfW3k9G2PvXFu2j",
      :returnUrl => "https://your-company.com/...",
      :merchantAccount => "YOUR_MERCHANT_ACCOUNT"
    })
    // Set your X-API-KEY with the API key from the Customer Area.
    Config config = new Config();
    config.setApiKey("Your X-API-KEY"));
    Client client = new Client(config);
     
    Checkout checkout = new Checkout(client);
    PaymentsRequest paymentsRequest = new PaymentsRequest();
    Amount amount = new Amount();
    amount.setCurrency("USD");
    amount.setValue(0L);
    paymentsRequest.setAmount(amount);
    paymentsRequest.setReference("YOUR_ORDER_NUMBER");
    paymentsRequest.setPaymentMethod(new HashMap<String, String>());
    paymentsRequest.putPaymentMethodItem("type","scheme");
    paymentsRequest.putPaymentMethodItem("number", "4111111111111111");
    paymentsRequest.putPaymentMethodItem("expiryMonth", "10");
    paymentsRequest.putPaymentMethodItem("expiryYear", "2020");
    paymentsRequest.putPaymentMethodItem("cvc", "737");
    paymentsRequest.putPaymentMethodItem("storeDetails", "true");
    paymentsRequest.setShopperReference("YOUR_UNIQUE_SHOPPER_ID_IOfW3k9G2PvXFu2j");
    paymentsRequest.setReturnUrl("https://your-company.com/...");
    paymentsRequest.setMerchantAccount("YOUR_MERCHANT_ACCOUNT");
    PaymentsResponse response = 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" => "USD",
        "value" => 0
      ),
      "reference" => "Your order number",
      "paymentMethod" => array(
        "type" => "scheme",
        "number" => "4111111111111111",
        "expiryMonth" => "10",
        "expiryYear" => "2020",
        "cvc" => "737",
        "holderName" => "John Smith",
        "storeDetails" => true
      ),
      "returnUrl" => "https://your-company.com/checkout/",
      "merchantAccount" => "YOUR_MERCHANT_ACCOUNT",
      "reference" => "YOUR_ORDER_NUMBER",
      "shopperReference" => "YOUR_UNIQUE_SHOPPER_ID_IOfW3k9G2PvXFu2j",
      "returnUrl" => "https://your-company.com/..."
    );
    $result = $service->payments($params);

    If the payment is successful, the resultCode will be Authorised, the payment detail will be tokenized, and a recurringDetailReference will be returned in the response.

    The recurringDetailReference is not returned synchronously by default. To enable synchronous tokens, log in to your Customer Area, navigate to Account > API URLs > Additional Data settings, and select Recurring details.

    {
    "additionalData": {
      "recurring.recurringDetailReference":"7219687191761347",
      "recurring.shopperReference": "YOUR_UNIQUE_SHOPPER_ID_IOfW3k9G2PvXFu2j"
    },
    "pspReference":"8814689190961342",
    "resultCode":"Authorised"
    }
  2. Save the recurringDetailReference. You will use the recurringDetailReference and the originally provided shopperReference to make future payments.

Pending and Refusal result codes

For some payment methods, you might not receive an Authorised immediately and instead receive a Pending status. In these cases, the payment details have not yet been tokenized. Instead, they will be tokenized once the payment as reached the Authorised status. You will receive this updated status via a webhook from our Notification service.

If you receive a resultCode with Refused, then the details were not tokenized and you need to submit another payment request in order to try tokenizing again.

Next steps