Pix: Instant Payments in Brazil

Pix is the instant payments ecosystem implementation led by the Central Bank of Brazil (BCB) to enable online money transfers with reduced costs, increased safety and 24/7 availability. Transfers occur directly from the payer’s account to the payee’s account, without the need for intermediaries, resulting in lower transaction costs.

Pix will be available for persons and businesses. Both need to have an identifier key registered in some financial entity - banks, fintechs or payment institutions - to proceed with the transaction. According to the eligibility criteria set forth by the BCB, certain entities will be required to offer this payment method, while others may optionally offer it or not be eligible to participate.

In this step, we’ll explain how to extend your Payment Provider Protocol implementation to allow stores to offer Pix as an additional payment method to their clients.

These are some of the benefits of an instant payments ecosystem [highlighted by the BCB](https://www.bcb.gov.br/en/financialstability/instantpayments)These are some of the benefits of an instant payments ecosystem [highlighted by the BCB](https://www.bcb.gov.br/en/financialstability/instantpayments)

These are some of the benefits of an instant payments ecosystem highlighted by the BCB

👍

Pix in e-commerce: everything you need to know

If you want to know more instant payments in Brazil, we have prepared a blog post with all the implications of this new payment method. You can also check out the FAQ provided by the BCB for more details.

🚧

Are you ready for a Payment Provider implementation?

This tutorial assumes you are already a VTEX Partner and understand how the Payment Provider Protocol works.

📘

Expected launch: November 2020

On November 3th, the BCB will realize some transactions strictly for tests.
On November 16th, Pix will be available for operations working fully.

Integration conditions

If you are ready to develop the middleware that implements our Payment Provider Protocol, you should be aware of these requirements:

  • All endpoints must be served over HTTPS on port 443 with TLS 1.2 support. Connections over non-secured HTTP will not be accepted under any circumstances.

  • The integrator must create a subdomain or a domain name for the provider endpoints. IP addresses will not be accepted as names under any circumstances.

  • The middleware must consistently respond within established response times. We enforce a maximum response time of 5 seconds for homologation tests, as well as a maximum response time of 20 seconds to any other API request.

While our protocol describes ten endpoints for implementation, not all of them are applicable when integrating Pix instant payments. Regarding the two provider flows:

The table below gives further detail on the applicability of each endpoint to Pix instant payments. More details on the integration steps are given in the rest of this tutorial.

Provider Flow

Endpoint

Applicable to Pix?

Payment

List Payment Methods

:warning: Obsolete

Payment

List Payment Provider Manifest

:white-check-mark: Yes

Payment

Create Payment

:white-check-mark: Yes

Payment

Cancel Payment

:white-check-mark: Yes

Payment

Capture Payment

:white-check-mark: Yes

Payment

Refund Payment

:white-check-mark: Yes

Payment

Inbound Request (BETA)

:white-check-mark: Yes

Configuration

Create Authorization Token

:x: No

Configuration

Provider Authentication

:x: No

Configuration

Get Credentials

:x: No

📘

Marketplace restrictions

Pix is not available for marketplace clients that use the Checkout Split.

❗️

GET List Payment Methods route

We strongly advise against using the GETList Payment Methods to proceed with the implementation. This route is obsolete and it will be deprecated in soon - early 2021

🚧

Request and response examples

The following JSONs are just examples. Each partner must adapt the models to their own realities, with the data needed to realize the integration.

Integration steps

Establish the payment methods available

The first information your provider has to inform us is which are the payment methods that it handles. To do so, you can make an API call using the GETList Payment Provider Manifest route.

The expected response is:

{
    "paymentMethods": [
        {
            "name": "Visa",
            "allowsSplit": "onCapture"
        },
        { 
            "name": "Pix",
            "allowsSplit": "disabled"
        },
        {
            "name": "Mastercard",
            "allowsSplit": "onCapture"
        },
        {
            "name": "American Express",
            "allowsSplit": "onCapture"
        },
        {
            "name": "BankInvoice",
            "allowsSplit": "onAuthorize"
        },
        {
            "name": "Privatelabels",
            "allowsSplit": "disabled"
        },
        {
            "name": "Promissories",
            "allowsSplit": "disabled"
        }
    ],
    "customFields": [
        {
            "name": "Merchant's custom field",
            "type": "text"
        },
        {
            "name": "Merchant's custom select field",
            "type": "select",
            "options": [
                {
                    "text": "Field option 1",
                    "value": "1",
                },
                {
                    "text": "Field option 2",
                    "value": "2",
                },
                {
                    "text": "Field option 3",
                    "value": "3",
                }
            ]
        }
    ]
}

🚧

Payment split for Pix

Pix does not handle payment split yet, this functionality will be released soon.

For more details, check the complete documentation.

Create Pix Payment Method

Now you have to create a new payment method and there’s only one route as an option: POSTCreate Payment.

There’s a lot of information needed stem from the cart data in the Smart Checkout, so be careful and validate all the payload’s information.

The request goes like this:

{
    "reference": "32478982",
    "orderId": "v967373115140abc",
    "transactionId": "D3AA1FC8372E430E8236649DB5EBD08E",
    "paymentId": "F5C1A4E20D3B4E07B7E871F5B5BC9F91",
    "paymentMethod": "Pix",
    "paymentMethodCustomCode": null,
    "merchantName": "mystore",
    "value": 4307.23,
    "currency": "BRL",
    "installments": 31,
    "deviceFingerprint": "12ade389087fe",
    "card": {
        "holder": null,
        "number": null,
        "csc": null,
        "expiration": {
            "month": null,
            "year": null
        }
    },
    "miniCart": {
        "shippingValue": 11.44,
        "taxValue": 10.01,
        "buyer": {
            "id": "c1245228-1c68-11e6-94ac-0afa86a846a5",
            "firstName": "John",
            "lastName": "Doe",
            "document": "01234567890",
            "documentType": "CPF",
            "email": "[email protected]",
            "phone": "+5521987654321"
        },
        "shippingAddress": {
            "country": "BRA",
            "street": "Praia de Botafogo St.",
            "number": "300",
            "complement": "3rd Floor",
            "neighborhood": "Botafogo",
            "postalCode": "22250040",
            "city": "Rio de Janeiro",
            "state": "RJ"
        },
        "billingAddress": {
            "country": "BRA",
            "street": "Brigadeiro Faria Lima Avenue",
            "number": "4440",
            "complement": "10th Floor",
            "neighborhood": "Itaim Bibi",
            "postalCode": "04538132",
            "city": "São Paulo",
            "state": "SP"
        },
        "items": [
            {
                "id": "132981",
                "name": "My First Product",
                "price": 2134.90,
                "quantity": 2,
                "discount": 5.00
            },
            {
                "id": "123242",
                "name": "My Second Product",
                "price": 21.98,
                "quantity": 1,
                "discount": 1.00
            }
        ]
    },
    "url": "https://admin.mystore.example.com/orders/v32478982",
    "callbackUrl": "https://api.example.com/some-path/to-notify/status-changes?an=mystore",
    "returnUrl": "https://mystore.example.com/checkout/order/v32478982"
}'

As a result, we expect the following response:

❗️

Establish an organized flow

Have in mind that, by default, the QRCode must have five minutes (300 seconds) expiration time. Also, the partner must respect the callback time (20 seconds).

{
  "paymentId": "F5C1A4E20D3B4E07B7E871F5B5BC9F91",
  "status": "undefined",
  "tid": "TID1578324421",
  "authorizationId": null,
  "nsu": null,
  "code": "APP123",
  "paymentAppData": {
    "payload": "{\"code\":\"https://bacen.pix/pix/code\",\"qrCodeBase64Image\":\"iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAABQGlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGDiSSwoyGFhYGDIzSspCnJ3UoiIjFJgf8LAxSDMwMkgwiCZmFxc4BgQ4ANUwgCjUcG3awyMIPqyLsgspwWXFu+Xeyundb6w0WL33C5M9SiAKyW1OBlI/wHihOSCohIGBsYYIFu5vKQAxG4AskWKgI4CsqeA2OkQ9goQOwnC3gNWExLkDGRfALIFkjMSU4DsB0C2ThKSeDoSG2ovCLAZGZkbhBNwKKmgJLWiBEQ75xdUFmWmZ5QoOAJDJ1XBMy9ZT0fByMDIgIEBFNYQ1Z9vgMOQUYwDIZapzMBgmQEUfIQQSxNmYNiZzsDAU4UQU5/PwMBrxMBw5GJBYlEi3AGM31iK04yNIGzu7QwMrNP+//8M9Ca7JgPD3+v////e/v//32UMDMy3GBgOfAMA4+RdqZ9YRkcAAABWZVhJZk1NACoAAAAIAAGHaQAEAAAAAQAAABoAAAAAAAOShgAHAAAAEgAAAESgAgAEAAAAAQAAAAKgAwAEAAAAAQAAAAIAAAAAQVNDSUkAAABTY3JlZW5zaG900Fpo3gAAAdJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MjwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlVzZXJDb21tZW50PlNjcmVlbnNob3Q8L2V4aWY6VXNlckNvbW1lbnQ+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4yPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Cl89Cn4AAAASSURBVAgdY/wPBAxAwAQiQAAAPfgEAIAu9DkAAAAASUVORK5CYII=\"}"
  },
  "message": "The customer needs to finish the payment flow",
  "delayToAutoSettle": 1209600,
  "delayToAutoSettleAfterAntifraud": 120,
  "delayToCancel": 300
}

The complete documentation is here.

Cancel a Payment

To cancel a payment, you must already have created one. To do so, you’ll make an API call using the route POSTCancel Payment:

{
    "paymentId": "F5C1A4E20D3B4E07B7E871F5B5BC9F91",
    "requestId": "1234"
}

After the provider realizes the payment cancelation, we expect is a response like this:

{
    "paymentId": "F5C1A4E20D3B4E07B7E871F5B5BC9F91",
    "message": "Successfully cancelled",
    "code": null,
    "cancellationId": "1457BD07E6",
    "requestId": "1234"
}

See the complete documentation for more details.

Capture Payment

If your transaction was completed successfully, the provider can capture the payment.

So, to capture payment, VTEX will send the information below through the POSTCapture Payment route:

{
    "paymentId": "5B127F1E0C944EF9ACE264FEC1FC0E91",
    "transactionId": "611966",
    "value": 20.0,
    "requestId": "5678"
}

The response should be similar to the following response body:

{
    "paymentId": "5B127F1E0C944EF9ACE264FEC1FC0E91",
    "settleId": "CEE16492C6",
    "value": 20.0,
    "code": null,
    "message": null,
    "requestId": "5678"
}

You can check more details in the endpoint’s documentation.

Refund Payment

The provider should be ready to receive the following request through the POSTRefund Payment route:

{
    "paymentId": "VQKIIBUVOFDBIDLKZPOWSKETDYWCMJSACDVXWFCJVSKXGYVBBVISZRJLLQEKERJEMDYEINOUMFAZZGNEDVBQBABLUKLFBSEEIGLCAQTOGOGURKLFCAHJQTDMBNKYBIST",
    "transactionId": "611966",
    "settleId": "31018A3281",
    "value": 10.0,
    "requestId": "5678"
}

The expected response is:

{
    "paymentId": "VQKIIBUVOFDBIDLKZPOWSKETDYWCMJSACDVXWFCJVSKXGYVBBVISZRJLLQEKERJEMDYEINOUMFAZZGNEDVBQBABLUKLFBSEEIGLCAQTOGOGURKLFCAHJQTDMBNKYBIST",
    "refundId": null,
    "value": 0.0,
    "code": "refund-manually",
    "message": "Refund should be done manually",
    "requestId": "5678"
}

Go to the route’s documentation to check all the details.

Communicate with the Gateway

The last route - POSTInbound Request (BETA) - implements an URL that facilitates a direct connection between our Gateway service and the Payment Provider.

The request will be:

'{
    "requestId": "LA4E20D3B4E07B7E871F5B5BC9F91",
    "transactionId": "D3AA1FC8372E430E8236649DB5EBD08E",
    "paymentId": "F5C1A4E20D3B4E07B7E871F5B5BC9F91",
    "authorizationId": "{{authorizationId}}",
    "tid": "{{tid}}",
    "requestData": {
        "body": "{{originalRequestBody}}"
    }
}'

As a result, the client should send the following response:

{
    "requestId": "{{requestId}}",
    "transactionId": "{{transactionId}}",
    "paymentId": "{{paymentId}}",
    "authorizationId": "{{authorizationId}}",
    "tid": "{{tid}}",
    "requestData": {
        "body": "{{originalRequestBody}}"
    }
}

📘

Not required for Payment App

The Inbound Request (BETA) is mandatory only for integrations via Payment Provider Protocol with an external Payment App. If the Pix payment method was implemented via VTEX Payment App, the Inbound Request is not necessary.

Check the complete endpoint documentation here.

For more information and frequently asked questions, refer to Pix - FAQ.

Wrapping up

If you have completed all integration steps, you should have a working implementation of our Payment Provider Protocol with Pix instant payments. The last step before VTEX stores can use your provider is to complete our homologation process.


Did this page help you?