Integration Flow
This guide walks through the complete payment flow. Each step references the corresponding POS API endpoint.
Full Flow Overview
Step 1: Create Transaction Preview
API: POST /v3/integrations/credit-transactions/preview
The user presents their QR code. The cashier scans it to extract the X-Transaction-Key. The POS sends the cart items to Cheers Loyalty.
curl -X POST https://api.dev.votesess.com/v3/integrations/credit-transactions/preview \
-H "X-API-Key: YOUR_API_KEY" \
-H "X-Transaction-Key: 5ccd7850844b415091071c027930101f" \
-H "X-Idempotency-Key: a7e454c6-17ab-4fee-b823-c595bf3adb4a" \
-H "Content-Type: application/json" \
-d '{
"paymentType": "SPLIT_PAYMENT",
"currencyCode": "HUF",
"items": [
{
"productId": "f04ce0c0-1034-40bf-a066-3e313f68c781",
"quantity": 3,
"unitPrice": 500,
"name": "Draft Beer 0.5L",
"vat": 27
}
]
}'
Response:
{
"transactionId": "b04ce0c0-1034-40bf-a066-3e313f68c782",
"totalCredits": 800,
"totalDiscount": 600,
"outstandingBalance": 100,
"currencyCode": "HUF",
"items": [
{
"productId": "f04ce0c0-1034-40bf-a066-3e313f68c781",
"name": "Draft Beer 0.5L",
"unitPrice": 500,
"quantity": 3,
"credits": 800,
"discount": 600,
"outstandingBalance": 100,
"vat": 27
}
]
}
Reading the response:
The customer ordered 3 beers at 500 each = 1,500 total. Cheers applied a 600 discount, leaving 900. Of that, 800 is covered by credits. The remaining 100 is the outstanding balance -- to be paid with cash or card.
| Field | Meaning |
|---|---|
totalCredits | Total credits spent from the user's wallet |
totalDiscount | Total discount amount applied by Cheers |
outstandingBalance | Amount the customer must pay externally (cash/card) |
Only send items that should be eligible for discounts. Do not send service fees, tips, or surcharges in this step -- they would incorrectly receive discounts. Add those in the update step instead.
Payment Type Fallback (no split payment support)
If your POS does not support split payments:
Step 2: Update Basket (Optional)
API: POST /v1/integrations/credit-transactions/{creditTransactionId}/update
After the preview, you can add extra items such as service fees or tips. No discounts are applied to items added in this step. This also extends the preview expiration by 10 minutes.
curl -X POST https://api.dev.votesess.com/v1/integrations/credit-transactions/b04ce0c0-1034-40bf-a066-3e313f68c782/update \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"currencyCode": "HUF",
"newItems": [
{
"productId": null,
"quantity": 1,
"unitPrice": 9,
"name": "Service fee",
"vat": 27
},
{
"productId": null,
"quantity": 1,
"unitPrice": 100,
"name": "Tip",
"vat": 0
}
]
}'
Response:
{
"transactionId": "b04ce0c0-1034-40bf-a066-3e313f68c782",
"totalCredits": 800,
"totalDiscount": 600,
"outstandingBalance": 209,
"currencyCode": "HUF",
"items": [
{
"productId": "f04ce0c0-1034-40bf-a066-3e313f68c781",
"name": "Draft Beer 0.5L",
"unitPrice": 500,
"quantity": 3,
"credits": 800,
"discount": 600,
"outstandingBalance": 100,
"vat": 27
},
{
"productId": null,
"name": "Service fee",
"unitPrice": 9,
"quantity": 1,
"credits": 0,
"discount": 0,
"outstandingBalance": 9,
"vat": 27
},
{
"productId": null,
"name": "Tip",
"unitPrice": 100,
"quantity": 1,
"credits": 0,
"discount": 0,
"outstandingBalance": 100,
"vat": 0
}
]
}
The service fee (9) and tip (100) were added with zero discount and zero credits. The total outstanding balance is now 209.
Step 3: Collect External Payment (if applicable)
If outstandingBalance > 0, collect the remaining amount from the customer via cash or card before finalizing.
If the external payment fails (e.g. card declined, insufficient cash), you must cancel the Cheers transaction instead of finalizing it. See Step 5: Cancel.
Step 4: Finalize Transaction
API: POST /v3/integrations/credit-transactions/{creditTransactionId}/finalize
After collecting any external payment, finalize the transaction. This deducts the credits from the user's wallet.
curl -X POST https://api.dev.votesess.com/v3/integrations/credit-transactions/b04ce0c0-1034-40bf-a066-3e313f68c782/finalize \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json"
Only the creditTransactionId from the preview response is needed. The cart state is not resent.
After finalization, the POS has all information needed to print the receipt:
- Per item: credits spent, discount applied, outstanding balance
- Totals: total credits, total discount, total outstanding balance
Step 5: Cancel Transaction
API: POST /v1/integrations/credit-transactions/{creditTransactionId}/cancel
Cancel an unfinalized transaction. Use this when the external payment step fails or the customer abandons the purchase.
curl -X POST https://api.dev.votesess.com/v1/integrations/credit-transactions/b04ce0c0-1034-40bf-a066-3e313f68c782/cancel \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json"
No credits are deducted. The user's Transaction Key is consumed and cannot be reused.
Step 6: Refund Transaction
API: POST /v1/integrations/credit-transactions/{creditTransactionId}/refund
Refund a finalized transaction. The credits are returned to the user's wallet.
curl -X POST https://api.dev.votesess.com/v1/integrations/credit-transactions/b04ce0c0-1034-40bf-a066-3e313f68c782/refund \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"comment": "Customer returned the order"
}'
Refunds are only available within 24 hours of finalization. After that, the API returns CREDIT_TRANSACTION_CAN_NO_LONGER_BE_REFUNDED_BY_EXTERNAL_DEVICE.