Search

Are you looking for test card numbers?

Would you like to contact support?

Payment-method icon

Pix for API-only

Accept Pix payments using our APIs, and build your own payment form.

Accept Pix payments using our APIs, and build your own payment form to have full control over the look and feel of your checkout page.

Before you begin

These instructions explain how to add Pix to your existing API-only integration. The API-only integration works the same way for all payment methods. If you haven't done this integration yet, refer to our API-only integration guide.

Before starting your Pix integration:

  1. Make sure that you have set up your back end implementation.
  2. Add Pix in your test Customer Area.

Build your payment form for Pix

Include Pix in the list of available payment methods. If you're using the /paymentMethods endpoint to show which payment methods are available to the shopper, specify in your request:

The response contains:

  • paymentMethod.type: pix

Collect additional parameters in your payment form

After the shopper selects Pix, collect the following optional details from the shopper:

Pass the following data to your server:

  • Payment method type: pix.
  • Data collected from your shopper in the previous step, if any.

Make a payment

From your server, make a /payments request with the following parameters:

Parameter Required Description
paymentMethod.type -white_check_mark- Set to pix.
amount -white_check_mark- The final price of the purchase.
shopperName -white_check_mark- The shopper's firstName and lastName. Keep the length under 200 characters, otherwise it will be truncated.
socialSecurityNumber -white_check_mark- The shopper's CPF or CNPJ number.
shopperStatement -x- Free-text field that will be shown to the shopper. By default this contains the message: $merchantName - Este pagamento PIX para $merchantName é processado por Adyen. If you provide any value, keep the length under 60 characters because this will be appended to the default message.
sessionValidity -x- The expiration date of the Pix payment. The default value is 24 hours, the maximum value is 5 days.
lineItems -x- Information about purchased items.
lineItems.id -x- The name of the purchased item. Maximum 50 characters.
lineItems.amountIncludingTax -x- The price of the purchased item including tax. Maximum 200 characters.

You need to send both shopperName and socialSecurityNumber because this information will be shown to the shopper to help identify the payment.

curl https://checkout-test.adyen.com/v66/payments \
-H "x-API-key: YOUR_X-API-KEY" \
-H "content-type: application/json" \
-d '{
    "merchantAccount": "YOUR_MERCHANT_ACCOUNT",
    "amount": {
        "currency": "BRL",
        "value": 100000
    },
    "paymentMethod": {
        "type": "pix"
    },
    "sessionValidity":"2021-12-21T13:00:00-03:00",
    "shopperStatement": "Merchant message to the shopper.",
    "shopperName": {
        "firstName": "Jose",
        "infix": "da",
        "lastName": "Silva"
    },
    "socialSecurityNumber": "01234567890",
    "lineItems": [
        {
            "id": "Item 1",
            "amountIncludingTax": "40000"
        },
        {
            "id": "Item 2",
            "amountIncludingTax": "60000"
        }
    ],
    "reference": "YOUR_ORDER_NUMBER"
}'
# 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({
  :merchantAccount => "YOUR_MERCHANT_ACCOUNT",
  :amount => {
    :currency => "BRL",
    :value => 100000
  },
  :paymentMethod => {
    :type => "pix"
  },
  :sessionValidity => "2021-12-21T13:00:00-03:00",
  :shopperStatement => "Merchant message to the shopper.",
  :shopperName => {
      :firstName => "Jose",
      :infix => "da",
      :lastName => "Silva"
  },
  :socialSecurityNumber => "01234567890",
  :lineItems => [
      {
          :id => "Item 1",
          :amountIncludingTax => "40000"
      },
      {
          :id => "Item 2",
          :amountIncludingTax => "60000"
      }
  ]
  :reference => "YOUR_ORDER_NUMBER"
})
// Set YOUR_X-API-KEY with the API key from the Customer Area.
// Change to Environment.LIVE and add the Live URL prefix when you're ready to accept live payments.
Client client = new Client("YOUR_X-API-KEY", Environment.TEST);
Checkout checkout = new Checkout(client);

PaymentsRequest paymentsRequest = new PaymentsRequest();

String merchantAccount = "YOUR_MERCHANT_ACCOUNT";
paymentsRequest.setMerchantAccount(merchantAccount);

Amount amount = new Amount();
amount.setCurrency("BRL");
amount.setValue(100000L);
paymentsRequest.setAmount(amount);

DefaultPaymentMethodDetails paymentMethodDetails = new DefaultPaymentMethodDetails();
paymentMethodDetails.setType("pix");
paymentsRequest.setPaymentMethod(paymentMethodDetails);

String sessionValidity = "2021-12-21T13:00:00-03:00";
String shopperStatement = "Merchant message to the shopper.";

ShopperName shopperName = new ShopperName();
shopperName.setFirstName("Jose");
shopperName.setInfix("da");
shopperName.setLastName("Silva");
paymentsRequest.setShopperName(shopperName);

String socialSecurityNumber = "01234567890";

List<LineItem> lineItems = new ArrayList<>();
lineItems.add(
        new LineItem()
                .id("Item 1")
                .amountIncludingTax(40000L)
);
lineItems.add(
        new LineItem()
                .id("Item 2")
                .amountIncludingTax(60000L)
);

paymentsRequest.setReference("YOUR_ORDER_NUMBER");

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 = [
  "merchantAccount" => "YOUR_MERCHANT_ACCOUNT",
  "amount" => [
    "currency" => "BRL",
    "value" => 100000
  ],
  "paymentMethod" => [
    "type" => "pix"
  ],
  "sessionValidity" => "2021-12-21T13:00:00-03:00",
  "shopperStatement" => "Merchant message to the shopper.",
  "shopperName" => [
      "firstName" => "Jose",
      "infix" => "da",
      "lastName" => "Silva"
  ],
  "socialSecurityNumber" => "01234567890",
  "lineItems": [
    [
        "id" => "Item 1",
        "amountIncludingTax" => "40000"
    ],
    [
        "id" => "Item 2",
        "amountIncludingTax" => "60000"
    ]
  ],
  "reference" => "YOUR_ORDER_NUMBER"
];
$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({
  "merchantAccount": "YOUR_MERCHANT_ACCOUNT",
  "reference": "YOUR_ORDER_NUMBER",
  "paymentMethod": {
    "type": "pix"
  },
  "amount": {
    "currency": "BRL",
    "value": 100000
  },
  "sessionValidity":"2021-12-21T13:00:00-03:00",
  "shopperStatement": "Merchant message to the shopper.",
  "shopperName": {
    "firstName": "Jose",
    "infix": "da",
    "lastName": "Silva"
  },
  "socialSecurityNumber": "01234567890",
  "lineItems": [
    {
      "id": "Item 1",
      "amountIncludingTax": "40000"
    },
    {
      "id": "Item 2",
      "amountIncludingTax": "60000"
    }
  ]
})
// 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 paymentRequest = new Adyen.Model.Checkout.PaymentRequest
{
   MerchantAccount = "YOUR_MERCHANT_ACCOUNT",
   Reference = "YOUR_ORDER_NUMBER",
   PaymentMethod = new DefaultPaymentMethodDetails { Type = "pix" },
   Amount = new Model.Checkout.Amount(Currency: "BRL", Value: 100000),
   SessionValidity = "2021-12-21T13:00:00-03:00",
   ShopperStatement = "Merchant message to the shopper.",
   ShopperName = new Model.Checkout.Name
   {
       FirstName = "Jose",
       Infix = "da"
       LastName = "Silva"
   },
   SocialSecurityNumber = "01234567890",
   LineItems = new List<LineItem>
{
   new LineItem(Id:"Item 1", AmountIncludingTax:40000),
   new LineItem(Id:"Item 2", AmountIncludingTax:60000)
}
return paymentRequest;
}
// Set your X-API-KEY with the API key from the Customer Area.
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 = '[API_KEY]';
config.merchantAccount = '[MERCHANT_ACCOUNT]';
const client = new Client({ config });
client.setEnvironment("TEST");
const checkout = new CheckoutAPI(client);
checkout.payments({
  merchantAccount: "YOUR_MERCHANT_ACCOUNT",
  reference: "YOUR_ORDER_NUMBER",
  paymentMethod: {
     type: "pix"
  },
  amount: {
     currency: "BRL",
     value: "100000"
  },
  sessionValidity: "2021-12-21T13:00:00-03:00",
  shopperStatement: "Merchant message to the shopper.",
  shopperName: {
     firstName": "Jose",
     infix": "da",
     lastName": "Silva"
  },
  socialSecurityNumber: "01234567890",
  lineItems: [
     {
        id: "item1",
        amountIncludingTax: "5000"
     },
     {
        id: "item2",
        amountIncludingTax: "10000"
     }
  ]
}).then(res => res);

The response contains the following:

  • resultCode: Pending
  • action: Contains the QR code URL and QR code data.
/payments response
{
    "resultCode": "Pending",
    "action": {
        "paymentData": "Ab02b4c0!BQABAgBIdtXNUNfQV/Glq0A6cfYBPKFJiNUn4...",
        "paymentMethodType": "pix",
        "url": "http://localhost:8080/hpp/generateQRCodeImage.shtml?url=00020101021226930014br.gov.bcb.pix2571api-h.developer.btgpactual.com%2Fv1%2Fp%2Fv2%2Fef31fdec9d6148a6831481b43f64a3dc520400005303986540510.005802BR5914Adyen+Merchant6015Cidade+da+Adyen61082000000062070503***6304DCEB",
        "qrCodeData": "00020101021226930014br.gov.bcb.pix2571api-h.developer.btgpactual.com/v1/p/v2/ef31fdec9d6148a6831481b43f64a3dc520400005303986540510.005802BR5914Adyen Merchant6015Cidade da Adyen61082000000062070503***6304DCEB",
        "type": "qrCode"
    }
}

Transaction conditions

Before approving the payment, Pix performs the following checks:

  • The shopper has sufficient funds in their transactional account.
  • The transaction time did not exceed the maximum time defined by the Central Bank.
  • There is no suspicion of fraud or breach of regulations to prevent money laundering and terrorist financing.
  • There is no authentication problems in the shopper’s financial or payment institution transactional account.
  • The shopper has not been excluded from their institution participating in Pix.

Adyen or the acquirer bank can reject the transaction in the following cases:

  • Suspicion of fraud or breach of regulations to prevent money laundering and terrorist financing.
  • Technical issue in the Pix ecosystem.

Render the QR code or present QR code data

Use the information in the action object of the /payments response to render the QR code or present the QR code data to the shopper.

  • action.url: Use this URL to download the QR code.
  • action.qrCodeData: Use this to render the QR Code on your checkout page or present as-is to the shopper to copy it.

The shopper can either scan the QR code, or copy the QR code data to paste to their banking or wallet app.

Payment result

After the shopper scans the QR code and completes the payment, you will receive the result of the payment asynchronously in a notification webhook.

Here's an example of a standard notification you may receive.

{
    "live":"false",
    "notificationItems": [
        {
            "NotificationRequestItem": {
                "additionalData": {
                    ...
                    "pix.originalAmountValue":"100000",
                    "pix.originalAmountCurrency":"BRL"
                },
                "amount": {
                    "currency":"BRL",
                    "value":100000
                },
                "eventCode":"AUTHORISATION",
                "eventDate":"2021-12-21T20:49:23-03:00",
                "merchantAccountCode":"YOUR_MERCHANT_ACCOUNT",
                "merchantReference":"YOUR_REFERENCE",
                "paymentMethod":"pix",
                "pspReference":"991607125682053H",
                "success":"true",
                ...
            }
        }
    ]
}
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"  xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soap:Body>
    <ns1:sendNotification xmlns:ns1="http://notification.services.adyen.com">
      <ns1:Notification>
        <live xmlns="http://notification.services.adyen.com">false</live>
        <notificationItems xmlns="http://notification.services.adyen.com">
          <NotificationRequestItem>
            <additionalData>
              <pix.originalAmountCurrency>BRL</pix.originalAmountCurrency>
              <pix.originalAmountValue>100000</pix.originalAmountValue>
            </additionalData>
            <amount>
              <currency xmlns="http://common.services.adyen.com">BRL</currency>
              <value xmlns="http://common.services.adyen.com">100000</value>
            </amount>
            <eventCode>AUTHORISATION</eventCode>
            <eventDate>2021-12-21T20:49:23-03:00</eventDate>
            <merchantAccountCode>YOUR_MERCHANT_ACCOUNT</merchantAccountCode>
            <merchantReference>YOUR_TRANSACTION_REFERENCE</merchantReference>
            <paymentMethod>pix</paymentMethod>
            <pspReference>991607125682053H</pspReference>
            <success>true</success>
          </NotificationRequestItem>
        </notificationItems>
      </ns1:Notification>
    </ns1:sendNotification>
  </soap:Body>
</soap:Envelope>

For more information about notifications, refer to Understanding notifications.

Compare original and paid amount

With Pix, shoppers can manually modify the amount they pay in their banking or wallet app after scanning the QR code or pasting the QR code data. Make sure to implement some business logic that matches additionalData.pix.originalAmountValue and amount.value.

If the actual paid amount doesn't match the original amount, we recommend that you cancel the payment and make a refund.

Refunds

You can refund a payment within 90 days after the payment in the Customer Area or via an API.

Test and go live

Pix is an asynchronous payment method. To be able to test this, make sure you have the following user roles in your test Customer Area:

  • Merchant view offers: This allows you to see Pix offers that are in the "Pending" state.
  • Promote offers to sale (test): This allows you to promote a Pix offer from "Pending" to "Authorised". This way you can test what happens when we process the payment. This permission is only available in TEST.

Check the status of Pix test payments in your Customer Area:

  • Pix payments that are pending or that have expired, are under TransactionsOffers.
  • Pix payments that have been paid (including test offers that you manually promoted to sale), are under Transactions > Payments.

Test the reconciliation process by promoting test payments from offer to sale in your test Customer Area.
Before you can accept live Pix payments, you need to submit a request for Pix in your live Customer Area.

See also