Search

Are you looking for test card numbers?

Would you like to contact support?

Point-of-sale icon

Tipping from the cash register

Implement tipping from the cash register in your payment flow.

Here we describe how to implement tipping in your payment flow where the payment request that you send from the cash register includes a tip amount. The terminal shows the original transaction amount and the tip amount. The customer then uses the terminal to confirm the tip, change the amount, or decline giving a tip.

Before you begin

Before you implement tipping, make sure you have:

Step 1: Configure tipping

The tip amount to propose to your customer on the terminal can be a percentage of the transaction amount, a fixed amount, one of various fixed amounts depending on the transaction amount, and so on.
You need to implement logic on your end to ensure your cash register provides the tip amount that you need to include in your payment request.

Step 2: Make a payment

After you configured tipping on the cash register, you are ready to make a payment request that includes a TipAmount. This shows the transaction amount and the proposed tip amount on the terminal display.

  • Make a POST request to a Terminal API endpoint, specifying:

    • MessageHeader: This follows the standard MessageHeader structure, explained in Terminal API fundamentals, which includes:

      • ProtocolVersion: 3.0
      • MessageClass: Service
      • MessageCategory: Payment. This indicates you are initiating a payment request.
      • MessageType: Request
      • SaleID: Your unique ID for the cash register.
      • ServiceID: Your unique ID for this transaction attempt, consisting of 1-10 alphanumeric characters. This value needs to be unique within the last 48 hours.
      • POIID: Unique ID of the terminal.¬†This indicates which terminal the payment will be routed to.
    • PaymentRequest: The request body for the payment request must include:

      • SaleData.SaleTransactionID.TransactionID: Your unique reference for this payment request.
      • SaleData.SaleTransactionID.TimeStamp: Date and time of the payment request, in UTC format.
      • PaymentTransaction.AmountsReq.Currency: The currency of the transaction.
      • PaymentTransaction.AmountsReq.RequestedAmount: The transaction amount.
      • PaymentTransaction.AmountsReq.TipAmount: The tip amount.

    The example below shows how you would initiate a 142.50 EUR payment with a 10% tip.

    For more information on the Terminal API request structure, refer to the Terminal API fundamentals.

    Payment request with tipping
    {
      "SaleToPOIRequest":{
        "MessageHeader":{
          "ProtocolVersion":"3.0",
          "MessageClass":"Service",
          "MessageCategory":"Payment",
          "MessageType":"Request",
          "SaleID":"POSSystemID12345",
          "ServiceID":"0207111104",
          "POIID":"P400Plus-275688710"
        },
        "PaymentRequest":{
          "SaleData":{
            "SaleTransactionID":{
              "TransactionID":"27908",
              "TimeStamp":"2019-12-17T10:11:03.000Z""
            }
          },
          "PaymentTransaction":{
            "AmountsReq":{
              "Currency":"EUR",
              "RequestedAmount":142.50,
              "TipAmount":14.25
            }
          }
        }
      }
    }

The payment request is routed to the payment terminal. The shopper accepts, changes, or declines the tip and completes the payment. The terminal then collects the payment details and sends the request for the original transaction amount plus the tip amount to the Adyen payments platform.

Step 3: Receive payment result

When the payment has been processed on the Adyen payments platform, you receive the payment result in a synchronous API response.

If your integration uses asynchronous cloud communications, you receive the result in a TENDER_FINAL display notification.

If the payment is successful:

  • Approved is displayed on the terminal display.
  • The payment result contains:

    • POIData.POITransactionID.TransactionID: Transaction identifier for the payment.
    • PaymentReceipt: Receipt data with the original transaction amount, the tip amount (not included if the customer didn't add a tip), and the total amount.
    • PaymentResult.AmountsResp:

      • TipAmount: Amount of the tip. If the customer didn't add a tip, this field is not included.
      • AuthorizedAmount: Total amount of the payment (original transaction amount plus tip amount).
      • Currency: Currency of the payment.

    • Response.Result: Success
    • Response.AdditionalResponse: A base64 string. When decoded, this is a JSON object with additional transaction data. This includes:
      • posadditionalamounts.originalAmountValue: Original transaction amount in minor units.
      • posAmountGratuityValue: Tip amount in minor units.
      • authorisedAmountValue: Total authorised amount in minor units.

    The example below shows the response for a 142.50 EUR transaction with a 10% tip added.

    Payment response with tip added
    {
      "SaleToPOIResponse": {
        "PaymentResponse": {
          "POIData": {
            "POITransactionID": {
              "TimeStamp": "2019-12-17T10:11:12.000Z",
              "TransactionID": "8ha5001575467786000.8815754678001083"
            },
          "SaleData": {...},
            "PaymentReceipt": [...],
            "PaymentResult": {
              "AuthenticationMethod": [...],
              "OnlineFlag": true,
              "PaymentAcquirerData": {...},
              "PaymentInstrumentData": {...},
              "AmountsResp": {
                "TipAmount": 14.25,
                "AuthorizedAmount": 156.75,
                "Currency": "EUR"
              }
            },
            "Response": {
              "Result": "Success",
              "AdditionalResponse": "...posadditionalamounts.originalAmountValue=14250&...posAmountGratuityValue=1425&gratuityAmount=1425&...authorisedAmountValue=15675...&posAuthAmountValue=15675&posadditionalamounts.gratuityAmount=1425"
              }
            },
            "MessageHeader": {...}
        }
    }

See also