A payment is the core operation: a sale, a refund, a pre-authorization, or a completion. They all go through one method — sendPaymentRequest — and you select the kind of payment with the paymentType field. This guide covers the regular payment; the variants differ only in paymentType and are noted at the end.
Prerequisite: a live session. See Session and login lifecycle — without a successful login, a payment request is ignored.
The call
viewModelScope.launch {
clientSDK.sendPaymentRequest(
RetailerMessageArguments.PaymentRequestMessageArguments
.RegularPaymentRequestMessageArguments(
saleTransactionId = "Sale001",
paymentAmounts = PaymentAmounts(
currency = "EUR",
amount = BigDecimal("10.00")
),
paymentType = PaymentType.NORMAL
)
)
}
The three fields you need:
saleTransactionId— your reference for the sale. Must be alphanumeric and 35 characters or fewer. If you derive it from a UUID, strip the hyphens — a raw UUID is 36 characters and will be rejected.paymentAmounts— aPaymentAmounts. At minimumcurrency(must match the terminal's configured currency) andamount(aBigDecimal). It can also carrytipAmount,cashbackAmount, andpaidAmount— see the API reference for the full field list.paymentType— aPaymentType.NORMALfor a standard sale.
Reading the result
The outcome arrives in your interceptor as a subtype of RetailerPaymentResponse:
when (message) {
is SuccessRetailerPaymentResponse -> { /* approved — read POI data, amounts */ }
is ErrorRetailerPaymentResponse -> { /* declined or failed */ }
is PartialRetailerPaymentResponse -> { /* partial outcome — handle explicitly */ }
is RetailerDisplayRequest -> { /* progress update during processing */ }
}
Handle the super-type's outcomes, not just success — see How the message model works for why. RetailerDisplayRequest messages arrive during processing to report what the terminal is doing; they are not the final result.
The
POITransactionIDmatters later. A successful payment response carries aPOITransactionIDin its POI data. If you may need to reverse this payment, capture that ID now — the reversal needs it. See Guide: reversing a transaction.
The payment variants
You do not call a different method for refunds or pre-authorizations — you change paymentType. The same request and response types apply; there are no separate refund/pre-auth response subtypes. A RetailerDisplayRequest during processing indicates which operation is running.
| You want to… | Set paymentType to |
|---|---|
| Take a standard sale | PaymentType.NORMAL |
| Refund a customer | PaymentType.REFUND |
| Pre-authorize (reserve an amount) | PaymentType.FIRSTRESERVATION |
| Complete a prior pre-authorization | PaymentType.COMPLETION |
PaymentType defines 13 values in total (including instalment, recurring, cash advance, and others). The four above are the common ones; the full enum is in the API reference. Use the exact enum constant — the values are upper-case (NORMAL, not Normal).
Aborting a payment in progress
A payment that has started but not yet reached host authorization can be cancelled with sendAbortRequest(). After authorization it's too late to abort — use a reversal instead. See Guide: reversing a transaction and Troubleshooting: abort has no effect after authorization.
Related
- Quickstart — the first-payment walkthrough.
- How the message model works — handling the response correctly.
- Guide: reversing a transaction — undoing a completed payment.
- Guide: card acquisition and two-step payments — pre-reading the card, then completing.
- API reference (
sdk-doc.zip) — fullPaymentAmountsfields and the completePaymentTypeenum.