Skip to main content
Unlisted page
This page is unlisted. Search engines will not index it, and only users having a direct link can access it.

Pix on File Device Linking (Enrollment)

Pix on File (JSR) works by establishing a device linking using FIDO2/WebAuthn authentication.

  1. Merchant initiates enrollment with customer to elect a bank from authorized banks
  2. Customer elects the bank and authorize the enrollment
  3. Customer returns to the merchant app and completes FIDO2 credential registration
  4. Enrollment becomes active and ready for payments

Requirements

  • EBANX Account
  • API Credentials - Ensure you have your EBANX integration Key. If not, complete the Merchant Signup Form.
Endpoint host

Pix on File is processed by the EBANX Brazilian payment institution, so all requests must be sent to the local hosts below — not to the cross-border hosts used by other payment methods.

See the API endpoints reference for the complete tenant and environment list.

Device Linking Initiation (Enrollment)

Device Linking begins with an enrollment request towards customer's banking institution. A list of available banking institutions can be recovered using the Bank List request. The following parameters are used for Device Linking requests:

ParameterRequirementDescription
integration_keyRequiredYour integration key
payment_type_codeRequiredMust be pix-jsr
operationRequiredMust be enrollment
enrollment.countryRequiredMust be br
enrollment.merchant_enrollment_codeRequiredUnique enrollment code
enrollment.notification_urlRequiredURL to callback after customer authorizes the device linking
enrollment.intent_urlRequiredDeeplink URL that will be used to trigger user redirection after confirming the device linking in the banking application (return to merchant app)
enrollment.emailRequiredCustomer e-mail
enrollment.identification_typeRequiredEither cpf or cnpj
enrollment.identificationRequiredCustomer document
enrollment.account_details.bank_idRequiredA valid bank_id
enrollment.fidoOptions.platformRequiredPlatform where the enrollment is being initiated (ANDROID, IOS, BROWSER, CROSS_PLATFORM).
enrollment.fidoOptions.risk_signalsRequiredRefer to the Risk Signals section.
Risk Signals

Risk Signals are contextual data points collected during user authentication that help Relying Parties (banks) assess the trust level of an authentication attempt.

Sample Request

Shell
curl -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": {}
}
}
}'

A successful request will return a JSON response like the one below, containing a redirect URL that will lead the customer to their banking application.

JSON
{
"status": "SUCCESS",
"redirect_url": "{redirect_url}",
"enrollment": {
"enrollment_code": "{merchant_enrollment_code}",
"status": "pending"
}
}
Field naming across surfaces

The 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 returns registration_options (snake_case). The two are not guaranteed to be byte-identical — the query response may add authenticatorSelection.residentKey: "required" and authenticatorSelection.requireResidentKey: true if the bank did not send them. Pass whichever object you received straight to navigator.credentials.create() without merging the two.

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

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. It requires the following parameters:

ParameterRequirementDescription
integration_keyRequiredYour integration key
payment_type_codeRequiredMust be pix-jsr
operationRequiredMust be authentication
enrollment.merchant_enrollment_codeRequiredUnique enrollment code
enrollment.authentication.credentialIdRequiredCredential ID (Base64 encoded)
enrollment.authentication.rawCredentialIdRequiredCredential ID in ArrayBuffer format (Base64 encoded)
enrollment.authentication.authenticatorAttachmentRequiredMust be platform.
enrollment.authentication.credentialTypeRequiredMust be public-key
enrollment.authentication.response.clientDataJSONRequiredClient data in JSON, encoded in Base64url
enrollment.authentication.response.attestationObjectRequiredAuthenticator attestation data, encoded in Base64url

Sample Request

Shell
curl -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}"
}
}
}
}'

A successful request will return 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 authentication

Device Linking confirmation is synchronous and conclusive. EBANX calls the bank during the request and only records the enrollment as accepted once the bank confirms it, so a SUCCESS response with accepted means 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.status is accepted. The full set of enrollment status values is:

StatusDescription
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 lowercase

Match these values exactly as returned. Note cancelled is spelled with a double L, and there is no rejected status — a bank rejection surfaces as revoked.