This guide takes you from a recipient to a completed PIX por biometria payment. For what PIX por biometria is and how the payer experiences it, see PIX por biometria.
Prerequisites
- Payment Initiation enabled for your client.
- A webhook registered for payment events, so you learn about completed payments and linked accounts without polling.
1. Create a recipient#
PIX por biometria pays the same recipients as any payment request. Create a bank account recipient as shown in the Payments Overview, or reuse one you already have. Smart account recipients are not supported.
2. Identify the payer (recommended)#
Create a Payment Customer with the payer's CPF (and CNPJ for business accounts), as described in Pre-filling the CPF/CNPJ, and pass its customerId when you create the payment request. Two things depend on it:
- The payment page uses the customer's tax number and does not ask for it. Without a customer, the payer types their CPF.
- You can list a payer's linked accounts by
customerId. See Managing linked accounts.
3. Create the payment request#
Create one payment request per purchase:
{
"amount": 149.9,
"recipientId": "ab276a3d-17ba-47eb-97bf-688475037ffe",
"description": "Order 4821",
"customerId": "a2d4c1e8-5b7f-4c3a-9e2d-1f6b8c0d7e55",
"clientPaymentId": "4821",
"linkedJourney": false,
"callbackUrls": {
"success": "https://my-store.com/orders/4821/paid",
"pending": "https://my-store.com/orders/4821/pending",
"error": "https://my-store.com/orders/4821/error"
}
}| Field | Required | Description |
|---|---|---|
amount | Yes | Amount in BRL, with up to two decimal places. Minimum 0.01. |
recipientId | Yes | The recipient that receives the payment. Bank account recipients only. |
description | No | Shown to the payer. Up to 140 characters. |
customerId | No | The Payment Customer that identifies the payer. Recommended. |
clientPaymentId | No | Your own identifier for the payment. Up to 200 characters. |
linkedJourney | No | true lets the payer also share their balance with you when they link. See Sharing balance. Defaults to false. |
callbackUrls | No | Where the payment page sends the payer when the payment succeeds, stays pending or fails. Same as in any payment request. |
For every field and response, see the API referenceAPI.
The response is a regular Payment Request with a pixBiometric object:
{
"id": "5b7e2c1d-3a4f-4e8b-9c6d-7f0a1b2c3d4e",
"amount": 149.9,
"description": "Order 4821",
"status": "CREATED",
"createdAt": "2026-10-28T13:00:00.000Z",
"updatedAt": "2026-10-28T13:00:00.000Z",
"callbackUrls": {
"success": "https://my-store.com/orders/4821/paid",
"pending": "https://my-store.com/orders/4821/pending",
"error": "https://my-store.com/orders/4821/error"
},
"paymentUrl": "https://pay.pluggy.ai/5b7e2c1d-3a4f-4e8b-9c6d-7f0a1b2c3d4e",
"clientPaymentId": "4821",
"pixBiometric": {
"linkedJourney": false,
"enrollment": null
}
}pixBiometric.enrollment is null until the request is paid. See step 5.
Sandbox in development
The PIX por biometria sandbox is in development. Until it is available, a request created with isSandbox: true is rejected with PIX_BIOMETRIC_SANDBOX_NOT_SUPPORTED. See Testing.
4. Send the payer to the payment page#
Send the payer the paymentUrl. The payment page handles the whole journey: choosing the bank, linking the account on the first payment, creating the passkey and confirming the payment with biometrics.
The payer must open the link in a browser that supports passkeys. Some apps' built-in browsers cannot use them; when the page detects one, it asks the payer to open the link in the device's browser.
Same browser from start to end
The first payment starts in one browser, continues at the bank and comes back to the payment page. If the bank sends the payer back to a different browser or device, the page asks them to return to where they started, or to link again from there.
You cannot create PIX por biometria payment intents through the API: POST /payments/intents answers 403 with PIX_BIOMETRIC_INTENT_INTERNAL_ONLY for these requests. The payment page creates them.
5. Track the payment#
The payment request and its intents move through the usual statuses (see Payment Intent Lifecycle and Errors), and you get the same webhooks.
First payment on a device (the payer links an account):
payment_intent/createdpayment_intent/waiting_payer_authorization: the payer is on their way to the bank to approve the link.pix_biometric_enrollment/authorized: the link is complete.payment_intent/completed
Later payments (the payer already has a link on that device):
payment_intent/createdpayment_intent/completed
payment_request/updated is sent whenever the request's status changes, as with any payment request.
Once the request is paid, it shows the linked account it was paid with:
{
"id": "5b7e2c1d-3a4f-4e8b-9c6d-7f0a1b2c3d4e",
"status": "COMPLETED",
"pixBiometric": {
"linkedJourney": false,
"enrollment": {
"id": "c91a5e2b-7d0f-4f3e-9a51-2f6b8e1d4c77",
"status": "AUTHORIZED",
"connector": {
"id": 608,
"name": "Santander",
"imageUrl": "https://cdn.pluggy.ai/assets/connector-icons/208.svg"
},
"debtor": {
"name": "John Doe",
"taxNumber": "***.456.789-**",
"bankAccount": {
"agency": "1234",
"account": "****4821",
"name": "Santander"
}
}
}
}
}enrollment.status is the link's current status, so it changes if the link is later revoked or expires. It stays null when the request was not paid, even if the payer created a link along the way: the pix_biometric_enrollment/* webhooks report that link.
Each payment intent carries paymentMethod: "PIX_BIOMETRIC" and the enrollmentId it was paid with.
When a payment fails#
Besides the payment errors in Payment Intent Lifecycle and Errors, a PIX por biometria intent can end with one of these errorDetail.code values:
| Intent status | errorDetail.code | Meaning |
|---|---|---|
CONSENT_REJECTED | ENROLLMENT_REJECTED | The institution or the payer rejected the link, so the first payment was not made. |
CONSENT_REJECTED | ENROLLMENT_NOT_COMPLETED | The link expired or ended before the payer completed it, for example because they did not come back from the bank in time. |
CANCELED | PIX_BIOMETRIC_SUPERSEDED | The payer started a new attempt on the same payment request, for example by choosing another bank. The new attempt continues. |
A failed attempt does not close the payment request: the payer can try again from the same paymentUrl.
Errors when creating the payment request#
| Status | codeDescription | Meaning |
|---|---|---|
400 | PIX_BIOMETRIC_SANDBOX_NOT_SUPPORTED | isSandbox was true. The PIX por biometria sandbox is in development. |
400 | PIX_BIOMETRIC_RECIPIENT_NOT_SUPPORTED | The recipient is a smart account. |
403 | PAYMENT_INITIATION_NOT_ALLOWED | Payment Initiation is not enabled for your client. |
404 | PAYMENT_RECIPIENT_NOT_FOUND | The recipientId does not exist for your client. |
404 | PAYMENT_CUSTOMER_NOT_FOUND | The customerId does not exist for your client. |
Testing#
The PIX por biometria sandbox is in development. Until it is available, testing means a real payment in production:
- Use a small amount, such as
0.01. - Pay from an account at an institution that supports linking (
supportsPixBiometric), on a phone or computer with biometrics or a screen lock. - Pay from an account other than the recipient's. A payment to the same account is rejected with
SAME_ORIGIN_DESTINATION_ACCOUNTS. - When you are done, revoke the test link with
POST /pix-biometric/enrollments/{id}/revoke, or undo it in the bank's app.
Next: Managing linked accounts.
