CheckoutRequest, one launch, and exactly one PaymentResult. This page follows a sale from the moment your app describes it to the moment it appears on the Rinne API.
Describe the sale
Long
required
What to charge, in cents. Positive, BRL only.
4990 is R$ 49,90.PaymentMethod
required
CREDIT or DEBIT. It is the credit-or-debit question every Brazilian point of sale asks before the tap, and it is recorded as the transaction’s payment_method. The card reader picks the card application by its own rules and never reports which, so the operator’s answer is the only source of the modality.Int
default:"1"
1 is à vista. Values above 1 apply to credit only and are relayed to the acquirer. The header of the checkout shows the per-installment figure, for example “Crédito · 3x de R$ 16,63”.String?
required
Your idempotency key, required on a purchase. The SDK never mints or changes it. Reuse the same value when you retry the same sale; a reused
requestId with different sale data is refused by the platform. It is also how you find the transaction on the API.Map<String, Any?>?
default:"null"
Your own data, stored against the transaction and returned with it. Capped at 4 KB serialized, and rejected rather than truncated when it is larger or when a key looks like card data (
pan, cardNumber, track2, cvv, expiryDate and similar). Ordinary keys such as panel pass.TransactionType
default:"PURCHASE"
PURCHASE for a sale. REFUND is a card re-tap for the full amount of an earlier sale, described in Refunds.requestId, throws IllegalArgumentException before the screen opens: it is a programming error, not a payment outcome.
Launch the checkout
Register the contract once and launch it per sale. The result comes back through Android’s activity-result machinery, which is what keeps it safe when the system kills your process while the payment screen is up.Payments.getReady; launching on an unprepared terminal ends in Failed with TERMINAL_NOT_READY. Preparing once at startup and again on resume is safe, because getReady returns at once on a prepared terminal.
What happens on the phone
The SDK owns the screen from here until the operator dismisses the outcome. Every screen carries the amount and the descriptor built from your request.
Your callback fires only after the operator taps Done, so a second
launch never races the first, and a decline can be retried from the screen without starting a second sale behind it. Walk through every screen in the simulator.
Whether a PIN is asked is decided by the card and the amount, not by your app. Cards ask above their contactless limit; the sandbox behaves the same way.
Handle the result
Approved means the money will move. Declined is the issuer’s answer, so offer another card or payment method rather than retrying the same card. Failed is a technical fault to fix, with a code that says whether retrying can help. Cancelled means nobody was charged. Every variant and every code is on Results and errors.
Find the transaction on the API
The SDK registers the transaction with Rinne while authorising, under therequestId you sent. Look it up on the transactions list, which requires the transaction.list permission, or receive it through a transaction.created webhook:
payment_method, your metadata, the status and the receipt fields. See Transactions for the lifecycle and Webhooks for the events.
Reconcile after an interruption
If Android kills your process while the payment screen is up, the restored screen deliversFailed with a message telling you to reconcile. The transaction may well have been captured, so look it up by requestId before charging the customer again. An approved record means the sale went through; no record means you can retry with the same requestId.
Next steps
Refunds
Refund a sale with a card re-tap or from your backend.
Testing in the sandbox
Pick the outcome with the amount and verify every sale on the API.

