Welcome
Spaaza’s API allows developers to create their own applications on top of the Spaaza platform. All Spaaza’s in-house apps and other services make use of the API endpoints described in this documentation.
Please get in touch with us using the chat button at spaaza.com if you have any more questions.
Concepts
This section of the documentation explains some of the core concepts used by Spaaza, and vocabulary used to describe them. We highly recommend reading this to provide some background which will help understand what our API endpoints aim to do, and how they work.
User
Associated Terms |
---|
Customer, Member, Shopper, Administrator |
Parameter Names Used |
---|
user_id , username , member_number , authentication_point_identifier , auxiliary_identifier |
In the Spaaza data model, a ‘user’ is an object representing an individual person with an account.
User Types
Spaaza has two types of users: end-users and administrative users. These are described below.
End-User
An end-user is an end-customer consuming a Spaaza service - that’s to say a real-life person with an account. Examples might be:
- An identified shopper ordering an item in a webshop
- A customer in a retailer’s physical store
- Someone using a Spaaza white-label retailer or customer organisation app at home
- A member of a digitally-provided service such as a car-sharing network who’s making use of incentives available when they drive a car
End-users are always associated with a particular Spaaza retailer or customer organisation, and are often a member of a loyalty or incentive marketing programme run by Spaaza, and hence have a ‘member number’ (sometimes referred to as a ‘customer number’). It is also possible for end-users to have other identifiers, such as an ‘auxiliary identifier’ or an ‘authentication point identifier’.
Many Spaaza API endpoints are available for adding end-users, viewing and updating their properties, carrying out actions on their behalf, and deleting their accounts.
End-users are often referred to as “customers” or “members.”
Administrative (Admin) User
An administrative (“admin”) user is an employee or other administrative account associated with a Spaaza retailer or customer organisation. Admin users have rights to view data and carry out actions on behalf of a retailer, or on behalf of an end-user associated with the retailer. Every admin user has permissions allowing them to carry out specific actions in administrative apps Spaaza provides, such as our “Console” site, and in the Spaaza API.
Examples of admin users are:
- A store employee logging into a Spaaza-provided “Store” site to create an end-user account for a customer
- A head office employee logging into the “Console” admin portal to configure campaigns and check analytics for a Spaaza promotional campaign
- A POS device in a store uploading transaction information
Admin users are treated separately from end-users. They do not take part in any campaign- or transaction-related incentive activities such as earning points, redeeming vouchers, or uploading transactions.
A Spaaza retailer normally has one or more admin users with “super user” permissions, who have the power to add, update and delete other admin user accounts.
Basket
Associated Terms |
---|
Transaction, Receipt, Cart, Order, Return |
Parameter Names Used |
---|
basket_id , retailer_basket_code , receipt_id , supplementary_basket_code |
In the Spaaza data model, a ‘basket’ represents an end-user or customer transaction stored in the backend.
Each basket is associated with a Spaaza retailer or customer organisation and is sent to Spaaza either via
Spaaza’s add-basket
API endpoint or imported in bulk by Spaaza using one of our operations
import scripts.
It is also possible to send the contents of a provisional basket to Spaaza via our
get-basket-price
API endpoint and Spaaza will respond with any adjustments
to that basket. See the ‘Provisional or adjusted Basket’ section below.
When purchased items are returned, this is not seen by Spaaza as an adjustment to a confirmed basket (see below for the distinction between confirmed and provisional baskets), but as a new basket with returned items which are linked to an original purchase basket. For more information, please see our documentation on ‘Processing a return inline’.
Please see the documentation below for more information about types of basket in the Spaaza model, and some of the important properties and concepts associated with baskets.
Types of basket
Spaaza has two types of basket. These are explained below.
Confirmed basket
When a basket is sent to Spaaza using our add-basket
API endpoint, it is stored in the
Spaaza database. Unlike in some e-commerce systems, a confirmed basket stored in Spaaza is immutable and cannot be updated
once it has been transmitted - this includes payment and tax details.
Spaaza retailers and customer organisations also make use of the facility to import large numbers of transactions in bulk. This is performed on a custom basis by Spaaza using our internally-available bulk import scripts and is usually carried out to import large numbers of historical baskets.
Provisional or adjusted basket
Spaaza’s data model has the concept of an adjusted or provisional basket. This is not a basket which is stored in the Spaaza backend, but is designed to return adjustments to a basket which apply to an individual end-user, and which can be applied to the confirmed basket or transaction when it is sent by the API client. It’s possible to request an adjusted basket multiple times and receive a different response each time.
Spaaza’s provisional basket API endpoint, (get-basket-price
)[#requesting-an-adjusted-basket], is used to request adjustments to the
supplied basket, which may include vouchers the end-user (customer) is entitled to use, and discounts at the item or basket level.
A good example of how a provisional basket works is as follows:
- Customer logs into e-commerce site and is opted into the site’s loyalty programme
- Customer adds items to cart in e-commerce site
- E-ecommerce site makes a request to Spaaza’s (
get-basket-price
endpoint)[#requesting-an-adjusted-basket], including information about the customer, items in the basket, prices and total order value - Spaaza responds with an adjusted basket, including vouchers the customer has indicated they would like to spend and an adjusted total order amount
- E-commerce site adjusts total amount the customer pays based on the response received from Spaaza
- Customer pays for the order in the e-commerce site
- E-ecommerce site sends confirmed basket with adjusted values
Campaign
Associated Terms |
---|
Promotion, Loyalty |
Parameter Names Used |
---|
campaign_id , campaign_type |
In the Spaaza data model, a ‘campaign’ does not only describe a traditional “promotional campaign” or “advertising campaign,” but has a much broader definition. A Spaaza ‘campaign’ represents a set of logic and actions which can be applied to end-users across the whole of the domain associated with a retailer or customer organisation. Spaaza has a set of API endpoints which can be used to add, view, manage or delete campaigns and their properties in order to affect the end-user experience. Additionally, a broad suite of analytics tools is provided to track performance of campaigns and the customers who make use of them.
For example, each of the following examples is managed as a campaign in Spaaza:
- Points wallet - using a ‘wallet campaign’ is it possible to give each customer a points wallet and add points to or remove them from the wallet when events occur such as signing up for membership, or making a purchase. Fine-grained actions are possible using customer segments, such as “double points between 2 PM and 6 PM on a Tuesday in Anytown branch store for customers who previously bought ACME-branded products.”
- Referral rewards - it is possible to configure a ‘referral campaign’ which rewards both a customer and their friend with a voucher when the customer signs their friend up and the friend makes a purchase.
- Order-level discount - a ‘basket campaign’ can be used to give opted-in customers a percentage- or monetary-based discount on one or multiple baskets
- Loyalty programme - a loyalty campaign and associated loyalty rules can be used to configure an entire loyalty programme with loyalty levels and rewards based on status and actions within the programme
Managing campaigns and monitoring performance
In almost all cases, campaigns are managed using the Spaaza Console portal. Performance is also tracked via the Spaaza console using our realtime analytics and graphing tools.
Campaign types
It is possible to configure and manage multiple types of campaign through the Spaaza API. A brief explanation of each campaign type is provided below:
- Basket (Discount) - a basket (discount) campaign is used to apply a percentage discount to qualifying baskets, based on combinations of items in the basket, total basket value, end-user (customer) segment or other parameters.
- Birthday - a birthday campaign allows the issuing of rewards such as points or vouchers to registered customers on or around their birthday.
- Content - content and mobile content campaigns are used to manage content appearing in media properties associated with a retailer or customer organisation, such as white-label mobile apps.
- Interaction - interaction campaigns are used to carry out defined actions when an end-user (customer) interacts with a retailer. Usually in this
case the Spaaza backend is notified of an interaction via the
interact-campaign
API endpoint and then, for example, a reward such as a voucher, discount, free product or points amount is granted to the end-user. - Login - a login campaign is used to reward the customer, or carry out another action, when a registered end-user (customer) first logs in
to a retailer property via the Spaaza
login
endpoint. The campaign can be filtered so this only applies when the login request is sent by specific types of client. - Loyalty - a loyalty campaign is used to manage all aspects of a loyalty campaign, such as status levels, associated discounts, points awards and status review cycles. Concepts associated with loyalty campaigns can include loyalty rules and loyalty status levels configurable via the Spaaza Console portal.
- Points Wallet - a points wallet is a ledger-based campaign which assigns a points wallet to individual end-users (customers) and can have amounts added to or removed from it, such as when a customer makes a purchase or interacts with an ‘Interaction’ campaign. Amounts in the points wallet can be converted into rewards and achieving a certain balance can be used as a trigger for ‘Loyalty’ campaign actions, such as changes in status level. Contributor campaigns, such as ‘Spend and Earn,’ can be configured to add amounts to the wallet when certain actions occur.
- Product (Discount) - product (discount) campaigns are used to provide personalised, item-level discounts on individual purchase items in a basket.
- Profile Completion - a profile completion campaign is used to reward an end-user (customer) on completion of their profile. It is possible to configure which profile parameters are required before a reward is issued.
- Purchase Count (Purchase Number) - a purchase count campaign is used to reward an end-user (customer) on their _N_th purchase. It is possible to filter basket value to a minimum limit and rewards are configurable.
- Referral - a referral campaign rewards an end-user (customer) for inviting their friends and contacts to register. It is possible to reward both invitee and inviter with differing rewards and also restrict the moment of reward to the moment the invitee makes their first purchase.
- Signup - a signup campaign rewards an end-user (customer) when they first create an account and opt-in to the associated incentive or loyalty programme.
- Spend & Earn - a spend and earn campaign is a type of “contributor” campaign which contributes points or wallet balance to an end-user’s (customer’s) (points) wallet at a defined percentage of basket value, or for a certain amount, when a purchase is made.
- Spend Target (Progress) - a spend target, or progress, campaign is used to reward an end-user (customer) when they reach a certain level of spending. Filters can be configured on spending, such as whether the target only applies to in-store or online purchases, and rewards are also configurable.
- Wallet - a (monetary) wallet is a ledger-based campaign which assigns a wallet to individual end-users (customers) and can have amounts added to or removed from it, such as when a customer makes a purchase or interacts with an ‘Interaction’ campaign. Amounts in the wallet can be redeemed as a discount on baskets by converting a specified amount of the balance into a wallet voucher. “Contributor” campaigns, such as ‘Spend and Earn,’ can be configured to add amounts to the wallet when certain actions occur.
Voucher
Associated Terms |
---|
Coupon, Discount, Personal Price |
Parameter Names Used |
---|
voucher_key , voucher_id , voucher_locking_code |
In the Spaaza data model, a ‘voucher’ does not only describe a “coupon” concept of a reserved right to a monetary discount on a retailer or customer organisation’s products and services, or a free product. Spaaza’s definition of a voucher broadly means a “title” or “right” which an end-user (customer) can exchange with a retailer or customer organisation against a defined item, reward or other object. In Spaaza, a voucher can be a title to a monetary or percentage discount, a free item, an experience or even an action taken by a third party.
A Spaaza voucher is always tied to a campaign configured in the Spaaza backend. What a voucher entitles an end-user (customer) to depends on the configuration details of the campaign and the type and configuration of the voucher itself.
Some examples of what vouchers are used to represent in the Spaaza data model:
- A fixed percentage discount on a purchase in a participating store or e-commerce site
- A free product when ordering a particular other item on an e-commerce site
- A monetary wallet amount converted into a discount on a purchase
- 10 minutes of free driving when you join a car-sharing service
- A personalised percentage discount on an individual item
- Free branded items in third-party stores
- Invitations to events
- The planting a specified number of trees by a charity when a customer has purchased certain items or services
Issuing vouchers and monitoring voucher redemption
Vouchers can be issued automatically when certain events occur, such as when an end-user (customer) registers for an account or makes a purchase above a certain value, in bulk using Spaaza tasks, or individually using Spaaza’s voucher creation endpoint.
In almost all cases, how vouchers are issued is managed using the campaigns configuration section in the Spaaza Console portal. Redemption analytics can be tracked via the Spaaza console using our realtime analytics and graphing tools.
Voucher types
It is possible to configure and manage multiple types of voucher through the Spaaza API. A brief explanation of each voucher type is provided below:
- Basket - a basket voucher provides a monetary discount at order level on a basket.
- Honour - an honour voucher provides a title to “honour” a third-party promotion and is usually configured with a specific “honour code” which is used to identify the promotion in the third-party system. This is often used to issue free items or provide discounts in third-party locations. Honour vouchers can be used anonymously or tied to individual end-users (customers).
- Percentage Basket - a percentage basket voucher provides a percentage discount at order level on a basket.
- Variable Price (Product) - a variable price or product voucher denotes the right to a personalised percentage or monetary discount on a product at item level in a basket.
- Variable Price Meta (Product Meta) - a variable price metavoucher denotes the right to variable prices on one of a range of products in a basket. During the basket process, a variable price metavoucher is converted into a variable price voucher which is redeemed in a confirmed basket.
Important properties of a voucher
The following is a list of some of the key properties of a voucher:
- Campaign - every voucher is tied to a campaign. A voucher’s campaign dictates its behaviour including when it can be awarded, how it can be redeemed, what happens if it is deleted or redeemed, whether a replacement is generated after a return, and many other aspects of its existence.
- Currency - a currency associated with a voucher. This field is not always populated. For example, in the case of an honour voucher, a currency may not be necessary.
- Description - a longer-form text field which can be displayed in a user interface.
- Discount Ratio - a percentage discount which applies to a “percentage basket” voucher, represented as a decimal.
- Expiry Date - a date and time beyond which it is no longer possible to change details of, or redeem, a voucher
- Image URL - the URL of an image which can be displayed in a user interface in association with a voucher.
- Key - every voucher has a unique key which can be used to identify it when retrieving details about it or carrying out actions on it such as claiming or redeeming it (see “Voucher status” section).
- Locking - to prevent fraud, a voucher can and should be locked during a transaction - see “Voucher locking” section below.
- Parent Voucher - in the case that a voucher has been redeemed in a transaction, and items purchased in that transaction are subsequently returned, a new voucher is created which represents the value of the voucher originally redeemed on the item(s) in the purchase transaction. The original voucher is listed as the “parent” of the new voucher.
- Status - see “Voucher status” section below.
- Title - a title or text string which can be displayed in a user interface.
- Value - a monetary value assigned to a voucher. This field is not always populated, for example in the case of an honour voucher, which may be redeemed in exchange for a free item.
Voucher status
Each voucher in Spaaza has a status. A voucher’s status dictates which properties a voucher can exhibit and which actions can be carried out on a voucher. The statuses are as follows:
- generated - a voucher exists in the Spaaza data store and may have been assigned to an end-user (customer), but cannot yet be redeemed or exchanged.
- claimed - an end-user (customer) who “owns” the voucher or an admin user or system has flagged the voucher as being ready to be redeemed in a transaction or other event. In order to be redeemed, a voucher must have this status.
- redeemed - a voucher has been redeemed (used) in a transaction or other event. The voucher can no longer be used or be altered in any way.
The following points regarding voucher status are also to be noted:
- A voucher is normally created with a status of ‘generated,’ but it is possible to configure a campaign to “auto-claim” vouchers when they are created, meaning they will be created with status ‘claimed’.
- It is possible to claim or unclaim a voucher using the claim-voucher and unclaim-voucher endpoints. It is not possible for an end-user (customer) to unclaim a voucher which is “locked” (see “Voucher locking” section).
Voucher locking
To prevent fraud a voucher should be locked before it is redeemed. This prevents an end-user (customer) making adjustments to a voucher when, for example, the value of the voucher is being used as a discount on a transaction. During the time a voucher is locked, it can only be adjusted by an administrative user or using privileged authentication.
A voucher has the following properties related to locking:
- Locked status - if a voucher is locked it will show
"locked": true
in API responses - Locking period - a voucher is locked for a period of time. This is shown by the
voucher_locked_until
field in API responses for a locked voucher, a field representing a date and time until which the voucher is locked - Exclusive retailer basket code - if a voucher is locked and can only be redeemed by a transaction with a
specific
retailer_basket_code
, this is shown in thevoucher_retailer_basket_code_exclusive
field. - Locking code - it is also possible to lock a voucher using a specific code which must also be supplied to redeem the voucher - this is shown
in the
voucher_locking_code
field.
There are 3 ways a voucher can be locked:
- Automatically - during a transaction, when a call is made to the get-basket-price API endpoint, claimed vouchers are
automatically locked for the default locking period (usually 5 minutes). If the
basket_voucher_lock_exclusively
parameter is also supplied, vouchers are locked so that they can only be redeemed by a call to the add-basket API endpoint with the sameretailer_basket_code
value. It is also possible to specify a differentvoucher_locking_code
using this method, shouldretailer_basket_code
not be a predictable value. - On Creation - when using the create-voucher API endpoint it is possible to specify a
voucher_lock_period
to lock the voucher. - Voucher Locking API Endpoint - the lock-voucher API endpoint can be used to explicitly lock a voucher.
When used with admin or privileged authentication, the unlock-voucher API endpoint can be used to unlock a voucher should that be necessary.
Voucher redemption
There is currently only one possible way to redeem a voucher:
- Transaction - when a claimed, unexpired voucher is added to the payload of a call to the add-basket API endpoint, the voucher is redeemed. Should it not be possible to redeem the voucher, the API call will not error, but will return a warning inline in the response.
Associated API endpoints:
Endpoint | Comments |
---|---|
get-card | Getting the “card” of an end-user (customer) |
create-voucher | Creating a voucher |
claim-voucher | Setting a voucher to “claimed” status |
lock-voucher | Locking a voucher |
expire-voucher | Expiring a voucher explicitly |
delete-voucher | Deleting a voucher |
get-vouchers | Getting all vouchers for an organisation, filterable to single voucher level |
get-user-vouchers | Getting all vouchers for an end-user (customer) |
get-basket-price | Requesting adjustments for a basket/transaction |
add-basket | Confirming a basket/transaction |
Versioning
Introduction
Occasionally Spaaza makes changes to the payload sent to or response received from an API endpoint. In order to maintain backwards compatibility with existing API clients a versioning policy is put in place. The aim of this policy is to make using endpoint features as simple as possible.
Usually a Spaaza API endpoint maintains backward compatibility without requiring special flags, but in the case that a specific version is required, the API documentation for that endpoint will show clearly what is needed. If there is no information about versioning in the documentation for a specific endpoint, then there is no need to do anything. Spaaza recommends sending an appropriate version header with all API requests.
Occasionally version-specific changes become available in the Spaaza API which affect multiple, or all, endpoints.
This kind of change is described in the section API-wide version information
below. Again, this kind of change
is designed to be non-breaking and as backwards-compatible as possible.
Using a specific endpoint version
With certain Spaaza API endpoints specific versions are implemented. In order to the latest version of an API endpoint, a version header is sent along with the request to the API endpoint. The documentation for a specific endpoint will always contain information about which version number should be used.
The following header is used for specifying a version:
- X-Spaaza-API-version:
Spaaza uses standard semantic numeric major.minor.fix version numbering, for example:
- X-Spaaza-API-version: 1.2.2
API-wide version information
This section includes information about version-specific changes which affect multiple, or all, endpoints in the Spaaza API. In the case that these changes affect all endpoints, for example a change in the way error responses are handled between different versions, a description of the change is not usually included in the documentation for any specific individual endpoints.
A description of each of this kind of version-specific change is shown below.
1.4.1 - Remove URL format requirements
- Remove requirement for .json or .php suffixes at the end of API endpoint URLs
- Remove requirement for
v1/
in API endpoint URLs
1.4.0 - Updates to formatting of JSON error responses
- Error responses for all API endpoints updated to reflect semantic correction of
errors
->error
where only a single error is returned.
API clients using a version number less than 1.4.0 will receive the previous error formatting in the JSON returned in the error response. Documentation for older clients is available on request.
1.1.8 - Updates to formatting of JSON in get-basket-price
and add-basket
endpoints.
get-basket-price
endpoint request and response JSON updated to change parameter namesadd-basket
endpoint request and response JSON updated to change parameter nameslock-voucher
endpoint parameters and response JSON updated to change parameter names
API clients using the above endpoints should use a version number greater than or equal to 1.1.8
. Documentation
for older clients is available on request.
Responses
Response Format
Unless otherwise indicated in the documentation for individual endpoints the Spaaza API responds with JSON - Content-Type: application/json
.
Success
JSON showing a success response to a request:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {}
}
If the HTTP request is successful the API will respond with a HTTP response code 200 and a “result” object in JSON showing a status of “ok”. This will be followed by a “results” section showing the results of the request.
Warnings
JSON showing an example warning inline in a success response
{
"result": {
"code": 1,
"status": "ok"
},
"warnings": [
{
"code": 183,
"name": "voucher_not_found",
"description": "No voucher has been found matching this voucher_key or voucher_id.",
"message": {
"key": "0886407851fc56c6211f01abe1b4eab1fb1b48640efb73b1169c1d7a50e9467b"
}
}
],
"results": {
}
}
On some occasions a single or multiple warnings are returned as extra information supplementary to the main “results” in a 200 “ok” response, when the issue is not deemed to be of critical severity or when it is not desirable to interrupt the flow of the client. Warnings are returned in their own “warnings” array.
For example, when a transaction is being uploaded by a POS using the add-basket
endpoint, but a voucher supplied is not recognised, it is still desirable to record the transaction in the Spaaza database because it has been paid for by the customer. In that case, a warning is added to the 200 “ok” response showing details of the unrecognised voucher.
A list of possible warning codes is found in the “Error and Warning Codes” section below.
Errors
JSON showing a sample error response to a request:
{
"result": {
"code": 2,
"status": "error"
},
"error": {
"code": 5,
"name": "password_error_or_non_existent",
"description": "Gebruikersnaam / wachtwoord zijn onbekend"
}
}
If the response is an error, the API responds with an HTTP error response code and a “result” object showing a status of “error” - the call to the API endpoint is discontinued on generation of the error. This is followed by an “error” object in the response JSON showing the error response - there is only a single error returned.
In the case of an “error” response, no warnings are returned.
See the “error codes” section below for information on individual error codes.
In some cases more information may be supplied with the error to help identify the possible cause, such as a list of which characters are not allowed, or a hint on the format of a postal code.
Note that versions of the API previous to 1.4.0
returned a slightly different error structure. See the ‘Versioning’ section of the documentation. Documentation for older clients is available on request.
Error and Warning Codes
The following is a list of possible error/warning codes:
Code | Name and Description | HTTP Status Code |
---|---|---|
1 | username_invalidThe username is incorrectly formatted. Your username should be a valid email address. | 400 |
2 | password_invalidThe password is invalid. Your password should be 6 characters or more. | 400 |
3 | http_vars_missingThis script is missing some required variables which must be submitted. | 400 |
4 | http_request_method_not_allowedThis HTTP method is not allowed for this API call | 405 |
5 | password_error_or_non_existentUsername and password do not match any on record | 400 |
6 | no_valid_sessionThe user needs to be logged in and a valid session key needs to be sent | 401 |
7 | user_username_invalidThe user_username passed must be a valid email address | 400 |
8 | user_username_not_presentThe user_username variable must be passed | 400 |
14 | user_username_not_permittedThe user_username passed must be the same as for the valid session | 500 |
15 | business_id_invalidThe business_id passed must be an integer | 500 |
16 | business_id_not_presentThe business_id must be passed | 500 |
20 | product_id_invalidThe product_id passed must be an integer or comma-separated list of integers with no spaces | 500 |
21 | product_id_not_presentThe product_id must be passed as a parameter | 500 |
22 | no_http_methodA valid HTTP method, GET, POST, PUT or DELETE must be used | 500 |
23 | http_method_errorSomething is wrong with the HTTP method processing | 500 |
30 | product_name_too_longThe product_name name must be 255 characters or less | 500 |
31 | product_description_too_longThe product_description must be 1024 characters or less | 500 |
32 | no_parameters_passedValid parameters must be passed | 500 |
33 | user_not_permitted_this_businessThis user is not permitted to make changes to this business | 500 |
34 | product_manufacturer_too_longThe product_manufacturer must be 64 characters or less | 500 |
35 | product_brand_too_longThe product_brand must be 64 characters or less | 500 |
36 | product_ean_code_too_longThe product_ean_code must be a number 10 digits or less | 500 |
37 | product_ean_code_incorrect_formatThe product_ean_code must be a number between 1 and 10 digits | 500 |
38 | product_weight_g_incorrectThe product_weight_g must be a number between 1 and 16 digits | 500 |
39 | product_length_cm_incorrectThe product_length_cm must be a number between 1 and 16 digits | 500 |
40 | product_width_cm_incorrectThe product_width_cm must be a number between 1 and 16 digits | 500 |
41 | product_height_cm_incorrectThe product_height_cm must be a number between 1 and 16 digits | 500 |
42 | product_volume_cm3_incorrectThe product_volume_cm3 must be a number between 1 and 16 digits | 500 |
43 | product_colour_incorrectThe product_colour must be 64 characters or less | 500 |
44 | product_year_of_manufacture_incorrectThe product_year_of_manufacture must be a number between 1 and 4 digits | 500 |
45 | category_id_invalidThe category_id must be an integer or comma-separated list of integers with no spaces | 500 |
46 | inventory_published_status_incorrectThe inventory_published_status must be either 1 for published or 0 for unpublished | 500 |
47 | inventory_stock_status_incorrectThe inventory_stock_status must be either 2 for in stock 1 for low stock or 0 for out of stock | 500 |
48 | inventory_quantity_incorrectThe inventory_quantity must be a number between 1 and 10 digits | 500 |
49 | inventory_condition_incorrectThe inventory_condition must be either new or used | 500 |
50 | inventory_price_blankThe inventory_price must not be blank | 500 |
51 | inventory_price_not_decimalThe inventory_price must be a decimal up to 8 digits before and 2 after the decimal place | 500 |
52 | missing_necessary_parametersOne of more of the required parameters is missing | 500 |
53 | inventory_published_expiry_date_incorrectThe inventory_published_expiry_date must be a valid date in YYYY-MM-DD format | 500 |
54 | session_key_invalidThe session_key value is incorrectly formatted. The session key should be 64 alphanumeric characters. | 500 |
55 | duplicate_primary_imageOnly one POSTed image is allowed to be primary. | 500 |
56 | imagefile_name_formatThe name of the POSTed value for the image must be imagefile_X, where X is a digit between 0 and 9. | 500 |
57 | imagefile_primary_invalidThe primary image is invalid. | 500 |
58 | imagefile_not_presentNo image file is present. | 500 |
59 | imagefile_incorrect_nameImage parameter must be named imagefile. | 400 |
60 | imagefile_invalidThe image file is invalid. File problem or size, width or height outside allowed parameters. | 500 |
61 | imagefile_unable_to_writeUnable to validate and rewrite image file. | 500 |
63 | search_string_length_errorThe search string must be 256 characters or less. | 500 |
64 | search_string_not_presentA search_string parameter must be present. | 500 |
65 | image_seq_num_invalidThe image_seq_num passed must be an integer between 0 and 9 | 400 |
66 | image_seq_num_not_presentThe image_seq_num must be passed as a parameter | 400 |
67 | image_seq_num_already_presentAn image with this sequence number already exists. POST using another image_seq_num or use PUT method to change existing image. | 400 |
68 | permission_denied_or_non_existentThis user has insufficient permissions for this object or the object does not exist. | 500 |
69 | entity_no_current_imagesThere are no current images listed for this entity. | 500 |
70 | image_primary_invalidThe image_primary parameter must be set to 1. | 500 |
71 | image_primary_not_presentThe image_primary parameter must be set. | 500 |
72 | image_already_primaryThe image is already set to primary. | 500 |
73 | image_not_presentThe image sequence number referred to is not listed for this entity. | 500 |
74 | image_primary_delete_lastThe image with this sequence number is set to primary. Delete other images first. | 500 |
75 | chain_or_business_id_requiredThis API requires either a valid chain_id or business_id to be supplied. Cannot be both. | 500 |
76 | chain_id_invalidThe chain_id passed must be an integer | 500 |
77 | product_add_to_business_chain_memberThe business is part of a chain. Products can only be added at chain level. | 500 |
78 | inventory_condition_compulsoryAn inventory_condition parameter must be supplied and can be new or used. | 500 |
79 | inventory_published_status_compulsoryAn inventory_published_status parameter must be supplied and can be 0 or 1. | 500 |
80 | inventory_stock_status_compulsoryAn inventory_stock_status parameter must be supplied and can be 0, 1 or 2. | 500 |
81 | product_not_associated_with_businessNo record can be found of this product being available for this business or the chain it may be a member of. | 500 |
82 | chain_id_requiredThis API requires a valid chain_id to be supplied. | 500 |
83 | product_id_or_category_id_requiredThis API requires either a valid product_id or category_id to be supplied. Cannot be both. | 500 |
84 | miscellaneous_data_errorA data error of a highly miscellaneous nature has occurred. | 500 |
85 | inventory_id_invalidThe inventory_id passed must be an integer | 500 |
86 | inventory_id_not_presentThe inventory_id must be passed | 500 |
87 | incorrect_inventory_id_business_id_comboNo record has been found for that inventory_id at that business_id | 500 |
88 | missing_or_invalid_inventory_delete_bulkThe inventory_delete_bulk flag must be passed as a parameter and must be set to 1 | 500 |
89 | product_inventory_not_deletedThere are still live inventory items matching this product_id. Please delete them first. | 500 |
90 | product_id_not_foundNo record has been found for that product_id | 404 |
91 | inventory_currency_id_invalidThe inventory_currency_id passed must be an integer 4 digits or less | 500 |
92 | inventory_currency_id_not_presentThe inventory_currency_id must be passed as a parameter | 500 |
93 | inventory_size_too_longThe inventory_size must be 10 characters or less | 500 |
94 | inventory_colour_too_longThe inventory_colour must be 32 characters or less | 500 |
95 | search_colour_length_errorThe search_colour string must be 256 characters or less. | 500 |
96 | gender_value_errorThe gender value submitted must be one of m/M or f/F. | 500 |
97 | adult_child_value_errorThe adult_child value sbumitted must be one of a/A or c/C. | 500 |
98 | lat_long_both_requiredBoth decimal latitude and longitude must be supplied | 500 |
99 | lat_long_invalidBoth latitude and longitude must be decimal degrees. Lat max +/- 90, long max +/- 180. | 500 |
100 | search_brand_length_errorThe search_brand string must be 256 characters or less. | 500 |
101 | search_radius_km_invalidSearch radius must be one of an agreed set of values in kilometres. | 500 |
102 | nuclear_option_invalidThe nuclear_option parameter can only be set to 1. | 500 |
103 | inventory_auto_added_invalidThe inventory_auto_added value can only be set to 0 or 1. | 500 |
104 | fb_page_id_invalidThe fb_page_id value must be an integer and can be up to 10 digits long. | 500 |
105 | fb_page_id_not_presentThe fb_page_id parameter must be passed. | 500 |
106 | fb_page_id_already_in_useThe Facebook page_id supplied is already associated with another business or chain. | 500 |
107 | product_published_status_invalidThe product_published_status value can only be set to 0 or 1. | 500 |
108 | fb_page_name_invalidThe Facebook page_name supplied can be up to 256 characters. | 500 |
109 | fb_page_link_invalidThe Facebook page_link supplied can be up to 256 characters. | 500 |
110 | fb_page_link_not_presentThe fb_page_link parameter must be passed. | 500 |
111 | fb_page_info_json_invalidThe Facebook page_info_json supplied can be up to 1024 characters. | 500 |
112 | fb_page_info_json_not_presentThe fb_page_info_json parameter must be passed. | 500 |
113 | fb_app_business_chain_missing_parametersOne of the following parameters must be passed - fb_page_id, business_id or chain_id. | 500 |
114 | fb_app_business_chain_too_many_parametersOnly one of the following parameters can be passed - fb_page_id, business_id or chain_id. | 500 |
117 | search_owner_code_length_errorThe search_owner_code string must be 64 characters or less. | 500 |
118 | business_id_distance_search_incompatibleIt is not possible to search both by business_id and by lat, long, distance. | 500 |
119 | product_size_invalidThe product_size value must be a string 10 characters or less. | 500 |
120 | product_name_not_presentThe product_name value must be passed. | 500 |
121 | product_manufacturer_not_presentThe product_manufacturer value must be passed. | 500 |
122 | category_id_not_presentThe category_id value must be passed. | 500 |
123 | product_currency_id_invalidThe product_currency_id passed must be an integer 4 digits or less | 500 |
124 | business_name_invalidThe business_name passed must be 128 characters or less | 500 |
125 | business_description_invalidThe business_description must be 512 characters or less | 500 |
126 | business_address_1_invalidThe business_address_1 value must be 128 characters or less | 500 |
127 | business_address_2_invalidThe business_address_2 value must be 128 characters or less | 500 |
128 | business_address_3_invalidThe business_address_3 value must be 128 characters or less | 500 |
129 | business_towncity_invalidThe business_towncity value must be 56 characters or less | 500 |
130 | business_region_invalidThe business_region value must be 56 characters or less | 500 |
131 | business_postalcode_invalidThe business_postalcode value must be 20 characters or less | 500 |
132 | business_country_code_invalidThe business_country_code value must be 2 characters | 500 |
133 | business_latitude_invalidThe business_latitude must be a decimal degree value, max +/- 90. | 500 |
134 | business_longitude_invalidThe business_longitude must be a decimal degree value, max +/- 180. | 500 |
135 | business_email_address_invalidThe business_email_address value passed must be a valid email address | 500 |
136 | business_phone_number_invalidThe business_phone_number value passed must be a valid phone number - can contain digits and spaces plus these characters - ().+- | 500 |
137 | business_fax_number_invalidThe business_fax_number value passed must be a valid fax number - can contain digits and spaces plus these characters - ().+- | 500 |
138 | business_website_url_invalidThe business_website_url value passed must be a valid URL. | 500 |
139 | business_facebook_url_invalidThe business_facebook_url value passed must be a valid URL. | 500 |
140 | business_twitter_username_invalidThe business_twitter_username value passed must be a valid Twitter username - letters, numbers and underscores only, max 15 chars. | 500 |
141 | business_linkedin_url_invalidThe business_linkedin_url value passed must be a valid Linkedin URL. | 500 |
142 | business_currency_id_invalidThe business_currency_id passed must be an integer 4 digits or less | 500 |
143 | business_owner_code_invalidThe business_owner_code must be 32 characters or less | 500 |
144 | business_id_not_foundNo record has been found for that business_id | 500 |
145 | search_size_too_longThe search_size must be 10 characters or less | 500 |
146 | product_web_url_invalidThe product_web_url value passed must be a valid URL. | 500 |
147 | product_currency_id_does_not_existThe product_currency_id passed must exist in the list of currencies available | 500 |
148 | category_id_does_not_existThe category_id passed must exist in the list of categories available. See the category-tree public API. | 500 |
149 | fb_access_token_invalidThe fb_access_token passed must be alphanumeric and between 1 and 2048 characters long. | 500 |
150 | fb_access_token_expiry_invalidThe fb_access_token_expiry passed must be numeric and between 1 and 8 digits long. | 500 |
151 | fb_graph_api_access_failedFailed to contact the Facebook Graph API. | 500 |
152 | fb_oauth_exceptionOAuth problem accessing Facebook with your access token. | 400 |
153 | fb_graph_misc_exceptionFacebook reports a miscellaneous error accessing the Graph API. | 500 |
154 | user_id_invalidThe user_id passed must be an integer up to 10 digits long | 400 |
155 | user_id_not_presentThe user_id parameter must be passed | 400 |
156 | product_price_missing or blankThe product_price must not be missing or blank | 500 |
157 | product_price_not_decimalThe product_price must be a decimal up to 7 digits before and 2 after the decimal place | 500 |
158 | var_price_gender_invalidThe gender value submitted must be one of m/M or f/F | 500 |
159 | base_price_threshold_invalidThe base_price_threshold value must be a decimal between 0.01 and 0.99 | 500 |
160 | base_price_threshold_not_presentThe base_price_threshold value must be passed | 500 |
161 | weighting_gender_invalidThe weighting_gender passed must be an integer (whole number) between 0 and 10 | 500 |
162 | gender_parameter_not_presentWhen gender is passed, both gender and weighting_gender values must both be passed. | 500 |
163 | age_range_low_invalidThe age_range_low passed must be an integer (whole number) between 0 and 99 | 500 |
164 | age_range_high_invalidThe age_range_low passed must be an integer (whole number) between 0 and 99 | 500 |
165 | weighting_age_range_invalidThe weighting_age_range passed must be an integer (whole number) between 0 and 10 | 500 |
167 | weighting_mailing_list_parent_entity_invalidThe weighting_mailing_list_parent_entity passed must be an integer (whole number) between 0 and 10 | 500 |
168 | weighting_missing_parametersOne of the following parameters must be passed - weighting_gender, weighting_age_range or weighing_mailing_list_parent_entity. | 500 |
169 | age_range_parameter_not_presentWhen age_range is passed, all of age_range_low, age_range_high and weighting_age_range values must both be passed. | 500 |
170 | var_price_record_already_presentThere is already a variable price record for this product. Please delete it before adding another one. | 500 |
171 | age_range_high_low_mismatchThe age_range_high value must be higher than the age_range_low value. | 500 |
172 | weighting_fb_share_link_invalidThe weighting_fb_share_link passed must be an integer (whole number) between 0 and 10 | 500 |
173 | var_price_id_invalidThe var_price_id passed must be an integer or comma-separated list of integers with no spaces | 500 |
174 | var_price_id_not_presentThe var_price_id must be passed as a parameter | 500 |
175 | var_price_id_not_foundNo record has been found for that var_price_id | 500 |
176 | no_valid_session_auth_method_facebookThe user needs to be logged in via Facebook, a valid session key needs to be sent. Also the Facebook access token may have expired, try renewing. | 500 |
177 | age_range_low_too_highThe age_range_low passed must be lower than the existing age_range_high value in the Spaaza system | 500 |
178 | age_range_high_too_lowThe age_range_high passed must be higher than the existing age_range_low value in the Spaaza system | 500 |
179 | voucher_id_invalidThe voucher_id passed must be an integer | 500 |
180 | claim_id_not_presentThe claim_id must be passed as a parameter | 500 |
181 | voucher_key_invalidThe voucher_key value is incorrectly formatted. The claim key should be 64 alphanumeric characters. | 500 |
182 | voucher_key_not_presentThe voucher_key must be passed as a parameter | 500 |
183 | voucher_not_foundNo voucher has been found matching this voucher_key or voucher_id. | 404 |
184 | var_price_claim_date_expiredThe latest date to claim this variable price has already expired. | 500 |
185 | var_price_claim_status_claimedThis variable price has already been claimed. | 500 |
186 | var_price_claim_status_redeemedThis variable price has already been claimed and verified by the shop | 500 |
187 | var_price_claim_authentication_failureThis user is not entitled to claim this variable price | 500 |
188 | claim_code_not_presentThe claim_code must be passed as a parameter | 500 |
189 | claim_code_invalidThe claim_code must be an integer under 10 digits in length | 500 |
190 | claim_view_type_not_presentThe claim_view_type must be passed as a parameter | 500 |
191 | claim_view_type_invalidThe claim_view_type must be set to either retailer or user | 500 |
192 | claim_not_foundNo valid claim has been found matching this claim_code. | 500 |
193 | var_price_claim_status_unclaimedThis variable price has not yet been claimed and may have expired. | 500 |
194 | product_owner_code_invalidThe product_owner_code passed can be up to 32 characters in length | 500 |
195 | customer_email_address_invalidThe customer_email_address value passed must be a valid email address | 500 |
196 | customer_email_address_not_presentThe customer_email_address parameter must be passed | 500 |
197 | customer_firstname_invalidThe customer_firstname value passed must be a valid name | 500 |
198 | customer_firstname_not_presentThe customer_firstname parameter must be passed | 500 |
199 | customer_lastname_invalidThe customer_lastname value passed must be a valid name | 500 |
200 | customer_lastname_not_presentThe customer_lastname parameter must be passed | 500 |
201 | inventory_id_not_in_stockThe inventory_id supplied is for an item which is no longer in stock. | 500 |
202 | inventory_reservation_id_invalidThe inventory_reservation_id value passed must be an integer up to 10 digits in length | 500 |
203 | inventory_reservation_id_not_presentThe inventory_reservation_id parameter must be passed | 500 |
204 | inventory_reservation_status_invalidThe inventory_reservation_status value passed must be either 1, 2, or 3 | 500 |
205 | inventory_reservation_status_not_presentThe inventory_reservation_status parameter must be passed | 500 |
206 | inventory_reservation_id_not_foundThe inventory_reservaton_id supplied could not be found. | 500 |
207 | customer_phone_number_invalidThe customer_phone_number value passed must be a valid phone number - can contain digits and spaces plus these characters - ().+- | 500 |
209 | include_expired_invalidThe include_expired value passed must be either 0 or 1 | 500 |
210 | claim_status_invalidThe claim_status value passed must be either 0, 1 or 2. | 500 |
211 | weighting_fixed_invalidThe weighting_fixed passed must be an integer (whole number) between 0 and 10 | 500 |
212 | claim_id_not_foundNo record has been found for that claim_id for that user with status = claimed | 500 |
213 | age_range_custom_string_invalidThe age_range_custom_string value must be a string 32 characters or less | 500 |
214 | user_entity_card_not_foundNo user entity card has been found for that user at that entity | 400 |
215 | unmatched_user_idThe user_id parameter supplied does not match that of the session or other parameter supplied | 400 |
216 | voucher_status_invalidThe voucher_status value passed must be either 0, 1 or 2. | 500 |
217 | chain_id_not_foundNo record has been found for that chain_id | 400 |
218 | entity_short_code_invalidThe entity_short_code parameter must be maximum 16 alphanumeric characters | 500 |
219 | entity_short_code_not_presentThe entity_short_code parameter must be passed | 500 |
220 | entity_short_code_not_foundNo record has been found for that entity_short_code | 500 |
221 | weighting_birthday_invalidThe weighting_birthday parameter must be an integer (whole number) between 0 and 10 | 500 |
222 | birthday_range_days_invalidThe birthday_range_days parameter must be an integer (whole number) between 1 and 99 | 500 |
223 | birthday_range_period_invalidThe birthday_range_period parameter must be an integer, either 0, 1 or 2 | 500 |
224 | parameter_combination_invalidThe chain_id, business_id or user_entity_code parameter cannot be combined with the claim_code parameter | 500 |
225 | chain_or_business_id_combi_requiredThis API requires either a valid chain_id or business_id if user_entity_code is also supplied. Cannot be both. | 500 |
226 | user_entity_code_not_presentThe user_entity_code parameter must be passed if the claim_code parameter is not being used | 500 |
227 | user_entity_code_invalidThe user_entity_code parameter must be an integer between 1 and 13 digits in length | 500 |
228 | auth_method_invalidThe given auth_method parameter has an invalid value. | 500 |
229 | json_post_expectedThis API call expects a JSON POST payload (application/json). | 400 |
230 | entity_not_foundThe requested entity was not found. | 500 |
231 | currency_not_foundThe given currency passed must exist in the list of currencies available | 500 |
233 | product_not_part_of_entityYou can only add items to a basket which belong to the same entity. | 500 |
234 | user_already_existsThere is already an account using this email address. Please login or use a different email address. | 400 |
237 | date_value_errorThe submitted date must be in the format YYYY-mm-dd. | 500 |
238 | myprice_app_not_foundThe MyPrice app you requested was not found. | 500 |
239 | user_id_not_permittedThe user_id passed must be the same as for the valid session | 500 |
240 | linking_existing_identityThe identity you are trying to link to this account is already in the system. | 500 |
241 | fb_deauthorise_errorThe Facebook deauthorise request did not succeed. | 500 |
242 | product_without_var_priceThis product does not have a var price | 500 |
243 | inventory_id_not_foundThe inventory_id supplied could not be found. | 500 |
244 | campaign_id_invalidThe campaign_id passed must be an integer | 400 |
245 | campaign_id_not_presentThe campaign_id must be passed as a parameter | 400 |
246 | campaign_id_not_foundThe campaign_id supplied could not be found. | 500 |
247 | campaign_rule_id_invalidThe campaign_rule_id passed must be an integer | 500 |
248 | campaign_rule_id_not_presentThe campaign_rule_id must be passed as a parameter | 500 |
249 | campaign_rule_id_not_foundThe campaign_rule_id supplied could not be found. | 500 |
250 | inventory_owner_code_not_foundThe inventory_owner_code supplied could not be found. | 500 |
251 | user_location_invalidThe input for user location was invalid. | 500 |
252 | basket_currency_missingThe basket_currency information is missing from the basket. | 500 |
253 | inventory_barcode_missingThe inventory_barcode value is missing. | 500 |
254 | inventory_barcode_invalidThe inventory_barcode value supplied is invalid - must be an integer 25 digits or less. | 500 |
255 | inventory_barcode_id_invalidThe inventory_barcode_id value supplied is invalid - must be an integer 10 digits or less. | 500 |
256 | inventory_barcode_id_not_presentThe inventory_barcode_id value must be supplied. | 500 |
257 | inventory_barcode_id_not_foundThe inventory_barcode_id value was not found. | 500 |
258 | inventory_barcode_not_presentThe inventory_barcode value is missing. | 500 |
259 | inventory_barcode_already_presentThe inventory_barcode value is already present for the inventory_id submitted. | 500 |
260 | product_season_too_longThe product_season must be 64 characters or less | 500 |
261 | colour_tags_requiredThe colour_tags property must be set. | 500 |
262 | app_platform_type_not_allowedThe app_platform_type submitted is not permitted. | 400 |
263 | invalid_operator_typeThe operator_type property has an invalid value. | 400 |
264 | myprice_app_without_entityThe requested MyPrice app does not have an entity associated with it. | 400 |
265 | authorization_invalidThe given authorization header is invalid. | 400 |
266 | access_token_invalidThe given access token is invalid. | 401 |
267 | no_valid_userA valid username needs to be specified | 401 |
268 | no_privileged_authPrivileged auth is required | 401 |
269 | no_myprice_appMyprice app is required | 400 |
270 | user_not_foundNo user was found | 404 |
271 | basket_promos_activeBasket promotions are active and take precedence | 400 |
272 | hasher_type_invalidInvalid hasher_type, must be integer 1-3 in length | 400 |
273 | voucher_amount_invalidInvalid voucher amount, not enough credit or negative amount supplied | 400 |
274 | magento_oauth_exceptionWij hebben een technisch probleem. Onze support team is op de hoogte gebracht | 400 |
275 | magento_unexpected_responseUnexpected response from Magento | 400 |
276 | legacy_loyalty_not_foundThis app does not have a legacy loyalty programme associated with it | 400 |
277 | legacy_loyalty_already_mergedThe legacy loyalty account for this user has already been merged | 400 |
278 | postalcode_invalidThe postal code submitted is in an invalid format | 400 |
279 | magento_unauthorisedOngeldige combinatie gebruikersnaam/email en wachtwoord. Nog een keer proberen aub. | 401 |
280 | voucher_lockedThis voucher cannot be deleted currently. | 401 |
281 | demandware_oauth_exceptionWij hebben een technisch probleem. Onze support team is op de hoogte gebracht | 500 |
282 | demandware_unauthorisedOngeldige combinatie gebruikersnaam/email en wachtwoord. Nog een keer proberen aub. | 401 |
283 | demandware_unexpected_responseUnexpected response from the authentication server | 400 |
284 | product_variant_id_not_foundNo record has been found for that product_variant_id | 401 |
285 | product_variant_id_not_presentThe product_variant_id must be passed as a parameter | 401 |
286 | product_id_and_variant_id_not_allowedYou cannot get both product_id and product_variant_id parameters | 401 |
287 | product_id_and_product_variant_id_not_foundYou must pass one of the product_id or product_variant_id parameters | 401 |
288 | voucher_status_claimedThe voucher has already been claimed or redeemed. | 401 |
289 | demandware_unexpected_customer_countUnexpected number of matching customers in Demandware | 500 |
290 | mailing_list_not_activatedThe mailing-list for this app is not activated | 401 |
291 | mailing_list_subscribed_boolean_requiredThe mailing_list_subscribed parameter must be boolean | 401 |
292 | mailing_list_sub_offered_boolean_requiredThe mailing_list_sub_offered parameter must be boolean | 401 |
293 | voucher_update_ongoingThis voucher cannot be modified currently. | 500 |
294 | invalid_voucher_statusThis voucher is not in the correct state for this action. | 400 |
295 | no_url_for_proxied_imageCould not generate a URL to proxy to. | 404 |
296 | data_update_conflictUnable to update the database due to data conflict. | 500 |
297 | s3_upload_failedCould not upload file to S3. | 500 |
298 | facebook_email_missingFacebook user has no email address. | 400 |
299 | legacy_loyalty_number_invalidInvalid legacy loyalty number. | 400 |
300 | currency_amount_invalidInvalid currency amount. Amount must be float with . decimal separator if supplied | 400 |
301 | currency_amount_not_presentA currency amount must be supplied | 400 |
302 | log_message_not_presentA text log_message parameter must be supplied | 400 |
303 | amount_above_daily_user_maxThe amount supplied is above the daily maximum for the user | 401 |
304 | max_manual_daily_amount_not_presentThe max_manual_daily_amount parameter must be supplied | 400 |
305 | unmatched_entitiesThe chain or business of the supplied objects do not match | 400 |
306 | missing_transactionDatabase transaction error | 500 |
307 | too_many_failed_loginsToo many failed login attempts within a certain time period | 403 |
308 | original_basket_not_foundCould not find the original basket for the ID specified | 400 |
309 | original_basket_item_not_foundCould not find the original basket item for the owner code specified | 400 |
310 | return_quantity_exceeds_original_quantityThe quantity returned exceeds the quantity in the original basket item | 400 |
311 | basket_already_existsA basket with this owner code has already been submitted | 400 |
312 | invalid_my_price_appMyprice app not allowed with this chain | 400 |
313 | insufficient_balanceThe amount supplied is more than the current balance | 400 |
314 | create_platform_endpoint_failedUnable to create notification endpoint | 500 |
315 | delete_platform_endpoint_failedUnable to delete notification endpoint | 500 |
316 | parameter_supplied_not_booleanOne of the parameters supplied must be boolean and is not | 400 |
317 | feature_toggle_not_foundThe feature toggle supplied could not be found | 404 |
318 | feature_toggle_value_not_suppliedA feature toggle value is required | 400 |
319 | return_item_not_negative_valueA return item must have negative value | 400 |
320 | opt_in_programme_not_activatedThe opt-in programme for this app is not activated | 400 |
321 | programme_opted_in_boolean_requiredThe programme_opted_in parameter must be boolean | 400 |
322 | secondary_email_invalidThe secondary email is incorrectly formatted. | 400 |
323 | voucher_status_redeemedThe voucher has already been claimed or redeemed. | 400 |
324 | illegal_user_purchase_progress_amountThis amount is not permitted | 400 |
325 | invalid_nonceThe provided nonce is invalid | 400 |
326 | expired_nonceThe provided nonce has expired | 400 |
327 | nonce_already_usedThe provided nonce has already been used | 400 |
328 | wallet_not_foundNo wallet was found for this chain | 400 |
329 | export_not_supportedEntity cannot be exported | 400 |
330 | server_errorUnexpected server error | 500 |
331 | receipt_not_foundNo receipt could be found for this transaction | 400 |
332 | saving_basket_errorDatabase error - unable to process | 500 |
333 | failed_logging_basket_eventUnable to log basket to analytics pipeline | 400 |
334 | dispatching_add_basket_event_errorUnable to publish topic | 400 |
335 | unknown_receipt_memberThis basket does not belong to a known member | 400 |
336 | unknown_receiptThis receipt cannot be found | 400 |
337 | basket_platform_type_unrecognisedThe basket_platform_type or app_platform_type is missing or unrecognised. | 400 |
338 | userfile_not_presentNo user file is present. | 400 |
339 | userfile_incorrect_nameUserfile parameter must be named userfile. | 400 |
400 | userfile_not_csvThe userfile uploaded parameter must be a valid CSV file with extension .csv | 400 |
401 | file_upload_failedThe file upload failed | 400 |
402 | file_too_bigThe file uploaded is too big | 400 |
403 | campaign_type_not_supportedThis type of campaign is not supported | 400 |
404 | user_id_or_member_number_requiredEither a user_id or a member_number parameter is required | 400 |
405 | entity_mismatchThe entities or chains supplied do not match | 400 |
406 | wallet_not_redeemableIt is not possible to create or redeem vouchers for this wallet | 400 |
407 | calculation_errorThere has been a calculation error | 400 |
408 | saving_object_errorDatabase error - unable to process | 500 |
409 | operand_campaign_mismatchThe operand campaign parameter does not match another parameter | 400 |
410 | parameter_not_numericA required numeric parameter is not numeric | 400 |
411 | parameter_not_in_whitelistThe parameter supplied is not in the list of permitted values | 400 |
412 | parameter_type_mismatchThe parameter supplied should be of a different type | 400 |
413 | campaign_not_foundThe campaign was not found | 400 |
416 | multiple_parameter_mismatchMultiple parameters supplied when fewer are required | 400 |
417 | string_parameter_too_longOne of the parameters passed is too long | 400 |
419 | parameter_invalidOne of the parameters is invalid and should be in a different format | 400 |
420 | country_code_invalidThe country code must be in ISO ALPHA-2 two-letter format | 400 |
421 | s3_operation_failedCould not carry out S3 operation. | 400 |
422 | update_not_permittedIt is not permitted to carry out this update. | 400 |
423 | parameter_supplied_not_integerOne of the parameters supplied must be an integer and is not | 400 |
424 | access_deniedAccess is denied | 400 |
425 | missing_default_authentication_point_multisiteThis authentication point is multisite and not configured with a default multisite ID | 400 |
426 | member_number_range_invalidmember_number value received is higher than set max allowed value for myprice app | 400 |
427 | member_number_duplicatemember number value has already been used for the current myprice app | 400 |
428 | parameter_combination_not_allowedThe combination of parameters supplied is not allowed | 400 |
429 | magento_2_api_exceptionWij hebben een technisch probleem. Onze support team is op de hoogte gebracht | 400 |
430 | magento_2_unexpected_responseUnexpected response from Magento 2 | 400 |
431 | objects_exceed_maximum_quantityMore than the maximum permitted number of objects | 400 |
432 | dispatching_sns_errorUnable to publish to SNS topic | 400 |
433 | invalid_urlThe URL supplied is invalid | 400 |
434 | too_many_duplicate_objectsToo many duplicate objects have been detected | 400 |
435 | insufficient_objectsInsufficient objects have been detected | 400 |
436 | voucher_expiredThis voucher has expired. | 404 |
437 | spar_zw_oauth_exceptionWe are having technical difficulties and our support team is looking into it. | 500 |
438 | spar_zw_unauthorisedInvalid username/email or password. Please try again. | 401 |
439 | spar_zw_find_user_exceptionInvalid username/email or password. Please try again. | 401 |
440 | spar_zw_unexpected_responseUnexpected response from the authentication server. | 400 |
441 | parameter_missingA parameter is missing. | 400 |
442 | oil_demandware_unexpected_responseError creating user in remote system - Talend OIL. | 400 |
443 | oil_demandware_password_invalidThe password does not meet the requirements. | 400 |
444 | oil_demandware_user_already_existsThere is already an account using this email address. | 400 |
445 | sandwich_oauth_exceptionWe are having technical difficulties and our support team is looking into it. | 400 |
446 | sandwich_find_user_exceptionError occurred while attempting to fetch user details. Please try again. | 400 |
447 | sandwich_unauthorisedInvalid username/email or password. Please try again. | 401 |
448 | sandwich_unexpected_responseUnexpected response from the authentication server. | 400 |
449 | campaign_not_activeThe requested campaign is not active. | 400 |
450 | campaign_fully_redeemedYou have fully redeemed the rewards of this campaign. | 400 |
451 | insufficient_points_for_interactionYou do not have enough points to continue. | 400 |
453 | object_parameter_invalidThe provided parameter does not have an associated object. | 400 |
454 | magento_unexpected_update_user_responseError updating customer information in Magento. | 400 |
455 | magento_unexpected_search_user_responseError unable to find customer in magento. | 400 |
456 | magento_unexpected_authenticate_user_responseError unable to authenticate customer in magento. | 400 |
457 | magento_unexpected_create_user_responseError unable to create customer in magento. | 400 |
458 | task_not_foundNo task was found. | 400 |
459 | recipient_reward_discount_ratio_invalidThe recipient reward discount ratio cannot exceed 1. | 400 |
460 | sender_reward_discount_ratio_invalidThe sender reward discount ratio cannot exceed 1. | 400 |
461 | voucher_discount_ratio_invalidThe voucher discount ratio cannot exceed 1. | 400 |
Authentication
Introduction
Spaaza supports three different authentication methods, with one sub-method. These allow users, admin users and privileged clients such as trusted 3rd parties to consume the Spaaza API.
User Authentication
End user authentication is available for various API endpoints. User authentication uses HTTP headers containing
user ID and session key values obtained from the login
API endpoint. The following headers must
be passed to any API endpoint using user authentication:
- session-user_id: user ID of the user obtained from the
login
endpoint - session-key: session key of the session obtained from the
login
endpoint - X-MyPrice-App-Hostname: hostname of the Spaaza app the user is affiliated with
Admin Authentication
Admin user authentication is available for various API endpoints. An admin user is a user with permissions to
create, update, delete or assign information for a particular Spaaza app or retailer. Admin authentication uses
HTTP headers containing user ID and session key values obtained from the login
API endpoint. Each time
admin authentication is used, the permissions of the user role are checked for validity for the particular
endpoint.
The following HTTP headers must be passed to any API endpoint using admin authentication:
- session-user-id: user ID of the user obtained from the
login
endpoint - session-key: session key of the session obtained from the
login
endpoint
Additionally the following HTTP header is often required:
- X-MyPrice-App-Hostname: hostname of the Spaaza app the user wishes to apply the change to
Privileged Authentication
Privileged authentication is available for certain trusted third party systems using various API endpoints. Key exchange is used to supply the API consumer with the correct credentials, which are checked during each use of the endpoint.
The following HTTP authentication header is used to present the API with credentials:
- Authorization: Bearer access token ID:access token secret
Additionally the following HTTP header is often required:
- X-MyPrice-App-Hostname: hostname of the Spaaza app the user wishes to apply the change to
Users
Adding a user
Returns an OK code and a JSON for the user. A sample is shown below:
{
"result":{
"code":1,
"status":"ok"
},
"results":{
"user_info":{
"id":123123,
"user_id":123123,
"authentication_point_identifier":"10555454555",
"first_name":"Foo",
"last_name":"Bar",
"gender":"M",
"birthday":"1986-01-30T00:00:00+00:00",
"country_code":"NL",
"address_streetname":"Herengracht",
"address_housenumber":"504",
"address_housenumber_extension":"II",
"address_line_2":"Grachtengordel",
"address_line_3":"Centrum",
"address_towncity":"Amsterdam",
"address_regionstate":"Noord-Holland",
"address_postalcode":"1017 CB",
"username":"foo@bar.com",
"phone_number":"+31-220445641",
"member_number":"178546",
"language":"en-GB",
"opt_in_secondary":true,
"mailing_list":{
"mailing_list_sub_offered":true,
"mailing_list_subscribed":false,
"printed_mailing_list_subscribed":true
},
"entity_code":{
"type":"custom",
"code":"123123"
},
"opt_in_programme":{
"programme_opted_in":true,
"join_date":"2019-04-02T03:05:42+00:00"
},
"signup_store":{
"signup_store_id":1383,
"signup_store_name":"ACME Inc"
},
"home_store":{
"home_store_id":2774,
"home_store_name":"Herengracht HQ"
},
"registered":true,
"is_employee": false,
"user_type":"new",
"updated_existing_user":false,
"loyalty_status":{
"campaign_id":2095,
"name":"Level 1",
"description":"Level 1 in the Programme",
"loyalty_level_id":2,
"points_to_proceed_next_level":500,
"points_to_remain_current_level":220,
"maintenance_points_level":200,
"last_review_date":"2019-04-04T00:05:22+00:00",
"next_review_date":"2020-04-04T00:05:22+00:00",
"date_reached":"2019-06-06T08:06:14+00:00"
},
"frequency":3,
"recency":5,
"monetary":2,
"overall":532,
"stores":null,
"online_shopper":true,
"offline_shopper":false,
"average_basket_value":"119.30",
"days_since_last_purchase":6,
"number_of_purchases":4,
"referring_user":{
"id":3593704,
"referral_code":"gizyvl"
},
"referral_code":"ptola9"
},
"result_type":"add-user"
}
}
Overview
- Call name: add-user
- Endpoint URL: https://api0.spaaza.com/internal/add-user
- Request methods: POST
- Request Content-Type: multipart/form-data or application/x-www-form-urlencoded
- Response Content-Type: application/json
- Auth required: yes
X-MyPrice-App-Hostname
header requirement: mandatory when using privileged authenticationX-Spaaza-Request
header: optional and can be used for to record signup channel (see below)
Introduction
This API call adds information about a new user.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
address_housenumber | (string, optional) The street number or house name of the user’s postal address. |
address_housenumber_extension | (string, optional) The extension of the street number of the user’s postal address, for example “Apartment 21” |
address_line_2 | (string, optional) The second line of the user’s postal address, which can be used to denote e.g. a neighbourhood or village. |
address_line_3 | (string, optional) The third line of the user’s postal address, which can be used to denote e.g. a village or borough |
address_postalcode | (string, optional) The user’s postal or zipcode. |
address_regionstate | (string, optional) The region or state of the user’s postal address. |
address_streetname | (string, optional) The street name of the user’s postal address. |
address_towncity | (string, optional) The user’s postal city. |
affiliate_code (string, optional) | Any affiliate code to be used in connection with a campaign such as an invite-a-friend campaign which causes secondary logic to be applied on creation of the user, such as creating a voucher for another user. |
authentication_point_identifier | (string, optional) The id of the user in a third-party identity system such as a webstore. Highly recommended in the case that e.g. an update to the member’s email address will be made by the source of identity if that source is not Spaaza - in this case the authentication_point_identifier can be used as a unique identifier for the customer. |
auxiliary_identifier | (string, optional) An auxiliary identifier string used by the retailer or other organisation. This value is returned in displays and is searchable in Spaaza analytics, but is not generally used as a primary identifier in API endpoints. |
birthday | (string, mandatory or optional depending on the setup of the member programme) The ISO 8601 (YYYY-MM-DD) or ISO 8601 extended (e.g. 1983-07-27T00:00:00+00:00 or 1983-07-27T00:00:00Z) format birthday of the user. If the birthday parameter is supplied in ISO 8601 extended format any timezone offset will be converted to UTC. |
branch_business_owner_code | (string, optional) A retailer-specific branch code used by the retailer to identify the individual branch in a chain in which the new account is being created, if it is being created in a branch. If the store_id value is also supplied, then store_id takes precedence. In order to use the branch_business_owner_code field there must be a record of the branch code in the Spaaza database. |
chain_id | (integer, mandatory when using admin authentication) The id of the chain (retailer) to which the user is connected. |
country_code | (string, optional) The ISO ALPHA-2 country code of the user. |
fb_access_token | (string, mandatory in the case that the user is being added on the basis of their Facebook account details) The Facebook access token of the user. |
first_name | (string, optional) The first name of the user. |
gender | (string, optional) The gender of the user. Allowed values are M and F in either upper or lower case. |
home_store_id | (integer, optional) Home store id in the Spaaza system for which the new account was created |
is_employee | (boolean, optional) Whether the user is an employee of a chain. The defualt value if this paramter is not supplied is false. |
language | (string, optional) The preferred IETF BCP 47 language code (eg. en-GB, nl, nl-BE, etc.) for a user. The language code should consist of an ISO 639 language tag (e.g. nl ) followed by optional subtags (e.g. BE ), using hyphens as separators, for example nl-BE . |
last_name | (string, mandatory unless the user is being added on the basis of their Facebook account details) The last name of the user. |
mailing_list_sub_offered | (boolean, optional) Whether a subscription to the mailing list was offered to the user. If this parameter is not supplied a default value of false is applied. |
mailing_list_subscribed | (boolean, optional) Whether the user is subscribed to the mailing list. If this parameter is not supplied a default value of false is applied. |
member_number | (string, optional) The unique membership number or code for the shopper within the membership or loyalty programme. If this is supplied it will override the Spaaza-generated member number. In most cases this is numeric, but string values are allowed. |
opt_in_secondary | (boolean, optional) Generic opt in field to be used by the retailers, for recording opt ins that the standard fields don’t allow. |
password | (string, optional except in cases where Spaaza is the source of authentication for the member) The password for the user. |
phone_number | (string, optional) The contact number for a user. |
printed_mailing_list_subscribed | (boolean, optional) Whether the user is subscribed to the mailing list for printed mail such as catalogues. |
programme_opted_in | (boolean, optional) The programme subscription status of the user. Note that if this chain has a programme using an opt-in value and this parameter is not supplied, a default value of true is applied. |
referral_code | (integer, optional) The referral code of the user which referred the user. If this is indeed a valid referral_code this will return the id of the referring user. |
registered | (boolean, optional) Whether the user is registered. The definition of the term ‘registered’ is flexible. The default value if this parameter is not supplied is true. |
store_id | (integer, optional) Spaaza ID of the branch in which the new account was created, assuming it was created in a branch. |
update_if_exists | (boolean, optional) If the user being added already exists, this flag can be used to update the existing user with the parameters supplied instead of returning an error. Only works if using admin or privileged authentication. See the Updating an Existing User section below for more details. |
username | (string, mandatory unless the fb_access_token parameter is being used to add a user on the basis of their Facebook account details) The username of the user in email address format. |
Permissions and Authentication
Admin authentication: the performing user needs to be logged in and have assign access
to the
entity (business or chain) to which the user is connected.
Privileged authentication: the use of privileged authentication is permitted for this endpoint.
Recording Signup Channel
It is possible to set a header to record the “signup channel” of the user:
Header | Description |
---|---|
X-Spaaza-Request | (string, optional) A JSON-encoded string using the ‘client_channel’ key to denote the signup channel of the user. Allowed values are mobile , pos and import . |
Example header:
{"client_channel":"pos"}
Updating an existing user
If the add-user
endpoint finds there is already an existing user with the same username
, member_number
or authentication_point_identifier
value, the default behaviour is to return a user_already_exists
error with a HTTP 400 response code. When using admin or privileged authentication it is possible to override the default behaviour and update the user account using the parameters supplied in the HTTP POST to add-user
.
In order to update an existing user either privileged authentication or admin authentication with assign access
must be used.
When a user has been updated instead of created the updated_existing_user
flag in the response is set to true and the user_type
attribute returns as registered
instead of new
.
The following points should be noted when using the update_if_exists
functionality:
- The functionality detects existing user accounts which have the same
username
,member_number
orauthentication_point_identifier
attributes as the parameters supplied. - It is possible to use any of the
username
,member_number
orauthentication_point_identifier
parameters to update an existing user. Therefore developers coding clients should take care not to update attributes which should be immutable in e.g. a remote system. - If multiple different existing customers are found based on the
username
,member_number
orauthentication_point_identifier
parameters supplied, the endpoint returns atoo_many_duplicate_objects
error. - Using the
update_if_exists
parameter also executes updates on remote authentication points such as a webstore, where applicable, and assuming theadd-user
request does not originate from the remote authentication point.
Possible error responses
The following represents a list of possible error responses for the add-user
endpoint:
Code | Name and Description | HTTP Status Code |
---|---|---|
1 | username_invalidThe username is incorrectly formatted. Your username should be a valid email address. | 400 |
2 | password_invalidThe password is invalid. Your password should be 6 characters or more. | 400 |
3 | http_vars_missingThis script is missing some required variables which must be submitted. | 400 |
6 | no_valid_sessionThe user needs to be logged in and a valid session key needs to be sent | 401 |
7 | user_username_invalidThe user_username passed must be a valid email address | 400 |
68 | permission_denied_or_non_existentThis user has insufficient permissions for this object or the object does not exist. | 500 |
96 | gender_value_errorThe gender value submitted must be one of m/M or f/F. | 500 |
151 | fb_graph_api_access_failedFailed to contact the Facebook Graph API. | 500 |
152 | fb_oauth_exceptionOAuth problem accessing Facebook with your access token. | 400 |
153 | fb_graph_misc_exceptionFacebook reports a miscellaneous error accessing the Graph API. | 500 |
217 | chain_id_not_foundNo record has been found for that chain_id | 400 |
228 | auth_method_invalidThe given auth_method parameter has an invalid value. | 500 |
234 | user_already_existsThere is already an account using this email address. Please login or use a different email address. | 400 |
237 | date_value_errorThe submitted date must be in the format YYYY-mm-dd. | 500 |
274 | magento_oauth_exceptionWij hebben een technisch probleem. Onze support team is op de hoogte gebracht | 400 |
275 | magento_unexpected_responseUnexpected response from Magento | 400 |
265 | authorization_invalidThe given authorization header is invalid. | 400 |
266 | access_token_invalidThe given access token is invalid. | 401 |
267 | no_valid_userA valid username needs to be specified | 401 |
272 | hasher_type_invalidInvalid hasher_type, must be integer 1-3 in length | 400 |
278 | postalcode_invalidThe postal code submitted is in an invalid format | 400 |
290 | mailing_list_not_activatedThe mailing-list for this app is not activated | 401 |
291 | mailing_list_subscribed_boolean_requiredThe mailing_list_subscribed parameter must be boolean | 401 |
292 | mailing_list_sub_offered_boolean_requiredThe mailing_list_sub_offered parameter must be boolean | 401 |
316 | parameter_supplied_not_booleanOne of the parameters supplied must be boolean and is not | 400 |
321 | programme_opted_in_boolean_requiredThe programme_opted_in parameter must be boolean | 400 |
322 | secondary_email_invalidThe secondary email is incorrectly formatted. | 400 |
417 | string_parameter_too_longOne of the parameters passed is too long | 400 |
420 | country_code_invalidThe country code must be in ISO ALPHA-2 two-letter format | 400 |
424 | access_deniedAccess is denied | 400 |
426 | member_number_range_invalidmember_number value received is higher than set max allowed value for myprice app | 400 |
434 | too_many_duplicate_objectsToo many duplicate objects have been detected | 400 |
435 | insufficient_objectsInsufficient objects have been detected | 400 |
Altering a user
Returns an OK code and a JSON for the user. A sample is shown below:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"user_info": {
"id": 123123,
"user_id": 123123,
"authentication_point_identifier": "10555454555",
"auxiliary_identifier": "peba4318xel",
"first_name": "Foo",
"last_name": "Bar",
"country_code": "NL",
"address_streetname": "Herengracht",
"address_housenumber": "504",
"address_housenumber_extension": "II",
"address_line_2": "Grachtengordel",
"address_line_3": "Centrum",
"address_towncity": "Amsterdam",
"address_regionstate": "Noord-Holland",
"address_postalcode": "1017 CB",
"lang_code": "en",
"gender": "F",
"birthday": "1986-01-30T00:00:00+00:00",
"username": "foo@bar.com",
"phone_number": "+31-220445641",
"member_number": "178546",
"language": "nl-BE",
"opt_in_secondary": false,
"user_facebook_id": "321321",
"user_facebook_access_token": "dAw2ISsd6asd67ASDLBJKd...",
"mailing_list": {
"mailing_list_sub_offered": true,
"mailing_list_subscribed": false,
"printed_mailing_list_subscribed": true
},
"entity_code": null,
"opt_in_programme": {
"programme_opted_in": true,
"join_date": "2019-06-06T08:06:14+00:00"
},
"signup_store": {
"signup_store_id": 1383,
"signup_store_name": "ACME Inc"
},
"home_store": {
"home_store_id": 2774,
"home_store_name": "Herengracht HQ"
},
"registered": true,
"is_employee": true
"user_type": "registered",
"loyalty_status": {
"campaign_id": 2095,
"name": "Level 1",
"description": "Level 1 in the Programme",
"loyalty_level_id": 2,
"points_to_proceed_next_level": 500,
"points_to_remain_current_level": 220,
"maintenance_points_level": 200,
"last_review_date": "2019-04-04T00:05:22+00:00",
"next_review_date": "2020-04-04T00:05:22+00:00",
"date_reached": "2019-06-06T08:06:14+00:00"
}
},
"result_type": "alter-user"
}
}
Overview
- Call name: alter-user
- Endpoint URL: https://api0.spaaza.com/internal/alter-user
- Request methods: PUT
- Request Content-Type: multipart/form-data or application/x-www-form-urlencoded
- Response Content-Type: application/json
- Auth required: yes
- X-MyPrice-App-Hostname header requirement: mandatory when using privileged authentication
Introduction
This API call modifies information about an existing user.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
address_housenumber | (string, optional) The street number or house name of the user’s postal address. |
address_housenumber_extension | (string, optional) The extension of the street number of the user’s postal address, for example “Apartment 21” |
address_line_2 | (string, optional) The second line of the user’s postal address, which can be used to denote e.g. a neighbourhood or village. |
address_line_3 | (string, optional) The third line of the user’s postal address, which can be used to denote e.g. a village or borough |
address_postalcode | (string, optional) The user’s postal or zipcode. |
address_regionstate | (string, optional) The region or state of the user’s postal address. |
address_streetname | (string, optional) The street name of the user’s postal address. |
address_towncity | (string, optional) The user’s postal city. |
authentication_point_identifier | (string, optional) The id of the user in a third-party identity system such as a webstore. Highly recommended in the case that e.g. an update to the member’s email address will be made by the source of identity if that source is not Spaaza - in this case the authentication_point_identifier can be used as a unique identifier for the customer. |
auxiliary_identifier | (string, optional) An auxiliary identifier string used by the retailer or other organisation. This value is returned in displays and is searchable in Spaaza analytics, but is not generally used as a primary identifier in API endpoints. |
birthday | (string, mandatory or optional depending on the setup of the member programme) The ISO 8601 (YYYY-MM-DD) or ISO 8601 extended (e.g. 1983-07-27T00:00:00+00:00 or 1983-07-27T00:00:00Z) format birthday of the user. If the birthday parameter is supplied in ISO 8601 extended format any timezone offset will be converted to UTC. |
branch_business_owner_code | (string, optional) A retailer-specific branch code used by the retailer to identify the individual branch in a chain in which the new account is being created, if it is being created in a branch. If the store_id value is also supplied, then store_id takes precedence. In order to use the branch_business_owner_code field there must be a record of the branch code in the Spaaza database. |
chain_id | (integer, mandatory when using admin authentication) The id of the chain (retailer) to which the user is connected. |
country_code | (string, optional) The ISO ALPHA-2 country code of the user. |
first_name | (string, optional) The first name of the user. |
gender | (string, optional) The gender of the user. Allowed values are M and F in either upper or lower case. |
home_store_id | (integer, optional) Home store id in the Spaaza system for which the new account was created |
language | (string, optional) The preferred IETF BCP 47 language code (eg. en-GB, nl, nl-BE, etc.) for a user. The language code should consist of an ISO 639 language tag (e.g. nl ) followed by optional subtags (e.g. BE ), using hyphens as separators, for example nl-BE . |
last_name | (string, mandatory unless the user is being added on the basis of their Facebook account details) The last name of the user. |
mailing_list_sub_offered | (boolean, optional) Whether a subscription to the mailing list was offered to the user. If this parameter is not supplied a default value of false is applied. |
mailing_list_subscribed | (boolean, optional) Whether the user is subscribed to the mailing list. If this parameter is not supplied a default value of false is applied. |
member_number (string, optional) | The unique membership number or code for the shopper within the membership or loyalty programme. In most cases this is numeric, but string values are allowed. It is only possible to alter the member_number parameter using privileged authentication or admin authentication with write permissions for the chain associated with the user. |
opt_in_secondary | (boolean, optional) Generic opt in field to be used by the retailers, for recording opt ins that the standard fields don’t allow. |
password | (string, optional) The password of the user. In some systems it is not possible to update the customer password in remote authentication systems via the Spaaza API. |
phone_number | (string, optional) The contact number for a user. |
printed_mailing_list_subscribed | (boolean) Whether the user is subscribed to the mailing list for printed mail such as catalogues. |
programme_opted_in | (boolean) The programme subscription status of the user. Note that if this chain requires a user to be opted into a programme, the programme will only work for the user if this is set to true. |
registered | (boolean, optional) Whether the user is registered. The definition of the term ‘registered’ is flexible. The default value if this parameter is not supplied is true. |
is_employee | (boolean, optional) Whether the user is an employee of a chain. The defualt value if this paramter is not supplied is false. |
store_id | (integer, optional) Spaaza ID of the branch in which the new account was created, assuming it was created in a branch. |
user_id | (integer, mandatory when not using username , member_number or authentication_point_identifier to identify the user) The ID of the user whose details are to be altered. This parameter can be used to identify the user. If this parameter is used to identify the user, the parameters username or authentication_point_identifier should not be used to identify the user, and will be altered if supplied and different from current values.* |
username | (string, mandatory when not using member_number , user_id or authentication_point_identifier to identify the user) The username of the user in email address format. This parameter can be used to identify the user. If this parameter is used to identify the user, the parameter authentication_point_identifier cannot be supplied to identify the user. In the case of admin authentication, this parameter cannot be used to identify the user. |
* In the case of admin authentication, the user whose details are to be altered must be identified by at least one of the parameters user_id
, username
or authentication_point_identifier
.
Note that, in order to remove values such as ‘address_housenumber_extension’ from a user record, it is necessary to send their parameters as empty values.
Permissions and Authentication
Admin authentication: The performing user needs to be logged in and have assign access
to the
entity (business or chain) to which the user is connected.
Privileged authentication: the use of privileged authentication is permitted for this endpoint.
Retrieving a user
Returns an OK code and a JSON for the user. A sample is shown below:
{
"result":{
"code":1,
"status":"ok"
},
"results":{
"user_info":{
"id":123123,
"user_id":123123,
"authentication_point_identifier":"1055550795",
"auxiliary_identifier":"pevau533xar",
"first_name":"Foo",
"last_name":"Bar",
"country_code":"NL",
"address_streetname":"Herengracht",
"address_housenumber":"504",
"address_housenumber_extension":"II",
"address_line_2":"Grachtengordel",
"address_line_3":"Centrum",
"address_towncity":"Amsterdam",
"address_regionstate":"Noord-Holland",
"address_postalcode":"1017 CB",
"lang_code":"en",
"gender":"M",
"birthday":"1900-01-30T00:00:00+00:00",
"username":"foo@bar.com",
"phone_number":"+31-220445641",
"user_facebook_id":"321321",
"user_facebook_access_token":"dAw2ISsd6asd67ASDLBJKd...",
"mailing_list":{
"mailing_list_sub_offered":true,
"mailing_list_subscribed":false,
"printed_mailing_list_subscribed":false
},
"entity_code":{
"type":"regular",
"code":"3593791"
},
"opt_in_programme":{
"programme_opted_in":true,
"join_date":"2019-06-06T08:06:14+00:00"
},
"registered":false,
"is_employee": false,
"loyalty_status":{
"campaign_id":2095,
"name":"Level 1",
"description":"Level 1 in the Programme",
"loyalty_level_id":2,
"points_balance_current":220,
"points_to_proceed_next_level":500,
"points_to_remain_current_level":0,
"last_review_date":"2019-04-04T00:05:22+00:00",
"next_review_date":"2020-04-04T00:05:22+00:00",
"date_reached":"2018-04-21T10:00:10+00:00"
},
"frequency":3,
"recency":5,
"monetary":2,
"overall":532,
"stores":null,
"online_shopper":true,
"offline_shopper":false,
"average_basket_value":"119.30",
"days_since_last_purchase":6,
"number_of_purchases":4,
"referring_user":{
"id":4,
"referral_code": "56uepf"
},
"referral_code" : "uyamct"
},
"result_type":"get-user"
}
}
Overview
- Call name: get-user
- Endpoint URL: https://api0.spaaza.com/internal/get-user
- Request methods: GET
- Response Content-Type: application/json
- Auth required: yes
- X-MyPrice-App-Hostname header requirement: mandatory when using privileged authentication or when using the
username
parameter to look up a user with admin authentication
This API call retrieves information about an existing user.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
chain_id | The chain id to which the user is connected. In the case of admin authentication, this parameter can be used in conjunction with the user_id parameter to look up the user (or the username parameter can be used on its own to look up the user). If this parameter is used with admin authentication, the user_id parameter must also be supplied. |
user_id | The ID of the user. In the case of admin authentication, this parameter can be used in conjunction with the chain_id parameter to look up the user or the username parameter (or the username parameter can be used on its own to look up the user). If this parameter is used with admin authentication, the chain_id parameter must also be supplied. |
username | The username of the user in email address form. This parameter can be used to look up the user with either admin or privileged authentication. In the case of admin authentication, if this parameter is supplied, and the parameters user_id and chain_id have already been supplied, this parameter will not be used to look up the user. If this parameter is used to look up the user then the X-MyPrice-App-Hostname header is required. |
authentication_point_identifier | The ID of the user in a third party identity system such as webstore. If the user_id parameter has been supplied, this parameter will not be used to look up the user information. If the username parameter has also been supplied and has been unsuccessful in looking up a user, the authentication_point_identifier parameter will be used. |
fb_access_token | The Facebook access token of the user. |
affiliate_code | The affiliate code of the user. |
Permissions
Admin authentication: the performing user needs to be logged in and have read access
to the entity (business or chain) to which the user is connected.
Privileged authentication: the use of privileged authentication is permitted for this endpoint. This API endpoint allows delegated authentication.
Setting the loyalty level of a user
Returns an OK code and a JSON for the user. A sample is shown below:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"loyalty_level": {
"id": 123,
"campaign_id": 123123,
"name": "VIP",
"description": "VIP level in the Loyalty Programme",
"automated_level_logic": "0"
}
},
"result_type": "alter-user-loyalty-level"
}
Overview
- Call name: alter-user-loyalty-level
- Endpoint URL: https://api0.spaaza.com/auth/alter-loyalty-level
- Request methods: PUT
- Auth required: yes
X-MyPrice-App-Hostname
header requirement: mandatory when using privileged authenticationX-Spaaza-Request
header: optional and can be used for to record signup channel (see below)
Introduction
This API call changes the loyalty level of a user to that supplied.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
user_id | (string/integer, mandatory) the ID of the user (programme member) in the Spaaza system. If the member_number parameter is supplied, this parameter should not be used. |
member_number | (string/integer, mandatory unless the user_id parameter is supplied) the member number in the programme of the user (member) whose loyalty level is being changed. If the user_id parameter is supplied then this parameter is not needed and the user_id parameter will take precedence. |
loyalty_level_id | (integer, mandatory) the ID of the loyalty level which that of the user (programme member) is to be changed to. |
Permissions and Authentication
Admin authentication: the performing user needs to be logged in and have write access
to the
entity (business or chain) to which the user is connected.
Privileged authentication: the use of privileged authentication is not permitted for this endpoint.
Exporting users (bulk)
curl "-XPOST -v -k \
-H 'X-MyPrice-App-Hostname: retailername.spaaza.com’ \
-H 'Authorization: Bearer <your key>:<your secret>’ \
-d 'export_entity=user’
'https://api0.spaaza.com/auth/export'"
That API end-point will respond with a download link for the CSV file. The link can only be used once and is time limited (currently 48 hours).
[
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"download_url": "https://services.spaaza.com/export/user?Nonce=2018-03-11T16%3A37%3A21ZAxagGQ9ZmaWBVyFLQZdYsCPWxcmlXoGSWzhCjqKaChA%3D&ChainId=1748&Segment=all",
"result_type": "spaaza\\api\\auth\\export"
}
}
]
POST to the API with the post data form encoded and the appropriate headers to specify the app hostname and your credentials.
You can make a GET request to the download link to get the CSV. The link contains a nonce which is signed with a secret known by our API and the download service.
At the moment the download service streams the CSV file over HTTP and it will contain all of the users. A future version will allow you to name a segment of users from the console.
User webhook
An example of a user webhook
{
"created": "2016-01-08T10:20:35Z",
"data": {
"birthday": "1975-07-30",
"chain_id": 1750,
"channel": "spaaza-mobile-web",
"contact_email": "james+nnlive1119@spaaza.com",
"created": "2016-01-08T10:20:29Z",
"did_opt_in": true,
"registered": false,
"entity_code": "XXX",
"firstname": "J",
"gender": "M",
"lastname": "B",
"object": "shopper",
"spaaza_id": 394261,
"username": "james+nnlive1119@spaaza.com",
"phone_number": "+31-220445641",
"address_streetname": "Nieuwe Nieuwstraat",
"address_housenumber": "104",
"address_housenumber_extension": "II",
"address_line_2": "Kleine Buurt",
"address_line_3": "Centrum",
"address_towncity": "Hoek van Holland",
"address_regionstate": "Zuid-Holland",
"address_postalcode": "1005 AT"
},
"id": "568f8d73669bc",
"object": "event",
"type": "shopper.opted-in"
}
Spaaza can call external webhooks for certain events, including:
- when the opt-in status of a user changes
- when the user is created
We can configure a webhook URL that you provide. Whenever the event occurs we send a simple POST request to the URL. The body of the POST is JSON that includes details of the event and the shopper that triggered it. So that you can verify that the POST really originates from Spaaza we provide a signature in a request header (X-Spaaza-Hmac-SHA256).
The value of the header is a base 64 encoded HMAC-SHA256 of the whole body of the request with a shared secret that we would provide. Your code to handle the event would need to recreate the signature using the shared secret and compare it to the value in the header.
Status level webhook
An example of a loyalty status level webhook
{
"type": "shopper.loyalty-level-changed",
"id": "5b69c11f4bf8c",
"chain_id": 1743,
"created": "2018-08-07T15:56:15Z",
"data": {
"campaign_id": 201,
"created_date": "2018-08-07T15:56:15+00:00",
"id": 80007,
"log_message": "Manual level change",
"loyalty_level": {
"automated_level_logic": true,
"campaign_id": 201,
"description": "Silver level in the ACME Programme",
"id": 4,
"name": "member"
},
"loyalty_level_previous": {
"automated_level_logic": true
"campaign_id": 201,
"description": "Bronze level in the ACME Programme",
"id": 18,
"name": "Bronze",
},
"mutation_owner_id": 1,
"user": {
"address_housenumber": null,
"address_housenumber_extension": null,
"address_line_2": null,
"address_line_3": null,
"address_postalcode": null,
"address_regionstate": null,
"address_streetname": null,
"address_towncity": null,
"authentication_point_identifier": "66141993",
"auxiliary_identifier": "peb209883x",
"birthday": "1988-05-06T00:00:00+00:00",
"country_code": "NL",
"first_name": "Sam",
"gender": "M",
"id": 34348394,
"language": "nl-NL",
"last_name": "Critchley",
"loyalty_status": {
"campaign_id": 201,
"name": "Silver",
"description": "Silver level in the ACME Programme",
"loyalty_level_id": 4,
"points_balance_current": 340,
"points_to_proceed_next_level": 410,
"points_to_remain_current_level": 60,
"last_review_date": "2019-06-28T09:30:40+00:00",
"next_review_date": "2020-06-28T09:30:40+00:00",
"date_reached": "2019-08-23T13:33:15+00:00"
},
"mailing_list": {
"mailing_list_sub_offered": false,
"mailing_list_subscribed": true,
"printed_mailing_list_subscribed": false
},
"member_number": {
"code": "30359901",
"type": "custom"
},
"opt_in_programme": {
"programme_opted_in": true,
"join_date": "2019-06-06T08:06:14+00:00"
},
"opt_in_secondary": false,
"push_notification_subscription": {
"subscribed": false,
"subscriptions": []
},
"registered": true,
"signup_channel": "webshop",
"user_id": 34348394,
"username": "acmestage691228534@cowcam.com"
},
}
}
Spaaza can call an external webhook when there is a change in a customer’s loyalty level.
We can configure a webhook URL that you provide. Whenever the voucher-issued event occurs we send a simple POST request to the URL. The body of the POST is JSON that includes details of the event and the voucher that triggered it. So that you can verify that the POST really originates from Spaaza we provide a signature in a request header (X-Spaaza-Hmac-SHA256).
The value of the header is a base 64 encoded HMAC-SHA256 of the whole body of the request with a shared secret that we would provide. Your code to handle the event should recreate the signature using the shared secret and compare it to the value in the header.
Note that the ‘data’ section of the webhook payload includes information about the user whose status has changed and about the new level:
Section | Description |
---|---|
loyalty_level | Information about the new loyalty level including the name and description of the level. |
user | Information about the user including their name, member number, email and address information. |
Logging users in
If the session is valid, the login call returns information about the user and the session, including: key, length of validity in hours and the authentication method used to establish the key. An example is shown below:
[
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"result_type": "login",
"session_info": {
"session_key": "acc5cf311f4bce26feaa80de400e2f294ff6168f49da765f0a4d6a798900460f",
"session_key_validity": "336",
"session_auth_method": "password",
"session_user_id": 114521,
"session_username": "test56767@spaaza.com",
"session_expires_date": "2020-04-06 11:19:10"
},
"user_info": {
"id": 114521,
"user_id": 114521,
"first_name": "Sam",
"last_name": "Critchley",
"gender": "M",
"birthday": "2014-10-21T00:00:00+00:00",
"username": "test56767@spaaza.com",
"mailing_list": {
"mailing_list_sub_offered": "true",
"mailing_list_subscribed": false,
"printed_mailing_list_subscribed": false
},
"entity_code": {
"type": "custom",
"code": "3021879"
},
"opt_in_programme": {
"programme_opted_in": true,
"join_date": "2016-01-30T14:37:22+00:00"
},
"registered": true,
"loyalty_status": {
"campaign_id": 2095,
"name": "Level 1",
"description": "Level 1 in the Programme",
"loyalty_level_id": 2,
"points_to_proceed_next_level": 500,
"points_to_remain_current_level": 220,
"maintenance_points_level": 200,
"last_review_date": "2019-04-04T00:05:22+00:00",
"next_review_date": "2020-04-04T00:05:22+00:00",
"date_reached": "2019-06-06T08:06:14+00:00"
}
}
}
}
]
- Call name: login
- Endpoint URL: https://api0.spaaza.com/auth/login
- Request methods: POST
- Request Content-Type: multipart/form-data or application/x-www-form-urlencoded
- Response Content-Type: application/json
- Auth required: no
When supplied with a username and password, this API checks whether the password is valid for the username. If it is valid, it deletes any existing sessions, and then creates a session with a session key in the database. It then returns session information in JSON. Note that the session_expires_date
is returned in UTC date time format.
HTTP Parameters
The following HTTP POST parameters can be passed to the API:
Parameter | Description |
---|---|
username required | The username (email address) of the user. |
password required | The password of the user. |
Permissions
This API call requires no specific permissions.
Headers
The following headers can/must be passed to the API call:
X-MyPrice-App-Hostname (mandatory in some cases) The hostname of the app which the signup is for. This header is mandatory when authenticating an end user (shopper or programme member). When authenticating an admin user, webshop or POS this header can be excluded.
Logging in on behalf of a user
Returns an OK code and a JSON for the user. A sample is shown below:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"user_info": {
"id": 3636813,
"user_id": 3636813,
"first_name": "Jane",
"last_name": "Smith",
"birthday": "1980-01-01T00:00:00+00:00",
"signup_channel": "mobile:ios",
"username": "jane.smith@example.com",
"authentication_point_identifier": null,
"auxiliary_identifier": null,
"mailing_list": {
"mailing_list_sub_offered": false,
"mailing_list_subscribed": true,
"printed_mailing_list_subscribed": true
},
"entity_code": {
"type": "regular",
"code": "3636813"
},
"opt_in_programme": {
"programme_opted_in": false,
"join_date": "2020-05-18T09:32:57+00:00"
},
"obfuscated": false,
"country_code": null,
"address_streetname": null,
"address_housenumber": null,
"address_housenumber_extension": null,
"address_line_2": null,
"address_line_3": null,
"address_towncity": null,
"address_regionstate": null,
"address_postalcode": null,
"member_number": "3636813",
"language": "en-GB",
"opt_in_secondary": null,
"registered": true,
"is_employee": false,
"push_notification_subscription": {
"subscribed": false,
"subscriptions": []
},
"loyalty_status": null,
"frequency": 0,
"recency": 0,
"monetary": 0,
"overall": 0,
"stores": "",
"online_shopper": false,
"offline_shopper": false,
"average_basket_value": "0.00",
"days_since_last_purchase": null,
"number_of_purchases": 0,
"referring_user": null,
"referral_code": "lxzwvs"
},
"session_info": {
"session_key": "84f895eda81892bacf53ac2538d96d14fda32a50889f55e85fa461e241e31f65",
"session_auth_method": "password",
"session_key_validity": "15552000",
"session_user_id": 3636813,
"session_username": "jane.smith@example.com",
"session_expires_date": "2021-04-28 11:14:40"
},
"result_type": "session"
}
}
Overview
- Call name: session
- Endpoint URL: https://api0.spaaza.com/auth/session
- Request methods: POST
- Request Content-Type: multipart/form-data or application/x-www-form-urlencoded
- Response Content-Type: application/json
- Auth required: yes
- X-MyPrice-App-Hostname header required: yes
This API call allows you to login on behalf of a user. This API call only works with privileged authentication.
HTTP Parameters
At least one of the below HTTP parameters must be passed to the API:
Parameter | Description |
---|---|
username | (string) The username (email address) of the user |
user_id | (string/integer) The Spaaza user id of the user. |
member_number | (string) The unique membership number or code for the shopper. |
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. |
Permissions and Authentication
This API call requires a valid Spaaza session. The session can be as follows:
Parameter | Description |
---|---|
privileged | An OAuth-based mechanism for trusted third-parties,the use of privileged authentication is permitted for this endpoint. |
Headers
The following headers can/must be passed to the API call:
Parameter | Description |
---|---|
X-MyPrice-App-Hostname (mandatory) | The hostname of the app the user is affiliated with. |
Getting user session status
If the session is valid, returns an ok signal. An example is below:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"id": 114521,
"user_id": 114521,
"first_name": "Sam",
"last_name": "test56767",
"gender": "M",
"birthday": "1982-05-21T00:00:00+00:00",
"username": "test56767@cowcam.com",
"mailing_list": {
"mailing_list_sub_offered": false,
"mailing_list_subscribed": false,
"printed_mailing_list_subscribed": false
},
"entity_code": {
"type": "custom",
"code": "3021879"
}
"result_type": "get-login-status"
}
}
If the session’s auth_method was “facebook”, extended information will be returned with the Facebook access token and detail about the expiry:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"user_id": 68076,
"username": null,
"user_facebook_id": "100005264048981",
"user_facebook_access_token": "AAADPxlzKZBy8BACux13ZCpass309BuPZA9tFpcVvZCP0zdzBlbyqTXwPnl7YpIbMLgqfoktUcaD4ZAOO1VS128bSx2tvuxDEgKCwjHxR6PkZCOCZAGLD7x7",
"user_facebook_access_token_expires": 3600,
"user_facebook_access_token_expires_timestamp_utc": "2017-03-08 00:14:40",
[...]
"mailing_list": {
"mailing_list_sub_offered": false,
"mailing_list_subscribed": false,
"printed_mailing_list_subscribed": false
},
"entity_code": {
"type": "custom",
"code": "3024075"
}
"result_type": "get-login-status"
}
}
- Call name: get-login-status
- Endpoint URL: https://api0.spaaza.com/auth/get-login-status
- Request methods: GET
- Auth required: no
When supplied with a username and session key, this API checks whether there’s a valid session for the username which has a matching session key. If there is a valid session, it returns code 1 (okay). If there is no valid session, it returns with an error.
The response also returns various details about the user, including email address (if present), date of birth and mailing-list subscription info.
HTTP Parameters
The following HTTP POST parameters can be passed to the API:
Parameter | Description |
---|---|
username mandatory if user_id is not passed | The username (email address) of the user |
user_id mandatory if username is not passed | The user id of the user whose session’s validity is being checked |
session_key mandatory | The session key associated with the session of the user |
Permissions
This API call requires no specific permissions.
Headers
The following headers can/must be passed to the API call:
X-MyPrice-App-Hostname (mandatory for programme member/non-admin sessions) The hostname of the app which the login session is associated with. This header is mandatory when authenticating an end user (shopper or programme member). When authenticating an admin user, webshop or POS this header can be excluded.
Logging users out
If the session is valid, returns an ok signal. Ae example is below:
[
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"result_type": "logout",
"username": "sam.critchley@spaaza.com"
}
}
]
- Call name: logout
- Endpoint URL: http://api0.spaaza.com/auth/logout
- Request methods: DELETE
- Response Content-Type: application/json
- Auth required: yes
Calling this API with a valid session (in HTTP headers) causes the session for that user to be destroyed, effectively logging the user out.
HTTP Parameters
No specific parameters required.
Permissions
This API call requires no specific permissions. Unless there’s been a security failure, only the user or the backend user is in possession of the session key, which means the session can only be validated if the validator is in possession of the key.
Deleting user accounts
Returns an OK code and echoes the obfuscated user details. A sample is shown below:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"user_info": {
"id": 3354896,
"user_id": 3354896,
"first_name": "Deleted",
"last_name": "Deleted",
"country_code": "IT",
"username": "3354896@deleted.spaaza.com",
"authentication_point_identifier": null,
"auxiliary_identifier": null,
"mailing_list": {
"mailing_list_sub_offered": false,
"mailing_list_subscribed": false,
"printed_mailing_list_subscribed": false
},
"entity_code": {
"type": "custom",
"code": "133791"
},
"opt_in_programme": {
"programme_opted_in": false,
"join_date": null
},
"registered": false,
"address_streetname": null,
"address_housenumber": null,
"address_housenumber_extension": null,
"address_line_2": null,
"address_line_3": null,
"address_towncity": null,
"address_regionstate": null,
"address_postalcode": null
},
"result_type": "delete-user"
}
}
Overview
- Call name: delete-user
- Endpoint URL: https://api0.spaaza.com/delete-user
- Request methods: DELETE
- Response Content-Type: application/json
- Auth required: yes
Delete a user for legal purposes. This API endpoint obfuscates all personally-idenfiable user details such as first name, last name, email address, gender, date of birth and address details.
Permissions and Authentication
This API call requires a valid Spaaza session. The session can be as follows:
Parameter | Description |
---|---|
or | |
admin | A session generated by administrative user login. The performing admin user needs to be logged in and have delete access to the entity (business or chain) to which the user is connected. |
or | |
privileged | An OAuth-based mechanism for trusted third-parties,the use of privileged authentication is permitted for this endpoint . |
Note that if admin authentication is used and the admin user does not have sufficient permissions to delete the user, an error will be generated.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
chain_id (mandatory in the case of admin authentication) | the id of the chain with which the user to be deleted is associated. |
user_id or username or member_number (one parameter mandatory) | the Spaaza user ID, username (email address) or member_number (user code) of the user to be deleted. One of these parameters must be supplied. |
Headers
The following headers can/must be passed to the API call:
Parameter | Description |
---|---|
X-MyPrice-App-Hostname (mandatory in the case of privileged authentication if user_id parameter not sent) | The hostname of the app for which the user is requesting the card. Required in the case of privileged authentication when the user is identified by either the username or member_number parameter. Not required in the case of admin authentication. |
Permissions
This API call requires delete permissions when using admin authentication.
Searching Users
curl "-XPOST -v -k \
-H 'Session-User-Id:<your user ID>' \
-H 'Session-Key:<your session key>' \
-H 'Session-Chain-Id:<your chain ID>' \
-d 'chain_id=<your chain ID>’ \
-d 'query=smith’ \
-d 'page=1 \
-d 'count=25 \
-d 'opted_in=1 \
'https://services-[API_ENVIRONMENT].spaaza.com/search/users'"
Example response
[
{
"id": 12345678,
"entity_code": {
"code": "100002"
},
"username": "john.smith@spaaza.com",
"firstname": "John",
"lastname": "Smith",
"created_date": "2017-10-19T12:46:34Z",
"gender": "M",
"birthday": "1982-06-30T00:00:00Z",
"spaaza_opted_in": true,
"country_code": "NL",
"store_id": ""
},
{
"id": 12345679,
"entity_code": {
"code": "100003"
},
"username": "jane.smith@example.com",
"firstname": "Jane",
"lastname": "Smith",
"created_date": "2017-10-29T13:24:33Z",
"gender": "M",
"birthday": "1979-04-29T00:00:00Z",
"spaaza_opted_in": true,
"country_code": "UK",
"store_id": "12"
}
]
Overview
- Call name: search
- Endpoint URL: https://services-[API_ENVIRONMENT].spaaza.com/search/users
- Request methods: HTTP POST
- Auth required: yes
You can use this API endpoint to search for users in Spaaza.
The API_ENVIRONMENT value varies according to whether the request is being made to Spaaza’s production or staging API:
Environment | API_ENVIRONMENT value |
---|---|
Production | prod |
Staging | test01 |
Headers
The following headers are required:
Header | Description |
---|---|
Session-User-Id | ID of the user obtained from the login endpoint |
Session-Key | key of the session obtained from the login endpoint |
Session-Chain-Id | the ID of the Spaaza chain or retailer |
The following authentication methods are permitted:
Method | Description |
---|---|
admin | A session generated by administrative user login. |
Query Parameters (application/x-www-form-urlencoded)
This API accepts the following parameters:
Parameter | Description |
---|---|
chain_id required | The ID of the Spaaza chain or retailer |
query | End-user supplied search term(s) (string) |
page | The page number of desired results |
count | Number of results to return |
opted_in (boolean) | Filter the search to opted-in users. To search for all users do not pass this parameter. |
Note objects
You can use the Spaaza API to manage any notes attached to a given user. This can be used to provide useful details about a user’s purchase habits, or any other generic notes that neeed to be saved for a user.
Fields in the Note object
The following fields are returned in the note object.
Identifying a note
Details for a note
Field | Description |
---|---|
id | the unique identifier (id) for a given note object. |
text | the text that makes up a note record. |
created_date | the timestamp for when the record was created. |
user_id | the unique user id for the user that the note is attached to. |
creating_user_id | the unique id for the user that created the note. |
Viewing user notes
User notes do not currently have their own API endpoint for fetching data. They can be fetched as part of the user get-card api call
Adding a note to a user
Example response
{
"id": 123456,
"text": "Customer very happy with her latest dress purchase.",
"created_date": "2017-07-03T11:56:04Z",
"user_id": 123123,
"creating_user_id": 321321
}
Overview
- Call name: add-user-note
- Endpoint URL: https://api0.spaaza.com/internal/add-user-note
- Request methods: POST
- Request Content-Type: multipart/form-data or application/x-www-form-urlencoded
- Response Content-Type: application/json
- Auth required: yes
X-MyPrice-App-Hostname
header requirement: mandatory when using privileged authentication
Introduction
This API call adds a new note record to an existing user.
HTTP parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
user_id | (integer, mandatory) The id of the user to which the note is being added. |
text | (string, mandatory) The text for the new note record - max. 1000 characters in length. |
Deleting a user note
Example response
{
"id": 123456,
"deleted": true
}
Overview
- Call name: delete-user-note
- Endpoint URL: https://api0.spaaza.com/internal/delete-user-note
- Request methods: DELETE
- Request Content-Type: multipart/form-data or application/x-www-form-urlencoded
- Response Content-Type: application/json
- Auth required: yes
X-MyPrice-App-Hostname
header requirement: mandatory when using privileged authentication
Introduction
This API call deletes a user’s note record.
HTTP parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
user_note_id | (integer, mandatory) The id of the user note that is to be deleted. |
Cross site authentication token
Used to facilitate seamless logins with third party site integrations. This API can be used to verify and login a user, without a user having to manually log in to several systems. Please check with Spaaza on availability of this API endpoint for the system you are attempting to integrate with.
The result output is a JSON array with its results section being something to the lines of the following:
{
"token": "7edc5f1e534cad2454ea150904f261468b90d073e8dde875b2c",
"expiry": "2019-04-04T00:00:00+00:00"
}
- Call name: get-cross-site-token
- Endpoint URL: https://api0.spaaza.com/auth/get-cross-site-token
- Request methods: POST
- Response Content-Type: application/json
- Auth required: yes
Get a token to do cross site authentication with the given app (see “Headers” section below).
Permissions and Authentication
This API call requires a valid Spaaza session. The session can be as follows:
- User authentication: a session generated by an end-user login.
HTTP Parameters
This API endpoint has no required parameters - all necessary information is supplied in the session and app hostname headers.
Headers
The following headers can/must be passed to the API call in addition to any authentication headers:
Parameter | Description |
---|---|
X-MyPrice-App-Hostname (mandatory) | The hostname of the app which the user is associated with. |
Permissions
This API call requires no specific permissions.
Possible error responses
The following represents a list of possible error responses for the get-card
endpoint:
Code | Name and Description | HTTP Status Code |
---|---|---|
6 | no_valid_sessionThe user needs to be logged in and a valid session key needs to be sent | 401 |
68 | permission_denied_or_non_existentThis user has insufficient permissions for this object or the object does not exist. | 500 |
269 | no_myprice_appMyprice app is required | 400 |
Card, points and vouchers
Getting the “card” of a user
The result output is a JSON array with its results section being something to the lines of the following:
[
{
"entity":{
"id":1752,
"name":"Big Chain Inc.",
"type":"chain"
},
"entity_images":[
],
"card_colour":{
"id":1,
"card_background":"#000000",
"card_text":"#FFFFFF"
},
"user_entity_card":{
"type":"custom",
"id":33000114
},
"user_info":{
"authentication_point_identifier":"SQ0057824",
"auxiliary_identifier":"ge0axuf62",
"birthday":"1983-09-09T00:00:00+00:00",
"entity_code":{
"code":"33000114",
"type":"custom"
},
"first_name":"Jiminy",
"gender":"M",
"id":305281,
"last_name":"Cricket",
"country_code":"NL",
"address_streetname":"Herengracht",
"address_housenumber":"504",
"address_housenumber_extension":"II",
"address_line_2":"Grachtengordel",
"address_line_3":"Centrum",
"address_towncity":"Amsterdam",
"address_regionstate":"Noord-Holland",
"address_postalcode":"1017 CB",
"phone_number":"+31-220445641",
"language":"nl-NL",
"opt_in_secondary":true,
"mailing_list":{
"mailing_list_sub_offered":true,
"mailing_list_subscribed":false,
"printed_mailing_list_subscribed":false
},
"opt_in_programme":{
"programme_opted_in":"true",
"join_date":"2019-06-06T08:06:14+00:00"
},
"registered":true,
"is_employee": false,
"user_id":3052761,
"username":"jiminy@mail.com",
"referring_user":{
"id":3593732,
"referral_code":"56uepf"
},
"referral_code":"uyamct"
},
"vouchers":[
{
"voucher_key":"07d9acafd261dff2c013c6b09e3867d7fc55df5a39953c17c4c0f5380d4b71c2",
"voucher_id":45657779,
"voucher_status":"generated",
"voucher_expiry_datetime_utc":"2014-01-13 18:04:01",
"voucher_expiry_seconds_remaining":5626,
"product_name":"QU HEADCOUNT",
"product_price":299.95,
"product_currency_id":1,
"product_voucher_price":296.95,
"product_original_price":299.95,
"campaign_id":4,
"campaign_title":"Test",
"voucher_text":"Thanks for being a great customer",
"voucher_notes":null,
"voucher_title":null,
"voucher_description":null,
"voucher_image_url":null
}
],
"meta_vouchers":[
],
"basket_vouchers":[
{
"voucher_key":"da64e01d486a7cca40de5700240bbe9c01f18cbfc3a72096da979d8bc427b05d",
"voucher_id":32455345,
"voucher_created_datetime":"2019-09-02T15:18:52+00:00",
"voucher_status":"generated",
"campaign_id":66,
"campaign_title":"Big Chain Invite-a-Friend",
"campaign_type":"affiliate",
"campaign_image_filename":null,
"campaign_image_url":null,
"campaign_image_link":null,
"campaign_image_dimension_x":null,
"campaign_image_dimension_y":null,
"campaign_title_localised":"Vriend uitnodigen NL",
"campaign_voucher_text_localised":"Big Chain bon NL",
"redeeming_basket":null,
"voucher_expiry_datetime_utc":"2024-12-27 10:20:50",
"voucher_expiry_seconds_remaining":4319835,
"creating_user":{
"user_id":21,
"full_name":"John Doe"
},
"voucher_currency_id":1,
"voucher_currency_symbol":"R",
"voucher_amount_original":50.00,
"voucher_amount_redeemed":"",
"voucher_amount":50.00,
"voucher_text":"You got a voucher from your friend.",
"voucher_notes":null,
"voucher_title":"€50 Friends Voucher",
"voucher_description":null,
"voucher_image_url":"https://www.example.com/image.jpg",
"voucher_honour_code":"honour004",
"voucher_discount_ratio": 0,
"voucher_type": "basket"
},
{
"voucher_key":"19361bbf9bf4a02b3d4fa413628768bb2096239cb9effa4fa60980b606bb33dc",
"voucher_id":3964201,
"voucher_created_datetime":"2020-03-02T16:43:52+00:00",
"voucher_status":"claimed",
"campaign_id":66,
"campaign_title":"Big Chain Loyalty Campaign",
"campaign_type":"loyalty",
"campaign_image_filename":null,
"campaign_image_url":null,
"campaign_image_link":null,
"campaign_image_dimension_x":null,
"campaign_image_dimension_y":null,
"campaign_title_localised": "Big winkelketen",
"campaign_voucher_text_localised":"Big Chain voucher NL",
"redeeming_basket":null,
"voucher_expiry_datetime_utc":"2024-12-31 10:20:50",
"voucher_expiry_seconds_remaining":4319835,
"creating_user":{
"user_id":21,
"full_name":"John Doe"
},
"voucher_currency_id":1,
"voucher_currency_symbol":"R",
"voucher_amount_original": null,
"voucher_amount_redeemed":"",
"voucher_amount": null,
"voucher_text":"You got a voucher from your friend.",
"voucher_notes":null,
"voucher_title":"€50 Friends Voucher",
"voucher_description":null,
"voucher_image_url":"https://www.example.com/image.jpg",
"voucher_honour_code": null,
"voucher_discount_ratio": 0.25,
"voucher_type": "basket_pct"
}
],
"honour_vouchers":[
{
"voucher_key":"138406421b611051c953a620c5f958348bbb045fdf4a7e92c8e9f53ccd04144e",
"voucher_id":94697,
"voucher_status":"claimed",
"voucher_locked":false,
"campaign_id":140,
"campaign_type":"loyalty",
"campaign_title":"ACME Loyalty Campaign",
"voucher_expiry_datetime_utc":"2018-07-30 00:00:00",
"voucher_expiry_seconds_remaining":5201979,
"creating_user":{
"user_id":21,
"full_name":"John Doe"
},
"voucher_currency_id":2,
"voucher_currency_symbol":"€",
"voucher_amount_original":0,
"voucher_amount_redeemed":0,
"voucher_amount":5,
"voucher_text":"Thanks for being a great customer",
"voucher_notes":"The notes for a voucher such as instructions for use, go here",
"voucher_title":"€5 Loyalty Campaign Voucher",
"voucher_description":"If you redeem this voucher online or in store you will get a free item.",
"voucher_type":"honour",
"voucher_honour_code":"HON00421"
}
],
"promotions":{
"progress":[
{
"type":"simple",
"title":"Big Chain Hit The Target Campaign",
"description":"Spend R200 and earn R25",
"actions":[
],
"progress":{
"target":200,
"achieved":0,
"percentage":0
},
"supports_contribution":true,
"is_contributor":true,
"currency":"ZAR",
"currency_symbol":"R",
"campaign_id":90,
"reward_money":25,
"image_filename":null,
"image_url":null,
"image_link":null,
"image_dimension_x":null,
"image_dimension_y":null,
"field_localisations":"{\"title\":{\"en\":{\"default\":\"Big Chain Hit The Target Campaign\",\"en-UK\":\"Big Chain Hit The Target Campaign UK\",\"en-US\":\"Big Chain Hit The Target Campaign US\"},\"nl\":{\"default\":\"Big Chain Bereiken Campagne\",\"nl-NL\":\"Big Chain Bereiken Campagne NL\",\"nl-BE\":\"Big Chain Bereiken Campagne BE\"}}",
"title_localised":"Big Chain Bereiken Campagne NL"
},
{
"type":"cashback",
"title":"Big Chain Rewards Programme",
"description":"Earn 5% rewards points every time you spend at Big Chain",
"actions":[
],
"earn_percentage":5,
"is_contributor":false,
"saved_amount":10.00,
"saved_amount_currency":"ZAR",
"saved_amount_currency_symbol":"R",
"supports_contribution":true,
"total_amount":10.00,
"campaign_id":60,
"unlocked_amount":0,
"image_filename":null,
"image_url":null,
"image_link":null,
"image_dimension_x":null,
"image_dimension_y":null,
"field_localisations":"{\"title\":{\"en\":{\"default\":\"Big Chain Rewards Campaign\",\"en-UK\":\"Big Chain Rewards Campaign UK\",\"en-US\":\"Big Chain Rewards Campaign US\"},\"nl\":{\"default\":\"Big Chain Rewards Campagne\",\"nl-NL\":\"Big Chain Rewards Campagne NL\",\"nl-BE\":\"Big Chain Rewards Campagne BE\"}}",
"title_localised":"Big Chain Rewards Campagne NL"
}
],
"basket":[
],
"product":[
],
"referral":[
{
"type":"referral",
"campaign_id":451,
"title":"Invite Friends!",
"description":"Invite friends and you will both earn rewards.",
"currency":"EUR",
"currency_symbol":"€",
"supports_contribution":false,
"is_contributor":false,
"image_url":"https://s3.eu-west-1.amazonaws.com/campaign-images-test01.spaaza.com/451/4.png",
"actions":[
],
"code":"uyamct"
}
],
"signup":[
{
"type":"signup",
"title":"Big Chain Signup Bonus",
"description":"Receive a R100 voucher to spend when you join.",
"actions":[
],
"signup_amount":100.00,
"title_localised":"Big Chain Inschrijfbonus",
"voucher_text_localised":"Uw R11 bonusvoucher"
}
],
"loyalty":[
{
"id":198,
"chain_id":1752,
"title":"Big Chain Loyalty",
"description":"The best loyalty programme",
"active":true,
"created_date":"2017-08-02T15:18:52+00:00",
"last_modified_date":"2017-08-02T15:18:52+00:00",
"currency_id":2,
"voucher_text":"Your Big Chain loyalty voucher",
"myprice_app_id":21,
"loyalty_rules":[
{
"id":5,
"campaign_id":198,
"title":"Points tracker rule for creating basket voucher",
"action":"createBasketVoucher",
"direction":"up",
"points_threshold":100.00,
"action_amount":5.00,
"action_is_repeatable":true,
"action_expiry_unit":"month",
"action_expiry_quantity":2,
"operand_campaign_id":140,
"type":"points_tracker"
},
{
"id":7,
"campaign_id":198,
"title":"Set level rule for joining programme",
"level":"bronze",
"loyalty_level_id":1,
"action":"setLevel",
"action_is_repeatable":false,
"type":"initial",
"loyalty_level_name":"bronze"
},
{
"id":8,
"campaign_id":198,
"title":"Rule for levelling up to silver in the programme",
"level":"silver",
"loyalty_level_id":2,
"action":"setLevel",
"direction":"up",
"points_threshold":250,
"action_is_repeatable":false,
"type":"points_tracker",
"loyalty_level_name":"silver"
},
{
"id":26,
"campaign_id":392,
"title":"ACME Wallet Review",
"description":"Subtract points threshold current level if balance above",
"action":"addPointsToWallet",
"direction":"down",
"action_is_repeatable":false,
"operand_campaign_id":140,
"type":"review"
}
],
"loyalty_levels":[
{
"id":1,
"campaign_id":159,
"name":"bronze",
"description":"Initial level in programme"
},
{
"id":2,
"campaign_id":159,
"name":"silver",
"description":"Second level in programme"
}
],
"is_active":true,
"type":"loyalty",
"created_voucher_claimed_by_default":false,
"supports_user_segments":false,
"user_segment_id":null,
"field_localisations":"{\"title\":{\"en\":{\"default\":\"Big Chain Loyalty Campaign\",\"en-UK\":\"Big Chain Loyalty Campaign UK\",\"en-US\":\"Big Chain Loyalty Campaign US\"},\"nl\":{\"default\":\"Big Chain Loyaliteitscampagne\",\"nl-NL\":\"Big Chain Loyaliteitscampagne NL\",\"nl-BE\":\"Big Chain Loyaliteitscampagne BE\"}}",
"title_localised":"Big Chain Loyaliteitscampagne NL",
"voucher_text_localised":"Uw Big Chain loyaltiteitsvoucher"
}
]
},
"points":{
"id":140,
"chain_id":1752,
"title":"Big Chain Points Wallet",
"description":"Points wallet the ultimate",
"active":true,
"operator_type":"or",
"created_date":"2017-08-02T14:32:22+00:00",
"last_modified_date":"2017-08-02T14:32:22+00:00",
"currency_id":5,
"max_manual_daily_amount":200.00,
"spend_on_promotional_items":true,
"balance_can_subzero":true,
"is_active":true,
"type":"points_wallet",
"parameters":[
],
"rounding_strategy":"round_down",
"rounding_precision":2,
"secondary_display_currency":"PTN",
"secondary_display_currency_symbol":"PTN",
"secondary_display_multiplication_factor":40,
"secondary_display_rounding_precision":0,
"created_voucher_claimed_by_default":false,
"is_redeemable":false,
"saved_amount":442,
"total_amount":442,
"currency":"PTS",
"currency_symbol":"pts",
"field_localisations":"{\"title\":{\"en\":{\"default\":\"Big Chain Points Wallet\",\"en-UK\":\"Big Chain Points Wallet UK\",\"en-US\":\"Big Chain Points Wallet US\"},\"nl\":{\"default\":\"Big Chain Puntenwallet\",\"nl-NL\":\"Big Chain Puntenwallet NL\",\"nl-BE\":\"Big Chain Puntenwallet BE\"}}",
"title_localised":"Big Chain Puntenwallet NL"
},
"wallet":{
"id":81,
"chain_id":1752,
"title":"Big Chain Money Wallet",
"description":"This is where your Big Chain rewards end up.",
"notes":"",
"active":true,
"created_date":"2017-05-18T13:31:38+00:00",
"last_modified_date":"2017-05-20T13:06:28+00:00",
"voucher_text":"",
"voucher_expiry_days":0,
"balance_can_subzero":true,
"spend_on_promotional_items":false,
"max_manual_daily_amount":200.00,
"is_active":true,
"type":"wallet",
"parameters":[
],
"rounding_strategy":"neutral",
"rounding_precision":2,
"secondary_display_currency":"PTN",
"secondary_display_currency_symbol":"PTN",
"secondary_display_multiplication_factor":40,
"secondary_display_rounding_precision":0,
"created_voucher_claimed_by_default":true,
"saved_amount":0,
"total_amount":0,
"currency":"ZAR",
"currency_symbol":"R",
"field_localisations":"{\"title\":{\"en\":{\"default\":\"Big Chain Money Wallet\",\"en-UK\":\"Big Chain Money Wallet UK\",\"en-US\":\"Big Chain Money Wallet US\"},\"nl\":{\"default\":\"Big Chain Monetairewallet\",\"nl-NL\":\"Big Chain Monetairewallet NL\",\"nl-BE\":\"Big Chain Monetairewallet BE\"}}",
"title_localised":"Big Chain Monetairewallet NL",
"voucher_text_localised":""
},
"loyalty_status":{
"campaign_id":198,
"name":"silver",
"description":"Second level in programme",
"loyalty_level_id":2,
"points_balance_current":220,
"points_to_proceed_next_level":30,
"points_to_remain_current_level":0,
"last_review_date":"2019-04-04T00:05:22+00:00",
"next_review_date":"2020-04-04T00:05:22+00:00",
"date_reached":"2018-04-21T10:00:10+00:00"
},
"frequency":3,
"recency":5,
"monetary":2,
"overall":532,
"stores":null,
"online_shopper":true,
"offline_shopper":false,
"average_basket_value":"119.30",
"days_since_last_purchase":6,
"number_of_purchases":4,
"referring_user":{
"id":4
},
"notes":[
{
"id":123456,
"text":"Customer was very happy with the new jeans",
"created_date":"2018-05-20T13:06:28+00:00",
"user":{
"user_id":65665
},
"creating_user":{
"user_id":55776,
"first_name":"John",
"last_name":"Doe",
"username":"john@email.com"
}
}
],
"result_type":"get-user-entity-card"
}
]
- Call name: get-card
- Endpoint URL: https://api0.spaaza.com/get-card
- Request methods: GET
- Response Content-Type: application/json
- Auth required: yes
Get the entity card (loyalty memberships) and claimed vouchers (but not those validated by the shop) for a user.
Permissions and Authentication
This API call requires a valid Spaaza session. The session can be as follows:
- User authentication: a session generated by an end-user login.
- Admin authentication: the performing user needs to be logged in and have
read access
to the entity (business or chain) to which the user is connected. - Privileged authentication: the use of privileged authentication is permitted for this endpoint.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
chain_id | (Integer. Required with admin authentication.) The id of the chain for which the information is being requested. |
user_id OR member_number OR username OR authentication_point_identifier | (required with admin and privileged authentication) The id, member_number (user code), username (email address) or identity in a third-party authentication system (authentication_point_identifier) of the user for whom the card details are being requested. |
Headers
The following headers can/must be passed to the API call:
Parameter | Description |
---|---|
X-MyPrice-App-Hostname | (mandatory) The hostname of the app for which the user is requesting the card. |
Accept-Language | (optional) A standard RFC 2616 header defining the ordered language preferences for the request. In the case that this is provided, localised versions of field names are also returned in the response where these are defined. The presence of localised fields is dynamic. If they are not defined in the field_localisations field for the specific object, then localised fields are not returned. |
Permissions
This API call requires no specific permissions other than to view entity card and vouchers associated with the user’s own account.
Possible error responses
The following represents a list of possible error responses for the get-card
endpoint:
Code | Name and Description | HTTP Status Code |
---|---|---|
1 | username_invalidThe username is incorrectly formatted. Your username should be a valid email address. | 400 |
6 | no_valid_sessionThe user needs to be logged in and a valid session key needs to be sent | 401 |
68 | permission_denied_or_non_existentThis user has insufficient permissions for this object or the object does not exist. | 500 |
144 | business_id_not_foundNo record has been found for that business_id | 500 |
149 | fb_access_token_invalidThe fb_access_token passed must be alphanumeric and between 1 and 2048 characters long. | 500 |
154 | user_id_invalidThe user_id passed must be an integer up to 10 digits long | 400 |
217 | chain_id_not_foundNo record has been found for that chain_id | 400 |
228 | auth_method_invalidThe given auth_method parameter has an invalid value. | 500 |
264 | myprice_app_without_entityThe requested MyPrice app does not have an entity associated with it. | 400 |
265 | authorization_invalidThe given authorization header is invalid. | 400 |
267 | no_valid_userA valid username needs to be specified | 401 |
269 | no_myprice_appMyprice app is required | 400 |
270 | user_not_foundNo user was found | 404 |
416 | multiple_parameter_mismatchMultiple parameters supplied when fewer are required | 400 |
424 | access_deniedAccess is denied | 400 |
Creating vouchers
Returns an OK code and returns the details of the created voucher
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"voucher_key": "0df3e1934e277240bd44072f302c75165dab108b6705d48695b38101634274ab",
"voucher_id": 44974,
"voucher_status": "generated",
"campaign_id": 2,
"campaign_title": "20 EUR voucher for every 200 EUR spent",
"voucher_expiry_datetime_utc": "2050-01-01 00:00:00",
"voucher_expiry_seconds_remaining": 1126928505,
"voucher_currency_id": 2,
"voucher_amount": 40,
"voucher_amount_redeemed": null,
"voucher_honour_code": "honour0004",
"voucher_title": "€20 Voucher",
"voucher_text": "Your new voucher, enjoy!",
"voucher_description": "Redeem this voucher in store to get €20 off your purchase.",
"voucher_notes": "Here is the place to put long-form notes such as terms and conditions or instructions for use.",
"voucher_image_url": "https://www.example.com/voucher-image.jpg",
"user_id": 1,
"user_entity_card": {
"type": "regular",
"code": "1"
},
"result_type": "create-voucher"
}
}
Overview
- Call name: create-voucher
- Endpoint URL: https://api0.spaaza.com/create-voucher
- Request methods: POST
- Request Content-Type: multipart/form-data or application/x-www-form-urlencoded
- Response Content-Type: application/json
- Auth required: yes
Creates a basket voucher for use in the next purchase.
Note that currently, this logic only works for vouchers from campaigns of type “wallet” and type “loyalty”.
The create call takes a ‘campaign id’ and a voucher amount.
In the case of a wallet campaign, the user being granted the voucher must have enough balance in the wallet for a voucher to be created.
Permissions and Authentication
This API call requires a valid Spaaza session. The session can be as follows:
- User authentication: a session generated by an end-user login.
- Admin authentication: the performing user needs to be logged in and have
write access
to the entity (business or chain) to which the user is connected. - Privileged authentication: the use of privileged authentication is permitted for this endpoint.
HTTP Parameters
The following HTTP parameters can be passed to the endpoint:
Parameter | Description |
---|---|
campaign_id | (integer, mandatory) The id of the wallet or loyalty campaign. Typically, this id is retrieved from looking at the ‘progress’, ‘wallet’ or ‘loyalty’ sections in the result of the get-card or get-user-vouchers call. |
voucher_amount | (float, mandatory in the case of ‘voucher_type’ being ‘basket’, prohibited in the case of ‘voucher_type’ being ‘basket_pct’) A floating point value greater than 0 and representing the value of the voucher. |
set_claimed | (boolean, optional) A boolean flag. When set to true , the generated voucher gets the voucher_status claimed immediately and will thus be directly used in the next sales transaction. Otherwise, the voucher gets the status generated , and must first be set to claimed in order to be used. |
delete_existing | (boolean, optional) A boolean flag. When set to true , any previous unlocked wallet vouchers will be deleted before creating a new wallet voucher. |
In the case of privileged or admin authentication, the following parameters can/must also be passed to the endpoint:
Parameter | Description |
---|---|
user_id or member_number or authentication_point_identifier | (one mandatory for admin or privileged authentication in the case of ‘voucher_type’ being ‘basket’. The id in the Spaaza system (user_id), member_number (member_number) or identifier in a third-party authentication system (authentication_point_identifier) of the user for whom the permissions details are being requested. |
voucher_type | (string, optional, default ‘basket’) The type of voucher to be created. Possible options are ‘basket’ for a basket voucher, ‘basket_pct’ for a basket percentage voucher and ‘honour’ for an honour voucher |
voucher_discount_ratio | (float, maximum 3 decimal places, mandatory in the case of ‘voucher_type’ being ‘basket_pct’, prohibited in the case of ‘voucher_type’ being ‘basket’) A floating point value representing a decimal discount provided by this voucher. For example, a value of 0.25 represents a 25% discount. |
voucher_lock_period | (integer, optional) The period in seconds for which the voucher should be locked. During this period it cannot be deleted except when redeemed as part of a basket transaction. It is highly recommended to lock the voucher for a period in the case of administrative or privileged authenticationn. The voucher_lock_period can be set to a minimum of 120 and a maximum of 3600 seconds. If no value is passed, the voucher_lock_period is set to a period of 300 seconds. |
voucher_locking_code | (string, optional) If the voucher is locked this parameter ensures it can only be redeemed as part of a basket transaction with a voucher_locking_code matching this one. If a voucher is locked with a voucher_locking_code, it must be redeemed by a basket transaction with a voucher_locking_code matching this value, regardless of the retailer_basket_code value sent. See get-basket-price and add-basket for more details of voucher_locking_code. This value can be an integer sent as a string. |
voucher_title | (string, optional, max 255 char.) A title to be used with the voucher. |
voucher_text | (string, optional, max 255 char.) A text string to be added to the voucher (which may be displayed in a client such as a browser or mobile app). |
voucher_description | (string, optional, max 1024 characters) A longer-form description for the voucher. |
voucher_notes | (string, optional, max 4095 char.) A field of notes to be added to the voucher which can be used for e.g. terms and conditions. |
voucher_honour_code | (string, mandatory with voucher_type ‘honour’, otherwise optional) 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 using the traditional means. |
voucher_image_url | (string, optional) The URL of an image associated with the voucher. |
retailer_basket_code | (string, optional) If the voucher is locked this parameter ensures it can only be redeemed as part of a basket transaction with a retailer_basket_code matching this one. See get-basket-price and add-basket for more details of retailer_basket_code. This value can be an integer sent as a string. |
expiry_date | (date, optional) The date after which the voucher should no longer be valid. This parameter can be in ‘Y-m-d’ date or ‘Y-m-d H:i:s’ format. If ‘Y-m-d’ format is used an expiry date is created using 00:00:00 as the time - e.g. ‘Y-m-d 00:00:00’. All times are in UTC. |
Claiming vouchers
A sample response is shown below.
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"voucher_key": "13918dc12e44bc183cb168fa10684d0714115ff37132d4c265f4a8ab6678a741",
"voucher_id": 35735,
"voucher_status": "claimed",
"voucher_locked": false,
"campaign_id": 136,
"campaign_type": "signup",
"campaign_title": "Earn €5 on signup",
"voucher_expiry_datetime_utc": "2050-01-01 00:00:00",
"voucher_expiry_seconds_remaining": 996899028,
"voucher_currency_id": 2,
"voucher_currency_symbol": "€",
"voucher_amount_original": 5,
"voucher_amount_redeemed": 0,
"voucher_amount": 5,
"voucher_text": null,
"user_id": 1107604,
"user_entity_card": {
"type": "custom",
"code": "404064"
},
"result_type": "claim-voucher"
}
}
Overview
- Call name: claim-voucher
- Endpoint URL: https://api0.spaaza.com/claim-voucher
- Request methods: POST
- Request Content-Type: multipart/form-data or application/x-www-form-urlencoded
- Response Content-Type: application/json
- Auth required: yes
Claims a voucher (variable price or other kind of voucher) which has been offered to a user.
The claim-voucher API allows a user to claim a voucher which has been earned in the get-var-price-user API call or through other voucher generating mechanisms. It uses the voucher_key values supplied to claim the price. Once the price has been claimed, the retailer can verify it using another call.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
voucher_key (string, mandatory*) | The unique voucher key generated for the voucher. This is a string, for instance c4bc4a3115e21e228936f4223dd89b22c238847c935514e1fdcb96f3c75118ac . |
voucher_id (integer, mandatory*) | The unique id generated for the voucher. This is an integer, for instance 4064783 . It is recommended to use the voucher_key parameter if possible. |
user_id required with admin and privileged authentication | The Spaaza user id of the user whose voucher is being claimed. |
chain_id required with admin and privileged authentication | The ID of the Spaaza Chain or Entity`. |
* At least one of the parameters voucher_key
or voucher_id
must be used.
Permissions
This API call requires no specific permissions for the user.
Unclaiming vouchers
Returns an OK code and echoes the updated voucher details including the new
voucher_status
field. A sample is below:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"voucher_key": "a8c34c86c136e5ddf0ad374e140aa1e3504ebbf23d76d84788677268fd99b809",
"voucher_id": 40577,
"voucher_status": "generated",
"voucher_locked": false,
"campaign_id": 2,
"campaign_type": "cashback",
"campaign_title": "20 EUR voucher for every 200 EUR spent",
"voucher_expiry_datetime_utc": "2050-01-01 00:00:00",
"voucher_expiry_seconds_remaining": 1013819756,
"voucher_currency_id": 2,
"voucher_currency_symbol": "\u20ac",
"voucher_amount_original": 20,
"voucher_amount_redeemed": 0,
"voucher_amount": 20,
"voucher_text": "Your new voucher, enjoy!",
"user_id": 1,
"user_entity_card": {
"type": "regular",
"code": "1"
},
"result_type": "unclaim-voucher"
}
}
Overview
- Call name: unclaim-voucher
- Endpoint URL: https://api0.spaaza.com/unclaim-voucher
- Request methods: POST or PUT
- Request Content-Type: multipart/form-data or application/x-www-form-urlencoded
- Response Content-Type: application/json
- Auth required: yes
Unclaims a voucher (variable price or other kind of voucher) which has been claimed by a user.
Permissions and Authentication
This API call requires a valid Spaaza session. The session can be as follows:
- User authentication: a session generated by an end-user login.
- Admin authentication: the performing user needs to be logged in and have
write access
to the entity (business or chain) to which the user is connected. - Privileged authentication: the use of privileged authentication is permitted for this endpoint.
Note that if a voucher is locked it can only be unclaimed using Admin or Privileged authentication.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
voucher_key (mandatory) | The unique voucher key of the voucher. This is a string, for instance c4bc4a3115e21e228936f4223dd89b22c238847c935514e1fdcb96f3c75118ac . |
user_id required with admin and privileged authentication | The Spaaza user id of the user whose voucher is being claimed. |
chain_id required with admin and privileged authentication | The ID of the Spaaza Chain or Entity`. |
Permissions
This API call requires write permissions for the user in the case of admin authentication.
Locking vouchers
Returns an OK code and returns the details of the locked voucher:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"voucher_key": "0df3e1934e277240bd44072f302c75165dab108b6705d48695b38101634274ab",
"voucher_id": 44974,
"voucher_status": "claimed",
"campaign_id": 2,
"campaign_title": "20 EUR voucher for every 200 EUR spent",
"voucher_expiry_datetime_utc": "2050-01-01 00:00:00",
"voucher_expiry_seconds_remaining": 1126928505,
"voucher_currency_id": 2,
"voucher_amount": 20,
"voucher_amount_redeemed": null,
"voucher_text": "Your new voucher, enjoy!",
"voucher_locked_until": "2018-10-16 15:54:01",
"voucher_locking_code": "lock4001",
"voucher_retailer_basket_code_exclusive": "RCPT401075452002",
"user_id": 1,
"user_entity_card": {
"type": "regular",
"code": "1"
},
"result_type": "lock-voucher"
}
}
Overview
- Call name: lock-voucher
- Endpoint URL: https://api0.spaaza.com/lock-voucher
- Request methods: PUT
- Request Content-Type: multipart/form-data or application/x-www-form-urlencoded (optional instead of DELETE params)
- Response Content-Type: application/json
- Auth required: yes
Lock a voucher which has already been created. Optionally add a period of time during which the voucher will be locked.
Note that currently, this logic only works for vouchers of type “basket voucher”.
Permissions and Authentication
This API call requires a valid Spaaza session. The session can be as follows:
- User authentication: a session generated by an end-user login.
- Admin authentication: the performing user needs to be logged in and have
write access
to the chain to which the voucher is connected. - Privileged authentication: the use of privileged authentication is permitted for this endpoint.
HTTP Parameters
The following HTTP parameters can be passed to the endpoint:
Parameter | Description |
---|---|
voucher_key (string, mandatory*) | The key of the voucher which is being locked. Typically, this information is retrieved from looking at the ‘progress’ or ‘wallet’ promotions in the result of the get-user-vouchers call. |
voucher_id (integer, mandatory*) | The ID of the voucher which is being locked. |
* At least one of the parameters voucher_key
or voucher_id
must be used.
In the case of admin authentication, the following parameters can/must also be passed to the endpoint:
Parameter | Description |
---|---|
retailer_basket_code | (string, optional) this parameter ensures that, once the voucher is locked, it can only be redeemed during the lock period as part of a basket transaction with a retailer_basket_code matching this one. See get-basket-price and add-basket for more details of retailer_basket_code. This value can be an integer sent as a string. |
voucher_locking_code | (string, optional) this parameter ensures that, once the voucher is locked, it can only be redeemed as part of a basket transaction with a voucher_locking_code matching this one. If a voucher is locked with a voucher_locking_code, it must be redeemed by a basket transaction with a voucher_locking_code matching this value, regardless of the retailer_basket_code value sent. See get-basket-price and add-basket for more details of voucher_locking_code. This value can be an integer sent as a string. |
voucher_lock_period | The period in seconds for which the voucher should be locked. During this period it cannot be deleted except when redeemed as part of a basket transaction. It is highly recommended to lock the voucher for a period in the case of administrative login. The voucher_lock_period can be set to a minimum of 120 and a maximum of 3600 seconds. If no value is passed, the voucher_lock_period is set to a period of 300 seconds. |
Unlocking vouchers
A sample response is shown below.
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"voucher_key": "13918dc12e44bc183cb168fa10684d0714115ff37132d4c265f4a8ab6678a741",
"voucher_id": 35735,
"voucher_status": "claimed",
"voucher_locked": false,
"campaign_id": 136,
"campaign_type": "signup",
"campaign_title": "Earn €5 on signup",
"voucher_expiry_datetime_utc": "2050-01-01 00:00:00",
"voucher_expiry_seconds_remaining": 996899028,
"voucher_currency_id": 2,
"voucher_currency_symbol": "€",
"voucher_amount_original": 5,
"voucher_amount_redeemed": 0,
"voucher_amount": 5,
"voucher_text": null,
"user_id": 1107604,
"user_entity_card": {
"type": "custom",
"code": "404064"
},
"result_type": "unlock-voucher"
}
}
Overview
- Call name: unlock-voucher
- Endpoint URL: https://api0.spaaza.com/unlock-voucher
- Request methods: PUT or POST
- Request Content-Type: multipart/form-data or application/x-www-form-urlencoded
- Response Content-Type: application/json
- Auth required: yes
Unlocks a basket voucher which has been locked.
The unlock-voucher API allows a client operating with admin or privileged authentication to unlock a locked voucher. When a voucher is unlocked, any locking associated with a particular retailer_basket_code
is also removed.
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
to the entity (business or chain) to which the user is connected. - Privileged authentication: the use of privileged authentication is permitted for this endpoint.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
voucher_key (string, mandatory*) | The unique voucher key of the voucher. This is a string, for instance c4bc4a3115e21e228936f4223dd89b22c238847c935514e1fdcb96f3c75118ac . |
voucher_id (integer, mandatory*) | The unique id generated for the voucher. This is an integer, for instance 4064783 . This can be used instead of voucher_key although it is recommended to use the voucher_key parameter if possible. If both are supplied the voucher_key value is used. |
* At least one of the parameters voucher_key
or voucher_id
must be used.
Expiring vouchers
Returns an OK code and echoes the ID of the variable price voucher key supplied. A sample is shown below:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"result_type": "expire-voucher",
"voucher_key": "c4bc4a3115e21e228936f4223dd89b22c238847c935514e1fdcb96f3c75118ac"
}
}
Overview
- Call name: expire-voucher
- Endpoint URL: https://api0.spaaza.com/expire-voucher
- Request methods: POST, PUT
- Response Content-Type: application/json
- Auth required: yes
The expire-voucher API sets the expiry date of a voucher which has status “claimed” to the current time, hence expiring the voucher.
Permissions and Authentication
This API call requires a valid Spaaza session. The session can be as follows:
Parameter | Description |
---|---|
user | A session generated by an end-user login. |
or | |
admin | A session generated by administrative user login. |
or | |
privileged | An OAuth-based mechanism for trusted third-parties. |
Note that if admin authentication is used and the admin user does not have sufficient permissions to expire the voucher, an error will be generated.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
voucher_key (string, mandatory*) | The unique key of the voucher which is being expired. This is a string, for instance c4bc4a3115e21e228936f4223dd89b22c238847c935514e1fdcb96f3c75118ac . |
voucher_id (integer, mandatory*) | The ID of the voucher which is being expired. |
user_id (required with admin and privileged authentication) | The (Spaaza) id of the user/member/shopper to whom the voucher is assigned. |
chain_id (required with privileged authentication - see description) | The chain_id of the retailer with which the user/member/shopper is associated. This parameter is only required with privileged authentication, and is not required if the X-MyPrice-App-Hostname header is passed with the request (see Headers section). |
* At least one of the parameters voucher_key
or voucher_id
must be used.
Headers
The following headers can/must be passed to the API call:
Parameter | Description |
---|---|
X-MyPrice-App-Hostname required with privileged authentication (see description) | The hostname of the app for which the user is requesting the card. Only required with privileged authentication, and not required if the chain_id parameter is passed in the request (see HTTP Parameters section). |
Permissions
For user authentication this API call requires no specific permissions other than that the session should be for the user associated with the variable price voucher. For admin authentication this API requires that the admin user has DELETE permissions for their own retailer entity.
Deleting vouchers
Returns an OK code and echoes the ID of the variable price voucher key supplied. A sample is shown below:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"result_type": "delete-voucher",
"voucher_key": "c4bc4a3115e21e228936f4223dd89b22c238847c935514e1fdcb96f3c75118ac"
}
}
Overview
- Call name: delete-voucher
- Endpoint URL: https://api0.spaaza.com/delete-voucher
- Request methods: DELETE
- Response Content-Type: application/json
- Auth required: yes
The delete-voucher API allows a user to delete a variable price voucher or other type of voucher which has status “claimed” (i.e. which has not yet been set to “verified” when verified by the retailer).
Permissions and Authentication
This API call requires a valid Spaaza session. The session can be as follows:
Parameter | Description |
---|---|
user | A session generated by an end-user login. |
or | |
admin | A session generated by administrative user login. |
or | |
privileged | An OAuth-based mechanism for trusted third-parties. |
Note that if admin authentication is used and the admin user does not have sufficient permissions to delete the voucher, an error will be generated.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
voucher_key (string, mandatory*) | The unique key of the voucher which is being locked. This is a string, for instance c4bc4a3115e21e228936f4223dd89b22c238847c935514e1fdcb96f3c75118ac . |
voucher_id (integer, mandatory*) | The ID of the voucher which is being locked. |
user_id (required with admin and privileged authentication) | The (Spaaza) id of the user/member/shopper to whom the voucher is assigned. |
chain_id (required with privileged authentication - see description) | The chain_id of the retailer with which the user/member/shopper is associated. This parameter is only required with privileged authentication, and is not required if the X-MyPrice-App-Hostname header is passed with the request (see Headers section). |
* At least one of the parameters voucher_key
or voucher_id
must be used.
Headers
The following headers can/must be passed to the API call:
Parameter | Description |
---|---|
X-MyPrice-App-Hostname required with privileged authentication (see description) | The hostname of the app for which the user is requesting the card. Only required with privileged authentication, and not required if the chain_id parameter is passed in the request (see HTTP Parameters section). |
Permissions
For user authentication this API call requires no specific permissions other than that the session should be for the user associated with the variable price voucher. For admin authentication this API requires that the admin user has DELETE permissions for their own retailer entity.
Get all vouchers for a user
An example output is shown below
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"basket_vouchers": [
{
"voucher_key": "13918dc12e44bc183cb168fa10684d0714115ff37132d4c265f4a8ab6678a741",
"voucher_id": 35735,
"voucher_status": "generated",
"voucher_locked": false,
"campaign_id": 136,
"campaign_type": "signup",
"campaign_title": "Earn €5 on signup",
"redeeming_basket": null,
"voucher_expiry_datetime_utc": "2050-01-01 00:00:00",
"voucher_expiry_seconds_remaining": 996901179,
"voucher_currency_id": 2,
"voucher_currency_symbol": "€",
"voucher_amount_original": 5,
"voucher_amount_redeemed": 0,
"voucher_amount": 5,
"voucher_honour_code": "honour0004",
"voucher_title": "€5 Signup Voucher",
"voucher_text": "Your new voucher, enjoy!",
"voucher_description": "Redeem this voucher in store to get €5 off your purchase.",
"voucher_notes": "Terms and conditions apply to the redemption of this voucher. Franchise owners may request proof of identity.",
"voucher_image_url": "https://www.example.com/voucher-image.jpg",
"voucher_type": "basket"
},
{
"voucher_key": "2ea66c08e3f0fa2d45bf62f382bb9fbff237a86fea79e45ede2b1b1328be56f0",
"voucher_id": 30880,
"voucher_status": "generated",
"voucher_locked": false,
"campaign_id": 140,
"campaign_type": "loyalty",
"campaign_title": "ACME Loyalty Campaign",
"redeeming_basket": null,
"voucher_expiry_datetime_utc": "2018-07-30 00:00:00",
"voucher_expiry_seconds_remaining": 5201979,
"creating_user": {
"user_id": 21,
"full_name": "John Doe"
},
"voucher_currency_id": 2,
"voucher_currency_symbol": "€",
"voucher_amount_original": 5,
"voucher_amount_redeemed": 0,
"voucher_amount": 5,
"voucher_title": null,
"voucher_text": "Thanks for being a great customer",
"voucher_description": null
"voucher_notes": "Text on how to use a voucher or other notes go here.",
"voucher_image_url": null,
"voucher_honour_code": "honour004",
"voucher_type": "basket"
},
{
"voucher_key": "4b900509eab95909e2cfcd74a9d039dce1dbbcba40d3463163b965ec1bbfdace",
"voucher_id": 94231,
"voucher_status": "claimed",
"voucher_locked": false,
"campaign_id": 140,
"campaign_type": "loyalty",
"campaign_title": "ACME Loyalty Campaign",
"voucher_expiry_datetime_utc": "2018-07-30 00:00:00",
"voucher_expiry_seconds_remaining": 5201979,
"creating_user": {
"user_id": 21,
"full_name": "John Doe"
},
"voucher_currency_id": 2,
"voucher_currency_symbol": "€",
"voucher_amount_original": 5,
"voucher_amount_redeemed": 0,
"voucher_amount": 5,
"voucher_text": "Thanks for being a great customer",
"voucher_notes": null,
"voucher_title": null,
"voucher_description": null
"voucher_image_url": null,
"voucher_type": "basket"
}
],
"honour_vouchers": [
{
"voucher_key": "138406421b611051c953a620c5f958348bbb045fdf4a7e92c8e9f53ccd04144e",
"voucher_id": 94697,
"voucher_status": "claimed",
"voucher_locked": false,
"campaign_id": 140,
"campaign_type": "loyalty",
"campaign_title": "ACME Loyalty Campaign",
"voucher_expiry_datetime_utc": "2018-07-30 00:00:00",
"voucher_expiry_seconds_remaining": 5201979,
"creating_user": {
"user_id": 21,
"full_name": "John Doe"
},
"voucher_currency_id": 2,
"voucher_currency_symbol": "€",
"voucher_amount_original": 5,
"voucher_amount_redeemed": 4,
"voucher_amount": 5,
"voucher_text": "Thanks for being a great customer",
"voucher_notes": null,
"voucher_title": null,
"voucher_description": "Redeem this voucher online for a free item.",
"voucher_image_url": null,
"voucher_type": "honour",
"voucher_honour_code": "HON00421"
}
],
"var_price_vouchers": [],
"promotions": {
"progress": [
{
"type": "cashback",
"title": "Get extra points at our Amsterdam store",
"description": "",
"actions": [],
"supports_contribution": true,
"is_contributor": true,
"recipient_campaign_id": 117,
"saved_amount": 0,
"saved_amount_currency": "EUR",
"saved_amount_currency_symbol": "€",
"currency": "EUR",
"currency_symbol": "€",
"campaign_id": 143,
"earn_percentage": 5,
"unlocked_amount": 0,
"total_amount": 0
},
{
"type": "simple",
"title": "Earn €10 when you spend €100",
"description": "Get €10 on your wallet when you spend €100",
"actions": [],
"progress": {
"target": 100,
"achieved": 50,
"percentage": 50
},
"supports_contribution": true,
"is_contributor": true,
"recipient_campaign_id": 116,
"currency": "EUR",
"currency_symbol": "€",
"campaign_id": 120,
"reward_money": 10
},
{
"type": "cashback",
"title": "ACME Cashback Contributor",
"description": "3 punten voor iedere €1 aankoop",
"actions": [],
"supports_contribution": true,
"is_contributor": true,
"recipient_campaign_id": 117,
"saved_amount": 0,
"saved_amount_currency": "PTN",
"saved_amount_currency_symbol": "PTN",
"currency": "PTN",
"currency_symbol": "PTN",
"campaign_id": 118,
"earn_percentage": 300,
"unlocked_amount": 0,
"total_amount": 0
}
],
"basket": [],
"product": [],
"affiliate": [],
"signup": [
{
"type": "signup",
"title": "Earn €5 on signup",
"description": "",
"actions": [],
"supports_contribution": true,
"is_contributor": false,
"signup_amount": 5,
"currency": "EUR",
"currency_symbol": "€",
"campaign_id": 136,
"reward_money": 5
},
{
"type": "signup",
"title": "Get 1000 points when you signup",
"description": "",
"actions": [],
"supports_contribution": true,
"is_contributor": true,
"recipient_campaign_id": 117,
"signup_amount": 1000,
"currency": "EUR",
"currency_symbol": "€",
"campaign_id": 121,
"reward_money": 1000
}
],
"birthday": [
{
"type": "birthday",
"title": "50 points on your birthday",
"description": "",
"actions": [],
"supports_contribution": true,
"is_contributor": true,
"recipient_campaign_id": 117,
"gift_amount": 50,
"currency": "EUR",
"currency_symbol": "€",
"campaign_id": 142,
"reward_money": 50,
"days_before": 7
}
],
"limited_cashback_contribution": [],
"loyalty": [
{
"id": 140,
"chain_id": 1743,
"title": "ACME Loyalty Campaign",
"description": "The best fashion loyalty programme",
"active": true,
"created_date": "2018-02-06T08:26:02+00:00",
"last_modified_date": "2018-02-06T08:26:02+00:00",
"created_voucher_claimed_by_default": false,
"currency_id": 2,
"voucher_text": "Your ACME loyalty voucher",
"myprice_app_id": 5,
"loyalty_rules": [],
"loyalty_levels": [],
"is_active": true,
"type": "loyalty",
"recipient_campaign_id": null,
"supports_user_segments": false,
"user_segment_id": null,
"secondary_display_currency": null,
"secondary_display_currency_symbol": null,
"secondary_display_multiplication_factor": null,
"secondary_display_rounding_precision": null
}
]
},
"wallet": {
"id": 116,
"chain_id": 1743,
"title": "ACME Wallet",
"description": "Converted wallet points come here",
"active": true,
"created_date": "2017-10-18T09:39:43+00:00",
"last_modified_date": "2017-10-18T09:39:43+00:00",
"is_redeemable": true,
"voucher_expiry_days": 0,
"balance_can_subzero": true,
"spend_on_promotional_items": true,
"max_manual_daily_amount": "200.00",
"is_active": true,
"type": "wallet",
"parameters": [],
"secondary_display_currency": null,
"secondary_display_currency_symbol": null,
"secondary_display_multiplication_factor": null,
"secondary_display_rounding_precision": null,
"rounding_strategy": "neutral",
"rounding_precision": 2,
"saved_amount": 170,
"total_amount": 170,
"currency": "EUR",
"currency_symbol": "€"
},
"result_type": "get-user-vouchers"
}
}
Overview
- Call name: get-user-vouchers
- Endpoint URL: https://api0.spaaza.com/get-user-vouchers
- Request methods: GET
- Response Content-Type: application/json
- Auth required: yes
The get-user-vouchers API retrieves the applicable vouchers for a user, given the user’s ID or entity card (member) number and the chain ID.
It will return:
-
basket_vouchers
, which are vouchers that are available for use in the next purchase. -
honour_vouchers
, which are vouchers that are used to redeem rewards offers in 3rd party systems -
var_price_vouchers
, which are vouchers for a specific product (Personal Pricing) -
promotions
, which are hints to the user that certain types of discount are available. -
wallet
, wallet information for users where the retailer has a wallet enabled.
Permissions and Authentication
This API call requires valid Spaaza authentication. The authentication can be as follows:
- User authentication: a session generated by an end-user login.
- Admin authentication: the performing user needs to be logged in and have
read access
to the entity (chain) to which the user is connected. - Privileged authentication: the use of privileged authentication is permitted for this endpoint.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
chain_id required for admin and privileged authentication | The id of the chain for which the information is being requested. |
user_id or member_number required for admin and privileged authentication | The id or member_number (user code) of the user for whom the voucher details are being requested. |
filter optional all | when set to all redeemed or ‘used’ vouchers will also be returned in the response together with expired vouchers that were not used. |
Output
The promotions
section contain hints to the user that a certain voucher or reward is available, for instance when buying this product in
combination with another product.
The voucher_key
(or voucher_id
) parameter needs to be sent to Spaaza in an add-basket post in order to redeem the voucher. Note that only vouchers with a status of claimed
can be redeemed. To claim a voucher use the claim-voucher endpoint (and to unclaim use the unclaim-voucher endpoint).
Use filter
:all
to get vouchers back that have already been redeemed or expired. If this parameter is not included only available vouchers are returned.
Get all vouchers for a chain
Sample JSON output is shown below:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"results_count_total": 654,
"vouchers": [
{
"voucher_key": "bb1e45cbd6d174164b77a58047779e8d0323fa9c61ac994d84223343c531334e",
"voucher_id": 5,
"voucher_created_datetime": "2019-08-02T15:18:52+00:00",
"voucher_status": "claimed",
"voucher_locked": false,
"campaign_id": 3,
"campaign_type": "birthday",
"campaign_title": "ACME birthday campaign",
"redeeming_basket": null,
"voucher_expiry_datetime_utc": "2050-01-01 00:00:00",
"voucher_expiry_seconds_remaining": 990857543,
"voucher_currency_id": 2,
"voucher_currency_symbol": "€",
"voucher_amount_original": 33,
"voucher_amount_redeemed": 0,
"voucher_amount": 33,
"voucher_text": null,
"voucher_honour_code": null,
"voucher_title": "ACME birthday voucher",
"voucher_description": "This voucher deserves a good length of description, but not too long",
"voucher_notes": "Terms and conditions: this voucher is issued within a few days before your recorded birthday, and can be used in any participating store or online within one week after issue.",
"voucher_image_url": "https://acme.example.com/images/voucher_image_birthday.jpg",
"type": "basket",
"user": {
"id": 6,
"user_id": 6,
"first_name": "Chewy",
"last_name": "Bacca",
"username": "chewy@bacca.example.com",
"authentication_point_identifier": null,
"auxiliary_identifier": "peb402xar",
"mailing_list": null,
"entity_code": {
"type": "custom",
"code": null
},
"opt_in_programme": {
"programme_opted_in": true,
"join_date": "2018-04-01T18:22:31+00:00"
},
"signup_channel": null,
"country_code": null,
"address_streetname": null,
"address_housenumber": null,
"address_housenumber_extension": null,
"address_line_2": null,
"address_line_3": null,
"address_towncity": null,
"address_regionstate": null,
"address_postalcode": null
}
},
{
"voucher_key": "8422190c7d04e8a06b15abacb710dae654c2387f22fc3eacfdb5d0724a4e49f1",
"voucher_id": 4,
"voucher_created_datetime": "2019-09-02T15:18:52+00:00",
"voucher_status": "claimed",
"voucher_locked": false,
"campaign_id": 3,
"campaign_type": "loyalty",
"campaign_title": "ACME loyalty campaign",
"redeeming_basket": null,
"voucher_expiry_datetime_utc": "2050-01-01 00:00:00",
"voucher_expiry_seconds_remaining": 990857543,
"voucher_currency_id": null,
"voucher_currency_symbol": null,
"voucher_amount_original": null,
"voucher_amount_redeemed": 0,
"voucher_amount": null,
"voucher_text": null,
"voucher_honour_code": "HON00432",
"type": "honour",
"voucher_title": "ACME loyalty honour voucher",
"voucher_description": "This voucher has a fairly long description, not too long though",
"voucher_notes": "Terms and conditions: this voucher is issued when you make your first purchase, and can be redeemed in store for a free tee-shirt.",
"voucher_image_url": "https://acme.example.com/images/voucher_image_honour.jpg",
"user": null
}
],
"result_type": "get-vouchers"
}
}
Sample CSV file output is shown below:
voucher_id,voucher_key,voucher_status,type,voucher_created_datetime,voucher_expiry_datetime,voucher_redeemed_datetime,voucher_locked,voucher_locked_until_datetime,voucher_retailer_basket_code_exclusive,voucher_amount,voucher_amount_redeemed,voucher_text,voucher_currency_code,voucher_currency_symbol,campaign_id,campaign_type,campaign_title,customer_spaaza_user_id,customer_member_number,customer_username,customer_first_name,customer_last_name,customer_mailing_list_subscribed,customer_printed_mailing_list_subscribed,voucher_redeeming_basket_id,voucher_redeeming_basket_retailer_basket_code,voucher_redeeming_basket_platform_type,voucher_redeeming_basket_branch_business_id,voucher_redeeming_basket_branch_business_owner_code,voucher_redeeming_basket_total_value,voucher_locking_code,voucher_honour_code,voucher_title,voucher_description,voucher_image_url
4,8422190c7d04e8a06b15abacb710dae654c2387f22fc3eacfdb5d0724a4e49f1,generated,basket,2018-05-05T17:59:11+00:00,2018-07-09T17:59:11+00:00,,0,,,5.00,0,Your voucher,EUR,€,219,signup,"Signup voucher",3355122,134014,georgina@cheeky.example.com,Georgina,Goodhope,1,,,,,,,,,,"Loyalty Signup Voucher","Thanks for signing up","https://acme.example.com/images/signup_voucher.jpg"
5,bb1e45cbd6d174164b77a58047779e8d0323fa9c61ac994d84223343c531334e,generated,basket,2018-05-05T17:44:36+00:00,2018-07-09T17:44:36+00:00,,0,,,5.00,0,Your voucher,EUR,€,219,signup,"Signup voucher",3354924,133816,chewy@bacca.example.com,Chewy,Bacca,1,,,,,,,,,,,,
6,8e4efe3f4afc0d26d69235c931b0f374c1a7b30d3ba043cd4332f689efccce77,generated,honour,2018-05-05T17:44:36+00:00,2018-07-09T17:44:36+00:00,,0,,,,0,Your voucher,EUR,,,loyalty,"Signup voucher",3354924,133816,chewy@bacca.example.com,Chewy,Bacca,1,,,,,,,,,"HONOUR004","Loyalty Honour Voucher","Voucher issued after two purchases","https://acme.example.com/images/honour_voucher.jpg"
Overview
- Call name: get-vouchers
- Endpoint URL: https://api0.spaaza.com/get-vouchers or https://api0.spaaza.com/get-vouchers.csv
- Request methods: GET
- Response Content-Type: application/json OR application/force-download with CSV file download
- Auth required: yes
The get-vouchers API endpoint returns all unredeemed basket vouchers for a chain, given the chain ID. It is possible to pass parameters to the endpoint so that it shows all redeemed vouchers, all vouchers for a particular campaign or vouchers matching various other parameters (see below).
When called without a suffix at the end of the URL or with a .json
suffix the endpoint will return:
vouchers
, which are vouchers that are used for a basket-level discount.
When called via the endpoint URL ending in .csv
the endpoint will automatically set the response content-type to application/force-download
and respond with a downloadable CSV file. Please see the section entitled “CSV Response Fields” below.
Note that the response is streamed, the API server does not buffer vouchers and wait until all are processed before sending.
Versioning-specific information
The following version-specific changes apply to this endpoint.
Version | Change details |
---|---|
>= 1.4.2 | Previous name of basket_vouchers array in response JSON changed to vouchers . |
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
read access
to the entity (business or chain) to which the user is connected. - Privileged authentication: the use of privileged authentication is permitted for this endpoint.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
chain_id (integer) required | The id of the chain for which the information is being requested. |
campaign_id (integer) optional | The Spaaza ID of a campaign. If supplied only vouchers will be returned which are associated with the specified campaign. |
user_id (integer) optional | The Spaaza ID of a particular user. Adding this parameter only returns vouchers associated with that user ID. |
exclude_regenerated (boolean) optional | If this flag is set to true, no vouchers are returned if they have been automatically generated when a purchased item is returned and the value of an original voucher redeemed on the item is regenerated into a new voucher. |
show_redeemed (boolean) optional | Return only vouchers which have been redeemed. The default is to show only unredeemed vouchers (status claimed and status generated ). Note that searching for redeemed vouchers causes the show_expired parameter and any expiry_datetime parameters to be overridden - all vouchers are shown, regardless of whether (un)expired. |
max_redeemed_datetime (ISO-8601 extended timestamp) optional, requires show_redeemed | The ISO-8601 extended datetime of the latest date/time for which redeemed vouchers are to be shown. This includes the offset from GMT/UTC in hours (and minutes). Valid examples: “2018-09-19T14:05:20+00:00”, “2018-09-19T08:05:20-06:00”, “2018-09-19T14:05:20Z” |
min_redeemed_datetime (ISO-8601 extended timestamp) optional, requires show_redeemed | The ISO-8601 extended datetime of the earliest date/time for which redeemed vouchers are to be shown. This includes the offset from GMT/UTC in hours (and minutes). Valid examples: “2018-09-19T13:27:56+00:00”, “2018-09-19T07:27:56-06:00”, “2018-09-19T13:27:56Z” |
show_all_statuses (boolean) optional | Return vouchers which are in any status, either generated , claimed or redeemed . This parameter overrides the show_redeemed , min_redeemed_datetime and max_redeemed_datetime parameters. |
show_expired (boolean) optional | Return only vouchers which have expired. The default is to show only unexpired vouchers (vouchers where the expiry date/time is greater than the current moment in time). Note that using the show_redeemed parameter causes this parameter to be ignored and the endpoint to return both expired and unexpired vouchers which are redeemed. This is because the expiry date of a voucher may be after the voucher was redeemed. |
min_created_datetime (ISO-8601 extended timestamp) optional | The ISO-8601 extended datetime of the earliest date/time of creation for which vouchers are to be shown. This includes the offset from GMT/UTC in hours (and minutes). Valid examples: “2018-09-19T13:27:56+00:00”, “2018-09-19T07:27:56-06:00”, “2018-09-19T13:27:56Z” |
min_created_datetime_relative (string) optional, overrides min_created_datetime | A string representing, relative to the current time, the earliest date/time of creation for which vouchers are to be shown. Includes (combinations of) integer numbers of months, days, hours and minutes. Valid examples: “7 days”, “-13 weeks”, “-6 months 5 days -2 minutes” |
max_created_datetime (ISO-8601 extended timestamp) optional | The ISO-8601 extended datetime of the latest date/time of creation for which vouchers are to be shown. This includes the offset from GMT/UTC in hours (and minutes). Valid examples: “2018-09-19T14:05:20+00:00”, “2018-09-19T08:05:20-06:00”, “2018-09-19T14:05:20Z” |
max_created_datetime_relative (string) optional, overrides max_created_datetime | A string representing, relative to the current time, the latest date/time of creation for which vouchers are to be shown. Includes (combinations of) integer numbers of months, days, hours and minutes. Valid examples: “+6 days”, “3 weeks”, “+6 months -5 days +2 minutes” |
min_expiry_datetime (ISO-8601 extended timestamp) optional | The ISO-8601 extended datetime of the earliest expiry date/time for which vouchers are to be shown. This includes the offset from GMT/UTC in hours (and minutes). Valid examples: “2018-09-19T13:27:56+00:00”, “2018-09-19T07:27:56-06:00”, “2018-09-19T13:27:56Z” |
min_expiry_datetime_relative (string) optional, overrides min_expiry_datetime | A string representing, relative to the current time, the earliest expiry date/time for which vouchers are to be shown. Includes (combinations of) integer numbers of months, days, hours and minutes. Valid examples: “7 days”, “-13 weeks”, “-6 months 5 days -2 minutes” |
max_expiry_datetime (ISO-8601 extended timestamp) optional | The ISO-8601 extended datetime of the latest expiry date/time for which vouchers are to be shown. This includes the offset from GMT/UTC in hours (and minutes). Valid examples: “2018-09-19T14:05:20+00:00”, “2018-09-19T08:05:20-06:00”, “2018-09-19T14:05:20Z” |
max_expiry_datetime_relative (string) optional, overrides max_expiry_datetime | A string representing, relative to the current time, the latest expiry date/time for which vouchers are to be shown. Includes (combinations of) integer numbers of months, days, hours and minutes. Valid examples: “+6 days”, “3 weeks”, “+6 months -5 days +2 minutes” |
number_results (integer) optional | The (maximum) number of results required in the response. The default action for CSV output is to return all possible vouchers. For JSON output the maximum number of results returned for a single request is 500. |
results_offset (integer) optional | The result number at which to start. For example, if there are 1000 vouchers, giving a results_offset of 500 will start at voucher 500. Numbering starts at 0. |
Output
The output contains information about vouchers and the users they are associated with.
JSON Response Fields
In addition to an object representing each voucher, the JSON response contains a field entitled results_count_total
which returns the number of vouchers matching the query parameters regardless of the number_results
or results_offset
values used.
CSV Response Fields
When called via the endpoint URL ending in .csv
the endpoint returns a downloadable CSV file named vouchers.csv
. The CSV file contains a header row in the first line followed by a single line per voucher.
The fields shown below are represented in the CSV file in the order shown. Unpopulated fields follow CSV convention and are left blank. Fields containing special characters are surrounded by double quotes - e.g. "String with spaces"
- following CSV convention. Other fields may be added to the CSV file in future, and these will be added at the end of each line.
Field | Description |
---|---|
voucher_id (integer) | The unique ID of the voucher in the Spaaza system. |
voucher_key (string) | The unique voucher key of the voucher. |
voucher_status (string) | The status of the voucher. Possible values are “generated”, “claimed” or “redeemed”. |
type (string) | The type of voucher. Currently this endpoint only returns vouchers of type “basket” and “basket_pct”. |
voucher_created_datetime (ISO-8601 timestamp) | The date and time the voucher was created. |
voucher_expiry_datetime (ISO-8601 timestamp) | The date and time the voucher is set to expire. |
voucher_redeemed_datetime (ISO-8601 timestamp) | The date and time the voucher was redeemed (if the voucher has status “redeemed”). |
voucher_locked (boolean) | Whether the voucher is currently locked. |
voucher_locked_until_datetime (ISO-8601 timestamp) | The date and time the voucher lock period expires if the voucher is locked. This field remains populated even when a lock period has expired and the voucher is no longer locked. |
voucher_retailer_basket_code_exclusive (string) | Any text string which has been chosen by the retailer in order to identity individual promotions or vouchers in an external system. |
voucher_amount (float) | The monetary value of the voucher. This remains unchanged even in cases where the voucher is only partially redeemed. |
voucher_amount_redeemed (float) | The monetary amount of the voucher which was redeemed. |
voucher_text (string) | Any text describing the voucher. |
voucher_currency_code (string, ISO-4217 currency code) | The ISO-4217 three-letter currency code of the voucher currency, e.g. “EUR” or “ZAR”. |
voucher_currency_symbol (string, ISO-4217 currency symbol) | The ISO-4217 three-letter currency code of the voucher currency, e.g. “EUR” or “ZAR”. |
campaign_id (integer) | The unique ID in the Spaaza system of the Spaaza campaign associated with the voucher. |
campaign_type (string) | The type of Spaaza campaign associated with the voucher, e.g. “wallet”, “basket” or “loyalty” |
campaign_title (string) | The title of the Spaaza campaign associated with the voucher. |
customer_spaaza_user_id (integer) | The unique ID in the Spaaza system of the |
customer_member_number (string) | The unique membership number or code for the shopper within the membership or loyalty programme. In most cases this is numeric, but string values are allowed. |
customer_authentication_point_identifier (string) | The ID of the user in a third party webshop or other identity system. |
customer_username (string, email address) | The username (email address) of the user. |
customer_first_name (string) | The first name of the customer. |
customer_last_name (string) | The last name of the customer. |
customer_mailing_list_subscribed (boolean) | Whether the user is subscribed to the mailing list if there is one. |
customer_printed_mailing_list_subscribed (boolean) | Whether the user is subscribed to the printed mailing list if there is one. |
voucher_redeeming_basket_id (integer) | The unique ID in the Spaaza system of the basket (transaction) with which the voucher was redeemed, in the case the voucher status is redeemed. |
voucher_redeeming_basket_retailer_basket_code (string) | The identifier in the retailer’s system used to identify the particular basket/transaction with which the voucher was redeemed, in the case the voucher status is redeemed. This field usually represents a receipt or order number. |
voucher_redeeming_basket_platform_type (string) | The type of platform of the particular basket/transaction with which the voucher was redeemed, in the case the voucher status is redeemed. This field is usually either “in_store” or “online”. |
voucher_redeeming_basket_branch_business_id (integer) | The unique ID in the Spaaza system of the retail branch at which the purchase basket/transaction with which the voucher was redeemed happened, in the case the voucher status is redeemed. |
voucher_redeeming_basket_branch_business_owner_code (string) | The retailer branch code of the retail branch at which the purchase basket/transaction with which the voucher was redeemed happened, in the case the voucher status is redeemed. |
voucher_redeeming_basket_total_value (float) | The total cash value of the particular basket/transaction with which the voucher was redeemed, in the case the voucher status is redeemed. |
voucher_locking_code (string) | Any locking code associated with a voucher. In the case that the voucher is in a claimed state, it can only be redeemed by a basket or redemption call supplying this locking code. |
voucher_honour_code (string) | A third party code used to allow third parties such as POS devices or web stores to decide whether to redeem (“honour”) a voucher. For example, a voucher_honour_code could flag a promotion running on a POS in a store. |
voucher_title (string) | A title used with the voucher. |
voucher_description (string) | A longer-form description for the voucher. |
voucher_image_url (string, URL) | The URL of an image associated with the voucher. |
voucher_discount_ratio (float) | The discount ratio of the voucher, denoting the percentage discount it may offer on a purchase. |
Adding a (points) wallet amount manually
Returns an OK code and a JSON representation of the newly created user purchase progress record. A sample is below:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"result_method": "post",
"username": "john.doe@spaaza.com",
"params": {
"user_id": "1334972",
"campaign_id": "57",
"amount": "5.25",
"log_message": "Adding a value"
},
"user_purchase_progress": {
"id": 17499239,
"user_id": 1334972,
"currency_id": 2,
"amount": "5.25",
"progress_type": "Manual",
"log_message": "Adding an amount manually",
"created_date": "2015-02-20T13:40:24+00:00",
"mutation_owner_id": 1
},
"result_type": "add-user-purchase-progress"
}
}
Overview
- Call name: add-user-purchase-progress
- Endpoint URL: https://api0.spaaza.com/auth/add-user-purchase-progress
- Request methods: POST
- Auth required: yes
Introduction
This API call adds a points or monetary wallet amount to the wallet of a specified user.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
user_id or username or member_number or authentication_point_identifier | (integer, one mandatory) the ID in the Spaaza system (user_id - integer), email address (username - email address), member number (member_number - string, normally numeric) or identity in a third-party authentication system (authentication_point_identifier - string) of the user to whose (points) wallet the amount is to be added. |
campaign_id | (integer, mandatory) the ID of the campaign of the (points) wallet. |
amount | (integer, mandatory) the currency amount to be added (positive value) to or subtracted (negative value) from the user’s cashback account. This amount should have maximum two (2) decimal places. |
log_message | (string, mandatory) a text log message used for recording why the amount was added or subtracted. |
Permissions and Authentication
This API call requires valid Spaaza authentication. The following authentication schemes are permitted:
- Admin authentication: the performing user needs to be logged in and have
write access
to the entity (business or chain) to which the user is connected. - Privileged authentication: the use of privileged authentication is permitted for this endpoint.
Wallet or points history
An example response with the wallet history for a customer (“type” parameter is “wallet”)
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"ledger": [
{
"date": "2017-05-30T11:06:10+00:00",
"currency_symbol": "€",
"amount": 25.05,
"receipt_id": 327597,
"retailer_basket_code": "testtransaction0001",
"campaign_type": "cashback",
"campaign_title": "Earn as you spend",
"campaign_title_localised": "Verdien punten van je aankopen",
"kind": "campaignContribution"
},
{
"date": "2017-05-30T11:05:05+00:00",
"currency_symbol": "€",
"amount": -9,
"receipt_id": null,
"retailer_basket_code": null,
"campaign_type": "wallet",
"campaign_title": "Example Campaign",
"campaign_title_localised": "Voorbeeld Campagne",
"kind": "voucherRedemption"
},
{
"date": "2017-05-29T15:27:08+00:00",
"currency_symbol": "€",
"amount": 25.05,
"receipt_id": 327596,
"retailer_basket_code": "testtransaction0002",
"campaign_type": "cashback",
"campaign_title": "Earn as you spend",
"campaign_title_localised": "Verdien punten van je aankopen",
"kind": "campaignContribution"
},
{
"date": "2016-05-02T12:35:06+00:00",
"currency_symbol": "€",
"amount": 2.3,
"receipt_id": null,
"retailer_basket_code": null,
"campaign_type": "manual",
"campaign_title": "Manual addition of wallet funds",
"kind": "manual"
}
],
"result_type": "user-wallet-ledger"
}
}
An example response with the points history for a customer (“type” parameter is “points”)
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"type": "points_wallet",
"ledger": [
{
"date": "2017-10-05T15:15:34+00:00",
"currency_symbol": "PTN",
"amount": 750,
"receipt_id": 331293,
"retailer_basket_code": "testtransaction0003",
"campaign_type": "cashback",
"campaign_title": "ACME Cashback Contributor",
"kind": "campaignContribution"
},
{
"date": "2017-10-05T15:12:35+00:00",
"currency_symbol": "PTN",
"amount": 200,
"receipt_id": null,
"retailer_basket_code": null,
"campaign_type": "signup",
"campaign_title": "Welkom bij ACME loyalty",
"campaign_title_localised": "Welcome to ACME loyalty",
"kind": "campaignContribution"
}
],
"result_type": "user-wallet-ledger"
}
}
An example response showing points and wallet contributions (no type parameter passed)
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"type": "points_wallet",
"ledger": [
{
"date": "2017-10-05T15:15:34+00:00",
"currency_symbol": "PTN",
"amount": 750,
"receipt_id": 331293,
"retailer_basket_code": "testtransaction0003",
"campaign_type": "cashback",
"campaign_title": "ACME Cashback Contributor",
"kind": "campaignContribution"
},
{
"date": "2017-10-05T15:12:35+00:00",
"currency_symbol": "PTN",
"amount": 200,
"receipt_id": null,
"retailer_basket_code": null,
"campaign_type": "signup",
"campaign_title": "Welkom bij ACME loyalty",
"kind": "campaignContribution"
},
{
"date": "2017-10-05T15:12:35+00:00",
"currency_symbol": "PTN",
"amount": 200,
"receipt_id": null,
"retailer_basket_code": null,
"campaign_type": "signup",
"campaign_title": "Welkom to the program",
"kind": "campaignContribution"
}
],
"result_type": "user-wallet-ledger"
}
}
Overview
- Call name: user-wallet-ledger
- Endpoint URL: https://api0.spaaza.com/user-wallet-ledger
- Request methods: GET
- Response Content-Type: application/json
- Auth required: yes
The user-wallet-ledger API retrieves the contributions that have been made to that user’s Spaaza Points balance and/or Spaaza Wallet. Points or Wallet contributions can happen as a result of a campaign in Spaaza, a manual adjustment by a staff member or as a result of the user spending a portion of a saved wallet amount. The list is returned in reverse chronological order.
It will return each “contribution” with the following data:
-
date
, the date and time the contribution was made in ISO8601 format including timezone offset from UTC. -
currency_symbol
, the currency symbol for the contribution. -
amount
, the value of the contribution (can be positive or negative). -
receipt_id
, the id of the transaction that resulted in the contribution (can also be null if the contribution was not as a result of a transaction). -
retailer_basket_code
, the identifier in the retailer’s system of the transaction that resulted in the contribution (can also be null if the contribution was not as a result of a transaction). -
campaign_type
, the type of campaign that caused the contribution, this will be one of ‘cashback’, ‘wallet’ or ‘manual’. -
campaign_title
, the name of the campaign that caused the contribution or the reason for a manual change to a wallet. -
kind
, the type of event that caused the contribution, this will be one of ‘campaignContribution’, ‘voucherRedemption’ or ‘manual’.
Versioning-specific information
The following version-specific changes apply to this endpoint.
Version | Change details |
---|---|
>= 1.4.1 | date fields in the response are returned in ISO8601 format including timezone offset from UTC instead of the former YYYY-MM-DD HH:MM:SS format. |
Permissions and authentication
This API call requires a valid Spaaza session. The session can be as follows:
- User authentication: a session generated by an end-user login.
- Admin authentication: the performing user needs to be logged in and have
read access
to the entity (business or chain) to which the user is connected. - Privileged authentication: the use of privileged authentication is permitted for this endpoint.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
chain_id required for admin authentication | The id of the chain for which the information is being requested. |
user_id OR member_number OR authentication_point_identifier required with admin or privileged authentication | The Spaaza unique ID (user_id), member_number (user code) or identity in a third-party authentication system (authentication_point_identifier) of the user for whom the wallet ledger is being requested. |
type | By default all contributions are returned for both the Wallet and Points balance. If you only want wallet contributions use “wallet”. If you only want points contributions use “points”. |
Headers
The following headers can/must be passed to the API call:
Parameter | Description |
---|---|
X-MyPrice-App-Hostname | (mandatory in the case of user authentication) The hostname of the app for which the user is requesting the card. |
Accept-Language | (optional) A standard RFC 2616 header defining the ordered language preferences for the request. In the case that this is provided, localised versions of field names are also returned in the response where these are defined. The presence of localised fields is dynamic. If they are not defined in the field_localisations field for the specific object, then localised fields are not returned. |
Possible error responses
The following represents a list of possible error responses for the user-wallet-ledger
endpoint:
Code | Name and Description | HTTP Status Code |
---|---|---|
6 | no_valid_sessionThe user needs to be logged in and a valid session key needs to be sent | 401 |
68 | permission_denied_or_non_existentThis user has insufficient permissions for this object or the object does not exist. | 500 |
154 | user_id_invalidThe user_id passed must be an integer up to 10 digits long | 400 |
217 | chain_id_not_foundNo record has been found for that chain_id | 400 |
228 | auth_method_invalidThe given auth_method parameter has an invalid value. | 500 |
264 | myprice_app_without_entityThe requested MyPrice app does not have an entity associated with it. | 400 |
265 | authorization_invalidThe given authorization header is invalid. | 400 |
266 | access_token_invalidThe given access token is invalid. | 401 |
267 | no_valid_userA valid username needs to be specified | 401 |
269 | no_myprice_appMyprice app is required | 400 |
270 | user_not_foundNo user was found | 404 |
405 | entity_mismatchThe entities or chains supplied do not match | 400 |
416 | multiple_parameter_mismatchMultiple parameters supplied when fewer are required | 400 |
Voucher webhook
An example of a new voucher webhook
{
"type": "shopper.voucher-issued",
"id": "5b63362028701",
"chain_id": 1743,
"created": "2018-08-02T16:49:36Z",
"data": {
"campaign_id": 1927,
"campaign_title": "Welcome Gift Voucher",
"campaign_type": "signup",
"type": "basket",
"user": {
"address_housenumber": null,
"address_housenumber_extension": null,
"address_line_2": null,
"address_line_3": null,
"address_postalcode": null,
"address_regionstate": null,
"address_streetname": null,
"address_towncity": null,
"authentication_point_identifier": "66141993",
"auxiliary_identifier": "get7566ota",
"birthday": "1988-05-06T00:00:00+00:00",
"country_code": "NL",
"first_name": "Sam",
"gender": "M",
"id": 34348394,
"last_name": "Critchley",
"loyalty_status": {
"campaign_id": 2095,
"name": "Level 1",
"description": "Level 1 in the Programme",
"loyalty_level_id": 2,
"points_balance_current": 220,
"points_to_proceed_next_level": 30,
"points_to_remain_current_level": 0,
"last_review_date": "2019-04-04T00:05:22+00:00",
"next_review_date": "2020-04-04T00:05:22+00:00",
"date_reached": "2019-06-06T08:06:14+00:00"
},
"mailing_list": {
"mailing_list_sub_offered": false,
"mailing_list_subscribed": true,
"printed_mailing_list_subscribed": false
},
"member_number": {
"code": "30359901",
"type": "custom"
},
"opt_in_programme": {
"programme_opted_in": true
},
"registered": true,
"signup_channel": "webshop",
"user_id": 34348394,
"username": "acmestage691228534@cowcam.com"
},
"voucher_amount": 5,
"voucher_amount_original": 5,
"voucher_amount_redeemed": 0,
"voucher_currency_id": 2,
"voucher_currency_symbol": "€",
"voucher_expiry_datetime_utc": "2018-10-11 16:49:35",
"voucher_expiry_seconds_remaining": 6047999,
"voucher_id": 80470,
"voucher_key": "11f52d2f1adcd8708db0f13e64f9acac108d782d070bbe7746481cad66df1d69",
"voucher_locked": false,
"voucher_status": "claimed",
"voucher_text": "New Acme Club Member"
}
}
Spaaza can call an external webhook when a customer voucher is created for a customer.
We can configure a webhook URL that you provide. Whenever the voucher-issued event occurs we send a simple POST request to the URL. The body of the POST is JSON that includes details of the event and the voucher that triggered it. So that you can verify that the POST really originates from Spaaza we provide a signature in a request header (X-Spaaza-Hmac-SHA256).
The value of the header is a base 64 encoded HMAC-SHA256 of the whole body of the request with a shared secret that we would provide. Your code to handle the event should recreate the signature using the shared secret and compare it to the value in the header.
Points or wallet webhook
An example of a points mutation webhook
{
"type": "shopper.points-mutation",
"id": "5b63362028701",
"chain_id": 1743,
"created": "2019-01-04T16:53:36Z",
"data": {
"amount": "10.00",
"basket": {
"created_date": "2019-05-17T09:56:34+00:00",
"id": 432440,
"retailer_basket_code": "20190517-test-00039",
"total_value": 235
},
"campaign": {
"campaign_id": 170,
"campaign_image_dimension_x": null,
"campaign_image_dimension_y": null,
"campaign_image_filename": null,
"campaign_image_link": null,
"campaign_image_url": null,
"campaign_title": "ACME Wallet",
"campaign_title_localised": "ACME Portemonnaie NL",
"campaign_type": "wallet",
"contributing_campaign": null
},
"created_date": "2019-05-17T10:23:03+00:00",
"currency_id": 2,
"earn_or_spend": "earn",
"receipt_id": null,
"returned_item": null,
"timestamp_microsecond": "2019-05-17 10:23:04.026549",
"type": "handleLoyaltyRule",
"user": {
"address_housenumber": null,
"address_housenumber_extension": null,
"address_line_2": null,
"address_line_3": null,
"address_postalcode": null,
"address_regionstate": null,
"address_streetname": null,
"address_towncity": null,
"authentication_point_identifier": "1180626",
"auxiliary_identifier": "eab465uxp41",
"birthday": "1981-04-29T00:00:00+00:00",
"country_code": null,
"first_name": "John",
"gender": "M",
"id": 3141779,
"language": "nl-BE",
"last_name": "Doe",
"loyalty_status": {
"campaign_id": 2095,
"name": "Level 1",
"description": "Level 1 in the Programme",
"loyalty_level_id": 2,
"points_balance_current": 230,
"points_to_proceed_next_level": 270,
"points_to_remain_current_level": 20,
"last_review_date": "2019-04-04T00:05:22+00:00",
"next_review_date": "2020-04-04T00:05:22+00:00",
"date_reached": "2019-06-06T08:06:14+00:00"
},
"mailing_list": {
"mailing_list_sub_offered": true,
"mailing_list_subscribed": true,
"printed_mailing_list_subscribed": false
},
"member_number": {
"code": "100130",
"type": "custom"
},
"opt_in_programme": {
"programme_opted_in": true,
"join_date": "2019-06-06T08:06:14+00:00"
},
"opt_in_secondary": null,
"push_notification_subscription": {
"subscribed": false,
"subscriptions": []
},
"registered": true,
"signup_channel": null,
"user_id": 3141779,
"username": "john.doe@spaaza.com"
},
"user_id": 3141779,
"user_purchase_progress": {
"id": 203676,
"log_message": "Loyalty contribution from addPointsToWallet:points_tracker",
"mutation_owner": null,
"uniqid": "5f637ba2de54a2.06408515"
},
"voucher": {
"creating_user": {
"full_name": "Jane Smit",
"user_id": 1
},
"generating_return_transaction": [],
"parent_voucher": null,
"voucher_amount": 2,
"voucher_amount_original": 2,
"voucher_amount_redeemed": 2,
"voucher_currency_id": 2,
"voucher_currency_symbol": "\u20ac",
"voucher_expiry_datetime_utc": "2020-01-01 00:00:00",
"voucher_expiry_seconds_remaining": 966521006,
"voucher_id": 119498,
"voucher_key": "1d5375bc6471b845503728775f3c8c58eed43a123e71ce3d6356d17bab24146c",
"voucher_locked": false,
"voucher_redeemed_datetime": "2019-05-17T09:56:34+00:00",
"voucher_status": "redeemed",
"voucher_text": "ACME wallet voucher",
"voucher_text_localised": "ACME puntenwallet voucher"
}
}
}
Spaaza can call an external webhook when a points or wallet amount is awarded or removed for a customer.
We can configure a webhook URL that you provide. Whenever the points-mutation event occurs we send a simple POST request to the URL. The body of the POST is JSON that includes details of the event and the points award or removal that triggered it. So that you can verify that the POST really originates from Spaaza we provide a signature in a request header (X-Spaaza-Hmac-SHA256).
The value of the header is a base 64 encoded HMAC-SHA256 of the whole body of the request with a shared secret that we would provide. Your code to handle the event should recreate the signature using the shared secret and compare it to the value in the header.
Baskets
Requesting an adjusted basket
Introduction
- 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 transction 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.
Authentication and Permissions
Note that in order for authentication to work properly the following HTTP headers must also be passed:
Request Header | Description |
---|---|
session_user_id | The user_id of the user with permissions to upload the basket. |
session_key | The key for the login session associated with the user. |
The values for these headers can be acquired by calling the login
authentication API call with the correct authentication details.
Permissions
This API call requires the following permissions scenarios: Write permissions for the entity on behalf of which the call is being made.
Uploading baskets for anonymous users
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.
JSON POST Request
The JSON file posted to the API call should be in the following format:
{
"entity": {
"entity_type": "chain",
"entity_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": 2703.85,
"basket_timestamp_iso8601": "2017-07-27T07:48:45+02:00",
"basket_timezone_name": "Europe/Amsterdam",
"basket_country_code": "NL",
"shipping_charge": 8.75,
"payment_methods": [
{
"payment_method": "cash",
"payment_amount": 2000
},
{
"payment_method": "mastercard",
"payment_amount": 703.85
}
],
"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,
"item_price": 250.00,
"basket_voucher_distribution": [
{
"voucher_key": "ac189592441c9c4e4d0a0f5be03216f6a7e026f0d482c44a293da8e373163fd0",
"voucher_id": 70994555,
"voucher_distribution_amount": 25.00
}
]
},
{
"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
}
]
}
}
The JSON file posted to the API call should be in the following format.
Identifying the Retailer (entity)
Field | Description |
---|---|
entity required | Details of the retailer which is submitting the basket. |
entity_type required | The type of entity of the retailer. If the retailer is a chain with branches, this will be “chain”. If the retailer is an independent business with a single branch, this will be “business”. |
entity_id required | The Spaaza ID of the retailer entity. |
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_id takes precedence. If the basket_platform_type is “in_store” and this value is not supplied, nor is a valid branch_business_id supplied, then the basket is recorded as a basket for the chain with no branch business_id 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. |
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_id takes precedence. If the basket_platform_type is “in_store” and this value is not supplied, nor is a valid branch_business_owner_code supplied, 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. |
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, 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) 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, 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. |
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 and is not used for calculating timestamps but for returning timestamp names in API responses. |
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. |
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)
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 . |
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 inventory item. The inventory_barcode must already be included in the Spaaza inventory system if the product is to be recognised. 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) The type of item in the basket. Possible values are “product”, “gift_certificate” and “shipping”. If this parameter is missing then “product” will be assumed. |
item_is_promotional | (boolean, optional) Can be set true or false to override any existing Spaaza record of whether an item is on promotion. If this parameter is missing a default value of false is applied. |
excluded_from_spaaza | (boolean, optional) Can be set true or false to override any existing Spaaza record of whether an item is on promotion. If this parameter is missing a default value of false is applied. |
item_quantity | (integer, optional) The quantity of an item. If this parameter is not supplied the quantity is assumed to be 1. |
item_price | (float, mandatory) The gross price being charged for the single-quantity item. Note that this does not change if the quantity is increased. |
item_subtotal | (float, optional) The subtotal of the basket item - this is usually item_price multiplied by item_quantity. If this parameter is not supplied a default value of item_price multipled by item_quantity is applied. |
product_name | The name of the product. |
Basket-Level Discounts (basket_voucher_distribution)
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 also applied at the basket item level using a “basket_voucher_distribution” method.
Normally the distribution of the value 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 to be distributed across this item. In the case that this is not supplied, the automatic distribution method 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_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. |
JSON POST Response
A JSON response to the POST is sent in the following format:
{
"entity": {
"entity_type": "chain",
"entity_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",
"basket_country_code": "NL",
"retailer_basket_code": "70401",
"voucher_locking_code": "locking4001",
"basket_total_price": 2703.85,
"shipping_charge": 8.75,
"payment_methods": [
{
"payment_method": "cash",
"payment_amount": 2000
},
{
"payment_method": "mastercard",
"payment_amount": 653.85
}
],
"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,
"item_price": 79.95,
"item_subtotal": 224.85,
"item_is_promotional": true,
"is_identified": true,
"excluded_from_spaaza": false,
"item_vouchers": [
{
"voucher_key": "a1df45e129dbae150c0bb01559a0b286cb7716f2426f381f5c49c642699af1b3",
"voucher_id": 989343244,
"voucher_amount": 5.00
}
]
},
{
"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.00,
"item_is_promotional": false,
"is_identified": true,
"excluded_from_spaaza": false,
"basket_voucher_distribution": [
{
"voucher_key": "ac189592441c9c4e4d0a0f5be03216f6a7e026f0d482c44a293da8e373163fd0",
"voucher_id": 84345653543
"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",
"retailer_item_code": "line_2",
"item_quantity": 1,
"item_price": 750.00,
"item_is_promotional": false,
"is_identified": true,
"excluded_from_spaaza": false,
"basket_voucher_distribution": [
{
"voucher_key": "ac189592441c9c4e4d0a0f5be03216f6a7e026f0d482c44a293da8e373163fd0",
"voucher_id": 84345653543,
"voucher_distribution_amount": 25.00,
}
]
},
{
"item_barcode": "2913458434455",
"retailer_item_code": "line_3",
"item_quantity": 1,
"item_price": 979.00,
"item_is_promotional": true,
"is_identified": true,
"excluded_from_spaaza": false
}
],
"basket_vouchers_applied": [
{
"voucher_key": "ac189592441c9c4e4d0a0f5be03216f6a7e026f0d482c44a293da8e373163fd0",
"voucher_id": 84345653543,
"voucher_status": "claimed",
"voucher_locked": true,
"campaign_id": 76,
"campaign_type": "cashback",
"campaign_title": "Store Rewards",
"voucher_expiry_datetime_utc": "2050-01-01 00:00:00",
"voucher_expiry_seconds_remaining": 1082711675,
"voucher_currency_id": 2,
"voucher_currency_symbol": "€",
"voucher_amount_original": 50,
"voucher_amount_redeemed": 50,
"voucher_amount": 50,
"voucher_text": "",
"voucher_type": "basket",
"voucher_basket_owner_code_exclusive": "70401",
"voucher_locking_code": "locking_4001",
"voucher_honour_code": "honour0004"
}
],
"honour_vouchers_applied": [
{
"voucher_key": "ae8887274d771c676eeab406fddaa9c523875044d029ac91b8ac219f43e9972b",
"voucher_id": 84345653544,
"voucher_status": "claimed",
"voucher_locked": true,
"campaign_id": 79,
"campaign_type": "loyalty",
"campaign_title": "ACME loyalty",
"voucher_expiry_datetime_utc": "2050-01-01 00:00:00",
"voucher_expiry_seconds_remaining": 1082711675,
"voucher_currency_id": null,
"voucher_currency_symbol": null,
"voucher_amount_original": 0,
"voucher_amount_redeemed": 0,
"voucher_amount": 0,
"voucher_text": "",
"voucher_type": "honour",
"voucher_basket_owner_code_exclusive": "70401",
"voucher_locking_code": "locking_4001",
"voucher_honour_code": "honour0008"
}
],
"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
}
],
"supplementary_basket_codes": [
"2023334434434343434",
"arf5546hu00223333333"
],
"basket_total_price_adjusted": 2653.85
}
}
The response can be described as follows:
Identifying the retailer
Field | Description |
---|---|
entity required | Details of the retailer which is submitting the basket. |
entity_type required | The type of entity of the retailer. If the retailer is a chain with branches, this will be “chain”. If the retailer is an independent business with a single branch, this will be “business”. |
entity_id required | The Spaaza ID of the retailer entity. |
branch_business_owner_code | A retailer-specifc branch code used by the retailer to identify individual branches in a chain. If the branch_business_id value is also supplied, then branch_business_id takes precedence. If the basket_platform_type is “in_store” and this value is not supplied, nor is a valid branch_business_id supplied, then the basket is recorded as a basket for the chain with no branch business_id associated with it and a warning is returned. If the basket_platform_type is “online” this field is not mandatory. |
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_id takes precedence. If the basket_platform_type is “in_store” and this value is not supplied, nor is a valid branch_business_owner_code supplied, 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. |
employee_name | The name of a retailer employee associated with the transaction. This information is commonly used on electronic receipts and in analytics. |
Shopper Information (user)
In the case that an identified 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). |
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. |
send_email_receipt | Whether the shopper should receive an email receipt if this service is activated for the retailer. |
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 | 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 | 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. |
Describing the 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. |
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_total_price required | 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 |
shipping_charge | The amount paid by the customer for any shipping fees. |
payment_method | The method used to pay for the transaction. |
basket_notes | Any text notes the retailer wishes to add for future analytics purposes. These are stored by Spaaza and can be retrieved later. |
Items in the Basket (basket_items)
Field | Description |
---|---|
basket_items | The list of items in the basket. Each item must contain either a product_id or a product_owner code value to identify the product in the Spaaza system. For products for which a MyPrice voucher has been supplied, the product_id value must be supplied. If both are supplied, product_id overrides retailer_product_code. Alternatively, you can specify a product by giving either its inventory_id or its inventory_owner_code (typically a bar code). Use of inventory id/owner code overrides the use of product id / owner code. Other values are optional. |
spaaza_product_id | The Spaaza product_id of the item sold. Note that, for products for which a MyPrice voucher has been applied to the price of the product, this value (or an inventory_owner_code or inventory_id value) must be supplied or the sale will not be registered properly for analytics purposes. |
product_name | The name of the product. |
retailer_product_code | The product ID used by the retailer (the “product owner”) to identify the basket item. The retailer_product_code must already be included in the Spaaza system if the product is to be recognised. |
retailer_item_code | Any retailer-specific code applied by the retailer to the basket item. |
spaaza_product_variant_id | The Spaaza product variant ID of the item sold. This will be used to look up the product for the basket item. |
retailer_product_variant_code | The product variant code used by the retailer to identify the product variant for the item in the basket. |
item_type | The type of item in the basket. Possible values are “product”, “gift_certificate” and “shipping”. If this is missing then “product” will be assumed. |
item_is_promotional | Can be set true or false to override any existing Spaaza record of whether an item is on promotion. |
item_barcode | The barcode used by the retailer to identify the inventory item. The inventory_barcode must already be included in the Spaaza inventory system if the product is to be recognised. For basket items where this value is used, it is not necessary to supply a product_id. |
item_quantity | The quantity of an item. If this is not supplied the quantity is assumed to be 1. |
item_price | The adjusted gross price being charged for the single-quantity item. Note that this does not change if the quantity is increased. |
item_subtotal | The subtotal of the basket item - this is usually item_price multiplied by item_quantity |
Item-Level Discounts (item_vouchers)
Many Spaaza campaigns used by members result in item-level discounts being applied. These are referred to as “vouchers” in Spaaza’s vocabulary. These are represented at the basket item level in the response by the item_vouchers section.
Field | Description |
---|---|
item_vouchers | A list of vouchers which are applied at the item level. Note that the values supplied are for a single quantity of the item. |
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 - can be used instead of voucher_key . |
voucher_amount | The monetary value of the item voucher applicable for a single quantity of the basket item. |
Basket-Level Discounts (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 also applied at the basket item level using a “basket_voucher_distribution” method. This is explained in this section.
Details of the basket-level voucher
Field | Description |
---|---|
basket_vouchers_applied | A list of any basket-level discounts which are applied to this 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_id | A unique voucher ID generated by Spaaza and used to identify a voucher and tie it to a member and a 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_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. |
campaign_id | The Spaaza ID of the 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. |
campaign_title | The title of the Spaaza promotional campaign which is being applied. |
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_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_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_amount | An amount equating to voucher_amount_redeemed value above. |
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_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_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_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. |
Distribution of the basket voucher over each basket item
Field | Description |
---|---|
basket_voucher_distribution | A list of basket-level vouchers which are applied to this purchase. |
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
Distribution of the amount earned in a progress campaign over each basket item
Field | Description |
---|---|
purchase_progress_distribution | An amount of purchase progress from a purchase progress campaign which are applied to this purchase. |
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. |
Purchase Progress (purchase_progress)
Any amounts earned in progress campaigns such as balance-based loyalty rewards or spending target-based programmes are recorded in this section of the response.
Field | Description |
---|---|
purchase_progress | Progress made in spending or progress campaigns on a per-campaign basis. This progress is also shown distributed on a per item basis in this response. |
purchase_progress_campaign_id | The Spaaza ID of a progress campaign. |
purchase_progress_campaign_title | The name or title of a progress campaign. |
purchase_progress_campaign_type | The type of campaign such as ‘cashback’ or ‘progress’. |
purchase_progress_amount | The amount of currency earned. |
Processing Returns
The (simplified) JSON below illustrates an item being returned in the same basket as a sale item, with annotation of fields/parameters not explained elsewhere on this page:
{
"entity": {
"entity_type": "chain",
"entity_id": "1739",
"branch_business_owner_code": "0123"
},
"user": {
"member_programme": "spaaza",
"member_number": "123456"
},
"basket": {
"basket_platform_type": "in_store",
"retailer_basket_code": "50000123456",
"basket_currency": {
"currency_code": "EUR"
},
"basket_tax": [{
"tax_rate": 21,
"tax_total": 4.69
}],
"basket_total_price": 27.00,
"basket_items": [
{
"item_barcode": "2000053021012",
"item_quantity": 1,
"item_price": 68.00
},
{
"item_barcode": "4000053029999",
"item_quantity": 1,
"return_item": true,
"item_price": -41.00,
"original_retailer_basket_code": "500002016088"
}
]
}
}
{
"user": {
"member_number": "123456"
},
"basket": {
"chain_id": 1739,
"basket_platform_type": "in_store",
"currency_id": 2,
"basket_total_price": 27.00,
"retailer_basket_code": "50000123456",
"basket_items": [],
"basket_vouchers_applied": [],
"return_transactions": [{
"basket_id": 338467,
"returned_items": [{
"item_id": 6157023,
"return_price": -41.00,
"quantity": 1,
"owner_code": null,
"sale_price": 41.00
}]
}],
"purchase_progress": null,
"basket_total_price_adjusted": 27.00
}
}
Returned items can be handled inline in the same basket JSON by flagging items in the basket as return items. It is possible for a return item to be the only item in a basket, or mixed with other purchased items (and other returned items).
POSTing Return Items
Field | Description |
---|---|
basket_total_price | The total cash price paid for the basket. It is possible for this value to be negative if the price of items being returned is greater than the price of items being purchased. |
return_item | A boolean value indicating that this is an item being returned - set this to true for a return item. |
item_price | The single-quantity price of the item. In the case of a return, this is usually negative. |
original_retailer_basket_code | The retailer_basket_code (transaction ID or number) of the basket in which the item was originally purchased. Note that if there were also supplementary_basket_code values POSTed with the original basket then it is possible to use those instead. If both fields are supplied then the original_retailer_basket_code takes precedence. |
original_supplementary_basket_code | One of the supplementary_basket_code values of the basket in which the item was originally purchased. |
Response to POSTed Return Items
Field | Description |
---|---|
return_transactions | An array of return transactions in a basket. Items from different original retailer baskets are separated into individual return transactions. |
basket_id | The Spaaza basket ID of the original purchase transaction. |
returned_items | An array of individual returned items. |
item_id | The original Spaaza item ID of the returned item. |
return_price | The price at which the item is being returned. |
sale_price | The price at which the item is originally sold. |
Adding a completed basket
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.
Authentication and Permissions
Note that in order for authentication to work properly the following HTTP headers must also be passed:
Field | Description |
---|---|
session_user_id | The user_id of the user with permissions to upload the basket. |
session_key | The key for the login session associated with the user. |
The values for these headers can be acquired by calling the login
authentication API call with the correct authentication details.
Permissions
This API call requires the following permissions scenarios: Write permissions for the entity on behalf of which the call is being made.
Creating baskets
curl "https://api0.spaaza.com/auth/add-basket"
An example POST to add a basket
{
"entity": {
"entity_type": "chain",
"entity_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",
"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,
"item_price": 79.95,
"item_subtotal": 224.85,
"item_is_promotional": true,
"item_vouchers": [
{
"voucher_key": "a1df45e129dbae150c0bb01559a0b286cb7716f2426f381f5c49c642699af1b3",
"voucher_amount": 5.00
}
]
},
{
"retailer_product_code": "WBGT0234",
"retailer_item_code": "line_1",
"item_type": "product",
"item_quantity": 3,
"excluded_from_spaaza": false,
"item_price": 250.00,
"basket_voucher_distribution": [
{
"voucher_key": "ac189592441c9c4e4d0a0f5be03216f6a7e026f0d482c44a293da8e373163fd0",
"voucher_distribution_amount": 25.00
}
]
},
{
"item_barcode": "2913458439012",
"retailer_item_code": "line_2",
"item_quantity": 1,
"item_price": 750.00,
"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.00,
"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",
"currency_id": 2,
"basket_total_price": 2653.85,
"shipping_charge": 8.75,
"basket_timestamp_iso8601": "2017-07-27T07:48:45+02:00",
"basket_timezone_name": "Europe/Amsterdam",
"basket_country_code": "NL",
"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,
"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
}
],
"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,
"business": {
"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,
"basket_item_quantity": 1,
"retailer_item_code": "abcdef",
"basket_item_subtotal": 234.33
}
]
}
},
"result_type": "add-basket"
}
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.
Fields in the POSTed JSON
Identifying the Retailer (entity)
Details of the retailer which is submitting the basket.
Field | Description |
---|---|
entity_type required | The type of entity of the retailer. If the retailer is a chain with branches, this will be “chain”. If the retailer is an independent business with a single branch, this will be “business”. |
entity_id required | The Spaaza ID of the retailer entity. |
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_id takes precedence. If the basket_platform_type is “in_store” and this value is not supplied, nor is a valid branch_business_id supplied, then the basket is recorded as a basket for the chain with no branch business_id 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. |
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_id takes precedence. If the basket_platform_type is “in_store” and this value is not supplied, nor is a valid branch_business_owner_code supplied, 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. |
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, 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, 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, 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, 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. |
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 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 | The “tz database” timezone name - e.g. “Europe/Amsterdam” or “EST”. Note this field is optional. If the basket_timezone_name field does not the timezone offset in the basket_timestamp_iso8601 field, |
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 response describing the single or multiple methods used to pay for the basket.
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 |
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 inventory item. The inventory_barcode must already be included in the Spaaza inventory system if the product is to be recognised. 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) | Any retailer-specific code applied by the retailer to the basket item. |
item_type (string) | The type of item in the basket. Possible values are “product”, “gift_certificate” and “shipping”. If this is missing then “product” will be assumed. |
item_is_promotional (boolean) | Can be set true or false to override any existing Spaaza record of whether an item is on promotion. |
excluded_from_spaaza (boolean) | Can be set true or false to override any existing Spaaza record of whether an item is on promotion. |
item_quantity (integer) | The quantity of an item. If this is not supplied the quantity is assumed to be 1. |
item_price (float) | The original gross price being charged for the single-quantity item. Note that this does not change if the quantity is increased. Note also that if vouchers are being redeemed, this value does not reduce. |
item_subtotal (float) | The subtotal of the basket item - this is usually item_price multiplied by item_quantity |
product_name | The name of the product. |
Item-Level Discounts (item_vouchers)
Many Spaaza campaigns used by members result in item-level discounts being applied. These are referred to as “vouchers” in Spaaza’s vocabulary. These are represented at the basket item level in the response by the item_vouchers section.
Field | Description |
---|---|
item_vouchers | A list of vouchers which are applied at the item level. Note that the values supplied are for a single quantity of the item. |
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. This can be used instead of voucher_key . |
voucher_amount | The monetary value of the item voucher applicable for a single quantity of the basket item. |
Basket-Level Discounts (basket_vouchers)
Discounts, standalone vouchers or loyalty reward redemptions which are calculated at the basket level (such as 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) are termed “basket vouchers” in the Spaaza basket. A basket voucher can be redeemed by specifying the unique “voucher_key” of the voucher in the “basket_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 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 | A unique voucher key for each basket voucher to be redeemed. |
voucher_id | A unique voucher ID for each basket 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.
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.
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_missingThis script is missing some required variables which must be submitted. | 400 |
6 | no_valid_sessionThe user needs to be logged in and a valid session key needs to be sent | 401 |
68 | permission_denied_or_non_existentThis user has insufficient permissions for this object or the object does not exist. | 500 |
183 | voucher_not_foundNo voucher has been found matching this voucher_key or voucher_id. | 404 |
228 | auth_method_invalidThe given auth_method parameter has an invalid value. | 500 |
231 | currency_not_foundThe given currency passed must exist in the list of currencies available | 500 |
252 | basket_currency_missingThe basket_currency information is missing from the basket. | 500 |
262 | app_platform_type_not_allowedThe app_platform_type submitted is not permitted. | 400 |
265 | authorization_invalidThe given authorization header is invalid. | 400 |
266 | access_token_invalidThe given access token is invalid. | 401 |
267 | no_valid_userA valid username needs to be specified | 401 |
309 | original_basket_item_not_foundCould 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_valueA return item must have negative value | 400 |
337 | basket_platform_type_unrecognisedThe basket_platform_type or app_platform_type is missing or unrecognised. | 400 |
407 | calculation_errorThere has been a calculation error | 400 |
Creating Products and Product Variants
It is possible to use the basket_items
array in the add-basket
API endpoint to create a store of item metadata which can then be used
to form segments used in Spaaza campaigns, populate item names on e-receipts and apps, and show performance using Spaaza’s analytics. For
example, Spaaza can show statistics about how many items of category “Tops > Sweaters” are bought by a particular customer segment in physical
stores in a month.
Spaaza’s object model contains the concept of products
, product variants
and barcodes
. These three models have a hierarchical relationship.
A product
is an item sold in a transaction, for example “Aran Sweater,” which has various defined properties associated with it. A product
can have
multiple product variants
, each one of which has its own properties. For example, one product variant' of the product "Aran Sweater" might have a colour of "blue" and a size of "XL," whilst another has colour "red" and size "M." Each
product variant` can have one or more barcodes which is used
to identify it in a transaction.
A product or product variant can be created via add-basket
by extending the information passed to the basket_items
array. In order to create a
product the retailer_product_code
must be included in the basket_items
array, and to create a product_variant
the item_barcode
must be included.
Once created, updates to product
or product variant
metadata can be passed by altering the fields sent in the basket_item
JSON object. Updates
will only be processed once in every six hour period - more frequent update attempts will be ignored.
An example request that will create a product and product_variant
{
"entity":{
"entity_type":"chain",
"entity_id":1743
},
"user":{
"member_programme":"Spaaza",
"member_number":"303484"
},
"basket":{
"basket_platform_type":"in_store",
"retailer_basket_code":"20201019_test_00000001",
"basket_total_price":125,
"basket_timestamp_iso8601":"",
"basket_timezone_name":"Europe/Amsterdam",
"shipping_charge":0,
"payment_methods":[
],
"basket_currency":{
"currency_id":0,
"currency_code":"EUR"
},
"basket_tax":[
],
"basket_items":[
{
"item_barcode":"2913458432854",
"retailer_product_code":"iou342oi",
"item_name":"Men's Merino Aran Jumper",
"item_description":"The Aran Jumper is a style of jumper that takes its name from the Aran Islands off the west coast of Ireland.",
"item_price":125.00,
"item_subtotal": 125.00,
"item_colour":"White",
"item_gender":"M",
"item_brand":"Aran Jumpers ltd",
"item_size":"L",
"item_season":"Winter",
"item_category":"Clothing > Tops > Jumpers > Aran Jumper",
"item_image_url":"www.image.jpg"
}
]
}
}
This will result in the following response edited to only include the relevant product information.
{
"result":{
"code":1,
"status":"ok"
},
"results":{
"basket":{
"id":1,
"chain_id":1,
"basket_platform_type":"in_store",
"currency_id":2,
"basket_total_price":125,
"retailer_basket_code":"20201019_test_00000001",
"basket_items":[
{
"product":{
"id":4,
"owner_code":"iou342oi",
"name":"Men's Merino Aran Jumper",
"description":"The Aran Jumper is a style of jumper that takes its name from the Aran Islands off the west coast of Ireland.",
"price":125,
"brand":"Aran Jumpers ltd",
"season":"Winter",
"category":"Clothing > Tops > Jumpers > Aran Jumper",
"webshop_url":null,
"image_url":"www.image.png",
"last_modified_date":"2020-10-19 08:31:18",
"created_date":"2020-10-19 08:31:18",
"product_variant":{
"id":2,
"condition":"new",
"colour":"White",
"barcode":[
],
"size":"M",
"price":125,
"cost_price":null,
"image_url":"www.image.png",
"web_url":null,
"last_modified_date":"2020-10-19 08:31:18",
"created_date":"2020-10-19 08:31:18"
}
},
"spaaza_product_variant_id":2,
"inventory_owner_code":null,
"item_barcode":"2913458432854",
"item_quantity":1,
"item_is_promotional":false,
"item_price":125,
"item_original_price":125,
"item_subtotal":125,
"is_identified":true,
"excluded_from_spaaza":false
}
],
"basket_vouchers_applied":[
],
"return_transactions":[
],
"payment_methods":[
],
"basket_tax":[
{
"id":1,
"basket_id":1,
"tax_rate":0.06,
"tax_total":100
}
],
"supplementary_basket_codes":null,
"regenerated_rewards":[
],
"honour_vouchers_applied":[
],
"employee":{
"employee_code":null,
"employee_name":null
},
"basket_timestamp_iso8601":"2020-10-19T08:31:18+00:00",
"basket_timezone_name":"UTC",
"purchase_progress":null
},
"user":{
"member_programme":"spaaza",
"member_number":3354863
},
"result_type":"add-basket"
}
}
The minimum information that is required to create a product is retailer_product_code
and the item_price
and the minimum required information to create a product_variant
is the item_barcode
.
Extract of basket_items array with minimum required information to create a
product
and aproduct_variant
.
{
"basket_items":[
{
"item_barcode":"2913458432854",
"retailer_product_code":"iou342oi",
"item_price":125.00,
"item_subtotal": 125.00
}
]
}
Extract of a response from add-basket with
product
andproduct_variant
information
{
"product":{
"id":4,
"owner_code":"iou342oi",
"name":null,
"description":null,
"price":125,
"brand":null,
"season":null,
"category":null,
"webshop_url":null,
"image_url":null,
"last_modified_date":"2020-10-19 08:31:18",
"created_date":"2020-10-19 08:31:18",
"product_variant":{
"id":2,
"condition":"new",
"colour":null,
"barcode":[
],
"size":null,
"price":125,
"cost_price":null,
"image_url":null,
"web_url":null,
"last_modified_date":"2020-10-19 08:31:18",
"created_date":"2020-10-19 08:31:18"
}
}
}
The fields which can be used to store item metadata are described below.
Field | Description |
---|---|
retailer_product_code (string, mandatory) | The product or SKU identifier used by the retailer to identify the basket item. |
item_barcode (string, mandatory) | The barcode used by the retailer to identify the item. |
item_name (string) | The name of the product. |
item_description (string) | The description of the product. |
item_brand (string) | The brand making the product. |
item_season (string) | The particular season that is associated with the product. |
item_category (string) | A retailer category string for the product. This can be a single category name or can include a retailer category hierarchy with the names of category levels separated by the character “>”. For example this could be “Woollen Sweaters” or “Clothing > Tops > Sweaters > Woollen Sweaters”. The Spaaza product ingester interprets the hierarchical string and can run analytics on different category levels. |
item_web_url (string) | The url link to the product page on the webshop. |
item_image_url (string) | The url link to the products image. |
item_price (float) | The adjusted gross price being charged for the single-quantity item. |
item_cost_price (float) | The cost price of the product before any profit margin is added to make the SELL INCL sale price. This field can be used for simple margin analytics calculations on a per-item but also per-retailer or per-customer segment basis. |
item_is_promotional (bool) | This can be set true or false to override any existing Spaaza record of whether an item is on promotion. |
item_colour (string) | The colour of the product_variant eg. “red” or “green”. |
item_size (string) | The size of the inventory item, e.g. “M” or “32". |
Processing a return inline
get-basket-price endpoint
The JSON below illustrates a POST request to the get-basket-price endpoint of an item being returned in the same basket as a sale item with the same barcode - this is effectively an “exchange” transaction.
{
"entity": {
"entity_type": "chain",
"entity_id": 1743
},
"user": {
"member_programme": "Spaaza",
"member_number": "303484"
},
"basket": {
"basket_platform_type": "in_store",
"retailer_basket_code": "20190127_test_00000003",
"basket_total_price": 2.08,
"basket_timestamp_iso8601": "",
"basket_timezone_name": "Europe/Amsterdam",
"shipping_charge": 0,
"payment_methods": [],
"basket_currency": {
"currency_id": 0,
"currency_code": "EUR"
},
"basket_tax": [],
"basket_items": [
{
"retailer_item_code": "line_3",
"item_barcode": "8718299601410",
"item_quantity": 1,
"item_price": -47.91,
"return_item": true,
"original_retailer_basket_code": "20190127_test_00000002"
},
{
"item_barcode": "8718299601410",
"retailer_item_code": "line_2",
"item_quantity": 1,
"item_price": 49.99
}
]
}
}
The JSON below illustrates the response for a POST request to the get-basket-price endpoint of an item being returned in the same basket as a sale item with the same barcode - this is effectively an “exchange” transaction.
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"user": {
"member_programme": "Spaaza",
"member_number": "303484"
},
"basket": {
"chain_id": 1743,
"basket_platform_type": "in_store",
"currency_id": 2,
"basket_total_price": 2.08,
"retailer_basket_code": "20190127_test_00000003",
"basket_items": [
{
"spaaza_product_id": null,
"product_name": null,
"retailer_product_code": null,
"item_quantity": 1,
"retailer_item_code": "line_2",
"item_is_promotional": false,
"item_price": 49.99,
"item_original_price": 49.99,
"item_subtotal": 49.99,
"is_identified": false,
"excluded_from_spaaza": false,
"basket_voucher_distribution": [
{
"voucher_campaign_id": 192,
"voucher_campaign_title": "Welcome gift",
"voucher_key": null,
"voucher_id": null,
"voucher_type": "basket",
"voucher_distribution_amount": 2.08
}
],
"item_barcode": "8718299601410"
}
],
"basket_vouchers_applied": [],
"return_transactions": [
{
"basket_id": 362722,
"returned_items": [
{
"item_id": 535952,
"return_price": -47.91,
"quantity": 1,
"owner_code": "line_2",
"sale_price": 49.99,
"voucher_distribution_refunds": [
{
"voucher_key": "0886407851fc56c6211f01abe1b4eab1fb1b48640efb73b1169c1d7a50e9467b",
"voucher_id": 2630,
"campaign_id": 192,
"amount": 2.08
}
],
"purchase_progress_distribution_reclaims": [
{
"campaign_id": 152,
"amount": -48
}
]
}
]
}
],
"payment_methods": [],
"supplementary_basket_codes": null,
"regenerated_rewards": [
{
"voucher_key": null,
"voucher_id": null,
"voucher_status": "claimed",
"voucher_locked": false,
"campaign_id": 192,
"campaign_type": "signup",
"campaign_title": "Welcome gift",
"voucher_expiry_datetime_utc": "2019-07-09 07:25:10",
"voucher_expiry_seconds_remaining": 14033163,
"voucher_redeemed_datetime": null,
"generating_return_transaction": {
"return_transaction_id": null,
"returning_basket_id": null,
"returning_basket_retailer_basket_code": "20190127_test_00000003"
},
"parent_voucher": {
"voucher_id": 2630,
"voucher_key": "0886407851fc56c6211f01abe1b4eab1fb1b48640efb73b1169c1d7a50e9467b",
"voucher_redeemed_datetime": "2019-01-27T21:13:37+00:00",
"voucher_amount_original": 5,
"voucher_amount_redeemed": 5,
"voucher_amount": 5,
"redeeming_basket": {
"basket_id": 362722,
"retailer_basket_code": "20190127_test_00000002"
}
},
"voucher_currency_id": 2,
"voucher_currency_symbol": "€",
"voucher_amount_original": 2.08,
"voucher_amount_redeemed": 2.08,
"voucher_amount": 2.08,
"voucher_text": "New ACME Club Member",
"redeeming_basket": []
}
],
"employee": {
"employee_code": null,
"employee_name": null
},
"purchase_progress": null,
"basket_total_price_adjusted": 0
},
"result_type": "get-basket-price"
}
}
- See “Requesting an adjusted basket” for more information on making a call to the get-basket-price endpoint
- See the documentation on “add-basket call” for more information on response fields
The response above illustrates that an item is being returned, and that in the case of this retailer, the returned value of the voucher which was redeemed in the original transaction on the purchase item which is now being returned in this transaction, is immediately being redeemed on the new purchase item.
add-basket call
The JSON below illustrates an item being returned in the same basket as a sale item, with annotation of fields/parameters not explained elsewhere on this page:
{
"entity": {
"entity_type": "chain",
"entity_id": 1743
},
"user": {
"member_programme": "Spaaza",
"member_number": "303484"
},
"basket": {
"basket_platform_type": "in_store",
"retailer_basket_code": "20190127_test_00000003",
"basket_total_price": 0,
"basket_timestamp_iso8601": "",
"basket_timezone_name": "Europe/Amsterdam",
"shipping_charge": 0,
"payment_methods": [],
"basket_currency": {
"currency_id": 0,
"currency_code": "EUR"
},
"basket_tax": [],
"basket_items": [
{
"retailer_item_code": "line_3",
"item_barcode": "8718299601410",
"item_quantity": 1,
"item_price": -47.91,
"return_item": true,
"original_retailer_basket_code": "20190127_test_00000002"
},
{
"item_barcode": "8718299601410",
"retailer_item_code": "line_2",
"item_quantity": 1,
"item_price": 49.99
}
]
}
}
The JSON below illustrates the response to return items posted.
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"basket": {
"id": 362723,
"chain_id": 1756,
"basket_platform_type": "in_store",
"currency_id": 2,
"basket_total_price": 0,
"shipping_charge": 0,
"retailer_basket_code": "20190127_test_00000003",
"basket_items": [
{
"spaaza_product_id": null,
"product_name": null,
"retailer_product_code": null,
"item_quantity": 1,
"retailer_item_code": "line_2",
"item_is_promotional": false,
"item_price": 49.99,
"item_original_price": 49.99,
"item_subtotal": 49.99,
"is_identified": false,
"excluded_from_spaaza": false,
"basket_voucher_distribution": [
{
"voucher_campaign_id": 192,
"voucher_campaign_title": "Welkomstcadeau",
"voucher_key": "b3cbf91d1f95e95d7412ec47aaafb9708c762ba7d94c71b5c454c39cdca64d93",
"voucher_id": 80252,
"voucher_type": "basket",
"voucher_distribution_amount": 2.08
}
],
"purchase_progress_distribution": [
{
"purchase_progress_campaign_id": 152,
"purchase_progress_campaign_title": "Didi's",
"purchase_progress_campaign_type": "points_wallet",
"purchase_progress_distribution_amount": 47,
"contributing_campaign": {
"campaign_id": 153,
"campaign_title": "Didi's",
"campaign_type": "cashback"
}
}
],
"item_barcode": "8718299601410"
}
],
"basket_vouchers_applied": [
{
"voucher_key": "b3cbf91d1f95e95d7412ec47aaafb9708c762ba7d94c71b5c454c39cdca64d93",
"voucher_id": 80252,
"voucher_status": "redeemed",
"voucher_locked": false,
"campaign_id": 192,
"campaign_type": "signup",
"campaign_title": "Welkomstcadeau",
"voucher_expiry_datetime_utc": "2019-07-09 07:25:10",
"voucher_expiry_seconds_remaining": 14032990,
"voucher_redeemed_datetime": "2019-01-27T21:22:00+00:00",
"generating_return_transaction": {
"return_transaction_id": 1171,
"returning_basket_id": 362723,
"returning_basket_retailer_basket_code": "20190127_test_00000003"
},
"parent_voucher": {
"voucher_id": 2630,
"voucher_key": "0886407851fc56c6211f01abe1b4eab1fb1b48640efb73b1169c1d7a50e9467b",
"voucher_redeemed_datetime": "2019-01-27T21:13:37+00:00",
"voucher_amount_original": 5,
"voucher_amount_redeemed": 5,
"voucher_amount": 5,
"redeeming_basket": {
"basket_id": 362722,
"retailer_basket_code": "20190127_test_00000002"
}
},
"voucher_currency_id": 2,
"voucher_currency_symbol": "€",
"voucher_amount_original": 2.08,
"voucher_amount_redeemed": 2.08,
"voucher_amount": 2.08,
"voucher_text": "Nieuwe Didi Club Member",
"redeeming_basket": {
"basket_id": 362723,
"retailer_basket_code": "20190127_test_00000003"
}
}
],
"return_transactions": [
{
"id": 1171,
"basket_id": 362722,
"returned_items": [
{
"id": 1221,
"return_transaction_id": 1171,
"item_id": 535952,
"return_price": -47.91,
"quantity": 1,
"owner_code": "line_2",
"sale_price": 49.99,
"voucher_distribution_refunds": [
{
"voucher_key": "0886407851fc56c6211f01abe1b4eab1fb1b48640efb73b1169c1d7a50e9467b",
"voucher_id": 2630,
"campaign_id": 192,
"amount": 2.08
}
],
"purchase_progress_distribution_reclaims": [
{
"campaign_id": 152,
"amount": -48
}
]
}
],
"returning_basket_id": 362723
}
],
"payment_methods": [],
"supplementary_basket_codes": null,
"regenerated_rewards": [
{
"voucher_key": "b3cbf91d1f95e95d7412ec47aaafb9708c762ba7d94c71b5c454c39cdca64d93",
"voucher_id": 80252,
"voucher_status": "redeemed",
"voucher_locked": false,
"campaign_id": 192,
"campaign_type": "signup",
"campaign_title": "Welkomstcadeau",
"voucher_expiry_datetime_utc": "2019-07-09 07:25:10",
"voucher_expiry_seconds_remaining": 14032990,
"voucher_redeemed_datetime": "2019-01-27T21:22:00+00:00",
"generating_return_transaction": {
"return_transaction_id": 1171,
"returning_basket_id": 362723,
"returning_basket_retailer_basket_code": "20190127_test_00000003"
},
"parent_voucher": {
"voucher_id": 2630,
"voucher_key": "0886407851fc56c6211f01abe1b4eab1fb1b48640efb73b1169c1d7a50e9467b",
"voucher_redeemed_datetime": "2019-01-27T21:13:37+00:00",
"voucher_amount_original": 5,
"voucher_amount_redeemed": 5,
"voucher_amount": 5,
"redeeming_basket": {
"basket_id": 362722,
"retailer_basket_code": "20190127_test_00000002"
}
},
"voucher_currency_id": 2,
"voucher_currency_symbol": "€",
"voucher_amount_original": 2.08,
"voucher_amount_redeemed": 2.08,
"voucher_amount": 2.08,
"voucher_text": "Nieuwe Didi Club Member",
"redeeming_basket": {
"basket_id": 362723,
"retailer_basket_code": "20190127_test_00000003"
}
}
],
"employee": {
"employee_code": null,
"employee_name": null
},
"purchase_progress": [
{
"purchase_progress_campaign_id": 152,
"purchase_progress_campaign_title": "Didi's",
"purchase_progress_campaign_type": "points_wallet",
"purchase_progress_amount": 47,
"contributing_campaign": {
"campaign_id": 153,
"campaign_title": "Didi's",
"campaign_type": "cashback"
}
},
{
"purchase_progress_campaign_id": 152,
"purchase_progress_campaign_title": "Didi's",
"purchase_progress_campaign_type": "points_wallet",
"purchase_progress_amount": -48,
"contributing_campaign": null,
"return_transaction_id": 1171,
"returned_item_id": 1221
}
]
},
"user": {
"member_programme": "Spaaza",
"member_number": "303484",
"spaaza_user_id": 3354863
},
"result_type": "add-basket"
}
}
Return currency
In the case that a basket is received containing return items, but where the basket currency is not supplied, the currency of the original transaction of the last-supplied returned item is applied instead of the default currency of the retailer.
Rules surrounding recognising the original purchase basket/transaction
In order to reverse the effect of any points earned and points or vouchers spent on a original transaction, a return transaction needs to be able to look up the original transaction of a returned item. In general, it uses the ‘original_retailer_basket_code’ and ‘original_retailer_item_code’ fields to do this. There is some logic to be aware of here:
- The customer account associated with the return item is, by default, independent of the customer account associated with the “returning” transaction in which the return item is being returned. This means that it is possible for “customer B” to return an item bought by “customer A”, and, even if “customer B” also buys items in the transaction where the item is returned, “customer A” will be created with any points or voucher reversals.
- It is possible to return an item in a basket where the “returning” customer remains anonymous. In that case, whether the revenue associated with the “returning” basket (which may be negative or positive depending on whether other items are purchased in that basket), depends on the retailer’s settings in Spaaza.
- In the case of a return item which does not have an ‘original_retailer_basket_code’, if the returning transaction is associated with a customer then an attempt will be made to find the original purchase item based on the barcode (or other identifier) of the return item - all items purchased by the customer with the same barcode will be checked, and the most recent item which has not yet been returned will be assumed to be the original purchase item.
Fields posted for a return
Returned items can be handled inline in the same basket JSON by flagging items in the basket as return items. It is possible for a return item to be the only item in a basket, or mixed with other purchased items (and other returned items).
Field | Description |
---|---|
basket_total_price | The total cash price paid for the basket. It is possible for this value to be negative if the price of items being returned is greater than the price of items being purchased. |
return_item | A boolean value indicating that this is an item being returned - set this to true for a return item |
item_price | (float, recommended) The single-quantity price of the item. In the case of a return, a negative value should be used. In the case that this value is not supplied, the negative of the original single-quantity item price is assumed. |
original_retailer_basket_code | The retailer_basket_code (transaction ID or number) of the basket in which the item was originally purchased. Note that if there were also supplementary_basket_code values POSTed with the original basket then it is possible to use those instead. If both fields are supplied then the original_retailer_basket_code takes precedence. |
original_retailer_item_code | The retailer_item_code of the item in the basket in which the item was originally purchased. This can be used to return specific items in a case where multiple items were purchased with the same identifier (e.g. the same barcode) and a retailer_item_code was specified in the original basket. |
original_supplementary_basket_code | One of the supplementary_basket_code values of the basket in which the item was originally purchased. |
Fields in the response for a return
The following fields are notable in the basket level of the response after posting a return.
Field | Subfield 1 | Subfield 2 | Description |
---|---|---|---|
basket_vouchers_applied | Any basket vouchers which are being redeemed in this transaction. Note that, in the case that a retailer is configured to automatically and immediately redeem vouchers which were redeemed in the original purchase transaction, this field may be populated even without voucher details being supplied in the request JSON, and this type of “regenerated” voucher is redeemed before other vouchers supplied in the JSON request. | ||
return_transactions | An array of return transactions in a basket. Items from different original retailer baskets are separated into individual return transactions. | ||
basket_id | The Spaaza basket ID of the original purchase transaction. | ||
returned_items | An array of individual returned items. | ||
item_id | The original Spaaza item ID of the returned item. | ||
return_price | The price at which the item is being returned. | ||
sale_price | The price at which the item is originally sold. | ||
voucher_distribution_refunds | Any refunds of amounts of vouchers which were redeemed (spent) on the originally-purchased item. | ||
purchase_progress_distribution_reclaims | Any reclaim of amounts of points or wallet amounts earned on the originally-purchased items. | ||
regenerated_rewards | An array of rewards, including basket vouchers, which have been automatically generated for immediate redemption on purchased items in the returning basket. For example, if a customer returns an item on which a voucher was partially redeemed, and immediately wishes to redeem the same voucher on the new item, this will appear in this section as a regenerated reward, in addition to appearing in the “basket_vouchers_applied” section of the response. This field also appears in the response to the “get-basket-price” endpoint (see “Requesting an adjusted basket”) although in the response to that endpoint any voucher keys or IDs have not yet been populated. |
Standalone returns
Introduction
- Call name: return
- Endpoint URL: https://api0.spaaza.com/auth/return
- Request methods: POST
- Request Content-Type: application/json
- Response Content-Type: application/json
- Auth required: yes
The return API endpoint allows the registration of returns (and associated refunds) of items from a single basket of products which has been bought at a retailer by a user (a shopper), once the transaction has closed. This is generally used to i) reset the shopper’s purchase history; ii) reset any campaign activity actions (such as the adding of wallet campaign credit or spending of vouchers) triggered by the purchase and; iii) ensure that retailer analytics figures are correct.
The returns 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 returns item submitted.
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
to the retailer chain to which the user is connected. - Privileged authentication: the use of privileged authentication is permitted for this endpoint.
### POST Input JSON format
Example JSON upload for a standalone return using “owner_code” to identify the item:
{
"entity": {
"entity_type": "chain",
"entity_id": "55555"
},
"return": {
"return_owner_code": "7040150-R",
"original_basket_id": "6543215",
"note": "This item is being returned",
"items": [
{
"owner_code": "PURCH-3A0EFF",
"quantity": 4
}
]
}
}
Example JSON upload for a standalone return using “item_barcode” to identify the item:
{
"entity": {
"entity_type": "chain",
"entity_id": "55555"
},
"return": {
"return_owner_code": "7040151-R",
"original_basket_id": "6543216",
"note": "This item is being returned",
"items": [
{
"item_barcode": "11009475660559",
"quantity": 1
}
]
}
}
In this call, individual values are as follows:
- entity_type: the type of entity of the retailer. If the retailer is a chain with branches, this will be “chain”. If the retailer is an independent business with a single branch, this will be “business”
- entity_id: the Spaaza ID of the retailer entity.
- return: the section of the JSON providing information about the return basket and items.
- return_owner_code: the retailer-specific unique string or numeric used to identity the return transaction.
- original_basket_id OR original_retailer_basket_code:
- original_basket_id: the Spaaza ID of the original purchase basket, returned in the response to add-basket.
- original_retailer_basket_code: the retailer’s code for the original purchase basket, such as a retailer-specific receipt or order number, sent in the request to add-basket
- note: a string describing any detail associated with the return transaction.
- items: the section of the JSON providing information about individual items being returned.
- owner_code OR item_barcode:
- owner_code: the retailer-specific string or code used to label the individual item in the original basket - the same as the retailer_item_code (formerly basket_item_owner_code) value supplied in the JSON POST in the add-basket API call.
- item_barcode: the barcode used to identify the item in the JSON POST for the original add-basket API call.
- quantity: the quantity of items being returned from the basket item in the original purchase basket. For example, if the product_quantity were set to 4 for a basket item in the original add-basket API call, this value would be set to a maximum of 4.
Output
Example output:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"id": 31,
"basket_id": 6543215,
"retailer_basket_code": "#555-test-receipt"
"returned_items": [
{
"id": 31,
"item_id": 1175922,
"owner_code": "PURCH-3A0EFF"
}
],
"result_type": "return-handler"
}
}
The API endpoint returns an OK code and various details, including the original basket ID assigned by Spaaza and the list of items returned successfully, including the owner_code value for each one.
In the case of error various error or warning codes can be returned.
Receipts
You can use the Spaaza API to get individual receipt objects or all receipts for a customer. This can be used to provide a customer with access to their full purchase history as well as their individual purchases. Spaaza also makes a PDF of the receipt available for the customer.
Receipt Object
Example response
{
"id": 123456,
"timestamp": "2017-07-03T11:56:04Z",
"type": "in_store",
"download_url": "https://s3-eu-west-1.amazonaws.com/test01-receipts-bucket/receipts/123456.pdf",
"quantity": 1,
"subtotal": 1000,
"total_value": 1000,
"payment_method": "unknown",
"line_items": [
{
"product_id": 0,
"barcode": "2000046371025",
"sku": "2000046371025",
"name": "ACME shorts",
"description": "the best pair you can buy",
"type": "shorts",
"original_price": 1000,
"quantity": 1,
"sale_price": 1000,
"vouchers": 0,
"metadata": {
"color": "blue",
"size": "L",
"image": ""
},
"sale_discount": ""
}
],
"tax_lines": [
{
"tax_value": 30.25,
"order_value": 100.99,
"rate": 0.21
},
{
"tax_value": 20.55,
"order_value": 99.99,
"rate": 0.06
},
{
"tax_value": 19.99,
"order_value": 200,
"rate": 1.5
}
],
"chain": {
"id": 1740,
"name": "ACME",
"email": "support@acme.co.za",
"logo_url": "https://s3-eu-west-1.amazonaws.com/receipts-chain-logo/1000.png",
"website_url": "",
"currency": "South African Rand",
"currency_symbol": "R",
"business": {
"id": 0,
"name": "ACME Cape Town",
"address": {
"address_1": "1 Table Mountain Drive",
"address_2": "",
"address_3": "",
"towncity": "Cape Town",
"postal_code": "",
"country_code": "ZA",
"location": {
"lat": -33.962822,
"lon": 18.4098410
}
},
"phone_number": "+272189777777",
"email": "table-mountain@acme.co.za",
"website_url": ""
},
"receipts_service_active": true
},
"shopper": {
"id": 897654,
"user_name": "",
"entity_code": "",
"first_name": "John",
"last_name": "Smith",
"country_code": "",
"gender": "M",
"birthday": "1982-05-30",
"total_points_balance": 0,
"email": "john.smith@email.com",
"registered": true,
"shipping_address": {
"address_1": "",
"address_2": "",
"address_3": "",
"towncity": "",
"postal_code": "",
"country_code": "",
"location": {
"lat": 0,
"lon": 0
}
},
"billing_address": {
"address_1": "",
"address_2": "",
"address_3": "",
"towncity": "",
"postal_code": "",
"country_code": "",
"location": {
"lat": 0,
"lon": 0
}
}
},
"monetary_wallet": {
"contributions": [
{
"amount": 100,
"campaign_title": "Earn big on every purchase"
}
],
"total": 1640,
"title": "ACME Bucks"
},
"points_wallet": {
"contributions": [],
"total": 0,
"title": ""
},
"basket_vouchers": [
{
"campaign_title": "Boardriders Bucks",
"voucher_text": "",
"amount": 500,
"type": "wallet"
}
],
"loyalty_status": {
"campaign_id": 2095,
"name": "Level 1",
"description": "Level 1 in the Programme",
"loyalty_level_id": 2,
"points_to_proceed_next_level": 500,
"points_to_remain_current_level": 220,
"maintenance_points_level": 200,
"last_review_date": "2019-04-04T00:05:22+00:00",
"next_review_date": "2020-04-04T00:05:22+00:00",
"date_reached": "2019-06-06T08:06:14+00:00"
}
}
Fields in the Receipt object
The following fields are returned in the receipt object.
Identifying the receipt
Details of the receipt
Field | Description |
---|---|
id | id of the receipt, this should be the same ID as used by the system that completed the sale (webshop, POS etc) |
timestamp | time of the receipt creation |
download_url | a URL to access a PDF for the receipt |
quantity | the number of items in the receipt |
subtotal | subtotal amount of the receipt without VAT |
total_value | the amount of the receipt with VAT |
payment_method | how the customer paid for the transaction |
Line items
An array of all the products purchased in the transaction.
Field | Description |
---|---|
product_id | Spaaza’s product ID |
barcode | the barcode of the product |
sku | the SKU of the product |
name | the name of the product |
description | the description of the product |
type | the type or category of the product |
original_price | the original price of the product |
quantity | how many items of the product were included in the transaction |
sale_price | what the final selling price was for the item |
vouchers | the total value of any vouchers redeemed against the item |
color (metadata) | the color of the product |
size (metadata) | the size of the product |
image (metadata) | a URL for an image of the product |
sale_discount | the discount applied on the sale of the product |
Tax lines
An array of the taxes applied to the transaction.
Field | Description |
---|---|
tax_value | the total amount of the applicable tax on the order |
order_value | the monetary value of the order that the tax applies to |
rate | the applicable rate or percentage of the tax |
Chain
Details of the retailer (referred to as a chain by Spaaza).
Field | Description |
---|---|
id | Spaaza’s ID for the retailer (or chain) |
name | the name of the retailer |
the contact details of the retailer | |
logo_url | a URL for the logo of the retailer |
currency | the currency name of the retailer |
currency_symbol | the currency symbol of the retailer |
receipts_service_active | whether the chain has activate the receipts service in Spaaza |
Business
Within the “chain” the details of the physical store where the transaction occured (referred to as a business by Spaaza) are included.
Field | Description |
---|---|
id | Spaaza’s store ID |
name | the name of the store |
address | a section that includes the address details of the store |
phone_number | the store’s phone number |
the store’s email address | |
website_url | the store’s website URL |
Shopper
The shopper (also referred to as a user or customer in other parts of this documentation) who completed the transaction.
Field | Description |
---|---|
id | Spaaza’s ID for the shopper. Note that this is not the same number as is shown on the customer’s loyalty card or in an app (see entity code) |
user_name | a user name for the shopper |
entity_code | Spaaza’s entity code which is the customer’s loyalty card number. |
first_name | tte customer’s first name |
last_name | the customer’s last name |
country_code | the ISO ALPHA-2 code for the customer’s country |
gender | the customer’s gender |
birthday | the customer’s birthday |
total_points_balance | the customer’s total points balance |
the customer’s email address | |
registered | whether the customer is ‘registered’ - the definition of ‘registered’ is determined by the retailer |
shipping_address | a section which includes the shipping address details of the customer |
billing_address | a section which includes the shipping address details of the customer |
Monetary Wallet
If the retailer (or Chain) is using Spaaza’s Wallet functionality then the details of what was earned on the shopper’s wallet as a result of the transaction are included in the receipt.
Field | Description |
---|---|
total | the total amount in the customer’s wallet directly after the transaction |
title | the title of the wallet rewards |
Monetary Wallet Contributions
The contributions section in the Monetary Wallet is an array of campaigns that added value to the customer’s wallet as a result of the transaction. For example: “customers earn 5% back” and “customer get an extra 5% back this weekend”.
Field | Description |
---|---|
amount | the amount added by the contributor campaign |
campaign_title | the title of the contributor campaign |
Points Wallet
If the retailer (or Chain) is using Spaaza’s points functionality then the details of the points earned as a result of the transaction are included in the receipt.
Field | Description |
---|---|
total | the total amount of points directly after the transaction |
title | the title of the points program |
Points Wallet Contributions
The contributions section in the Points Wallet is an array of campaigns that added points as a result of the transaction. For example: “customers earn 100 points on every €100 spent” and “customer get an extra 100 points on every €100 spent this weekend”.
Field | Description |
---|---|
amount | the amount added by the contributor campaign |
campaign_title | the title of the contributor campaign |
Template content
Some styling and content settings for a receipt.
Field | Description |
---|---|
subject | a custom subject for a receipt email |
background_color | a custom color, typucally used for any receipt actions (ie a download PDF button) |
Get All Receipts For a User
curl "https://services-[API_ENVIRONMENT].spaaza.com/receipts/?shopper_id=1234567"
The above command returns JSON structured like this:
[
{
"id": 123456,
"timestamp": "2017-07-03T11:56:04Z",
"type": "in_store",
"download_url": "https://s3-eu-west-1.amazonaws.com/test01-receipts-bucket/receipts/123456.pdf",
"quantity": 1,
"subtotal": 1000,
"total_value": 1000,
"payment_method": "unknown",
"line_items": [
{
"product_id": 0,
"barcode": "2000046371025",
"sku": "2000046371025",
"name": "ACME shorts",
"description": "the best pair you can buy",
"type": "shorts",
"original_price": 1000,
"quantity": 1,
"sale_price": 1000,
"vouchers": 0,
"metadata": {
"color": "blue",
"size": "L",
"image": ""
},
"sale_discount": ""
}
],
"tax_lines": [],
"chain": {
"id": 1740,
"name": "ACME",
"email": "support@acme.co.za",
"logo_url": "https://s3-eu-west-1.amazonaws.com/receipts-chain-logo/1000.png",
"website_url": "",
"currency": "South African Rand",
"currency_symbol": "R",
"business": {
"id": 0,
"name": "ACME Cape Town",
"address": {
"address_1": "1 Table Mountain Drive",
"address_2": "",
"address_3": "",
"towncity": "Cape Town",
"postal_code": "",
"country_code": "ZA",
"location": {
"lat": -33.962822,
"lon": 18.4098410
}
},
"phone_number": "+272189777777",
"email": "table-mountain@acme.co.za",
"website_url": ""
},
"receipts_service_active": true
},
"shopper": {
"id": 897654,
"user_name": "",
"entity_code": "",
"first_name": "John",
"last_name": "Smith",
"country_code": "",
"gender": "M",
"birthday": "1982-05-30",
"total_points_balance": 0,
"email": "john.smith@email.com",
"registered": false,
"shipping_address": {
"address_1": "",
"address_2": "",
"address_3": "",
"towncity": "",
"postal_code": "",
"country_code": "",
"location": {
"lat": 0,
"lon": 0
}
},
"billing_address": {
"address_1": "",
"address_2": "",
"address_3": "",
"towncity": "",
"postal_code": "",
"country_code": "",
"location": {
"lat": 0,
"lon": 0
}
}
},
"monetary_wallet": {
"contributions": [
{
"amount": 100,
"campaign_title": "Earn big on every purchase"
}
],
"total": 1640,
"title": "ACME Bucks"
},
"points_wallet": {
"contributions": [],
"total": 0,
"title": ""
},
"basket_vouchers": [
{
"campaign_title": "Boardriders Bucks",
"voucher_text": "",
"amount": 500,
"type": "wallet"
}
]
},
{
"id": 678910,
"timestamp": "2017-07-03T11:35:52Z",
"type": "in_store",
"download_url": "https://s3-eu-west-1.amazonaws.com/test01-receipts-bucket/receipts/77888.pdf",
"quantity": 1,
"subtotal": 2000,
"total_value": 2000,
"payment_method": "unknown",
"line_items": [
{
"product_id": 0,
"barcode": "2000046371025",
"sku": "2000046371025",
"name": "Best tee",
"description": "The best t-shirt money can buy",
"type": "T-shirt",
"original_price": 2000,
"quantity": 1,
"sale_price": 2000,
"vouchers": 0,
"metadata": {
"color": "grey",
"size": "S",
"image": ""
},
"sale_discount": ""
}
],
"tax_lines": [],
"chain": {
"id": 1740,
"name": "ACME",
"email": "support@acme.co.za",
"logo_url": "https://s3-eu-west-1.amazonaws.com/receipts-chain-logo/1740.png",
"website_url": "",
"currency": "South African Rand",
"currency_symbol": "R",
"business": {
"id": 1,
"name": "ACME Waterfront",
"address": {
"address_1": "2 Waterfront bay",
"address_2": "",
"address_3": "",
"towncity": "Cape Town",
"postal_code": "",
"country_code": "ZA",
"location": {
"lat": -33.901988,
"lon": 18.420828
}
},
"phone_number": "+27218998765",
"email": "waterfront@acme.co.za",
"website_url": ""
},
"receipts_service_active": true
},
"shopper": {
"id": 897654,
"user_name": "",
"entity_code": "",
"first_name": "John",
"last_name": "Smith",
"country_code": "",
"gender": "M",
"birthday": "1982-05-30",
"total_points_balance": 0,
"email": "john.smith@email.com",
"registered": false,
"shipping_address": {
"address_1": "",
"address_2": "",
"address_3": "",
"towncity": "",
"postal_code": "",
"country_code": "",
"location": {
"lat": 0,
"lon": 0
}
},
"billing_address": {
"address_1": "",
"address_2": "",
"address_3": "",
"towncity": "",
"postal_code": "",
"country_code": "",
"location": {
"lat": 0,
"lon": 0
}
}
},
"monetary_wallet": {
"contributions": [
{
"amount": 200,
"campaign_title": "Earn big on every purchase"
}
],
"total": 1540,
"title": "ACME Bucks"
},
"points_wallet": {
"contributions": [],
"total": 0,
"title": ""
},
"basket_vouchers": [],
"template_content": {
"subject": "",
"background_color": ""
}
}
]
This endpoint returns all receipts objects for a specific user.
HTTP Request
Use the following GET request to request all receipts for a shopper:
GET https://services-[API_ENVIRONMENT].spaaza.com/receipts?shopper_id=<ID>
The API_ENVIRONMENT value varies according to whether the request is being made to Spaaza’s production or staging API:
Environment | API_ENVIRONMENT value |
---|---|
Production | prod |
Staging | test01 |
Headers
For admin or user authentication the following headers are required:
Header | Description |
---|---|
Session-User-Id | ID of the user obtained from the login endpoint |
Session-Key | key of the session obtained from the login endpoint |
Session-Chain-Id | the ID of the Spaaza chain or retailer |
For privileged authentication the following headers are required:
Header | Description |
---|---|
Session-Chain-Id | the ID of the Spaaza chain or retailer |
Authorization | Bearer access token see: privileged |
The following authentication methods are permitted:
Method | Description |
---|---|
user | A session generated by an end-user login. |
or | |
admin | A session generated by administrative user login. |
or | |
privileged | A token generated to privileged users. |
Query Parameters
This API accepts the following parameters:
Parameter | Description |
---|---|
shopper_id required | The Spaaza User ID of the shopper/customer |
Get All Receipts for a Chain
Sample JSON output for two receipts is shown below:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"receipts": [{
"id": 32892596,
"retailer_basket_code": "600240649-1497440106",
"timestamp": "2019-06-14T11:35:06Z",
"type": "online",
"quantity": 1,
"currency": {
"currency_id": 2,
"currency_code": "EUR",
"currency_name_en": "Euro",
"currency_symbol": "€"
},
"subtotal": 43.9,
"total_value": 43.9,
"shipping_charge": 3.26,
"payment_methods": null,
"employee": {
"code": null,
"name": null
},
"line_items": [{
"name": "ACME HONEYCOMB GREEN",
"retailer_product_code": "ACME00001",
"quantity": 1,
"item_is_promotional": false,
"sale_price": 39.95,
"original_price": 39.95,
"basket_item_subtotal": 39.95,
"is_identified": true,
"excluded_from_spaaza": false,
"barcode": "3385100168132",
"sku": "ACME00001",
"description": "GREEN HONEYCOMB TOP",
"metadata": {
"barcode": "3385100168132",
"color": "",
"size": null
}
}],
"tax_lines": null,
"chain": {
"id": 1743,
"name": "ACME",
"type": "chain",
"email": "acme@spaaza.com",
"currency": "Euro",
"currency_symbol": "€",
"receipts_service_active": false,
"business": null,
"webhook_config_url": null,
"webhook_config_basic_auth_user": null,
"webhook_config_basic_auth_pass": null
},
"shopper": {
"id": 3140280,
"first_name": "Marcella",
"last_name": "Janssen",
"address_streetname": "Groningenstraat",
"address_housenumber": "466",
"address_housenumber_extension": "2",
"address_towncity": "Lisse",
"address_postalcode": "2152 AB",
"country_code": "NL",
"gender": "F",
"birthday": "1977-12-11",
"username": "test2@example.com",
"signup_channel": null,
"address_line_2": null,
"address_line_3": null,
"address_regionstate": null,
"member_number": "100002",
"email": "test2@example.com",
"registered": false,
"send_email_receipt": true,
"member_program": {
"program_name": "spaaza",
"member_number": "100002"
},
"shipping_address": null,
"billing_address": null
},
"notes": null,
"monetary_wallet": null,
"points_wallet": null,
"basket_vouchers": []
},
{
"id": 32901174,
"retailer_basket_code": "600240649-1498034963",
"timestamp": "2019-06-21T08:49:23Z",
"type": "in_store",
"quantity": 2,
"currency": {
"currency_id": 2,
"currency_code": "EUR",
"currency_name_en": "Euro",
"currency_symbol": "€"
},
"subtotal": 43.9,
"total_value": 43.9,
"shipping_charge": 3.26,
"payment_methods": null,
"employee": {
"code": null,
"name": null
},
"line_items": [{
"name": "ACME STICK UP TEE",
"retailer_product_code": "ACME07249",
"quantity": 1,
"item_is_promotional": false,
"sale_price": 39.95,
"original_price": 229.95,
"basket_item_subtotal": 39.95,
"is_identified": true,
"excluded_from_spaaza": false,
"barcode": "3385100168687",
"sku": "ACME07249",
"description": "BLACK TEE SHIRT",
"metadata": {
"barcode": "3385100168687",
"color": "",
"size": null
}
},
{
"name": "ACME AFRICA TEE",
"retailer_product_code": "ACME96302",
"quantity": 1,
"item_is_promotional": false,
"sale_price": 219.95,
"original_price": 219.95,
"basket_item_subtotal": 219.95,
"is_identified": true,
"excluded_from_spaaza": false,
"barcode": "3385100168742",
"sku": "ACME96302",
"description": "MASAI-THEMED TEE SHIRT",
"metadata": {
"barcode": "3385100168742",
"color": "",
"size": null
}
}
],
"tax_lines": null,
"chain": {
"id": 1743,
"name": "ACME",
"type": "chain",
"email": "acme@spaaza.com",
"currency": "Euro",
"currency_symbol": "€",
"receipts_service_active": false,
"business": {
"id": 1578,
"name": "Test branch",
"branch_code": "0192",
"address": {
"address_1": "Maastrichtstraat",
"address_2": null,
"address_3": null,
"towncity": "Alkmaar",
"postalcode": "1701 AB",
"latitude": 52.86347800002301,
"longitude": 4.749566000001578
}
},
"webhook_config_url": null,
"webhook_config_basic_auth_user": null,
"webhook_config_basic_auth_pass": null
},
"shopper": {
"id": 3140280,
"first_name": "Mark",
"last_name": "Jansen",
"address_streetname": "Utrechtsestraat",
"address_housenumber": "23",
"address_housenumber_extension": "2",
"address_towncity": "Lisse",
"address_postalcode": "2148 AB",
"country_code": "NL",
"gender": "F",
"birthday": "1988-02-01",
"username": "test42@example.com",
"signup_channel": null,
"address_line_2": null,
"address_line_3": null,
"address_regionstate": null,
"member_number": "1090043",
"email": "test2@ecomni.nl",
"send_email_receipt": true,
"registered": true,
"member_program": {
"program_name": "spaaza",
"member_number": "1090043"
},
"shipping_address": null,
"billing_address": null
},
"notes": null,
"monetary_wallet": null,
"points_wallet": null,
"basket_vouchers": []
}
]
}
}
Sample CSV file output is shown below:
id,retailer_basket_code,timestamp,type,items_count,currency_code,currency_symbol,subtotal,total_value,shipping_charge,employee_code,employee_name,chain_business_id,chain_business_name,chain_business_owner_code,shopper_id,shopper_member_program,shopper_member_number,shopper_authentication_point_identifier,shopper_email,shopper_firstname,shopper_lastname,shopper_gender,shopper_birthday,shopper_country_code,shopper_address_postalcode,notes
32901174,600240649-1498034963,2019-06-21T08:49:23+00:00,online,1,EUR,€,43.90,43.90,3.26,,,,,,3140280,spaaza,100002,661196,test2@example,Marcella,"van der Jansen",F,1977-01-14T00:00:00+00:00,NL,"2150 AD",
Overview
- Call name: get-receipts
- Endpoint URL: https://api0.spaaza.com/get-receipts or https://api0.spaaza.com/get-receipts.csv
- Request methods: GET
- Response Content-Type: application/json OR application/force-download with CSV file download
- Auth required: yes
The get-receipts API endpoint returns all receipts for a chain, given the chain ID. It is possible to pass parameters to the endpoint so that it shows all receipts within a particular time period, all receipts for a particular branch or receipts matching various other parameters (see below).
When called without a suffix at the end of the URL or with a .json
suffix the endpoint will return an array in the JSON response:
receipts
, which are receipts matching the request parameters.
When called via the endpoint URL ending in .csv
the endpoint will automatically set the response content-type to application/force-download
and respond with a downloadable CSV file. Please see the section entitled “CSV Response Fields” below.
Note that the response is streamed, the API server does not buffer receipts and wait until all are processed before sending.
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
read access
to the entity (business or chain) to which the user is connected. - Privileged authentication: the use of privileged authentication is permitted for this endpoint.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
chain_id (integer) required | The id of the chain for which the information is being requested. |
user_id (integer) optional | The Spaaza ID of a particular user. Adding this parameter only returns receipts associated with that user ID. |
max_created_datetime (ISO-8601 extended timestamp) optional | The ISO-8601 extended datetime of the latest creation date/time for which receipts are to be shown. This includes the offset from GMT/UTC in hours (and minutes). Valid examples: “2018-09-19T14:05:20+00:00”, “2018-09-19T08:05:20-06:00”, “2018-09-19T14:05:20Z” |
max_created_datetime_relative (string) optional, overrides max_created_datetime | A string representing, relative to the current time, the latest creation date/time for which receipts are to be shown. Includes (combinations of) integer numbers of months, days, hours and minutes. Valid examples: “+6 days”, “3 weeks”, “+6 months -5 days +2 minutes” |
min_created_datetime (ISO-8601 extended timestamp) optional | The ISO-8601 extended datetime of the earliest creation date/time for which receipts are to be shown. This includes the offset from GMT/UTC in hours (and minutes). Valid examples: “2018-09-19T13:27:56+00:00”, “2018-09-19T07:27:56-06:00”, “2018-09-19T13:27:56Z” |
min_created_datetime_relative (string) optional, overrides min_created_datetime | A string representing, relative to the current time, the earliest creation date/time for which receipts are to be shown. Includes (combinations of) integer numbers of months, days, hours and minutes. Valid examples: “7 days”, “-13 weeks”, “-6 months 5 days -2 minutes” |
branch_business_id (integer) optional | The Spaaza ID of a branch stored in the Spaaza system. If this parameter is passed, only receipts will be returned which were created in the store specified. Usually the branch_business_owner_code parameter is used by retailers instead of this parameter. If both this parameter and the branch_business_owner_code parameter are passed, an error is generated. |
branch_business_owner_code (string) optional | The retailer’s identifier for a branch, usually known as a branch code. If this parameter is passed, only receipts will be returned which were created in the store specified. If both this parameter and the branch_business_id parameter are passed, an error is generated. |
retailer_basket_code (string) optional | A retailer transaction code or receipt number. If this parameter is passed, only receipts will be returned which match this exact transaction code or receipt number. For retailers with strict transaction code restrictions enabled, only a single receipt will be returned. |
number_results (integer) optional | The (maximum) number of results required in the response. The default action for CSV output is to return all possible receipts. For JSON output the maximum number of results returned for a single request is 500. |
results_offset (integer) optional | The result number at which to start. For example, if there are 1000 receipts, giving a results_offset of 500 will start at receipt 500. Numbering starts at 0. |
Output
The output contains information about vouchers and the users they are associated with.
CSV Response Fields
When called via the endpoint URL ending in .csv
the endpoint returns a downloadable CSV file named vouchers.csv
. The CSV file contains a header row in the first line followed by a single line per voucher.
The fields shown below are represented in the CSV file in the order shown. Unpopulated fields follow CSV convention and are left blank. Fields containing special characters are surrounded by double quotes - e.g. "String with spaces"
- following CSV convention. Other fields may be added to the CSV file in future, and these will be added at the end of each line.
Field | Description |
---|---|
id (integer) | The unique ID of the receipt in the Spaaza system. |
retailer_basket_code (string) | The retailer transaction code or receipt number. |
timestamp (ISO-8601 timestamp) | The date and time the receipt was created. |
type (string) | The type of receipt. Current ossible values are “online” or “in_store”. |
items_count (integer) | The count of the number of items purchased in the receipt. |
currency_code (string, ISO-4217 currency code) | The ISO-4217 three-letter currency code of the voucher currency, e.g. “EUR” or “ZAR”. |
currency_symbol (string, ISO-4217 currency symbol) | The ISO-4217 three-letter currency symbol of the voucher currency, e.g. “€” or “$”. |
subtotal (float) | The subtotal of the receipt. |
total_value (float) | The total transaction value of the receipt. |
shipping_charge (float) | The shipping charge amount of the receipt. This is stored separately from the total value. |
employee_code (string) | The employee code of the employee handling the transaction. |
employee_name (string) | The name of the employee handling the transaction. |
chain_business_id (integer) | The unique ID in the Spaaza system of the branch in which the transaction was made. |
chain_business_name (string) | The name of the branch in which the transaction was made. |
chain_business_owner_code (string) | The retailer’s identifier for the branch in which the transaction was made, usually known as a branch code. |
shopper_id (integer) | The unique ID of the shopper/customer in the Spaaza system. |
shopper_member_program (string) | The name of the member program of which the shopper/customer is a member. Usually this is ‘spaaza’. |
shopper_member_number (string) | The member number of the shopper/customer in the program. |
shopper_authentication_point_identifier (string) | The ID of the user in a third party webshop or other identity system. |
shopper_email (string) | The email address of the shopper/customer, also known as the ‘username’. |
shopper_firstname (string) | The first name of the shopper/customer. |
shopper_lastname (string) | The last name of the shopper/customer. |
shopper_gender (string) | The gender of the shopper/customer. If populated, two values are possible, “M” and “F”. |
shopper_birthday (ISO-8601 timestamp) | The birth date of the shopper/customer. |
shopper_country_code (string) | The ISO ALPHA-2 code for the country of the shopper/customer. |
shopper_address_postalcode (string) | The shopper/customer’s postal or zipcode. |
notes (string) | Any notes associated with the receipt. |
Get a Specific Receipt
curl "https://services-[API_ENVIRONMENT].spaaza.com/receipts/12345678"
The above command returns JSON structured like this:
{
"id": 123456,
"timestamp": "2017-07-03T11:56:04Z",
"type": "in_store",
"download_url": "https://s3-eu-west-1.amazonaws.com/test01-receipts-bucket/receipts/123456.pdf",
"quantity": 1,
"subtotal": 1000,
"total_value": 1000,
"payment_method": "unknown",
"line_items": [
{
"product_id": 0,
"barcode": "2000046371025",
"sku": "2000046371025",
"name": "ACME shorts",
"description": "the best pair you can buy",
"type": "shorts",
"original_price": 1000,
"quantity": 1,
"sale_price": 1000,
"vouchers": 0,
"metadata": {
"color": "blue",
"size": "L",
"image": ""
},
"sale_discount": ""
}
],
"tax_lines": [],
"chain": {
"id": 1740,
"name": "ACME",
"email": "support@acme.co.za",
"logo_url": "https://s3-eu-west-1.amazonaws.com/receipts-chain-logo/1000.png",
"website_url": "",
"currency": "South African Rand",
"currency_symbol": "R",
"business": {
"id": 0,
"name": "ACME Cape Town",
"address": {
"address_1": "1 Table Mountain Drive",
"address_2": "",
"address_3": "",
"towncity": "Cape Town",
"postal_code": "",
"country_code": "ZA",
"location": {
"lat": -33.962822,
"lon": 18.4098410
}
},
"phone_number": "+272189777777",
"email": "table-mountain@acme.co.za",
"website_url": ""
},
"receipts_service_active": true
},
"shopper": {
"id": 897654,
"user_name": "",
"entity_code": "",
"first_name": "John",
"last_name": "Smith",
"country_code": "",
"gender": "M",
"birthday": "1982-05-30",
"total_points_balance": 0,
"email": "john.smith@email.com",
"registered": false,
"shipping_address": {
"address_1": "",
"address_2": "",
"address_3": "",
"towncity": "",
"postal_code": "",
"country_code": "",
"location": {
"lat": 0,
"lon": 0
}
},
"billing_address": {
"address_1": "",
"address_2": "",
"address_3": "",
"towncity": "",
"postal_code": "",
"country_code": "",
"location": {
"lat": 0,
"lon": 0
}
}
},
"monetary_wallet": {
"contributions": [
{
"amount": 100,
"campaign_title": "Earn big on every purchase"
}
],
"total": 1640,
"title": "ACME Bucks"
},
"points_wallet": {
"contributions": [],
"total": 0,
"title": ""
},
"basket_vouchers": [
{
"campaign_title": "Boardriders Bucks",
"voucher_text": "",
"amount": 500,
"type": "wallet"
}
],
"loyalty_status": {
"campaign_id": 2095,
"name": "Level 1",
"description": "Level 1 in the Programme",
"loyalty_level_id": 2,
"points_to_proceed_next_level": 500,
"points_to_remain_current_level": 220,
"maintenance_points_level": 200,
"last_review_date": "2019-04-04T00:05:22+00:00",
"next_review_date": "2020-04-04T00:05:22+00:00",
"date_reached": "2019-06-06T08:06:14+00:00"
}
}
Give a specific id, this endpoint returns the corresponding receipt object.
HTTP Request
Use the following GET request to get an individual receipt:
GET https://services-[API_ENVIRONMENT].spaaza.com/receipts/<id>
The API_ENVIRONMENT value varies according to whether the request is being made to Spaaza’s production or staging API:
Environment | API_ENVIRONMENT value |
---|---|
Production | prod |
Staging | test01 |
Headers
For admin or user authentication the following headers are required:
Header | Description |
---|---|
Session-User-Id | ID of the user obtained from the login endpoint |
Session-Key | key of the session obtained from the login endpoint |
Session-Chain-Id | the ID of the Spaaza chain or retailer |
For privileged authentication the following headers are required:
Header | Description |
---|---|
Session-Chain-Id | the ID of the Spaaza chain or retailer |
Authorization | Bearer access token see: privileged |
The following authentication methods are permitted:
Method | Description |
---|---|
user | A session generated by an end-user login. |
or | |
admin | A session generated by administrative user login. |
or | |
privileged | A token generated to privileged users. |
URL Parameters
This API accepts the following parameters:
Parameter | Description |
---|---|
id required | Id of the receipt |
Receipts Webhook
The object returned as a result of registering to this webhook is as follows:
{
"id": 123456,
"timestamp": "2017-07-03T11:56:04Z",
"type": "in_store",
"download_url": "https://s3-eu-west-1.amazonaws.com/test01-receipts-bucket/receipts/123456.pdf",
"quantity": 1,
"subtotal": 1000,
"total_value": 1000,
"payment_method": "unknown",
"line_items": [
{
"product_id": 0,
"barcode": "2000046371025",
"sku": "2000046371025",
"name": "ACME shorts",
"description": "the best pair you can buy",
"type": "shorts",
"original_price": 1000,
"quantity": 1,
"sale_price": 1000,
"vouchers": 0,
"metadata": {
"color": "blue",
"size": "L",
"image": ""
},
"sale_discount": ""
}
],
"tax_lines": [],
"chain": {
"id": 1740,
"name": "ACME",
"email": "support@acme.co.za",
"logo_url": "https://s3-eu-west-1.amazonaws.com/receipts-chain-logo/1000.png",
"website_url": "",
"currency": "South African Rand",
"currency_symbol": "R",
"business": {
"id": 0,
"name": "ACME Cape Town",
"address": {
"address_1": "1 Table Mountain Drive",
"address_2": "",
"address_3": "",
"towncity": "Cape Town",
"postal_code": "",
"country_code": "ZA",
"location": {
"lat": -33.962822,
"lon": 18.4098410
}
},
"phone_number": "+272189777777",
"email": "table-mountain@acme.co.za",
"website_url": ""
},
"receipts_service_active": true
},
"shopper": {
"id": 897654,
"user_name": "",
"entity_code": "",
"first_name": "John",
"last_name": "Smith",
"country_code": "",
"gender": "M",
"birthday": "1982-05-30",
"total_points_balance": 0,
"email": "john.smith@email.com",
"registered": false,
"shipping_address": {
"address_1": "",
"address_2": "",
"address_3": "",
"towncity": "",
"postal_code": "",
"country_code": "",
"location": {
"lat": 0,
"lon": 0
}
},
"billing_address": {
"address_1": "",
"address_2": "",
"address_3": "",
"towncity": "",
"postal_code": "",
"country_code": "",
"location": {
"lat": 0,
"lon": 0
}
}
},
"monetary_wallet": {
"contributions": [
{
"amount": 100,
"campaign_title": "Earn big on every purchase"
}
],
"total": 1640,
"title": "ACME Bucks"
},
"points_wallet": {
"contributions": [],
"total": 0,
"title": ""
},
"basket_vouchers": [
{
"campaign_title": "Boardriders Bucks",
"voucher_text": "",
"amount": 500,
"type": "wallet"
}
]
},
Spaaza can call external webhooks for receipt or “transaction” events.
We can configure a webhook URL that you provide. Whenever the receipt event occurs we send a simple POST request to the URL. The body of the POST is JSON that includes the receipt object. So that you can verify that the POST really originates from Spaaza we provide a signature in a request header (X-Spaaza-Hmac-SHA256).
The value of the header is a base 64 encoded HMAC-SHA256 of the whole body of the request with a shared secret that we would provide. Your code to handle the event would need to recreate the signature using the shared secret and compare it to the value in the header.
Campaigns
Interact with campaign
An example response for successful interaction with any campaign
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"success": true,
"result_type": "interact-campaign"
}
}
Overview
- Call name: interaction-campaign
- Endpoint URL: https://api0.spaaza.com/interact-campaign
- Request methods: GET
- Response Content-Type: application/json
- Auth required: yes
The interact-campaign API endpoint carries out a configured campaign interaction for an end-user (customer). This might result in one of many possible actions, such as the issuing of points or vouchers for a campaign.
The campaign logic itself dictates the result of the interaction. The role of the interact-campaign endpoint is not to describe this result, but only to respond with whether the interaction was successful or not.
Note that, in the case a reward has already been redeemed, a 200 OK response is sent along with a warning campaign_fully_redeemed
.
Permissions and authentication
This API call requires a valid Spaaza session. The session can be as follows:
- User authentication: a session generated by an end-user login.
- Admin authentication: the performing user needs to be logged in and have
read access
to the entity (business or chain) to which the user is connected. - Privileged authentication: the use of privileged authentication is permitted for this endpoint.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
campaign_id mandatory | (integer) The ID in the Spaaza system of the campaign with which the customer/user is interacting. |
chain_id mandatory with admin authentication | (integer) The id of the chain for which the information is being requested. |
user_id OR member_number OR authentication_point_identifier mandatory with admin or privileged authentication | The Spaaza unique ID (user_id), member_number (user code) or identity in a third-party authentication system (authentication_point_identifier) of the user for whom the campaign interaction is being requested. |
Headers
The following headers can/must be passed to the API call:
Parameter | Description |
---|---|
X-MyPrice-App-Hostname | (mandatory in the case of user authentication, not required otherwise) The hostname of the app for which the user is requesting the card. |
Possible error responses
The following represents a list of possible error responses for the interact-campaign
endpoint:
Code | Name and Description | HTTP Status Code |
---|---|---|
6 | no_valid_sessionThe user needs to be logged in and a valid session key needs to be sent | 401 |
68 | permission_denied_or_non_existentThis user has insufficient permissions for this object or the object does not exist. | 500 |
154 | user_id_invalidThe user_id passed must be an integer up to 10 digits long | 400 |
217 | chain_id_not_foundNo record has been found for that chain_id | 400 |
228 | auth_method_invalidThe given auth_method parameter has an invalid value. | 500 |
238 | myprice_app_not_foundThe MyPrice app you requested was not found. | 500 |
245 | campaign_id_not_presentThe campaign_id must be passed as a parameter. | 400 |
246 | campaign_id_not_foundThe campaign_id supplied could not be found. | 404 |
247 | campaign_id_invalidThe campaign_rule_id passed must be an integer. | 400 |
264 | myprice_app_without_entityThe requested MyPrice app does not have an entity associated with it. | 400 |
265 | authorization_invalidThe given authorization header is invalid. | 400 |
266 | access_token_invalidThe given access token is invalid. | 401 |
267 | no_valid_userA valid username needs to be specified. | 401 |
269 | no_myprice_appMyprice app is required. | 400 |
270 | user_not_foundNo user was found. | 404 |
405 | entity_mismatchThe entities or chains supplied do not match. | 400 |
416 | multiple_parameter_mismatchMultiple parameters supplied when fewer are required. | 400 |
419 | parameter_invalidOne of the parameters is invalid and should be in a different format. | 400 |
424 | access_deniedAccess is denied. | 400 |
449 | campaign_not_activeThe requested campaign is not active. | 400 |
450 | campaign_fully_redeemedThe rewards of this campaign have been fully redeemed. | 400 |
451 | insufficient_points_for_interactionNot enough points available to continue. | 400 |
Chain and Branch
Altering a branch
Returns an OK code and a JSON for the user. A sample is shown below:
{
"result": {
"code": 1,
"status": "ok"
},
"results": {
"business": {
"id": 1383,
"chain_id": 1743,
"name": "ACME Inc",
"address_1": "Herengracht 504",
"address_2": "Foo",
"address_3": "Bar",
"towncity": "Amsterdam",
"region": "Noord Holland",
"postalcode": "1017 CB",
"countrycode": "NL",
"latitude": "52.37021570",
"longitude": "1.89516789",
"owner_code": "10001",
"email_address": "ops@spaaza.com",
"website_url": "http://www.spaaza.com",
"business_image_url": "https://media.licdn.com/dms/image/C4D0BAQEN6wx-nP_Crg/company-logo_400_400/0?e=1578528000&v=beta&t=1qKTWg0qbIJMydHHG02YPhD8N4LONyW5Rp06wn5DvN0",
"business_review_url" : "https://g.page/spaaza/review"
"type": "business"
},
"result_type": "alter-business"
}
}
Overview
- Call name: alter-business
- Endpoint URL: https://api0.spaaza.com/internal/alter-business
- Request methods: PUT
- Request Content-Type: multipart/form-data or application/x-www-form-urlencoded
- Response Content-Type: application/json
- Auth required: yes
- X-MyPrice-App-Hostname header requirement: mandatory when using privileged authentication
Introduction
In Spaaza terminology, a “business” is a branch of a retailer (a “chain”). This API call updates an existing business.
HTTP Parameters
The following HTTP parameters can be passed to the API:
Parameter | Description |
---|---|
business_id | (integer) The ID of the business whose details are to be altered. This parameter can be used to identify the business. |
name | (string) The name of the business. |
address_1 | (string) The first line of the business address. |
address_2 | (string) The second line of the business address. |
address_3 | (string) The third line of the business address. |
address_towncity | (string) The postal city of the business. |
region | (sting) The region or country of the business. |
countrycode | (string) The ISO ALPHA-2 country code of the business. |
postalcode | (string) The postalcode of the business. |
latitude | (float) The latitude of the business in decimal degrees. |
longitude | (float) The longitude of the business in decimal degrees. |
business_image_url | (string) The url link to the businesses image/logo. |
business_review_url | (string) The url link to the review business page. |
Permissions and Authentication
Admin authentication: The performing user needs to be logged in and have write access
to the
entity (business or chain) to which the user is connected. –>