Pix on File Device Linking
Pix on File is a Pix payment flow in Brazil that links the customer's device to their bank account, so customers can authorize payments without being redirected to their bank app. Pix on File is available on both the Cross-border and Local tenants.
Device Linking is the one-time enrollment that establishes this link. It relies on FIDO2/WebAuthn: after the customer authorizes the enrollment in their banking app, they register a FIDO2 credential on their device, which is then used to authenticate every payment.
This guide outlines the key concepts and implementation details required to link a device for Pix on File via API. It covers essential steps such as creating the enrollment, handling the callback, and confirming the device linking with the customer's FIDO2 credential.
Requirements
- API authentication - All API requests must be authenticated using JWS (JSON Web Signature). The legacy
integration_keyis being deprecated — if you still use it, follow the Migration Guide to transition to JWS. If you don't have credentials yet, complete the Merchant Signup Form. - Familiarity with EBANX Direct - This setup follows the same general structure as other payment methods, with a few unique parameters. See EBANX Direct for more info.
How it works
- Initiate enrollment - The merchant creates an enrollment for the bank the customer selected from the Bank List.
- Customer authorization - The customer is redirected to their banking app and authorizes the enrollment.
- Credential registration - The customer returns to the merchant app and completes the FIDO2 credential registration.
- Active enrollment - The merchant confirms the device linking, and the enrollment becomes active and ready for payments.
Instructions
Follow the steps below.
The sample requests on this page are sent to the Local sandbox host. If you operate Cross-border, send the same request to the Cross-border host — paths and payloads are identical.
- Select your environment
Select the appropriate environment for your integration. Use the sandbox environment for testing, or the production environment for live transactions. Use the URL for your HTTP requests based on your selection.
Check the method's availability for your country and tenant in Payment Methods by Country. Questions about tenant and environment? Check our API Operability and API Endpoints.
Cross-border sandboxhttps://sandbox.ebanxpay.com/ws/userenrollment - Enrollment request
Device Linking begins with an enrollment request towards the customer's banking institution, using the ws/userenrollment endpoint. A list of available banking institutions can be retrieved using the Bank List request. The following parameters are used for Device Linking requests:
Parameter Requirement Description integration_keyRequired Your integration key payment_type_codeRequired Must be pix-jsroperationRequired Must be enrollmentenrollment.countryRequired Must be brenrollment.merchant_enrollment_codeRequired Unique enrollment code enrollment.notification_urlRequired URL to callback after customer authorizes the device linking enrollment.intent_urlRequired Deeplink URL that will be used to trigger user redirection after confirming the device linking in the banking application (return to merchant app) enrollment.emailRequired Customer e-mail enrollment.identification_typeRequired Either cpforcnpjenrollment.identificationRequired Customer document enrollment.account_details.bank_idRequired A valid bank_idenrollment.fidoOptions.platformRequired Platform where the enrollment is being initiated ( ANDROID,IOS,BROWSER,CROSS_PLATFORM).enrollment.fidoOptions.risk_signalsRequired Refer to Risk Signals. Risk SignalsRisk Signalsare contextual data points collected during user authentication that help Relying Parties (banks) assess the trust level of an authentication attempt.Sample request
Shellcurl -X POST \
--location 'https://sandbox-local-latam.ebanxpay.com/ws/userenrollment' \
--header 'Content-Type: application/json' \
--data '{
"integration_key": "{your_ebanx_integration_key}",
"payment_type_code": "pix-jsr",
"operation": "enrollment",
"enrollment": {
"country": "br",
"merchant_enrollment_code": "{merchant_enrollment_code}",
"notification_url": "{notification_url_backend}",
"intent_url": "{intent_url_device}",
"email": "john.doe@example.com",
"identification_type": "{cpf/cnpj}",
"identification": "{document_number}",
"account_details": {
"bank_id": "{bank_id}"
},
"fidoOptions": {
"platform": "{ENUM}",
"risk_signals": {}
}
}
}' - Enrollment response
A successful request returns a JSON response like the one below, containing a redirect URL that leads the customer to their banking application.
JSON{
"status": "SUCCESS",
"redirect_url": "{redirect_url}",
"enrollment": {
"enrollment_code": "{merchant_enrollment_code}",
"status": "pending"
}
}Field naming across surfacesThe enrollment code is named differently depending on the surface. Map each one explicitly instead of reusing a single key:
- Request body:
enrollment.merchant_enrollment_code - API response:
enrollment.enrollment_code - Callback (webhook):
enrollment.merchant_enrollment_code
The FIDO2 registration options follow the same pattern: the callback sends
registrationOptions(camelCase), while the enrollment query response returnsregistration_options(snake_case). The two are not guaranteed to be byte-identical — the query response may addauthenticatorSelection.residentKey: "required"andauthenticatorSelection.requireResidentKey: trueif the bank did not send them. Pass whichever object you received straight tonavigator.credentials.create()without merging the two. - Request body:
- Receive the callback
Once the customer authorizes the device linking in their banking application, the banking application will redirect the user to the
{intent_url}informed in the original request and a status update will be sent to the{notification_url}informed in the initiation step with additional information that will be required to complete the FIDO2/WebAuthn authentication in the device.JSON{
"enrollment": {
"merchant_enrollment_code": "{merchant_enrollment_code}",
"status": "pending",
"registrationOptions": {
"rp": {
"id": "string",
"name": "string"
},
"user": {
"id": "string",
"name": "string",
"displayName": "string"
},
"challenge": "string",
"pubKeyCredParams": [
{
"alg": -7,
"type": "public-key"
}
]
}
}
} - Device linking confirmation request
The last stage for Device Linking is processing the results of the FIDO2/WebAuthn authentication performed by the customer after confirming the enrollment and returning to the merchant application. Send the following parameters to the ws/userenrollment/authentication endpoint:
Parameter Requirement Description integration_keyRequired Your integration key payment_type_codeRequired Must be pix-jsroperationRequired Must be authenticationenrollment.merchant_enrollment_codeRequired Unique enrollment code enrollment.authentication.credentialIdRequired Credential ID (Base64 encoded) enrollment.authentication.rawCredentialIdRequired Credential ID in ArrayBuffer format (Base64 encoded) enrollment.authentication.authenticatorAttachmentRequired Must be platform.enrollment.authentication.credentialTypeRequired Must be public-keyenrollment.authentication.response.clientDataJSONRequired Client data in JSON, encoded in Base64url enrollment.authentication.response.attestationObjectRequired Authenticator attestation data, encoded in Base64url Sample request
Shellcurl -X POST \
--location 'https://sandbox-local-latam.ebanxpay.com/ws/userenrollment/authentication' \
--header 'Content-Type: application/json' \
--data '{
"integration_key": "{your_ebanx_integration_key}",
"payment_type_code": "pix-jsr",
"operation": "authentication",
"enrollment": {
"merchant_enrollment_code": "{merchant_enrollment_code}",
"authentication": {
"credentialId": "{fido_id}",
"rawCredentialId": "{fido_raw_id}",
"authenticatorAttachment": "platform",
"credentialType": "public-key",
"response": {
"clientDataJSON": "{client_data_json}",
"attestationObject": "{attestation_object}"
}
}
}
}' - Device linking confirmation response
A successful request returns a JSON response like the one below, confirming that the enrollment is ready to be used for payment processing.
JSON{
"status": "SUCCESS",
"payment_type": "pix-jsr",
"enrollment": {
"status": "accepted"
}
}This response is conclusive — unlike payment authenticationDevice Linking confirmation is synchronous and conclusive. EBANX calls the bank during the request and only records the enrollment as
acceptedonce the bank confirms it, so aSUCCESSresponse withacceptedmeans the enrollment is genuinely active. You can proceed to request payments immediately — there is no notification to wait for, and no need to poll.Do not carry this assumption over to payment authentication, on the Payment page. That call is also synchronous, but it is not conclusive: it returns the payment still in
PE, and confirmation arrives later. The two flows differ deliberately.An enrollment is only usable for payments once
enrollment.statusisaccepted. The full set of enrollment status values is:Status Description pendingOne or more required parties have not yet accepted or rejected the enrollment agreement. acceptedAll required parties accepted. The enrollment is active and usable for payments. not_acceptedA party did not accept the enrollment agreement. revokedA party revoked the enrollment agreement. A provider rejection is also returned as revoked.cancelledThe merchant revoked the enrollment agreement. expiredA required party did not accept before the enrollment expired. pausedA party paused the enrollment agreement. It cannot be used for payments while paused. not_foundThe enrollment agreement no longer exists, or could no longer be found. Status values are lowercaseMatch these values exactly as returned. Note
cancelledis spelled with a double L, and there is norejectedstatus — a bank rejection surfaces asrevoked. - Congratulations!
You have successfully linked the customer's device for Pix on File.
Next, request payments against the active enrollment inPix on File Paymentchevron_right
Resources
Use the following resources when testing in your sandbox environment.
API Reference
Click here to access detailed API documentation to integrate efficiently.
Mock Customer Data
Click here to view mock customer data for testing and validating user flows.
Error Codes
Click here to review common error codes to troubleshoot and resolve issues quickly.
Still need help?
We hope this article was helpful. If you still have questions, you can explore the following options:
- Merchant support: Contact our support team at sales.engineering@ebanx.com for assistance.
- Not a partner yet? Please complete the Merchant Signup Form, and our commercial team will reach out to you.