Instant Pix (JSR)
Take an immediate Pix payment in-app, device-signed with a passkey (FIDO2) and no redirection. This is the JSR counterpart of Instant Pix (redirect): instead of sending the payer to their bank, the payer approves on their own device with the passkey registered during account linking.
Method sequence
enrollments.listByUserJsr(cpf, { deviceId })— gate: confirm the payer has anAUTHORISEDenrollment and pick it.pix.getDetails({ pixKey })— resolve the Pix key into the payee's account so you can build thecreditor(skip this for a QR Code — see Pay a QR Code).consents.createJsr(req)— open a JSR consent with apaymentcarryingdetails,value,cpfCnpj,redirectUri, and thecreditor. Returns{ id, consentId, fidoSignOptions };idis thepaymentRequestId.- [device] the device calls
navigator.credentials.get()withconsent.fidoSignOptionsand produces a FIDO2 assertion. payments.processJsr(req)— submit theassertionplusriskSignalsto execute the payment immediately. Check the result with theisPaidhelper.
Steps 4–5 are identical across every JSR flow — see Execute a JSR payment for the full code.
Sequence diagram
Carregando diagrama…
Code
Steps 1–3: gate on the enrollment, resolve the payee, and open the consent.
Both consents.createJsr and payments.processJsr require the clientIp
(the X-Client-IP header).
// 1) Gate: an AUTHORISED enrollment is required
const user = await client.enrollments.listByUserJsr(cpf, { deviceId: riskSignals.deviceId });
const enrollment = user.enrollments[0];
// 2) Resolve the Pix key into the payee account
const details = await client.pix.getDetails({ pixKey });
// 3) Create the consent with the full transfer payload
const consent = await client.consents.createJsr({
enrollmentId: enrollment.enrollmentId,
payment: {
details: 'Instant Pix',
value: 150.5,
cpfCnpj: cpf,
redirectUri: 'https://app.example.com/payment-success',
creditor: {
name: details.account.name,
personType: details.account.personType,
cpfCnpj: details.account.cpfCnpj,
accountNumber: details.account.accountNumber,
accountIssuer: details.account.accountIssuer,
accountPixKey: details.pixKey,
accountIspb: details.account.accountIspb,
accountType: details.account.accountType,
},
},
fidoSignOptions: { platform: 'ANDROID' },
}, { clientIp });
// consent.id is the paymentRequestId — sign on device and call payments.processJsr,
// see Execute a JSR payment// 1) Gate: an AUTHORISED enrollment is required
UserEnrollments user = client.enrollments.listByUserJsr(cpf, ListEnrollmentsQuery.deviceId(deviceId));
EnrollmentSummary enrollment = user.enrollments().get(0);
// 2) Resolve the Pix key into the payee account
PixDetails d = client.pix.getDetails(PixDetailsRequest.byKey(pixKey));
Creditor creditor = new Creditor();
creditor.name = d.account().name();
creditor.personType = d.account().personType();
creditor.cpfCnpj = d.account().cpfCnpj();
creditor.accountNumber = d.account().accountNumber();
creditor.accountIssuer = d.account().accountIssuer();
creditor.accountPixKey = d.pixKey();
creditor.accountIspb = d.account().accountIspb();
creditor.accountType = d.account().accountType();
// 3) Create the consent with the full transfer payload
JsrConsentResult consent = client.consents.createJsr(
new CreateJsrConsentRequest()
.enrollmentId(enrollment.enrollmentId())
.payment(JsrPayment.transfer("Instant Pix", 150.5, cpf,
"https://app.example.com/payment-success", creditor))
.fidoSignOptions(new FidoSignOptionsInput("ANDROID")),
CallOptions.clientIp(ip));
// consent.id() is the paymentRequestId — sign on device and call payments.processJsr,
// see Execute a JSR payment// 1) Gate: an AUTHORISED enrollment is required
let user = try await client.enrollments.listByUserJsr(cpf, query: ListEnrollmentsQuery(deviceId: deviceId))
guard let enrollment = user.enrollments.first else { return }
// 2) Resolve the Pix key into the payee account
let d = try await client.pix.getDetails(.byKey(pixKey))
let creditor = Creditor(
name: d.account.name, personType: d.account.personType, cpfCnpj: d.account.cpfCnpj,
accountNumber: d.account.accountNumber, accountIssuer: d.account.accountIssuer,
accountPixKey: d.pixKey, accountIspb: d.account.accountIspb, accountType: d.account.accountType)
// 3) Create the consent with the full transfer payload
let consent = try await client.consents.createJsr(
CreateJsrConsentRequest(
enrollmentId: enrollment.enrollmentId,
fidoSignOptions: FidoSignOptionsInput(platform: "IOS"),
payment: .transfer(details: "Instant Pix", value: 150.5, cpfCnpj: cpf,
redirectUri: "https://app.example.com/payment-success", creditor: creditor)),
options: .clientIp(ip))
// consent.id is the paymentRequestId — sign on device and call payments.processJsr,
// see Execute a JSR payment// 1) Gate: an AUTHORISED enrollment is required
var user = await client.Enrollments.ListByUserJsrAsync(cpf, new ListEnrollmentsQuery { DeviceId = deviceId });
var enrollment = user.Enrollments[0];
// 2) Resolve the Pix key into the payee account
var d = await client.Pix.GetDetailsAsync(PixDetailsRequest.ByKey(pixKey));
var creditor = new Creditor
{
Name = d.Account.Name, PersonType = d.Account.PersonType, CpfCnpj = d.Account.CpfCnpj,
AccountNumber = d.Account.AccountNumber, AccountIssuer = d.Account.AccountIssuer,
AccountPixKey = d.PixKey, AccountIspb = d.Account.AccountIspb, AccountType = d.Account.AccountType,
};
// 3) Create the consent with the full transfer payload
var consent = await client.Consents.CreateJsrAsync(new CreateJsrConsentRequest
{
EnrollmentId = enrollment.EnrollmentId,
FidoSignOptions = new FidoSignOptionsInput { Platform = "ANDROID" },
Payment = JsrPayment.ForTransfer("Instant Pix", 150.5, cpf, "https://app.example.com/payment-success", creditor),
}, CallOptions.WithClientIp(ip));
// consent.Id is the paymentRequestId — sign on device and call payments.processJsr,
// see Execute a JSR paymentNext steps
- Execute a JSR payment — sign on device and run
processJsr. - Pay a QR Code — the same JSR flow with a QR Code instead of a Pix key.
- Pix transfer by key — the transfer-payload details in depth.