Skip to main content
Every checkout ends in exactly one PaymentResult, delivered to the callback you registered with Checkout.Contract after the operator dismisses the outcome screen. Preparing the terminal ends in exactly one ReadyResult. Both use the same thirteen ErrorCode values.

How a checkout ends

The operator reads the outcome and taps Done before your callback fires, so a second launch never races the first. Try every path in the simulator: the Scenario section picks the outcome and the error code.

PaymentResult

PaymentResult
Authorised. The money will move.
PaymentResult
The issuer or the card refused. The transaction completed correctly and the answer was no, so retrying the same card usually fails the same way.
PaymentResult
Did not complete for a technical reason. This is a fault to fix, not an answer to relay to the customer.
PaymentResult
Ended deliberately before an outcome existed, by the operator, the cardholder at the PIN pad or your app.
Every variant also carries raw, a JSON snapshot of the card reader’s response for support triage, and diagnostics, decoded card diagnostics when the reader returned any. Neither ever contains cardholder data.
Receipt fields such as the authorisation code, the masked last four digits and the timestamp are not on PaymentResult. Read them from the transaction record on the Rinne API, which is the authoritative source. Inventing them from the SDK identifiers puts fabricated data on a customer’s receipt.

After a process death

If Android kills your process while the payment screen is up, the restored screen delivers Failed with a message telling you to reconcile against the Rinne API using your requestId. It is deliberately not Cancelled: nobody cancelled anything, and the transaction may well have been captured. Reconcile before charging the customer again, with a key that holds the transaction.list permission:
An approved transaction in the response means the sale went through; an empty list means it did not, and you can retry with the same requestId.

ReadyResult

Payments.getReady answers with Ready or Failed(code, message). Three codes are worth handling at setup, because each one names who fixes it:

ErrorCode

The code on Declined, Failed, Cancelled and ReadyResult.Failed is one of thirteen values, in a fixed order that only ever grows. The managed checkout shows the operator text in the device language and offers Try again only where retrying could work. If you build your own error screen, key it off the code and use ErrorCatalog[code] for a default message, retry hint and retriable flag.
Declined and Failed are different screens on purpose. Showing a network failure as “payment declined” tells the operator to ask for another card when the real problem is connectivity, and offers a retry guaranteed to fail the same way.

Next steps

Simulator

Pick any error code and see the screen, the operator text and whether Try again appears.

Device setup

Catch NFC, location and connectivity problems before a customer is waiting.