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.
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.
2. Create a consent
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)
}
}status | Meaning |
|---|---|
PENDENTE | Awaiting processing. |
EM_PROCESSAMENTO | Being processed. |
CONSUMIDO | Consent consumed. |
PAGO | Paid successfully. |
EXPIRADO | Expired. |
CANCELADO | Cancelled. |
ERRO_NA_DETENTORA | Failure at the account holder (bank). |
ERRO | Generic 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 —
LinaPayErrorand status codes.