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:

  1. 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.
  2. 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:

FieldRequiredEffect
requestPartialPayment: trueEnables the customer to adjust the amount before paying. Must be true for tipping to work.
requestTip: truePrompts the customer to add a tip in the wallet UI
tipFixedoptionalSuggested fixed tip amount (e.g. R10). The wallet offers this as a one-tap option.
tipPercentageoptionalSuggested 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 screenPattern A — let the customer pick the tip on your screen
Are using printed QRs on counters or restaurant checksPattern B — the wallet UI handles the prompt
Want full control over the tip-suggestion UXPattern A
Want to A/B test tip suggestions across acquirer-supported walletsPattern 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