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.
This step only determines the offerings and does not finalise the transaction
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:
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.
code
array
An array of code strings indicating the type of operation. Possible values per code are P (payment), R (redemption), or E (earning). Defaults to [] if omitted
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.
user
object
An object containing customer identification details. See User Object below.
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.
User Object:
Note: If
user._idis not provided butcell_numberis, the API will attempt to find or create the customer. Additionally, the user can be omitted if providing codes as codes are tied to a user and will be prioritised when selecting a user.
_id
string
Known Let'sTrade user ID. If provided, skips user lookup.
name
string
Customer first name.
surname
string
Customer surname.
email
string
Customer email address (must be valid email format).
cell_country_code
string
Phone country code (e.g. "+27").
cell_number
string
Customer phone number.
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
string
A string representing the stock keeping unit (SKU) of the product that the voucher applies to in the product_list of the basket
quantity
string
The number of units to discount. If omitted, the discount applies to all units of the matched product. If provided, only this many units are discounted (capped at the product quantity).
apply_to_promotion
boolean
If true and the matched product is on promotion, the voucher discount is calculated against the promotion_price instead of the regular price.
Product List (array):
sku*
string
A string representing the stock keeping unit (SKU) of the product, used for inventory tracking.
pid*
string
The product identifier in Let'sTrade.
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.
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
condiments
array
An array of condiment/modifier items attached to the product. See Condiments below.
Condiments (array):
Note: Condiments represent modifiers attached to a parent product (e.g. milk choice on a coffee). They are sent as a flat array on the product. The API resolves them into condiment groups internally and returns them as a flat array in the response.
pid*
string
The condiment product identifier in Let'sTrade.
sku
string
The condiment SKU.
title
string
The condiment name (e.g. "Almond Milk").
price
string
The condiment price.
quantity
string
The condiment quantity.
Sample request
Response
Response descriptions
order_id
string
Unique order identifier for tracking.
order_code
string
Human-readable order code for tracking.
basket.outstanding_amount
string
The remaining amount to be paid after discounts have been applied.
basket.service_fee
string
Service fee applied to the basket.
basket.product_handling_fees
string
Product-related handling fees.
basket.product_list[].vouchers
array
An array of voucher objects applied to the product.
basket.product_list[].vouchers[].discount
string
The discount amount applied to the product by the voucher.
basket.product_list[].vouchers[].discounted_price
string
The price of the product after the voucher discount has been applied.
basket.product_list[].deal
object
A deal object applied to the product, or null if no deal applies.
basket.product_list[].subscription
object
Subscription discount applied to the product, if applicable. Contains redemption_id and discount.
basket.product_list[].condiments
array
Flat array of condiment/modifier items on the product (pid, sku, title, price, quantity).
basket.card
object
Card payment breakdown. Only present if a P (payment) code with card details was submitted.
basket.card.amount
number
The amount that was paid using a card.
basket.wallet
object
Wallet payment breakdown. Only present if a P (payment) code with wallet details was submitted.
basket.wallet.amount
number
The amount that was paid using a wallet.
basket.vouchers
array
An array of basket-level vouchers applied.
basket.vouchers[].discount
number
The discount amount applied to the basket by the voucher.
basket.deals
array
An array of basket-level deals applied.
basket.subscriptions
array
Subscription discounts applied to the cheapest qualifying products. Contains redemption_id, product_pid, product_title, and discount.
Finalise
POST /v1/finalise/offerings
This endpoint is used to finalise the transaction by confirming the codes and processing the details.
Headers
Content-Type
application/json
Authorization
Bearer <token>
Body
Fields marked with * are required.
Root:
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.
code
array
An array of code strings indicating the type of operation. Possible values per code are P (payment), R (redemption), or E (earning). Defaults to [] if omitted.
Basket Object:
uuid*
string
A string representing the unique identifier of the basket.
total*
string
The total amount of the basket, including all fees and taxes.
product_list*
array
An array of objects representing the products in the basket. Minimum 1 item required.
outstanding_amount
string
The remaining amount to be paid after all discounts, fees, and vouchers have been applied.
vat
string
The Value Added Tax amount for the basket.
sub_total
string
The subtotal amount of the basket, excluding VAT and fees.
delivery_fee
string
The fee for delivering the items in the basket.
service_fee
string
An additional service fee applied to the basket, such as tips.
discount
string
The total discount applied to the basket.
product_handling_fees
string
Product-related handling fees applied to the basket.
user
object
An object containing customer identification details. Same structure as the Offerings User Object.
deals
array
An array of deal objects from the offerings response — pass back any deals the POS applied.
vouchers
array
An array of voucher objects from the offerings response — pass back any vouchers the POS applied.
Note: The
external_vouchersfield is not accepted on the finalise endpoint — external vouchers are only processed during get/offerings.
Product List (array):
Same fields as the Offerings Product List, plus:
vouchers
array
Voucher objects from the offerings response — pass back any product-level vouchers.
deal
object
Deal object from the offerings response — pass back if a deal was applied to this product. May be null.
Sample request
Response
Response descriptions
client_id
string
The client identifier. Only present in the finalise response.
order_id
string
Unique order identifier for tracking.
order_code
string
Human-readable order code for tracking.
basket.outstanding_amount
string
The remaining amount to be paid after discounts have been applied.
basket.service_fee
string
Service fee applied to the basket.
basket.product_handling_fees
string
Product-related handling fees.
basket.product_list[].vouchers
array
Product-level vouchers, echoed from the request.
basket.product_list[].vouchers[].discount
string
The discount amount applied to the product by the voucher.
basket.product_list[].vouchers[].discounted_price
string
The price of the product after the voucher discount has been applied.
basket.product_list[].deal
object
A deal object applied to the product, echoed from the request. null if no deal applies.
basket.product_list[].condiments
array
Flat array of condiment/modifier items on the product (pid, sku, title, price, quantity).
basket.vouchers
array
An array of basket-level vouchers (filtered to BASKET apply_to only).
basket.vouchers[].discount
number
The discount amount applied to the basket by the voucher.
basket.deals
array
An array of basket-level deals 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
Response
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)
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