Adding a completed basket
Contents
- Overview
- Version-specific information
- Permissions and Authentication
- Constructing Baskets
- Fields in the POSTed JSON
- Interpreting the Response
- Possible error responses
Overview
- Call name: add-basket
- Endpoint URL: https://api0.spaaza.com/auth/add-basket
- 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 basket of products which have been bought at a retailer by a shopper once the transaction has closed. This is generally used to i) generate analytics figures for the retailer; ii) generate purchase history for shoppers who are Spaaza members which can be used to provide a more personalised shopping experience in future; and iii) update the status of any shopper vouchers or associated member profile records.
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”.
In general use of this API call is as a follow-up to the get-basket-price
call which returns adjustments to the shopper’s provisional basket.
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.
Note: Please note it is possible to add fields to item information in the add-basket
endpoint in order to create a record of product information in Spaaza. This is useful for information displayed on receipts, for analytics purposes, and for campaign targeting. The required fields are not documented here, but in a separate document: Creating products and product variants using the add-basket endpoint.
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 | When all purchase items in a basket have both item_price and item_original_price fields populated, the difference between the two values is used to calculate the redemption amount and distribution of vouchers being redeemed instead of making any reference to previously calculated voucher redemption values. This allows client-specific discounts to still be applied between calls to the get-basket-price and add-basket endpoints, although we recommend caution and testing when applying this technique. See the subsection called Basket Discounts and Vouchers for more information about voucher redemption. |
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 now redeemed 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 ) | |
A retailer identifier of chain_id should now be used instead of separate entity_type and entity_id values. See the Identifying the Retailer section below. (backwards compatible to release 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.7 | Update item_price field in add-basket request to be used to send the item unit price net of Spaaza rewards applied to/distributed on it, and use item_original_price field for the gross item price (without any Spaaza rewards applied to it). See the subsection called Basket Discounts and Vouchers for important information on this change. |
>= 1.4.5 | Update request and response JSON to include item_original_price field. Display voucher_distribution_estimated warning for requests that include on the fly basket campaign vouchers, but where the item_original_price field is not present in all the basket items |
>= 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 add a 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",
"send_email_receipt": true
},
"basket": {
"basket_platform_type": "in_store",
"retailer_basket_code": "70401",
"basket_country_code": "NL",
"voucher_locking_code": "locking4001",
"supplementary_basket_codes": [
"2023334434434343434",
"arf5546hu00223333333"
],
"basket_total_price": 2653.85,
"shipping_charge": 8.75,
"payment_methods": [
{
"payment_method": "cash",
"payment_amount": 2000
},
{
"payment_method": "mastercard",
"payment_amount": 653.85
}
],
"basket_timestamp_iso8601": "2017-07-27T07:48:45+02:00",
"basket_timezone_name": "Europe/Amsterdam",
"apply_refunds": true,
"basket_notes": "Notes text here",
"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.0,
"item_quantity_unit": "item",
"item_price": 74.95,
"item_original_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,
"excluded_from_spaaza": false,
"item_price": 241.67,
"item_original_price": 250,
"item_subtotal": 725,
"basket_voucher_distribution": [
{
"voucher_key": "ac189592441c9c4e4d0a0f5be03216f6a7e026f0d482c44a293da8e373163fd0",
"voucher_distribution_amount": 25.00
}
]
},
{
"item_barcode": "2913458439012",
"retailer_item_code": "line_2",
"item_quantity": 0.875,
"item_quantity_unit": "kg",
"item_price": 778.57,
"item_original_price": 750,
"item_subtotal": 681.25,
"basket_voucher_distribution": [
{
"voucher_key": "ac189592441c9c4e4d0a0f5be03216f6a7e026f0d482c44a293da8e373163fd0",
"voucher_distribution_amount": 25.00
}
]
},
{
"item_barcode": "2913458434455",
"retailer_item_code": "line_3",
"item_quantity": 1,
"item_price": 979,
"item_original_price": 979,
"item_subtotal": 979,
"item_is_promotional": true
}
],
"basket_vouchers": [
{
"voucher_key": "ac189592441c9c4e4d0a0f5be03216f6a7e026f0d482c44a293da8e373163fd0"
}
],
"honour_vouchers": [
{
"voucher_key": "bb1e45cbd6d174164b77a58047779e8d0323fa9c61ac994d84223343c531334e"
}
]
}
}
An example response for an identified customer.
{
"basket": {
"id": 1163166,
"chain_id": 1739,
"basket_platform_type": "in_store",
"basket_total_price": 2653.85,
"currency_id": 2,
"shipping_charge": 8.75,
"basket_timestamp_iso8601": "2017-07-27T07:48:45+02:00",
"basket_timezone_name": "Europe/Amsterdam",
"basket_country_code": "NL",
"apply_refunds": true,
"retailer_basket_code": "70401",
"voucher_locking_code": "locking4001",
"payment_methods": [
{
"payment_method": "cash",
"payment_amount": 2000
},
{
"payment_method": "mastercard",
"payment_amount": 653.85
}
],
"basket_items": [
{
"spaaza_product_id": 1905743,
"item_barcode": "2913458432854",
"product_name": "Winter sweater",
"retailer_item_code": "line_0",
"item_quantity": 3.25,
"item_is_promotional": true,
"item_price": 74.95,
"item_original_price": 79.95,
"item_subtotal": 224.85,
"is_identified": true,
"excluded_from_spaaza": false
},
{
"item_barcode": null,
"product_name": "Vest Kiara",
"retailer_product_code": "WBGT0234",
"retailer_item_code": "line_1",
"item_type": "product",
"item_quantity": 3,
"item_is_promotional": false,
"item_price": 250.00,
"item_original_price": 250.00,
"item_subtotal": 750.00,
"is_identified": true,
"excluded_from_spaaza": false,
"basket_voucher_distribution": [
{
"voucher_key": "ac189592441c9c4e4d0a0f5be03216f6a7e026f0d482c44a293da8e373163fd0",
"voucher_type": "basket",
"voucher_distribution_amount": 25.00
}
],
"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
}
]
},
{
"item_barcode": "2913458439012",
"product_name": "Leather gloves",
"retailer_item_code": "line_2",
"item_quantity": 1,
"item_is_promotional": false,
"item_price": 750.00,
"item_original_price": 750.00,
"item_subtotal": 750.00,
"is_identified": true,
"excluded_from_spaaza": false,
"basket_voucher_distribution": [
{
"voucher_key": "ac189592441c9c4e4d0a0f5be03216f6a7e026f0d482c44a293da8e373163fd0",
"voucher_type": "basket",
"voucher_distribution_amount": 25.00
}
]
},
{
"item_barcode": "2913458434455",
"product_name": "Khaki pants",
"retailer_item_code": "line_3",
"item_quantity": 1,
"item_is_promotional": true,
"item_price": 979.00,
"item_original_price": 979.00,
"item_subtotal": 979.00,
"is_identified": true,
"excluded_from_spaaza": false
}
],
"basket_vouchers_applied": [
{
"voucher_key": "bb1e45cbd6d174164b77a58047779e8d0323fa9c61ac994d84223343c531334e",
"voucher_id": 112656,
"voucher_status": "redeemed",
"voucher_locked": true,
"campaign_id": 402,
"campaign_type": "loyalty",
"campaign_title": "ACME Rewards",
"voucher_expiry_datetime_utc": "2050-01-01 00:00:00",
"voucher_expiry_seconds_remaining": 1082631271,
"voucher_currency_id": 2,
"voucher_currency_symbol": "€",
"voucher_amount_original": 50.00,
"voucher_amount_redeemed": 50.00,
"voucher_amount": 50.00,
"voucher_text": "Thanks for shopping with ACME",
"voucher_basket_owner_code_exclusive": "",
"voucher_locking_code": "locking4001",
"voucher_type": "basket",
"voucher_honour_code": null
}
],
"honour_vouchers_applied": [
{
"voucher_key": "ac189592441c9c4e4d0a0f5be03216f6a7e026f0d482c44a293da8e373163fd0",
"voucher_id": 11268,
"voucher_status": "redeemed",
"voucher_locked": true,
"campaign_id": 76,
"campaign_type": "cashback",
"campaign_title": "ACME Rewards",
"voucher_expiry_datetime_utc": "2050-01-01 00:00:00",
"voucher_expiry_seconds_remaining": 1082631271,
"voucher_currency_id": 2,
"voucher_currency_symbol": "€",
"voucher_amount_original": 50.00,
"voucher_amount_redeemed": 50.00,
"voucher_amount": 50.00,
"voucher_text": "Thanks for shopping with ACME",
"voucher_basket_owner_code_exclusive": "",
"voucher_locking_code": "locking4001",
"voucher_type": "honour",
"voucher_honour_code": "HON0042"
}
],
"return_transactions": [],
"purchase_progress": [
{
"purchase_progress_campaign_id": 76,
"purchase_progress_campaign_title": "Store Rewards",
"purchase_progress_campaign_type": "cashback",
"purchase_progress_amount": 37.50,
"purchase_progress_balance": 87.50,
"purchase_progress_balance_previous": 50
}
],
"supplementary_basket_codes": [
"2023334434434343434",
"arf5546hu00223333333"
]
},
"user": {
"member_programme": "spaaza",
"member_number": "555555",
"user_id": 268003,
"send_email_receipt": true
}
}
The following is the response from a basket upload for an anonymous user. Notice that the “user” parameter is now set to null:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"user": null,
"basket": {
"id": 5,
"chain": {
"id": 1411
},
"basket_timestamp_iso8601": "2017-07-27T07:48:45+02:00",
"basket_timezone_name": "Europe/Amsterdam",
"basket_country_code": "NL",
"app_platform_type": "in_store",
"currency": {
"currency_id": 2,
"currency_code": "EUR",
"currency_name_en": "Euro",
"currency_symbol": "€"
},
"total_value": 234.33,
"owner_code": "70401",
"items": [
{
"id": 3,
"item_barcode": "2913458432854",
"product_sale_price": 234.33,
"item_quantity": 1,
"retailer_item_code": "abcdef",
"item_subtotal": 234.33
}
]
}
},
"result_type": "add-basket"
}
Fields in the POSTed JSON
Identifying the Retailer
Details of the retailer which is submitting the basket.
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 | (string, max 64 chars) 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.
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)
The section of the POSTed JSON providing information about the contents of the basket to be purchased by the shopper.
Field | Description |
---|---|
basket_platform_type | (string, optional) 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, can be numeric, max 255 chars, mandatory) 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. 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, can be numeric, max 255 chars, optional) A locking code which, when supplied, allows any locked basket vouchers supplied in the call to be redeemed if they have a matching voucher_locking_code - if the vouchers are locked and do not have a matching voucher_locking_code they will not be redeemed. This parameter takes precedence over retailer_basket_code when used for voucher locking, meaning that i) if there is a match between the voucher_locking_code of a basket and that of a voucher, the voucher will be redeemed regardless of any “retailer_basket_code_exclusive” value it has; and ii) if the voucher and basket have voucher_locking_code values which do not match, the voucher will not be redeemed, regardless of whether there is a match with the voucher’s retailer_basket_code_exclusive value. |
supplementary_basket_codes | (array, string elements which can be numeric, optional) 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, max 2 decimals, recommended) 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. |
shipping_charge | (float, max 2 decimals, 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, max 1024 chars, 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 | (ISO-8601 extended, optional) The timestamp of the basket in ISO8601 extended format including timezone offset from UTC. Note that the timestamps of all baskets are converted to UTC (if not already in UTC) before storage in the Spaaza datastore. |
basket_timezone_name | (TZ database value, optional) 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 | (integer, optional) 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 | (ISO-4217 3 letter country code, optional) 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 response describing the single or multiple methods used to pay for the basket.
Note that Spaaza records the payment methods used to pay for a basket, but no logic is applied to them and they are independent of other amounts in the basket.
Field | Description |
---|---|
payment_method | (string, max 64 chars, optional) The payment method used, such as “mastercard” or “cash”. |
payment_amount | (float, max 2 decimals, optional) 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 to a basket. This section shows the total amount present for each tax rate.
Note that Spaaza records the tax rates applied to a basket, but no logic is applied to them and they are independent of other amounts in the basket.
Field | Description |
---|---|
tax_rate | (float, max 4 decimals, optional) 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 | (float, max 2 decimals, optional) 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.
Note: Please note it is possible to add extra fields to item information in the add-basket
endpoint in order to create a record of product information in Spaaza. This is useful for information displayed on receipts, for analytics purposes, and for campaign targeting. The required fields are not documented here, but in a separate document: Creating products and product variants using the add-basket endpoint.
One of the following identifiers must be used to identify the item:
Field | Description |
---|---|
item_barcode | (string, numeric allowed, max 255 chars, 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, max 64 chars, 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. See the documentation about creating products using the add-basket endpoint. |
Additionally, the following fields are used to supply the other information about the item in the basket:
Field | Description |
---|---|
retailer_item_code | (string, max 255 chars, 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, max 16 chars, 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 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.
Basket Discounts and Vouchers (basket_vouchers)
Discounts, standalone vouchers or loyalty reward redemptions are calculated and can be applied to a basket by passing details of the voucher(s) to be redeemed. Examples of this include: a shopper redeeming their loyalty rewards on a purchase, a promotional mechanic such as “buy 3 items from a range of qualifying products and only pay the price of 2 of them”, or a customer being given a one-time €10 discount voucher.
The concept of a “basket voucher” is used to record the discount or voucher redemption. More information on how vouchers work in Spaaza in general can be found on the Vouchers page of this site. Applying a basket voucher to a basket is called “redeeming” the voucher.
Whether a voucher is applied to all items in a basket, or only certain items, is controlled at the campaign level. When a voucher is redeemed in a basket, its value is spread over the items to which is it applied. This is known as “voucher distribution” - i.e. distributing the value of the voucher over the items in the basket. See the “Voucher Distribution” section below for more information.
A basket voucher can be redeemed by specifying the unique voucher_key
or voucher_id
of the voucher in the basket_vouchers
section of the JSON POSTed to the endpoint. In order to be redeemed a basket voucher should have a status of “claimed”, indicating it is ready to be redeemed by the customer.
The following fields are used to signal a basket voucher for redemption in a basket:
Field | Description |
---|---|
basket_vouchers | The section of the add-basket JSON which lists basket vouchers to be redeemed. |
voucher_key | (string, max 128 chars) A unique voucher key for each basket voucher to be redeemed. |
voucher_id | (integer) A unique voucher ID for each basket voucher to be redeemed. This can be used instead of voucher_key or third_party_id . |
third_party_id | (integer, max 10 digits) The unique id generated for a voucher when the chain has uses_third_party_voucher_id set true . This can be used instead of voucher_key or voucher_id . |
For each voucher_key or voucher_id value supplied, the Spaaza API carries out various checks, such as whether the voucher applies to this customer and that the status of the voucher is set to “claimed”. If the checks pass, the voucher status is set to “redeemed” so it cannot be used again and various other reconciliation actions may take place in the background according to the rules associated with the voucher. Note that, at this stage discounts may already have been applied in the partner system so the onus is on the partner logic to ensure beforehand (partly using other available Spaaza API endpoints) that the voucher is valid for this customer.
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.
The following points are important to note:
- If the value of a voucher is distributed over an item, the value of that distribution is shown in the response in the
basket_voucher_distribution
section for each item which the voucher value is distribued over. - It is not possible to distribute more of the value of a voucher on an item than the value of the item itself. In the case of “standalone” monetary vouchers, if the value of the voucher is greater than the value of the items over which it is distributed, what happens to the non-redeemed portion of the voucher is determined by the campaign settings. The default behaviour is to create an additional voucher which can be used by the customer on a subsequent transaction.
- In order to correctly calculate the distribution of the value of basket vouchers across individual items in a basket, the
item_original_price
field must be populated for each item in the basket. This is the original gross price being charged for 1 quantity unit of an item. - If the
item_original_price
field is not populated or is set to 0, the voucher distribution will be calculated based on theitem_price
field. Note that if theitem_price
field is set to 0 and theitem_original_price
field is not populated, the value of the voucher will not be distributed across the items in the basket because they are seen to have zero value. - 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 theitem_original_price
field is not populated, and an estimated distribution of vouchers is recorded.
It is possible to override the Spaaza-calculated voucher distribution (see “Overriding Spaaza-Calculated Basket Voucher Distribution” below), but this is not recommended.
Overriding Spaaza-Calculated Basket Voucher Distribution (basket_voucher_distribution)
For each basket-level discount (“basket voucher”) redeemed in a basket, each item in the basket is assigned a proportion of the value of the voucher. 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.
Normally the distribution of the value of basket vouchers across individual items in a basket is calculated automatically by this API endpoint and returned in the response, but it is possible to override this by supplying a distribution amount for a particular voucher inline in the JSON for a particular item. Note that this overrides all voucher distribution amounts for the same basket voucher for other items in the same basket, so it is necessary to supply a voucher distribution amount for each item in the basket for which an amount is intended - zero basket voucher distribution will be applied to items omitted.
Note also that manually overriding the automatically-generated distribution of a basket voucher for items in a basket overrides any background settings such as not allowing basket vouchers to be distributed over promotional items or forcing the redemption of the full value of a voucher in all cases. For example, if a basket voucher is created for a value of 10 currency units and only 8 of them are distributed, 2 unused currency units will be returned to the shopper regardless of other settings.
Distribution in the basket item:
Field | Description |
---|---|
basket_voucher_distribution | A list of basket-level vouchers which are applied at the item level. In the case that this is not supplied, the distribution method used in the previous step (get-basket-price ) will be applied. |
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_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)
Vouchers which are generated by or stored in Spaaza and used to redeem (“honour”) third-party promotions or other mechanics outside of Spaaza are termed “honour vouchers” in the Spaaza basket. When an honour voucher is redeemed, it can be included in the basket contents and Spaaza will update its status to redeemed. An honour voucher can be redeemed by specifying the unique “voucher_key” of the voucher in the “honour_vouchers” section of the JSON. In order to be redeemed a basket voucher should have a status of “claimed”, indicating it is ready to be redeemed by the customer.
The following fields are used to signal an honour voucher for redemption in a basket:
Field | Description |
---|---|
honour_vouchers | The section of the add-basket JSON which lists honour vouchers to be redeemed. |
voucher_key | A unique voucher key for each honour voucher to be redeemed. |
voucher_id | A Spaaza-unique voucher ID for each honour voucher to be redeemed. This can be used instead of voucher_key . |
For each voucher_key or voucher_id value supplied, the Spaaza API carries out various checks, such as whether the voucher applies to this customer and that the status of the voucher is set to “claimed”. If the checks pass, the voucher status is set to “redeemed” so it cannot be used again and various other reconciliation actions may take place in the background according to the rules associated with the voucher. Note that, at this stage discounts may already have been applied in the partner system so the onus is on the partner logic to ensure beforehand (partly using other available Spaaza API endpoints) that the voucher is valid for this customer.
Interpreting the Response
Except for the xxxx_adjusted
fields and the population of IDs of objects returned, the response to add-basket
is broadly the same as the response to get-basket-price
. Please consult that section of the documentation for more information.
Possible error responses
The following represents a list of possible error responses for the add-basket
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 |
183 | voucher_not_found No voucher has been found matching this voucher_key or voucher_id. | 404 |
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 |