POS Integration
Let’s Trade’s POS integration enables seamless interaction between your Point of Sale (POS) system and Let’sTrade offerings. This integration allows your POS system to send codes to Let’sTrade to determine applicable offerings and finalise transactions, facilitating earning rewards, redeeming vouchers, and making payments..
API Base URL
The base URL for all API endpoints is:
https://lets-trade-integration-prod.letstrade.globalAuthentication
Let'sTrade API uses Bearer Token Authentication for securing API requests. Each API call must include a valid bearer token in the Authorisation header. Here’s an example of how to include the bearer token in your request:
Authorization: Bearer YOUR_ACCESS_TOKENEnsure that you replace YOUR_ACCESS_TOKEN with a valid token obtained during the authentication process.
Key Features:
1. Request Offerings: Send a code (either P, R, or E) along with basket details to Let’sTrade to determine applicable offerings for rewards, voucher redemptions, or payments.
2. Finalise Transaction: Complete the transaction by confirming the codes, processing rewards, payments, and finalising vouchers.
Step 1: Request Offerings
1. Check Code Applicability:
The POS can call the offerings endpoint to check what the provided code and basket applies to:
For
Pcodes, the backend simulates the payment and returns deducted outstanding amount.For
Rcodes, the backend returns voucher details without redeeming them.For
Ecodes, no action is taken at this stage.
2. Code Expiry:
Codes are set to have a 10-minute expiry from the moment they are generated. The user has 10 minutes to complete the transaction and use the code. If the code expires, a new code must be generated and passed.
Step 2: Finalise Transaction
1. Complete Order on POS:
Once the order is complete on the POS and payment is being finalised, the finalise endpoint is called. This step executes the rules linked to the provided code/s and finalises the transaction.
For
Pcodes: Payment is finalise, card and/or wallet charged.For
Rcodes: The voucher is redeemed (burned) in the system.For
Ecodes: Points or rewards are awarded once based on the transaction.
2. Irreversibility:
Once the finalise endpoint is called, the transaction is executed based on the rules linked to the code, and this action cannot be undone.
3. Payment Scenarios:
If the code is used for payment, the offerings endpoint will indicate the breakdown of the payment amount per type (e.g., card, wallet, loan).
Example Workflow
1. User at POS:
The user at the POS system receives a code (P, R, or E), either by reading it out or scanning a QR code.
2. POS Requests Offerings:
The POS sends the code and basket details to the offerings endpoint to determine what the code applies to (e.g., earning rewards, or redeeming vouchers). If the code is used for payment, this call ensures that the payment process is initiated and handled by Let’sTrade.
3. Display Offerings:
The POS displays the applicable offerings to the user based on the response.
4. User Confirms Transaction:
The user confirms the transaction within 10 minutes of the code generation.
5. Finalise Transaction:
The POS calls the finalise endpoint to execute the rules linked to the code and complete the transaction. If the code is used for earning rewards or redeeming vouchers, this call ensures that rewards are credited and vouchers are redeemed (burned) in the system accordingly.
By following this process, the integration ensures that the POS system can effectively manage code-based transactions, provide timely information to the user, and finalise transactions securely and efficiently.
Sequence


Offerings
POST /v1/get/offerings
This endpoint is used to retrieve applicable offerings for a given code at the POS.
Headers
Content-Type
application/json
Authorization
Bearer <token>
Body
Root:
code*
string
A string indicating the type of operation. Possible values are:
store_id*
string
A string representing the unique identifier of the store where the transaction is taking place.
terminal_id*
string
A string representing the unique identifier of the terminal within the store where the transaction is processed.
basket*
object
An object containing details about the customer’s shopping basket.
Basket Object:
uuid*
string
A string representing the unique identifier of the basket.
total*
string
A number indicating the total amount of the basket, including all fees and taxes.
outstanding*
string
A number representing the remaining amount to be paid after all discounts, fees, and vouchers have been applied.
product_list*
array
An array of objects representing the products in the basket.
vat
string
A number representing the Value Added Tax amount for the basket.
sub_total
string
A number indicating the subtotal amount of the basket, excluding VAT and fees.
delivery_fee
string
A number representing the fee for delivering the items in the basket.
service_fee
string
A number representing the additional service fee applied to the basket, such as tips.
discount
string
A number indicating the total discount applied to the basket.
external_vouchers
array
An array of objects representing external vouchers applied to the basket.
External_vouchers (array):
title
string
A string indicating the name of the voucher.
id*
string
A string representing the unique identifier of the voucher.
value*
string
A number indicating the monetary value of the voucher.
sku
object
A string representing the stock keeping unit (SKU) of the product that the voucher applies to in the product_list of the basket
Product List (array):
sku*
string
A string representing the stock keeping unit (SKU) of the product, used for inventory tracking.
quantity*
string
A number indicating the quantity of the product in the basket.
price*
string
A number representing the price of the product before any discounts are applied.
title
string
A string indicating the name of the product.
discount
string
A number indicating the discount amount applied to the product.
on_promotion
boolean
A boolean indicating whether the product is currently on promotion.
promotion_price
string
A number representing the promotional price of the product, if applicable.
barcode
string
A string representing the barcode of the product, used for scanning and inventory purposes.
add_ons
array
An array of objects representing additional items or accessories related to the main product. Array of product objects
Sample request
{
"code": "E | R | P",
"store_id": "232323",
"terminal_id": "1234234",
"basket": {
"uuid": "6697b10a9a1620583b208f77",
"user_id": "65f7e8d2b531f1c92cf94825",
"total": "289.95",
"vat": "29.99",
"sub_total": "199.96",
"delivery_fee": "60.00",
"service_fee": "60.00",
"discount": "100.00",
"outstanding": "10.00",
"external_vouchers": [
{
"title": "Sample Product A",
"id": "uywduci",
"value": "100.00",
"sku": "1234567890123"
}
],
"product_list": [
{
"title": "Sample Product A",
"sku": "1234567890123",
"quantity": "1",
"price": "229.95",
"discount": "100.00",
"on_promotion": false,
"promotion_price": "0.00",
"barcode": "1234567890123",
"add_ons": [
{
"title": "Sample Product A Add-on",
"sku": "1234567890123",
"quantity": "1",
"price": "229.95",
"discount": "100.00",
"on_promotion": false,
"promotion_price": "0.00",
"barcode": "1234567890123",
"add_ons": []
}
]
}
]
}
}
Response
{
"success": true,
"message": "Successfully retrieved offerings",
"content": {
"code": ["P", "R", "E"],
"store_id": "000000",
"terminal_id": "000000",
"client_id": "00",
"basket": {
"uuid": "0000000000000000000000",
"user_id": "65f7e8d2b531f1c92cf94825",
"delivery_fee": "0.00",
"service_fee": "0.00",
"outstanding_amount": "166.00",
"total": "166.00",
"product_handling_fees": "0.00",
"vat": "21.65",
"sub_total": "144.35",
"product_list": [
{
"image_url": "https://....jpg",
"title": "Latte Coffee",
"sub_title": "Medium Latte",
"description": "<p>Smooth and creamy coffee.</p>",
"sku": "001",
"pid": "001",
"quantity": "1",
"price": "30.00",
"on_promotion": true,
"promotion_price": "25.00",
"barcode": "001",
"vouchers": [
{
"voucher_name": "R10 off",
"quantity": "1",
"price": "30.00",
"discounted_price": "20.00",
"discount": "10.00",
"voucher_id": "66ebc52c084f1481c69d59f9",
"voucher_type": "VALUE"
}
],
"deal": {
"configuration": "DISCOUNT",
"quantity": "1",
"discounted_price": "112.00",
"discount": "28.00",
"deal_id": "68e5fb3d61dea1aabc20876e",
"deal_name": "Sample Discount",
"deal_priority": 1,
"apply_to": "PRODUCT",
"deal_image_url": "https://....png"
}
},
{
"image_url": "https://....jpg",
"title": "Blueberry Muffin",
"sub_title": "Fresh Muffin",
"description": "<p>Delicious blueberry muffin.</p>",
"sku": "002",
"pid": "002",
"quantity": "3",
"price": "47.00",
"on_promotion": false,
"promotion_price": "0.00",
"barcode": "002",
"deal": null
}
],
"card": {
"_id": "",
"amount": "66.00",
"currency": "ZAR"
},
"wallet": {
"amount": "100.00",
"currency": "ZAR",
"provider": "LETS-TRADE"
},
"vouchers": [
{
"voucher_name": "R10 off",
"quantity": "1",
"discount": "10.00",
"voucher_id": "66ebc52c084f1481c69d59f9",
"voucher_type": "VALUE"
}
],
"deals": [
{
"configuration": "DISCOUNT",
"quantity": "1",
"discounted_price": "272.00",
"discount": "68.00",
"deal_id": "68f22aa8d2f808da3b0246a7",
"deal_name": "Sample Basket Deal",
"deal_priority": 100,
"apply_to": "BASKET",
"deal_image_url": "https://....png"
}
]
},
"customer": {
"name": "Customer Name",
"surname": "Customer Surname",
"birthday": "1995-10-08T22:00:00.000Z"
},
"rewards": [
{
"title": "cashback",
"value": "100.00"
}
]
}
}
Response descriptions
customer
object
An object containing information about the customer.
rewards
array
An array of objects representing the rewards applicable to the customer, that they have earned due to this transaction.
transaction_details
object
An object containing details about the transaction.
ref
string
A string representing a unique reference identifier for the transaction content.
discount
string
A number indicating the total discount that needs to be applied to the order.
basket.outstanding
string
A number representing the remaining amount to be paid after discounts have been applied.
basket.product_list.voucher.discount
string
A number indicating the discount applied to the product.
basket.product_list.voucher.discounted_price
string
A number representing the price of the product after the discount has been applied.
basket.card.amount
string
A number representing the amount that was paid using a card
basket.wallet.amount
string
A number representing the amount that was paid using a card
basket.vouchers.discount
string
A number indicating the discount applied to the basket.
Finalise
POST /v1/finalise/offerings
This endpoint is used to finalise the transaction by confirming the code and processing the details.
Headers
Content-Type
application/json
Authorization
Bearer <token>
Sample request
{
"code": ["E", "R", "P"],
"store_id": "232323",
"terminal_id": "1234234",
"basket": {
"uuid": "6697b10a9a1620583b208f77",
"user_id": "65f7e8d2b531f1c92cf94825",
"total": "289.95",
"vat": "29.99",
"sub_total": "199.96",
"delivery_fee": "60.00",
"service_fee": "60.00",
"discount": "100.00",
"outstanding": "10.00",
"vouchers": [
{
"title": "Sample Product A",
"id": "uywduci",
"value": "100.00",
"sku": "100.00"
}
],
"deals": [
{
"configuration": "DISCOUNT",
"quantity": "1",
"discounted_price": "272.00",
"discount": "68.00",
"deal_id": "68f22aa8d2f808da3b0246a7",
"deal_name": "Sample Basket Deal",
"deal_priority": 100,
"apply_to": "BASKET",
"deal_image_url": "https://....png"
}
],
"product_list": [
{
"title": "Sample Product A",
"sku": "1234567890123",
"quantity": "1",
"price": "229.95",
"discount": "100.00",
"on_promotion": false,
"promotion_price": "0.00",
"barcode": "1234567890123",
"add_ons": [
{
"title": "Sample Product A Add-on",
"sku": "1234567890123",
"quantity": "1",
"price": "229.95",
"discount": "100.00",
"on_promotion": false,
"promotion_price": "0.00",
"barcode": "1234567890123",
"add_ons": []
}
],
"deal": {
"configuration": "DISCOUNT",
"quantity": "1",
"discounted_price": "112.00",
"discount": "28.00",
"deal_id": "68e5fb3d61dea1aabc20876e",
"deal_name": "Sample Discount",
"deal_priority": 1,
"apply_to": "PRODUCT",
"deal_image_url": "https://....png"
}
}
]
}
}
Response
{
"success": true,
"message": "Successfully retrieved offerings",
"content": {
"code": ["P", "R", "E"],
"store_id": "000000",
"terminal_id": "000000",
"client_id": "00",
"basket": {
"uuid": "0000000000000000000000",
"delivery_fee": "0.00",
"service_fee": "0.00",
"outstanding_amount": "166.00",
"total": "166.00",
"product_handling_fees": "0.00",
"vat": "21.65",
"sub_total": "144.35",
"product_list": [
{
"image_url": "https://....jpg",
"title": "Latte Coffee",
"sub_title": "Medium Latte",
"description": "<p>Smooth and creamy coffee.</p>",
"sku": "001",
"pid": "001",
"quantity": "1",
"price": "30.00",
"on_promotion": true,
"promotion_price": "25.00",
"barcode": "001",
"vouchers": [
{
"voucher_name": "R10 off",
"quantity": "1",
"price": "30.00",
"discounted_price": "20.00",
"discount": "10.00",
"voucher_id": "66ebc52c084f1481c69d59f9",
"voucher_type": "VALUE"
}
],
"deal": {
"configuration": "DISCOUNT",
"quantity": "1",
"discounted_price": "112.00",
"discount": "28.00",
"deal_id": "68e5fb3d61dea1aabc20876e",
"deal_name": "Sample Discount",
"deal_priority": 1,
"apply_to": "PRODUCT",
"deal_image_url": "https://....png"
}
},
{
"image_url": "https://....jpg",
"title": "Blueberry Muffin",
"sub_title": "Fresh Muffin",
"description": "<p>Delicious blueberry muffin.</p>",
"sku": "002",
"pid": "002",
"quantity": "3",
"price": "47.00",
"on_promotion": false,
"promotion_price": "0.00",
"barcode": "002"
}
],
"card": {
"_id": "",
"amount": "66.00",
"currency": "ZAR"
},
"wallet": {
"amount": "100.00",
"currency": "ZAR",
"provider": "LETS-TRADE"
},
"vouchers": [
{
"voucher_name": "R10 off",
"quantity": "1",
"price": "30.00",
"discounted_price": "20.00",
"discount": "10.00",
"voucher_id": "66ebc52c084f1481c69d59f9",
"voucher_type": "VALUE"
}
],
"deals": [
{
"configuration": "DISCOUNT",
"quantity": "1",
"discounted_price": "272.00",
"discount": "68.00",
"deal_id": "68f22aa8d2f808da3b0246a7",
"deal_name": "Sample Basket Deal",
"deal_priority": 100,
"apply_to": "BASKET",
"deal_image_url": "https://....png"
}
]
},
"customer": {
"name": "Customer Name",
"surname": "Customer Surname",
"birthday": "1995-10-08T22:00:00.000Z"
},
"rewards": [
{
"title": "cashback",
"value": "100.00"
}
]
}
}Respons descriptions
customer
object
An object containing information about the customer.
rewards
array
An array of objects representing the rewards applicable to the customer, that they have earned due to this transaction.
transaction_details
object
An object containing details about the transaction.
ref
string
A string representing a unique reference identifier for the transaction content.
discount
string
A number indicating the total discount that needs to be applied to the order.
outstanding
string
A number representing the remaining amount to be paid after discounts have been applied.
product_list.sku
string
A string representing the product that the discount applies to.
product_list.reward
string
A string representing the name of the reward that applies to the product
product_list.discount
string
A number indicating the discount applied to the product.
product_list.discounted_price
string
A number representing the price of the product after the discount has been applied.
Refund
UPCOMING FEATURE
The Refund API is designed to handle situations where a user requests a refund for codes that have already been used or when an order needs to be voided entirely. This ensures flexibility for Point of Sale (POS) transactions by providing a secure and efficient way to reverse actions associated with codes and baskets.
Purpose:
1. Refund Codes:
Allows the system to reverse the actions associated with codes (e.g., rewards awarded, vouchers redeemed, or payments processed).
Ensures that any benefits or deductions linked to the code are voided.
2. Void Basket:
Cancels the entire basket linked to the transaction.
Clears any processed payments, redeemed vouchers, or rewards associated with the transaction.
POST /v1/refund
This endpoint is used to refund codes that have been used but where the customer has asked to void the order.
Headers
Content-Type
application/json
Authorization
Bearer <token>
Sample request
{
"code": ["E", "R", "P"],
"store_id": "232323",
"terminal_id": "1234234"
}
Response
{
"success": true,
"message": "Successfully refunded codes",
"content": {
"code": ["P", "R", "E"],
"store_id": "000000",
"terminal_id": "000000"
}
}QR Code Slip Printing (Loyalty Scanning)
This section describes how the POS should support printed QR codes on the customer bill/slip to enable loyalty scanning and voucher selection in the Let’sTrade app.
Goal
Allow a customer to scan a QR code on a printed bill to:
Identify the store/terminal/transaction in Let’sTrade.
View/select applicable offerings (earn and/or redeem vouchers) in-app before the cashier finalises the bill.
1. Get Offerings on Bill Print (for QR)
Trigger
When the bill is printed (pre-payment), the POS must call Get Offerings so that:
Let’sTrade can calculate eligible offerings for the basket, and
The POS can print a QR tied to the open bill.
Endpoint
POST /v1/get/offerings
Send the request exactly as per the /v1/get/offerings Offerings endpoint above, including full store_id, terminal_id, and complete basket payload in that same structure. The only difference for QR slip printing is that code may be null / omitted at this stage because the customer has not yet scanned or selected a code in-app.
2. Customer Scans QR in App (Pre-Finalise)
Customer scans the printed QR.
A client's app uses
store_id + terminal_id + transaction_idto load the open bill’s offerings.Customer selects vouchers to apply (optional).
Before bill closure, Let’sTrade must be able to send the selected vouchers to the POS.
3. Append Vouchers to Order (Pre-Closure)
Important: This is NOT a Let’sTrade endpoint. The POS provider must implement this endpoint on their side, and Let’sTrade will call it to append vouchers to the open order.
POS-Provided Endpoint
POST {POS_BASE_URL}/append-vouchers (name/path chosen by POS provider)
Use Case
POS already printed the QR and kept the bill open.
Customer selects vouchers in Client's app.
Let’sTrade calls the POS endpoint to attach those vouchers to the live bill before payment finalisation.
Request Body (from Let’sTrade → POS)
{
"uid": "string", // Let’sTrade basket UUID
"reference": "string", // Reference to display on bill (voucher label/ref)
"store_id": "string", // Store ID
"transaction_id": "string", // POS bill/transaction ID from QR
"original_amount": 123.45,
"discount_amount": 50.00,
"remaining_amount": 73.45
}Field Notes
uid: identifies the basket in Let'sTrade the user is applying vouchers to.reference: printable reference the POS must show on the slip (e.g., voucher name/code).store_id+transaction_id: binds to the exact open bill.Amounts are for reconciliation and validation:
original_amount: bill total before vouchers.discount_amount: total discount selected in app.remaining_amount: amount due after voucher application.
Expected POS Behaviour
Validate the open bill exists and matches identifiers.
Apply discounts / attach vouchers to the transaction.
Update totals accordingly.
Optionally reprint the bill showing voucher application.
4. Finalise Offerings on Bill Close (Always)
Trigger
When the cashier closes the bill after payment, the POS must call Finalise Offerings every time, even if:
no QR was scanned,
no vouchers were applied,
no offerings were returned.
Endpoint
POST /v1/finalise/offerings
Why this matters
Finalise is the commit step that:
creates the order in Let’sTrade, and
ensures earn/burn rules execute correctly.
End-to-End Workflow Summary
Bill print (pre-payment) POS →
POST /v1/get/offeringsPOS prints QR withstore_id,terminal_id,transaction_id.Customer scans QR App loads offerings for that open bill.
Customer selects vouchers (optional) Client App → POS-provided
POST /append-voucherswith voucher bundle.Payment occurs POS processes payment normally.
Bill close / commit (always) POS →
POST /v1/finalise/offerings
Last updated