Get basket adjustments
Contents
- Overview
- Version-Specific Information
- Permissions and Authentication
- Constructing Baskets
- Fields In the Posted JSON
- Interpreting the Response
- Possible error responses
Overview
- Call name: get-basket-price
- Endpoint URL: https://api0.spaaza.com/auth/get-basket-price
- Request methods: HTTP POST
- Request Content-Type: application/json
- Response Content-Type: application/json
- Auth required: yes
This API call allows the uploading of a provisional basket of products which are going to be bought at a retailer by a shopper in order to check for any Spaaza-related price adjustments. This call will look up information about the shopper and return an adjusted basket based on that individual shopper’s profile and activity. For each item in the basket, it will look up any applicable vouchers or loyalty programme adjustments and return the associated price and voucher information.
Once the client receives the response to this call, it is normal that the transaction is confirmed with a call to the add-basket
API call.
The shopper can be represented as a member of a Spaaza programme, as a member of another programme, or not be represented, in which case the basket is considered to be “anonymous”.
The basket information and other parameters are JSON-encoded and POSTed as a single JSON file with content type application/json. Assuming that no error conditions are encountered, the call returns a JSON object containing various information, including a response for each basket item submitted.
Important: It is important to note that it is possible to make repeated calls to the get-basket-price
endpoint for the same transaction. For example, if a customer adds an item to the basket, or if they decide between the first and a subsequent request that they would like to redeem a voucher by setting its status to claimed
. Basket state is not stored in Spaaza between get-basket-price
requests and values sent in subsequent requests should not reflect any prices or other information received in the previous get-basket-price
responses for the same transaction, or there may be a risk of discount values being multiplied erroneously.
Version-Specific Information
The following version-specific changes apply to this endpoint. See the versioning page for more details.
Version | Change details |
---|---|
>= 1.5.5 | If it is not possible to match a returned item to an original purchase item, the item will be treated as a negatively-priced purchase item in the returning basket and the excluded_from_spaaza parameter will be set to true to avoid applying any Spaaza campaign logic to the item. See returns documentation for more information. |
>= 1.5.4 | The endpoint now returns a parameter_mismatch warning if the sum of the item_price of sale items in the basket does not add up to the same as the basket_total_price value (backwards compatible to version 1.0.0 ) |
The endpoint now returns a original_basket_item_not_found warning if a return item cannot be matched to an original purchase transaction (backwards compatible to version 1.0.0 ) | |
Percentage basket standalone vouchers are calculated for redemption before (monetary) basket standalone vouchers. See the Voucher Types section of the voucher documentation for more information on voucher types. (backwards compatible to version 1.0.0 ) | |
>= 1.5.2 | The endpoint now returns a user_not_found warning if a user identifier is passed, but the user is not found (backwards compatible to release 1.0.0) |
Vouchers now show a voucher_third_party_id field when chain configuration requires it | |
The title field was added to the vouchers_created section of the response (backwards compatible to release 1.4.8) | |
>= 1.5.1 | Upgrade allowed rounding from 2 to 4 decimal places in basket_item price fields, show same rounding in response fields |
>= 1.4.8 | Response JSON: new structure for purchase_progress array and addition of vouchers_created array |
>= 1.4.2 | Allow float values for basket item quantities |
Permissions and Authentication
This API call requires a valid Spaaza session. The session can be as follows:
- Admin authentication: the performing user needs to be logged in and have
write access
for the chain on behalf of which the call is being made. - Privileged authentication: the use of privileged authentication is permitted for this endpoint.
Constructing Baskets
The basket information and other fields/parameters are JSON-encoded and POSTed as a single JSON file with content type application/json. Assuming that no error conditions are encountered, the call returns a JSON object containing various information, including a response for each basket item submitted.
Example basket JSON
There follows sample JSON for a POST request and response. The Spaaza POSTMAN collection also contains more samples - details here.
An example POST to send a provisional basket:
{
"entity": {
"chain_id": 1739,
"branch_business_owner_code": "501",
"branch_business_id": 1341,
"employee_code": "AMS_007",
"employee_name": "James Bond"
},
"user": {
"member_programme": "spaaza",
"member_number": "555555"
},
"basket": {
"basket_platform_type": "in_store",
"retailer_basket_code": "70401",
"voucher_locking_code": "locking4001",
"supplementary_basket_codes": [
"2023334434434343434",
"arf5546hu00223333333"
],
"basket_total_price": 2717.98,
"basket_timestamp_iso8601": "2017-07-27T07:48:45+02:00",
"basket_timezone_name": "Europe/Amsterdam",
"basket_country_code": "NL",
"apply_refunds": true,
"shipping_charge": 8.75,
"payment_methods": [
{
"payment_method": "cash",
"payment_amount": 2000
},
{
"payment_method": "mastercard",
"payment_amount": 717.98
}
],
"basket_notes": "Notes text here",
"basket_vouchers_lock_exclusively": false,
"basket_currency": {
"currency_id": 2,
"currency_code": "EUR"
},
"basket_tax": [
{
"tax_rate": 0.21,
"tax_total": 521.00
},
{
"tax_rate": 0.06,
"tax_total": 36.29
}
],
"basket_items": [
{
"item_barcode": "2913458432854",
"retailer_item_code": "line_0",
"item_quantity": 3,
"item_price": 79.95,
"item_subtotal": 224.85,
"item_is_promotional": true
},
{
"retailer_product_code": "WBGT0234",
"retailer_item_code": "line_1",
"item_type": "product",
"item_quantity": 3.055,
"item_quantity_unit": "kg",
"item_price": 250.125,
"item_subtotal": 764.13
},
{
"item_barcode": "2913458439012",
"retailer_item_code": "line_2",
"excluded_from_spaaza": false,
"item_quantity": 1,
"item_price": 750.00
},
{
"item_barcode": "2913458434455",
"retailer_product_variant_code": "70214506af",
"retailer_item_code": "line_3",
"item_quantity": 1,
"item_price": 979.00,
"item_is_promotional": true
}
]
}
}
Note that the arrangement of items and prices is provided for example and does not necessarily represent a real-world scenario.
Fields in the POSTed JSON
Identifying the Retailer (entity)
Field | Description |
---|---|
entity (required) | Details of the retailer which is submitting the basket. |
chain_id required | The Spaaza ID of the retailer chain. |
branch_business_owner_code | A retailer-specific branch code used by the retailer to identify individual branches in a chain. If the Spaaza-specific branch_business_id value is also supplied, then branch_business_owner_code takes precedence. If this value is not supplied, nor is a valid branch_business_id supplied, or if this value is supplied and there is no branch found with a matching branch_business_owner_code , then the basket is recorded as a basket for the chain with no branch associated with it and a warning is returned. In the case of most integrations with a POS or other in-store device this field is sent and the branch_business_id field is not used. If the basket_platform_type is “online” this field is not mandatory, although often this value is used to identify an e-commerce channel. |
branch_business_id | The Spaaza ID of the business to identify an individual branch in a chain. If the branch_business_owner_code value is also supplied, then branch_business_owner_code takes precedence assuming its value can be resolved to a valid branch in the Spaaza backend. If this value is not supplied, nor is a valid branch_business_owner_code supplied, or if this value is supplied and there is no branch found with a matching branch_business_id , then the basket is recorded as a basket for the chain with no branch business_id associated with it and a warning is returned. |
employee_code | A number or string used to identify a retailer employee associated with the transaction. Commonly this may be a store assistant or other member of staff. If no employee is associated with the sale this field should not be included. |
employee_name | The name of a retailer employee associated with the transaction. This information is commonly used on electronic receipts and in analytics. If no employee is associated with the sale this field should not be included. |
Sending Shopper Information (user)
The user
section of the basket JSON is used to identify and to pass other information about the shopper making the purchase (or member of a retailer programme such as a loyalty programme). It is possible to use one of several identifiers to identify the customer - these are detailed in the “shopper identification fields” section.
General fields
The following are general fields used to supply customer information:
Field | Description |
---|---|
user | (JSON object) The section of the JSON response describing the shopper (or member of a retailer programme such as a loyalty programme). |
member_programme | (string) The name of the membership programme the shopper is a member of. If this is not supplied, a default value of “spaaza” is assumed, implying the member_number being supplied is for a Spaaza membership programme. This can also be used to supply details of another membership programme. |
send_email_receipt | (boolean) Whether the shopper should receive an email receipt if the service is activated for this retailer. |
Shopper identification Fields
One of the fields below must be used if the shopper is to be identified. If it is not possible to identify the shopper, they are presumed to be anonymous. The possible fields are described below:
Field | Description |
---|---|
member_number | (string) The unique membership number or code for the shopper. If an unrecognised code or no code is given, the shopper is presumed to be anonymous. However, if a chain business opts to allow for anonymous returns, the shopper will be recognised by the member_number from the original_retailer_basket_code. |
authentication_point_identifier | (string) The ID of the customer on a third-party identity system, such as a webstore. In order to be used, this value must be known in the Spaaza system. |
spaaza_user_id | (integer) The Spaaza-unique user ID for the shopper. Used if known and if member_number and authentication_point_identifier are not used. It is not recommended to use this field unless the Spaaza ID of all shoppers is known. |
Note if it is not possible to identify the shopper based on the fields supplied, the basket is considered to be an “anonymous” basket (see below) and a warning will be returned in the response.
Dummy shopper
It is possible to apply a “dummy” shopper account in order to force the endpoint to simulate a shopper-specific response, such as the number of points to be earned for a transaction or discounts which would be applied. In addition, it is possible to specify a segment ID which the dummy customer is a member of. The following fields are used to specify a dummy shopper:
Field | Description |
apply_artificial_user | (boolean, optional) Whether to use a dummy shopper in the request. Any previously-identified “real” shoppers specified in the user section override this setting and cause a dummy shopper (and segment) not to be applied. |
artificial_segment_ids | (array of strings, optional) The IDs of customer segments (managed in Spaaza Console). If this parameter is used the dummy shopper will “match” any segments associated with campaigns. If this parameter is not specified or its array is empty, the “Opted-in Customers” standard segment will be used if a dummy shopper is deployed. |
If a dummy shopper is applied, the do_not_create_vouchers_dynamically
parameter will be set to true automatically.
An example of dummy shopper JSON is as follows:
"user": {
"apply_artificial_user": true,
"artificial_segment_ids": [
"AXwrhxrBxvui4MoE3uLw",
"AXXb2XNQlg22bgNfhlbI"
]
}
Baskets with No Shopper Information (anonymous baskets)
It is possible to upload a basket without specifying a shopper’s member number. In that case, pass in null
as the parameter to user
, instead of the user object.
Describing the Basket Contents (basket)
Field | Description |
---|---|
basket required | The section of the POSTed JSON providing information about the contents of the basket to be purchased by the shopper |
basket_platform_type | (string, optional, recommended) The type of platform supplying the basket. If this basket is being uploaded from a retail store, this should be set to “in_store”. If it’s coming from a store’s website, it should be set to “online”. In the case that this value is not supplied, this will be set to “in_store”. |
retailer_basket_code | (string, mandatory) An identifier in the retailer’s system used to identify a particular user basket. This is stored by Spaaza and can be used to identify individual baskets at a later time, such as during any returns or refund process which may be in place. Please note that if a chain opts to be strict about repeated baskets, when an add-basket call is made with a retailer_basket_code which already exists in the Spaaza system, this will return a warning with Status Code 311 (basket_already_exists) and will return the previous existing basket. |
voucher_locking_code | (string, optional) A locking code which, when supplied, and when the basket_vouchers_lock_exclusively parameter is also supplied (see ‘Controlling voucher locking behaviour’ below), is assigned to any vouchers which are automatically locked by the call to get-basket-price . If a voucher is locked with a voucher_locking_code it can only be redeemed by a call to add-basket using the same voucher_locking_code value. Note that, in the case of basket vouchers created on the fly by a “Basket Campaign” and representing a basket discount, any previously-created unredeemed and undeleted basket vouchers for the same customer with the same voucher_locking_code will be deleted before the creation of a new voucher. |
supplementary_basket_codes | (array, string elements) An array containing one or many supplementary identifiers in the retailer’s system used to identify a particular user basket - for example a shipping code. This is stored by Spaaza and can be used to identify individual baskets at a later time, such as during any returns or refund process which may be in place. |
basket_items_subtotal | (float, optional) The total price of the basket sale/transaction to be paid by the shopper in currency for the items as calculated, before the subtraction (or addition) of any basket-level discounts or additions. This equates to the sum of each item_subtotal in the basket. This value is used to record the total gross revenue to the retailer for this basket, a value which is also used to calculate effects on member programmes such as loyalty schemes. If the total price of items in the basket does not add up to basket_total_price, the basket_total_price value is used for these calculations. |
basket_total_price | (float, recommended, max 2 decimals) The total price of the basket sale/transaction to be paid by the shopper in currency. This value is used to record the total gross revenue to the retailer for the items purchased in this basket, a value which is also used to calculate effects on member programmes such as loyalty schemes. If the total price of items in the basket does not add up to basket_total_price, the basket_total_price value is used for these calculations. If this field is not populated, a value of 0 is recorded rather than returning an error. Important - if making multiple get-basket-price requests, do not include any Spaaza price adjustments in subsequent prices. |
shipping_charge | (float, optional) The amount paid by the customer for any shipping fees. This field can be removed or set to 0 if there is no shipping charge. |
basket_notes | (string, optional) Any text notes the retailer wishes to add for future analytics purposes. These are stored by Spaaza and can be retrieved later. |
apply_refunds | (boolean, optional, default true) Whether to refund rewards redeemed on previously-purchased items which are returned in a basket. See information about returns for more information. The value of this field does not affect the processing of rewards earned on the previously-purchased item. If this field is omitted, the value is assumed to be true. |
Setting the timestamp and timezone of the Basket
Setting the local time and timezone of the moment the basket was created is useful and is used for generation of receipts and other purposes. If these fields are omitted, Spaaza will set the timestamp of the basket and assume a UTC timezone.
Field | Description |
---|---|
basket_timestamp_iso8601 | The timestamp of the basket in ISO8601 format including timezone offset from UTC |
basket_timezone_name | The “tz database” timezone name - e.g. “Europe/Amsterdam” or “EST”. Note this field is optional. If the basket_timestamp_iso8601 field does not contain the timezone offset, the basket_timezone_name field is used to store the value. |
Currency used for the basket (basket_currency)
The section of the JSON response describing the currency used. If this section of the JSON is not included the default currency for the retailer is assumed, except in the case of a return item, where the currency used in the original purchase transaction of the returned item is assumed.
Field | Description |
---|---|
currency_id | The Spaaza ID of the currency used in the basket calculations. IDs for common currencies are 2 = EUR, 3 = GBP and 4 = USD. |
currency_code | The ISO-4217 three letter code of the currency used in the basket calculations. If the currency_id field is not supplied this field can be used exclusively. |
Country code of the basket
Field | Description |
---|---|
basket_country_code | (string, 2 letters, optional) The ISO 3166-2 alpha-2 two-letter country code of the country the transaction is associated with, e.g. ‘NL’. If no basket_country_code field is supplied, the endpoint will attempt to use the country code of a branch, in the case of an in-store purchase, followed by the country code of the customer, if present. |
Payment methods used for the basket (payment_methods)
The section of the JSON POST describing the single or multiple methods used to pay for the basket.
It is not mandatory to POST payment methods to this call as they are often unknown at this stage.
Field | Description |
---|---|
payment_method | (string, max 64 chars) The payment method used, such as “mastercard” or “cash”. |
payment_amount | (float) The amount of the payment paid with this method. |
For each payment method POSTed, both fields must be populated or else the payment method will not be recorded.
If a single “payment_method” is provided in the POSTed JSON, this is treated as if it were the first in the array and the “basket_total_price” value is used as the “payment_amount”.
If an error is detected in the payment methods POSTed a warning will be returned inline in the JSON response, but the basket will still be processed and no payment method saved.
Basket tax structure (basket_tax)
Multiple tax rates can be applied a basket. This section shows the total amount present for each tax rate.
Field | Description |
---|---|
tax_rate | A percentage rate at which tax is charged on this basket. For example, a value of 0.21 here equates to a 21% tax rate. |
tax_total | The total currency amount of tax paid at a particular rate. |
Controlling voucher locking behaviour (basket_vouchers_lock_exclusively)
Voucher locking is a method used to prevent fraud. See the voucher locking section for more information.
Normally basket vouchers returned in the response to a get-basket-price call are locked for a default period of time in order to avoid an end customer removing or unclaiming the voucher before the purchase is complete. During the locking period it is still possible to redeem a claimed voucher in an add-basket
call. It is also possible to use the basket_vouchers_lock_exclusively
flag to control whether a voucher is locked in such a way that it can only be redeemed using an add-basket
call with the same retailer_basket_code
as the get-basket-price
call performing the locking.
Field | Description |
---|---|
basket_vouchers_lock_exclusively (optional, boolean) | A field denoting whether any basket vouchers returned should be locked exclusively so that they can only be redeemed by an add-basket call with the same voucher_locking_code or retailer_basket_code as this call to get-basket-price . Not including this field or setting it to false will cause vouchers to be locked using the default behaviour, which is not to lock a voucher to a particular voucher_locking_code or retailer_basket_code . |
NOTE when using percentage discount vouchers (with type ‘basket_pct’) you MUST set the basket_vouchers_lock_exclusively
flag to true
in this request as an anti-fraud measure, and the voucher can only be redeemed by an add-basket
call with a matching code. This is because the voucher is assigned a monetary value during the get-basket-price
call and it might be possible for it to be redeemed by another call were this flag not set.
Controlling the creation of dynamic vouchers (do_not_create_vouchers_dynamically)
The get-basket-price endpoint is designed to be able to create dynamic basket vouchers “on the fly” when campaigns (such as for basket-level discounts for certain customer segments) are configured to enable this. It is possible to override this using the do_not_create_vouchers_dynamically
parameter at the basket level. It should be noted that this also has the effect of removing any automatic locking or adjustment of other vouchers.
It is recommended to use this parameter to improve performance when making large numbers of requests which don’t require any vouchers to be created or adjusted.
Field | Description |
---|---|
do_not_create_vouchers_dynamically (optional, boolean) | A field to override the default behaviour of creating basket vouchers dynamically when making a get-basket-price request for a customer. |
Items in the Basket (basket_items)
The section of the JSON describing the items in the basket is introduced with the following field:
Field | Description |
---|---|
basket_items | The list of items in the basket. Each item must contain a valid identifier to identify the product in the Spaaza system. For products for which a Personal Pricing campaign voucher has been supplied, the spaaza_product_id value must be supplied. If both are supplied, spaaza_product_id overrides retailer_product_code. Alternatively, you can specify a product by passing its item_barcode. |
An item in the basket is identified as a product in the Spaaza data structure using one of a number of possible identifiers - with item_barcode being the most commonly-used parameter. Additionally, other information is supplied such as the price of the item, the quantity and whether the item is promotional.
One of the following identifiers must be used to identify the item:
Field | Description |
---|---|
item_barcode | (string, mandatory) The barcode used by the retailer to identify the basket item. For basket items where this value is used, it is not necessary to supply another product identifier. Most integrations with point of sale (POS) or webshops use this field exclusively. |
retailer_product_code | (string, optional, mandatory if no item_barcode value is supplied) The product or SKU identifier used by the retailer to identify the basket item. The retailer_product_code must already be included in the Spaaza system if the product is to be recognised. In most cases this is used as a fallback value. |
Additionally, the following fields are used to supply the other information about the item in the basket:
Field | Description |
---|---|
retailer_item_code | (string, optional) Any retailer-specific code applied by the retailer to the basket item. |
item_type | (string, optional, default “product”) The type of item in the basket. Possible values are “product”, “gift_certificate” and “shipping”. |
item_is_promotional | (boolean, optional, default false) Can be set true or false to override any existing Spaaza record of whether an item is on promotion. |
excluded_from_spaaza | (boolean, optional, default false) Can be set true or false to exclude an item from all Spaaza campaigns. |
item_quantity | (float, optional, max 4 decimals, default 1) The quantity of an item. |
item_quantity_unit | (string, optional, default “item”) The unit used for the quantity of the item. This could be “item” (the item is sold in single units, such as t-shirts), or another unit such as “kg” or “litres”. |
item_price | (float, mandatory, max 4 decimals) The gross price being charged for 1 quantity unit of an item. Note that this does not change if the quantity is increased. Important - if making multiple get-basket-price requests, do not include any Spaaza price adjustments in subsequent prices. |
item_original_price | (float, optional, max 4 decimals) The original price of the item. This is not used for calculations in the get-basket-price call because, at the point the request is sent, the item_price value does not include any Spaaza-calculated adjustments, but is returned in the response. |
item_cost_price | (float, optional, max 4 decimals) The cost price of the item. The cost price for 1 quantity unit of an item. This is used to provide margin analytics, which Spaaza is able to slice by item, category, store and customer segment. |
item_subtotal | (float, optional, max 2 decimals, default item_price * item_quantity ) The subtotal of the basket item - this is usually item_price multiplied by item_quantity. |
Note: In the subsequent add-basket
call to add a basket, supplementary basket_item
-level fields can be used to create a store of item and product metadata which can then be used to form segments used in Spaaza campaigns, populate item names on e-receipts and apps, and show sales performance analytics sliced by item, category, store, customer segment and other properties. More details can be found in the following document in this site: Creating products and product variants using the add-basket endpoint.
Note: Return items are also represented within the basket_items
array, but are covered by separate documentation in the returns section of the documentation.
Interpreting the Response
Example JSON Response
A response to the POST is sent which is equivalent to the following sample JSON (although note that objects and elements in the response are in alphabetical order):
{
"user": {
"authentication_point_identifier": "1234567890",
"member_number": "555555",
"member_programme": "spaaza",
"spaaza_user_id": 3928927
},
"basket": {
"basket_country_code": "NL",
"basket_notes": "Notes text here",
"basket_platform_type": "in_store",
"basket_total_price": 2703.85,
"basket_total_price_adjusted": 2653.85,
"retailer_basket_code": "70401",
"shipping_charge": 8.75,
"voucher_locking_code": "locking4001",
"basket_currency": {
"currency_id": 2,
"currency_code": "EUR"
},
"basket_tax": [
{
"tax_rate": 0.21,
"tax_total": 521
},
{
"tax_rate": 0.06,
"tax_total": 36.29
}
],
"basket_items": [
{
"item_barcode": "2913458432854",
"retailer_item_code": "line_0",
"item_quantity": 3,
"item_price": 79.95,
"item_price_adjusted": 79.95,
"item_subtotal": 224.85,
"item_subtotal_adjusted": 224.85,
"item_is_promotional": true,
"is_identified": true,
"excluded_from_spaaza": false
},
{
"item_barcode": null,
"spaaza_product_id": 18605,
"retailer_product_code": "WBGT0234",
"retailer_item_code": "line_1",
"item_type": "product",
"item_quantity": 3,
"item_price": 250.125,
"item_price_adjusted": 241.674,
"item_subtotal": 750,
"item_subtotal_adjusted": 725,
"item_is_promotional": false,
"is_identified": true,
"excluded_from_spaaza": false,
"basket_voucher_distribution": [
{
"voucher_key": "ac189592441c9c4e4d0a0f5be03216f6a7e026f0d482c44a293da8e373163fd0",
"voucher_id": 84345653543,
"voucher_distribution_amount": 25
}
],
"purchase_progress_distribution": [
{
"purchase_progress_campaign_id": 76,
"purchase_progress_campaign_title": "Store Rewards",
"purchase_progress_campaign_type": "cashback",
"purchase_progress_distribution_amount": 37.50,
"contributing_campaign": {
"campaign_id": 500,
"campaign_title": "1 point for every €1 spent",
"campaign_title_localised": "1 point for every €1 spent",
"campaign_type": "cashback"
}
}
]
},
{
"item_barcode": "2913458439012",
"retailer_item_code": "line_2",
"item_quantity": 1,
"item_price": 750,
"item_price_adjusted": 725,
"item_subtotal": 750,
"item_subtotal_adjusted": 725,
"item_is_promotional": false,
"is_identified": true,
"excluded_from_spaaza": false,
"basket_voucher_distribution": [
{
"voucher_key": "ac189592441c9c4e4d0a0f5be03216f6a7e026f0d482c44a293da8e373163fd0",
"voucher_id": 84345653543,
"voucher_distribution_amount": 25
}
]
},
{
"item_barcode": "2913458434455",
"retailer_item_code": "line_3",
"item_quantity": 1,
"item_price": 979,
"item_price_adjusted": 979,
"item_subtotal": 979,
"item_subtotal_adjusted": 979,
"item_is_promotional": true,
"is_identified": true,
"excluded_from_spaaza": false
}
],
"basket_vouchers_applied": [
{
"campaign_id": 76,
"campaign_owner_code": "ACME_CASHBACK_001",
"campaign_product_promotion_type": null,
"campaign_title": "Store Rewards",
"campaign_type": "matching_item",
"voucher_amount": 50,
"voucher_amount_original": 50,
"voucher_amount_redeemed": 50,
"voucher_basket_owner_code_exclusive": "70401",
"voucher_currency_id": 2,
"voucher_currency_symbol": "€",
"voucher_expiry_datetime_utc": "2050-01-01 00:00:00",
"voucher_expiry_seconds_remaining": 1082711675,
"voucher_honour_code": null,
"voucher_id": 84345653543,
"voucher_key": "ac189592441c9c4e4d0a0f5be03216f6a7e026f0d482c44a293da8e373163fd0",
"voucher_locked": true,
"voucher_locking_code": "locking_4001",
"voucher_status": "claimed",
"voucher_text": "",
"voucher_type": "basket"
}
],
"honour_vouchers_applied": [
{
"campaign_id": 79,
"campaign_owner_code": "ACME_LOYALTY_001",
"campaign_product_promotion_type": null,
"campaign_title": "ACME loyalty",
"campaign_type": "loyalty",
"voucher_amount": 0,
"voucher_amount_original": 0,
"voucher_amount_redeemed": 0,
"voucher_basket_owner_code_exclusive": "70401",
"voucher_currency_id": null,
"voucher_currency_symbol": null,
"voucher_expiry_datetime_utc": "2050-01-01 00:00:00",
"voucher_expiry_seconds_remaining": 1082711675,
"voucher_honour_code": "honour0008",
"voucher_id": 84345653544,
"voucher_key": "ae8887274d771c676eeab406fddaa9c523875044d029ac91b8ac219f43e9972b",
"voucher_locked": true,
"voucher_locking_code": "locking_4001",
"voucher_status": "claimed",
"voucher_text": "",
"voucher_type": "honour"
}
],
"payment_methods": [
{
"payment_method": "cash",
"payment_amount": 2000
},
{
"payment_method": "mastercard",
"payment_amount": 653.85
}
],
"purchase_progress": [
{
"balance_new": 87.50,
"balance_previous": 50,
"campaign_id": 76,
"campaign_type": "points_wallet",
"is_default": true,
"mutations": [
{
"amount": 37.50,
"contributing_campaign_id": 500,
"contributing_campaign_title": "1 point for every €1 spent",
"contributing_campaign_title_localised": "1 point for every €1 spent",
"contributing_campaign_type": "cashback",
"log_message": "contribution from cashback",
"timestamp": "2023-05-08T12:35:53+00:00",
"type": "campaignContribution"
}
],
"title": "ACME Points Wallet"
},
{
"balance_new": 0,
"balance_previous": 0,
"campaign_id": 1255,
"campaign_type": "wallet",
"is_default": true,
"mutations": [],
"title": "ACME Monetary Wallet"
}
],
"return_transactions": [],
"supplementary_basket_codes": [
"2023334434434343434",
"arf5546hu00223333333"
],
"vouchers_created": [
{
"amount": 10,
"campaign_title": "ACME Loyalty Campaign",
"campaign_type": "loyalty",
"currency_code": "EUR",
"currency_symbol": "€",
"discount_ratio": 0,
"expiry_datetime_utc": "2023-07-08T12:35:53+00:00",
"id": null,
"key": "cb0a182488c05823ee8d0a35e52327d7138b559adc1cbe5edd4be2a73d76b9ac",
"loyalty_rule": {
"loyalty_rule_id": 88,
"loyalty_rule_type": "points_tracker"
},
"status": "generated",
"text": "Your Voucher",
"type": "basket"
}
]
}
}
Note that the arrangement of items, prices, points, vouchers and other elements is provided for example purposes in order to demonstrate where fields and values may occur, and does not necessarily represent a real-world scenario.
The response can be described as follows:
General Basket Information
Shopper Information (user)
In the case that an identified user/member is found based on the POST request, various details about the member are returned. In the case of an anonymous basket or the member not being found, these details are missing and various other details such as any Spaaza-specific discount information is not supplied.
Field | Description |
---|---|
user | The section of the JSON response describing the shopper (or member of a retailer programme such as a loyalty programme). |
authentication_point_identifier | The ID of the customer on a third-party identity system, such as a webstore. |
member_programme | The name of the membership programme the shopper is a member of. If this is not supplied, a default value of “spaaza” is assumed, implying the member_number being supplied is for a Spaaza membership programme. This can also be used to supply details of another membership programme. |
member_number | The unique membership number or code for the shopper. If an unrecognised code or no code is given, the shopper is presumed to be anonymous. |
spaaza_user_id | The Spaaza-unique user ID for the shopper. |
Basket Contents (basket)
Field | Description |
---|---|
basket | The section of the POSTed JSON providing information about the contents of the basket to be purchased by the shopper |
The subsections below describe the fields returned in the basket section of the JSON response.
Top-level elements in the basket
The following top-level elements are returned in the basket section of the JSON response:
Field | Description |
---|---|
basket_platform_type | The type of platform supplying the basket. If this basket is being uploaded from a retail store, this should be set to “in_store”. If it’s coming from a store’s website, it should be set to “online”. In the case that this value is not supplied, this will be set to “in_store”. |
basket_items_subtotal | The total price of the basket sale/transaction to be paid by the shopper in currency for the items as calculated, before the subtraction (or addition) of any basket-level discounts or additions. This equates to the sum of each item_subtotal in the basket. This value is used to record the total gross revenue to the retailer for this basket, a value which is also used to calculate effects on member programmes such as loyalty schemes. If the total price of items in the basket does not add up to basket_total_price, the basket_total_price value is used for these calculations. |
basket_notes | Any text notes the retailer wishes to add for future analytics purposes. These are stored by Spaaza and can be retrieved later. |
basket_total_price | The total price of the basket sale/transaction to be paid by the shopper in currency. This value is used to record the total gross revenue to the retailer for this basket, a value which is also used to calculate effects on member programmes such as loyalty schemes. If the total price of items in the basket does not add up to basket_total_price, the basket_total_price value is used for these calculations. |
basket_total_price_adjusted | The total price of the basket sale/transaction to be paid by the shopper in currency. This is the amount calculated by Spaaza to be carried over to the next step add-basket |
retailer_basket_code | Any identifier in the retailer’s system used to identify a particular user basket. This is stored by Spaaza and can be used to identify individual baskets at a later time, such as during any returns or refund process which may be in place. |
shipping_charge | The amount paid by the customer for any shipping fees. |
Timestamp and timezone of the Basket
Field | Description |
---|---|
basket_timestamp_iso8601 | The timestamp of the basket in ISO8601 format including timezone offset from UTC |
basket_timezone_name | The “tz database” timezone name - e.g. “Europe/Amsterdam” or “EST”. Note this field is optional and is not used for calculating timestamps but for returning timestamp names in API responses. |
Currency used for the basket (basket_currency)
Field | Description |
---|---|
currency_id | The Spaaza ID of the currency used in the basket calculations. IDs for common currencies are 2 = EUR, 3 = GBP and 4 = USD. |
currency_code | The ISO-4217 three letter code of the currency used in the basket calculations. |
Country code of the basket
Field | Description |
---|---|
basket_country_code | (string, 2 letters, optional) The ISO 3166-2 alpha-2 two-letter country code of the country the transaction is associated with, e.g. ‘NL’. If no basket_country_code field is supplied, the endpoint will attempt to use the country code of a branch, in the case of an in-store purchase, followed by the country code of the customer, if present. |
Payment methods used for the basket (payment_methods)
The section of the JSON response describing the single or multiple methods used to pay for the basket, should they have been posted.
Field | Description |
---|---|
payment_method | (string, max 64 chars) The payment method used, such as “mastercard” or “cash”. |
payment_amount | (float) The amount of the payment paid with this method. |
If a single “payment_method” is provided in the POSTed JSON, this is treated as if it were the first in the array and the “basket_total_price” value is used as the “payment_amount”.
If no payment methods have been POSTed then an empty “payment_methods” array will be returned.
Basket tax structure (basket_tax)
Multiple tax rates can be applied a basket. This section shows the total amount present for each tax rate.
Field | Description |
---|---|
tax_rate | A percentage rate at which tax is charged on this basket. For example, a value of 0.21 here equates to a 21% tax rate. |
tax_total | The total currency amount of tax paid at a particular rate. |
Items in the basket (basket_items)
The section of the JSON describing the items in the basket is introduced with the following field:
Field | Description |
---|---|
basket_items | The list of items in the basket. Each item must contain a valid identifier to identify the product in the Spaaza system. For products for which a Personal Pricing campaign voucher has been supplied, the spaaza_product_id value must be supplied. If both are supplied, spaaza_product_id overrides retailer_product_code. Alternatively, you can specify a product by passing its item_barcode. |
An item in the basket is identified as a product in the Spaaza data structure using one of a number of possible identifiers - with item_barcode being the most commonly-used parameter. Additionally, other information is supplied such as the price of the item, the quantity and whether the item is promotional.
One of the following identifiers must be used to identify the item:
Field | Description |
---|---|
item_barcode | (string, numeric allowed, mandatory) Preferred. The barcode used by the retailer to identify the basket item. For basket items where this value is used, it is not necessary to supply another product identifier. Most integrations with point of sale (POS) or webshops use this field exclusively. |
retailer_product_code | (string, optional, mandatory if no item_barcode value is supplied) The product or SKU identifier used by the retailer to identify the basket item. The retailer_product_code must already be included in the Spaaza system if the product is to be recognised. In most cases this is used as a fallback value. |
Additionally, the following fields are used to supply the other information about the item in the basket:
Field | Description |
---|---|
retailer_item_code | (string, optional) Any retailer-specific code applied by the retailer to the basket item. |
item_type | (string, optional, default “product”) The type of item in the basket. Possible values are “product”, “gift_certificate” and “shipping”. |
item_is_promotional | (boolean, optional, default false) Can be set true or false to override any existing Spaaza record of whether an item is on promotion. Certain campaigns can be configured not to take effect on items marked as promotional using this flag. |
excluded_from_spaaza | (boolean, optional, default false) Can be set true or false to exclude an item from all Spaaza campaigns. |
item_quantity | (float, optional, max 4 decimals, default 1) The quantity of an item. If this is not supplied the quantity is assumed to be 1. |
item_quantity_unit | (string, optional, default “item”) The unit used for the quantity of the item. This could be “item” (the item is sold in single units, such as t-shirts), or another unit such as “kg” or “litres”. |
item_price | (float, mandatory, max 4 decimals) The price being charged for 1 quantity unit of an item net of any Spaaza vouchers being redeemed on it. In the case that the add-basket call has been preceded by a call to get-basket-price , this value is normally the same as the item_price_adjusted field in the get-basket-price response. Note that this does not change if the quantity is increased or decreased. Please see also the item_original_price field and the section below “Voucher Distribution” for important information regarding this field. |
item_original_price | (float, optional, max 4 decimals) The original gross price being charged for 1 quantity unit of an item. Note that this does not change if the quantity is increased. Note also that if vouchers are being redeemed, this value is not reduced. In the case of requests including basket vouchers to be redeemed that have been created on-the-fly by promotional campaigns, a voucher_distribution_estimated warning is generated if this field is not populated, and an estimated distribution of vouchers is recorded. |
item_cost_price | (float, optional, max 4 decimals) The cost price of the item. The cost price for 1 quantity unit of an item. This is used to provide margin analytics, which Spaaza is able to slice by item, category, store and customer segment. |
item_subtotal | (float, optional, max 2 decimals, default item_price * item_quantity ) The subtotal of the basket item - this is usually item_price multiplied by item_quantity |
Note: Supplementary fields can be used to create a store of item and product metadata which can then be used to form segments used in Spaaza campaigns, populate item names on e-receipts and apps, and show sales performance analytics sliced by item, category, store, customer segment and other properties. For more details please see the Creating products section of this site.
Note: Return items are also represented within the basket_items
array, but are covered by separate documentation in the returns section of the documentation.
Discounts, Wallets and Vouchers
See the vouchers section for more information on how vouchers work.
Vouchers applied (basket_vouchers_applied)
Discounts or loyalty rewards which are calculated at the basket level (such as a shopper applying their loyalty rewards on a purchase or a promotional mechanic such as “buy 3 items from a range of qualifying products and only pay the price of 2 of them”) are viewed as “vouchers” and are shown in the basket_vouchers_applied
array of the response.
The intention of showing applicable vouchers in the response is to allow the client to the apply the vouchers returned in the subsequent call to add-basket
so that the vouchers can be redeemed.
The distribution of voucher value at the basket item level is carried out using a “basket_voucher_distribution” method. This is explained in this section.
Details of each voucher in the basket_vouchers_applied
array:
Field | Description |
---|---|
campaign_id | The Spaaza ID of the promotional campaign which is being applied. |
campaign_owner_code | A text string (which can be numeric recorded as a string) which has been chosen by the retailer in order to identity individual promotions or vouchers in an external system and which can be configured as a campaign parameter in Spaaza. |
campaign_product_promotion_type | The type of product promotion which is being applied. This is only applicable to vouchers associated with product promotions. Applicable types are product_combo_price , free_product , fixed_monetary_discount and meal_deal . See the campaigns section of the documentation for more information on setting up campaigns, and the documentation section on “Fields specific to type: basket” section for more information on specific product promotions. |
campaign_title | The title of the Spaaza promotional campaign which is being applied. |
campaign_type | The type of Spaaza promotional campaign which is being applied. Spaaza has several different types of retail mechanic available which can be applied at the basket level. |
voucher_amount | An amount equating to voucher_amount_redeemed value above. |
voucher_amount_original | The original value of the voucher. In some cases it is not possible to redeem 100% of the voucher value, but this value is always set to the 100% value. |
voucher_amount_redeemed | The amount of the voucher value which is actually redeemed in this transaction. Any remaining value will be returned to the customer. |
voucher_basket_owner_code_exclusive | A text string (which can be numeric recorded as a string) which has been chosen by the retailer in order to identity individual promotions or vouchers in an external system. |
voucher_currency_id | The Spaaza ID of the denomination currency of the voucher. |
voucher_currency_symbol | The ISO-4217 currency symbol of the denomination currency of the voucher. |
voucher_expiry_datetime_utc | The date and time in UTC when the voucher is due to expire and no longer be available for transactions. |
voucher_expiry_seconds_remaining | The remaining time in seconds until expiry of the voucher. |
voucher_honour_code | A code which can be used to signal that the voucher should be honoured in a 3rd party system. For example, a promotional code can be used to signal to a webshop that this voucher should be redeemed and the customer issued with a free gift item. The webshop can then redeem the voucher as normal. |
voucher_id | A unique voucher ID generated by Spaaza and used to identify a voucher and tie it to a member and a basket. |
voucher_key | A unique voucher key generated by Spaaza and used to identify a voucher and tie it to a member and a basket. |
voucher_locked | Whether the voucher is locked. When a call is made to get-basket-price, the voucher is generally locked for a short period of time to allow the same basket to be confirmed during the subsequent add-basket call. This avoids fraud such as a discount being provided to the customer in the response to get-basket-price and the customer deleting the voucher (they are unable to do this if it’s locked) before the transaction is confirmed in the add-basket call. |
voucher_locked_until | A datetime indicating the time until which the voucher is locked. |
voucher_locking_code | A text string (which can be numeric recorded as a string) chosen as a locking code. If this code is present and the voucher is locked, it cannot be redeemed without supplying a matching voucher_locking_code value in the call to add-basket |
voucher_status | The status of the voucher. In nearly all cases this is set to “claimed” as it has been claimed by the shopper but not yet redeemed. |
voucher_text | Any text description accompanying the voucher. This can be used in a receipt or displayed upon completion of purchase. |
voucher_type | The type of the voucher |
Voucher distribution
Spaaza automatically calculates the distribution of the value of basket vouchers which are redeemed on individual items in a basket. This ensures that, should the item be returned, the correct action can be taken to reconcile the amount of the voucher spent on the item - for example by returning points to a customer’s loyalty wallet. This is known as “voucher distribution” - i.e. distributing the value of the voucher over the items in the basket.
Note that the distribution of voucher value in a basket item also affects the net price paid for the item. The new per-single-unit price is reflected in the item_price_adjusted
field of the basket item in the response.
In the response, how the value of the voucher is apportioned to each basket item is shown in the basket_voucher_distribution
array under each basket item. The following key fields are returned:
Field | Description |
---|---|
voucher_key | A unique voucher key generated by Spaaza and used to identify a voucher and tie it to a member and a basket. |
voucher_id | A unique voucher ID generated by Spaaza and used to identify a voucher and tie it to a member and a basket. |
voucher_distribution_amount | The amount of the voucher distributed to this basket item. This can be used to show a line-item discount on a receipt, for example. |
Honour vouchers (honour_vouchers_applied)
Vouchers which can be used to redeem (“honour”) third party promotions in systems such as webshops or POS devices. These are recognised by the 3rd-party ‘voucher_honour_code’.
All fields and properties of honour vouchers are the same as for basket vouchers (see “Basket-Level Discounts”) but the following should be noted about honour vouchers:
- A monetary value is not necessary
- A currency is not necessary
- When redeemed, the value of an honour voucher is not recorded and no value is distributed over individual items in the basket
Wallet or progress amounts earned (purchase_progress)
Any amounts earned in wallets or progress campaigns such as balance-based loyalty rewards or spending target-based programmes are recorded in the purchase_progress
array in the response. Each active wallet is returned as an element in the array, even if no points, wallet or purchase progress amounts have been awarded.
Each (points) wallet or purchase progress object in the array contains the following fields:
Field | Description |
---|---|
balance_new | The new balance of the wallet after the transaction. |
balance_previous | The old balance of the wallet before the transaction. |
campaign_id | The Spaaza ID of the wallet or purchase progress campaign. |
campaign_type | The type of campaign such as ‘wallet’, ‘points_wallet’ or ‘progress’. |
is_default | Whether this is the default wallet for the member. |
title | The name or title of the wallet or purchase progress campaign. |
mutations | An array of mutations to the wallet or purchase progress campaign. This array may contain no or multiple elements. |
Each mutation object in the mutations
array contains the following fields:
Field | Description |
---|---|
amount | The amount of currency awarded. |
contributing_campaign_id | The Spaaza ID of the campaign which contributed to this mutation. |
contributing_campaign_title | The name or title of the campaign which contributed to this mutation. |
contributing_campaign_type | The type of campaign which contributed to this mutation. |
log_message | A message describing the reason for the mutation. |
timestamp | The time in UTC at which the mutation was awarded. |
type | The type of mutation. |
transaction_message | The processed reward_message_text field from the contributing campaign, if present, otherwise null. |
Progress or wallet distribution
Spaaza automatically calculates the distribution of the amount earned in a progress or wallet campaign over each basket item in a basket. This ensures that, should the item be returned, the correct action can be taken to reconcile the amount of the progress or wallet campaign earned on the item - for example by reclaiming points from a customer’s loyalty wallet. This is known as “purchase progress distribution”
- i.e. distributing the amount earned in a progress or wallet campaign over the items in the basket.
The following fields are returned in each element of the purchase_progress_distribution
array under each basket item:
Field | Description |
---|---|
purchase_progress_campaign_id | The Spaaza ID of the progress campaign |
purchase_progress_campaign_title | The name or title of the progress campaign |
purchase_progress_campaign_type | The type of campaign such as ‘cashback’ or ‘progress’. |
purchase_progress_distribution_amount | The amount of progress or currency which is applied to this individual basket item. |
contributing_campaign | An object describing the campaign which contributed to this progress or wallet campaign distribution. |
Vouchers created (vouchers_created)
Any vouchers created as a result of the basket transaction are returned in the vouchers_created
array in the response.
Each voucher in the array contains the following fields:
Field | Description |
---|---|
amount | An amount equating to voucher_amount_redeemed value above. |
campaign_title | The title of the Spaaza promotional campaign which is being applied. |
campaign_type | The type of Spaaza promotional campaign which is being applied. Spaaza has several different types of retail mechanic available which can be applied at the basket level. |
currency_code | The ISO-4217 three letter code of the denomination currency of the voucher. |
voucher_currency_symbol | The ISO-4217 currency symbol of the denomination currency of the voucher. |
discount_ratio | The discount ratio of the voucher, denoting the percentage discount it may offer on a purchase. This is expressed as a decimal, where 0 is 0% discount and 1 is 100% discount. |
expiry_datetime_utc | The date and time in UTC when the voucher is due to expire and no longer be available for transactions. |
id | A unique voucher ID generated by Spaaza and used to identify a voucher and tie it to a member and a basket. |
key | A unique voucher key generated by Spaaza and used to identify a voucher and tie it to a member and a basket. |
loyalty_rule | An object describing any rule used to create the voucher and including the ‘loyalty_rule_id’ and ‘loyalty_rule_type’ fields |
status | The status of the voucher. In nearly all cases this is set to “claimed” as it has been claimed by the shopper but not yet redeemed. |
text | Any text description accompanying the voucher. This can be used in a receipt or displayed upon completion of purchase. |
type | The type of the voucher |
transaction_message | The processed reward_message_text field from the campaign being applied, if present, otherwise null. |
Possible error responses
The following represents a list of possible error responses for the get-basket-price
endpoint:
Code | Name and Description | HTTP Status Code |
---|---|---|
3 | http_vars_missing This script is missing some required variables which must be submitted. | 400 |
6 | no_valid_session The user needs to be logged in and a valid session key needs to be sent | 401 |
68 | permission_denied_or_non_existent This user has insufficient permissions for this object or the object does not exist. | 500 |
228 | auth_method_invalid The given auth_method parameter has an invalid value. | 500 |
231 | currency_not_found The given currency passed must exist in the list of currencies available | 500 |
252 | basket_currency_missing The basket_currency information is missing from the basket. | 500 |
262 | app_platform_type_not_allowed The app_platform_type submitted is not permitted. | 400 |
265 | authorization_invalid The given authorization header is invalid. | 400 |
266 | access_token_invalid The given access token is invalid. | 401 |
267 | no_valid_user A valid username needs to be specified | 401 |
309 | original_basket_item_not_found Could not find the original basket item for the owner code specified | 400 |
311 | basket_already_exists A basket with this owner code has already been submitted | 200 |
319 | return_item_not_negative_value A return item must have negative value | 400 |
337 | basket_platform_type_unrecognised The basket_platform_type or app_platform_type is missing or unrecognised. | 400 |
407 | calculation_error There has been a calculation error | 400 |