Gratuity
Tipping modes
The SDK supports three gratuity modes, configured via GratuityConfig.mode:
Mode | Description |
|---|---|
GratuityMode.NONE | No tipping prompt is shown. This is the default. |
GratuityMode.STANDARD | The SDK shows a built-in tipping menu with 10%, 15%, and 20% options. No additional configuration required. |
GratuityMode.CONFIGURED | The SDK builds a tipping menu from the fixed amounts or percentages you supply. |
In STANDARD and CONFIGURED modes, the SDK handles the full on-device flow automatically, including the initial "Add Gratuity?" yes/no prompt, the selection menu, a built-in "Other Amount" option for free-form tip entry.
Global configuration
Set gratuityConfig in ToroConfig to apply the same tipping behaviour to every transaction:
val config = ToroConfig(
gratuityConfig = GratuityConfig(mode = GratuityMode.STANDARD),
// ...
)Per-transaction configuration
Pass a GratuityConfig in TransactionMetadata to override the global config for a specific transaction. This is the recommended approach when tipping behaviour varies per transaction - for example, when switching between amounts and percentages based on business logic.
val metadata = TransactionMetadata(
gratuityConfig = GratuityConfig(
mode = GratuityMode.CONFIGURED,
percentages = listOf(20, 10, 5),
header = "Select a Tip / Gratuity:"
)
)
toro.startTransaction(
amount = 1000,
type = TransactionType.Purchase,
currencyCode = CurrencyCode.GBP,
metadata = metadata,
// ...
)STANDARD mode
GratuityMode.STANDARD presents a built-in tipping menu with 10%, 15%, and 20% options. No amounts or percentages need to be supplied.
GratuityConfig(mode = GratuityMode.STANDARD)Supplying amounts or percentages in STANDARD mode will throw an IllegalArgumentException. Use CONFIGURED mode instead.
CONFIGURED mode
GratuityMode.CONFIGURED lets you define exactly which amounts or percentages to offer. Supply either amounts (in pence) or percentages - not both. A maximum of 3 options may be provided. The SDK automatically appends an "Other Amount" option for free-form entry.
Fixed amounts:
GratuityConfig(
mode = GratuityMode.CONFIGURED,
amounts = listOf(300, 200, 100), // rendered as £3.00, £2.00, £1.00
header = "Select a Tip / Gratuity:"
)Percentage-based:
GratuityConfig(
mode = GratuityMode.CONFIGURED,
percentages = listOf(20, 10, 5), // rendered as 20%, 10%, 5%
header = "Select a Tip / Gratuity:"
)Mixing amounts and percentages in the same config will throw an IllegalArgumentException.
Customising prompt text
Two text fields control what is shown on-device before and during the tip selection:
- addGratuityPrompt: text shown on the initial yes/no screen asking the cardholder whether they want to add a tip (default: "Add Gratuity?")
- header: title shown at the top of the tip selection menu (default: "Add Gratuity?", max 30 characters)
GratuityConfig(
mode = GratuityMode.CONFIGURED,
percentages = listOf(20, 10, 5),
addGratuityPrompt = "Add a tip?",
header = "Select a Tip / Gratuity:"
)Responding to the customer's selection
When the customer confirms a tip, the onGratuityConfirmed callback is triggered:
onGratuityConfirmed = { gratuityAmount, gratuityPercentage ->
// gratuityAmount: tip in the smallest currency unit (e.g. pence)
// gratuityPercentage: whole number percentage (e.g. 15), or 0 for a fixed-amount or free-form tip
}If the customer declines the tip, onGratuityConfirmed is still called with gratuityAmount = 0.
Custom pre-transaction flow
If you prefer to collect the tip before calling startTransaction(), for example in your own application UI, pass it directly via TransactionMetadata.gratuityAmount. In this case leave gratuityConfig unset (or set mode to NONE) and include the tip in the total amount.
val metadata = TransactionMetadata(
gratuityAmount = 100 // £1.00
)
toro.startTransaction(
amount = 1100, // £11.00 total (£10.00 + £1.00 tip)
type = TransactionType.Purchase,
currencyCode = CurrencyCode.GBP,
metadata = metadata,
// ...
)TransactionMetadata.gratuityAmount and a non-NONE gratuityConfig cannot both be set on the same transaction - this will throw an IllegalArgumentException.
The amount parameter in startTransaction() must be the total transaction amount, including any gratuity.
The onGratuityConfirmed callback is not triggered when using the custom pre-transaction flow.