Handling tips
Two patterns for collecting tips on a Scan to Pay transaction — merchant-side or customer-prompted in the wallet.
Restaurants, salons, food trucks, ride-hailing, and any other "service-with-gratuity" business needs a way to add a tip to a Scan to Pay transaction. The platform supports two patterns:
- Merchant-collected tip — your till asks the customer for the tip amount, you add it to the total, and the customer pays one combined amount.
- Customer-prompted tip — your code asks the platform to prompt the customer for a tip inside the wallet app. Optionally with suggested fixed amounts or percentages.
Both end with a single transaction that contains the tip portion. The webhook payload includes a tipAmount field so you can reconcile and pay the tip out separately if needed.
Pattern A — merchant-collected tip
Your till or POS asks the customer "Add a tip?" before generating the QR. The till adds the tip to the bill total and creates a code for the combined amount.
This is the simpler and more flexible pattern. Most service merchants use it.
Implementation
When creating the code, set the amount to the total including tip, and pass the tip portion as an additional field so the platform can break it out on the webhook:
curl -X POST "https://qa.scantopay.io/pluto/code/create" \
-u "$USERNAME:$PASSWORD" \
-H 'Content-Type: application/json' \
-d '{
"merchantReference": "table-12-bill-2025-05-14-007",
"amount": 110.00,
"useOnce": true,
"shortDescription": "Acme Coffee — table 12",
"additionalFields": [
{ "id": "tipAmount", "value": "10.00" }
]
}'For a R100 bill with a R10 tip:
amount: 110.00 (the total the customer pays)additionalFields[].tipAmount: 10.00 (the portion that's a tip)
The customer sees R110 and confirms.
What you get back
On the webhook, tipAmount is broken out as a top-level field:
{
"transactionId": 81234,
"merchantId": 25,
"reference": "table-12-bill-2025-05-14-007",
"amount": 110.00,
"tipAmount": 10.00,
"currencyCode": "ZAR",
"status": "SUCCESS",
...
}Reconcile: post R100 to your sales ledger, R10 to your tip-pool ledger.
Pattern B — customer-prompted tip
You can ask the Scan to Pay wallet itself to prompt the customer for a tip after they scan. The customer sees the base amount, a "Add a tip?" prompt, and optionally suggested amounts or percentages.
This pattern is useful when:
- Your till can't collect the tip ahead of time (e.g. a printed QR on a check)
- You want the wallet's standard tipping UI rather than building your own
- You want to nudge customers toward tip suggestions
Implementation
curl -X POST "https://qa.scantopay.io/pluto/code/create" \
-u "$USERNAME:$PASSWORD" \
-H 'Content-Type: application/json' \
-d '{
"merchantReference": "table-12-check-2025-05-14-007",
"amount": 100.00,
"useOnce": true,
"requestPartialPayment": true,
"requestTip": true,
"tipFixed": 10.00,
"tipPercentage": 10
}'Required field combination:
| Field | Required | Effect |
|---|---|---|
requestPartialPayment: true | ✓ | Enables the customer to adjust the amount before paying. Must be true for tipping to work. |
requestTip: true | ✓ | Prompts the customer to add a tip in the wallet UI |
tipFixed | optional | Suggested fixed tip amount (e.g. R10). The wallet offers this as a one-tap option. |
tipPercentage | optional | Suggested tip percentage (e.g. 10 for 10%). The wallet offers this as a one-tap option. |
The base amount is what the customer owes before the tip. The customer can accept a suggestion, type a custom amount, or skip the tip entirely.
What you get back
Same webhook shape as Pattern A. The amount field shows the total the customer paid (including any tip), and tipAmount shows the portion that was a tip.
If the customer skipped the tip, tipAmount is 0 or omitted.
Which pattern to choose
| If you... | Use |
|---|---|
| Have a tablet POS with a customer-facing screen | Pattern A — let the customer pick the tip on your screen |
| Are using printed QRs on counters or restaurant checks | Pattern B — the wallet UI handles the prompt |
| Want full control over the tip-suggestion UX | Pattern A |
| Want to A/B test tip suggestions across acquirer-supported wallets | Pattern B |
Have a useOnce: false code (rare for tipping) | Pattern A — requestTip requires requestPartialPayment which has compatibility constraints |
Both patterns produce identical webhooks, so your reconciliation logic is the same regardless of which you pick.
Operational notes
- Tip is part of the transaction, not separate. The whole amount (base + tip) flows through the acquirer in one authorisation and settles together. You can't refund the tip independently — refund the whole transaction or refund a partial amount.
- Tip caps. Some merchant categories cap tip amounts (e.g. ride-hailing typically caps at 25% of base). Scan to Pay doesn't enforce category-specific caps at the platform level; if you need to cap, validate before calling
createCode. - Refunding tips. When you refund a transaction that included a tip, the refund amount is what your code specifies — there's no separate "tip refund" mechanism. Decide whether to refund tip + base or base only based on your operational policy.
- Settlement. Tips settle as part of the parent transaction. Your acquirer doesn't see a separate "tip" line item.
What's next
- The full code-create reference → Dynamic QR (
requestTip,tipFixed,tipPercentage,requestPartialPaymentall live onTransactionInfoCreate) - Receive and reconcile the tip via webhook → Webhooks
- Refund a transaction that included a tip → Refunds and reversals
- Business rules that apply to all amount-related fields → QR Code Payments — business rules
Updated 4 days ago
