Pular para o conteúdo

Payment flow

The redirect-based Open Finance payment flow has four steps: list participants, create a consent, let the payer authorize at their bank, then finish the payment with the parameters the bank redirects back with.

The four-step redirect payment flow

1. List registered participants

import { getParticipants, type Participant, LinaPayError } from 'react-native-lina-pay-sdk'

async function fetchParticipants() {
try {
  const participants = await getParticipants({
    subtenantId: 'your-subtenant-id',
    subtenantSecret: 'your-subtenant-secret',
  })

  participants.forEach((p) => console.log(p.customerFriendlyName, p.registrationNumber))
} catch (error) {
  if (error instanceof LinaPayError) {
    console.error('Lina Pay error:', error.message, error.statusCode)
  }
}
}

An institution with more than one authorization server appears as multiple entries; one with none is filtered out automatically.

import { createConsent, type CreateConsentRequest, LinaPayError } from 'react-native-lina-pay-sdk'
import { Linking } from 'react-native'

async function createPaymentConsent(selected: Participant) {
const payload: CreateConsentRequest = {
  organisationId: selected.organisationId,
  authorisationServerId: selected.authorisationServerId,
  payment: {
    redirectUri: 'https://your-app.com/payment-callback', // your app's deep link / callback
    value: 1500.5,
    creditor: {
      name: 'Beneficiary Company',
      personType: 'PESSOA_JURIDICA',
      cpfCnpj: '12345678000190',
      accountNumber: '123456',
      accountIssuer: '0001',
      accountPixKey: 'company@example.com',
      accountIspb: '12345678',
      accountType: 'CACC',
    },
  },
  platform: 'APP',
}

try {
  const consent = await createConsent(
    { subtenantId: 'your-subtenant-id', subtenantSecret: 'your-subtenant-secret' },
    payload,
  )

  // Redirect the payer to their bank to authorize
  Linking.openURL(consent.redirectUrl)
} catch (error) {
  if (error instanceof LinaPayError) console.error('Error creating consent:', error.message)
}
}

redirectUri must point back into your app (a universal link / deep link) — the bank redirects the payer there once they authorize.

3. Handle the callback

Your app receives state, code, and an ID token (id_token or idToken, depending on the bank) as query parameters on the redirect URL — for example https://your-app.com/payment-callback?state=rumUP&code=1RDYVFQnPn721&id_token=eyJhbGciOiJQUz....

Extract them with whatever routing/deep-link library your app uses, and keep tenantId on hand — it's the same value as subtenantId.

4. Finish the payment

import { createPayment, LinaPayError } from 'react-native-lina-pay-sdk'

async function handlePaymentCallback(state: string, code: string, idToken: string) {
try {
  const payment = await createPayment(
    { subtenantId: 'your-subtenant-id', subtenantSecret: 'your-subtenant-secret' },
    { state, code, idToken, tenantId: 'your-subtenant-id' },
  )

  console.log(payment.id, payment.status, payment.value)
} catch (error) {
  if (error instanceof LinaPayError) console.error('Error processing payment:', error.message)
}
}
statusMeaning
PENDENTEAwaiting processing.
EM_PROCESSAMENTOBeing processed.
CONSUMIDOConsent consumed.
PAGOPaid successfully.
EXPIRADOExpired.
CANCELADOCancelled.
ERRO_NA_DETENTORAFailure at the account holder (bank).
ERROGeneric error.

The response's value is returned as a string, and payments holds one entry per processed payment item.

Next steps

  • Enrollments — skip the redirect on future payments by linking the payer's device.
  • Error handling — LinaPayError and status codes.