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 eighteen ErrorCode values.
How a checkout ends
The operator reads the outcome and taps Done before your callback fires, so a secondlaunch never races the first. Try every path in the simulator: the Scenario section picks the outcome and the error code.
PaymentResult
PaymentResult
Authorized. The money will move.
PaymentResult
The issuer, the card or the device 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. A card exchange that broke (
CARD_ERROR) or authorization data that came back unusable (AUTHORIZATION_ERROR) arrives here, not as Declined, because nobody answered no.PaymentResult
Ended deliberately before an outcome existed, by the operator, the cardholder at the PIN pad or your app.
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: the SDK withholds the card number, track data, cardholder name, expiry date, service code and cryptogram before either reaches your app.
Who refused a declined payment
Thecode on Declined tells you where the refusal happened, and that decides whether Rinne has a record of it:
A
null transaction with one of the last three codes means nothing reached Rinne, so there is nothing to look up or reverse. The phone cannot tell an issuer’s refusal from Rinne refusing the transaction: both arrive as DECLINED_BY_ISSUER. The case an operator can fix is a refund tapped with a card other than the sale’s. If a merchant reports declines on every card, send the requestId to support.
After a process death
If Android kills your process while the payment screen is up, the restored screen deliversFailed 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:
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
Thecode on Declined, Failed, Cancelled and ReadyResult.Failed is one of eighteen 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.Read the SDK logs
The SDK writes its own lines to Logcat under theRinneSDK tag, in debug and release builds alike. Filter by the tag to follow a payment on a connected phone:
None of these lines carries card data, a PIN, an access token or the body of a response from Rinne. The
raw they log is the same card reader snapshot your app receives, with cardholder data already withheld. When you report a payment to support, send its charge payment. line; the requestId in it ties the device to Rinne’s records.
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.

