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, and 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:
let config = ToroConfig(
gratuityConfig: GratuityConfig(mode: .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.
let metadata = TransactionMetadata(
gratuityConfig: GratuityConfig(
mode: .configured,
percentages: [20, 10, 5],
header: "Select a Tip / Gratuity:"
)
)
toro.startTransaction(
amount: 1000,
type: .purchase,
currency: .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: .standard)Supplying amounts or percentages in standard mode will cause startTransaction() to fail with a validation error. 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: .configured,
amounts: [300, 200, 100], // rendered as £3.00, £2.00, £1.00
header: "Select a Tip / Gratuity:"
)Percentage-based:
GratuityConfig(
mode: .configured,
percentages: [20, 10, 5], // rendered as 20%, 10%, 5%
header: "Select a Tip / Gratuity:"
)Mixing amounts and percentages in the same config will cause startTransaction() to fail with a validation error.
Customising prompt text
Two text fields control what is shown on-device before and during tip selection:
- addGratuityPrompt: text shown on the initial yes/no screen asking the cardholder whether they want to add a tip (default: "Add Gratuity?", max 30 characters)
- header: title shown at the top of the tip selection menu (default: "Select Tip", max 30 characters)
GratuityConfig(
mode: .configured,
percentages: [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 in
// 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.
let metadata = TransactionMetadata(
gratuityAmount: 100 // £1.00
)
toro.startTransaction(
amount: 1100, // £11.00 total (£10.00 + £1.00 tip)
type: .purchase,
currency: .gbp,
metadata: metadata,
// ...
)TransactionMetadata.gratuityAmount and a non-none gratuityConfig cannot both be set on the same transaction - startTransaction() will fail with a validation error.
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.