Task for the implementation of data exchange between the Cash System and ABM Loyalty
Task for the implementation of data exchange between the Cash System and ABM Loyalty
Content
2. Registration of a new member of the loyalty program at the checkout 6
2.1. Request for registration of a new PL participant (without SMS verification) 6
2.2. Registration of the PL participant (with SMS verification) 7
2.3. Queries to determine the values of the id_city and id_region parameters 15
2.4. Assign a card to a program member 16
3.1. Request for authorization by phone number 16
3.2. SMS verification request 16
4. Loyalty program member information 17
4.1. Request for information about a loyalty program member and card by card number 17
4.2. Request information about a member of the loyalty program by phone number 19
5. Loyalty Program Membership Card Information 23
5.1. Request for information about the card of a member of the loyalty program by card number 23
5.2. Request for information about the card of a member of the loyalty program by card number 23
5.3. Changing the status of the card at the checkout 24
6.1. Request pre-calculation by check 25
6.2. Sales Confirmation Request 30
9. Referral program 34
10. Mistakes 38
The essence of the problem - organize regular automatic (without human intervention) data exchange between the Client's cash system and the ABM Loyalty loyalty system.
General information:
In the systemAVM Loyalty transferredall transactions, both identified and unidentified.
Data exchange between the cash system and the ABM Loyalty system must be implemented in two modes:
- Online - the interaction of the cash desk and the ABM Loyalty system takes place in real time)
- Offline- if it is impossible to interact with the cash desk and the Loyalty ABM system online (for example, there is no Internet connection), the cash desk must record transactions in a queue with card numbers (checking them by mask) and transfer them when the connection with Loyalty ABM is restored. If, when sending a transaction from the queue to the loyalty system, the loyalty system returns an error that the card was not found, the request is sent again as an unidentified purchase.
Data is transmitted by methodsRESTful API according to the protocol https.
The following API methods are used to interact with the checkout and Loyalty:
POST /partner/operation/user/registration – registers a new member of the loyalty program;
POST /v2.1/client/phone-auth – request for authorization by phone number;
POST/v2.1/client/phone-auth-confirm- confirmation of the phone number via SMS;
GET /partner/operation/user/{token}/card-user-info - gives information about the status of the card and the holder of this card, if the card is assigned to the account;
POST /partner/card/card-update - used to change the status of the card at the checkout;
POST /partner/operation/pre-check - pre-calculation by check;
POST /partner/operation/check-confirm - sale confirmation request;
POST /partner/operation/check-return – return request;
POST /partner/referral/link - to create a link referral-referrer (according to the work of the referral program)
Sales Operations:
List of sales operations at the checkout:
- Mode online - when there is continuous access to the Internet
- Buying a product
- Return of goods (full, partial, repeated)
- Mode offline - no access to the Internet - sales data cannot be sent to the Loyalty CRM directly at the time of the sale.
The procedure for performing sales operations:
Map-user-info
- Get pre-calculation response POST /v2/partner/operation/pre-check.
- Display a message how much bonuses can be written off for this check, if bonuses can be written off - the value from the "receipt_bonus_amount" parameter: Asking whether to write off bonuses (Answer Yes, and Answer No).
- If the answer is yes. Display a field for entering the amount to be written off, while displaying the maximum allowable amount to be written off. If the user entered the amount of bonuses more than the allowable one, display a corresponding message and do not send data. Add a button after entering - Submit (perform the second pre-calculation POST /v2/partner/operation/pre-check) and Cancel - do not write off bonuses (display the amount payable on the check and the number of accrued bonuses positionally and the total amount per check) When you click send, withdraw the amount payable per check and the number of accrued and written off bonuses item by item and the total amount per check).
- If the answer is No, display the amount payable on the check and the number of accrued bonuses positionally and the total amount.
- After entering the amount payable - confirmation of the sale operation POST /v2/partner/operation/check-confirm
For any changes in sales - send a POST request /v2/partner/operation/pre-check
The description of the methods is also available at the link:
API channel: https://api.sandbox.abmloyalty.app
key (token):
version: v2
key:
!! access to the test database. Then you will need to switch to the grocery system
A description of all methods is available at the link:
https://documenter.getpostman.com/view/10073265/TzJuAdf5
Registration of a new member of the loyalty program (PL) at the checkout
Request for registration of a new PL participant (without SMS verification)
POST /partner/operation/user/registration
- Creates a new account in the system, fills out a form for a new program participant.
- In the parameters, you should pass the personal data of the client.
Mandatory parameters are those fields of the questionnaire that are set as mandatory (in this example, 5 parameters). - The method returns the phone and guid of a new loyalty program member created in the system.
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
phone | string | Mobile phone number in the format380######### | |
first_name | integer | PL Member Name | |
middle_name | string | Middle name of the participant of the submarine | |
last_name | string | Surname of the PL participant | |
birth_day | string | Date of birth of the participant in the PL in the format 1989-03-17 | |
id_region | integer | Global directory of region of residence | |
id_city | integer | The global directory of the city of residence, linked to the region. | |
gender | integer | Gender: 1 - man 2- woman | |
sms_notify | integer | Subscribe to SMS newsletter: 1-I agree 0-disagree | |
email_notify | integer | Subscribe to email newsletter: 1-I agree 0-disagree | |
string | Email in the format abm@abmcloud.com | ||
address | string | PL participant's address | |
channel_reg | integer | registration channel.For checkout: 5. |
An example of a response, with a successful request:
{
"success": true,
"status": 201,
"data": {
"phone": "380931000013",
"guid": “68c147a2-edbd-4df5-a8b2-dadfb3a70ebc”,
}
}
Registration of the PL participant (with SMS verification)
- Registration via SMS with a card
- Checking the card number
- Registration via SMS with a card
The method checks if there is such a card in the loyalty program, if there is a card in the availability parameter, it returns 1, if there is no card - 0.
GET /client/card/{number}/availability
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
number | string | PL membership card number |
- Request a list of required fields
GET /client/profile-params – returns a list of fields of the main questionnaire and their mandatory completion.
- Request a list of additional fields
GET /system/profile-fields- returns a list of additional fields in the form and their mandatory fields.
- Request a list of regions
GET /v2/client/geo/{country}/regions - returns all regions and their IDs
{country} - country ID
- Request a list of cities
GET /v2/client/geo/{country}/{city}/search-city - search by part of the city name, returns the cities (regions, countries) of the given country, max = 10pcs
{country} - country ID
{city} - part of the city name
{country} - Specify the country ID in the query by default and do not display it in the user interface for selection.
For example, country ID Kazakhstan = 81
- Checking a member's phone number
POST /v2/client/check-phone – the method checks if this phone number is already in the loyalty program, if it is, then true is returned to the is_exist parameter, if not, false.
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
phone | string | Mobile phone number in the format380######### |
- Registration by SMS
POST /v2.1/client/registration – the method registers a phone number and sends an SMS with a confirmation code to the number
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
phone | string | Mobile phone number in the format380######### | |
password | string | Permanent password, you can enter the standard 111111 |
- Password confirmation with SMS
POST /v2.1/client/registration-confirm - the method sends a code with SMS and confirms the registration
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
code | string | Code with sms | |
sms_id | integer | Id sms received in previous request |
- Assigning a card to a user
POST /v2/client/card/set-card – the method assigns the specified card number to the participant (by token)
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
number | string | PL membership card number |
- Sending personal data
PUT /v2/client /profile– the method assigns the specified data to the participant (by token)
- Registration with SMS without a card (a virtual card is generated)
- Request a list of required fields
- Registration with SMS without a card (a virtual card is generated)
GET /client/profile-params – returns a list of fields of the main questionnaire and their mandatory completion.
- Request a list of additional fields
GET /system/profile-fields- returns a list of additional fields in the form and their mandatory fields.
- Request a list of regions
GET /v2/client/geo/{country}/regions - returns all regions and their IDs
{country} - country ID
- Request a list of cities
GET /v2/client/geo/{country}/{city}/search-city - search by part of the city name, returns cities (regions, countries) of the given country, max = 10pcs
{country} - country ID
{city} - part of the city name
{country} - Specify the country ID in the query by default and do not display it in the user interface for selection.
For example, country ID Kazakhstan = 81
- Membership number verification
POST /v2/client/check-phone – the method checks if this phone number is already in the loyalty program, if it is, then true is returned to the is_exist parameter, if not, false.
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
phone | string | Mobile phone number in the format380######### |
- Registration by SMS
POST /v2.1/client/registration – the method registers a phone number and sends an SMS with a confirmation code to the number
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
phone | string | Mobile phone number in the format380######### | |
password | string | Permanent password, you can enter the standard 111111 |
- Password confirmation with SMS
POST /v2.1/client/registration-confirm -the method sends a code with SMS and confirms the registration
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
code | string | Code with sms | |
sms_id | integer | Id sms received in previous request |
- Virtual Map Generation
GET /v2/client/card/generate-card – the method generates a virtual card for the PL participant (by token)
- Sending personal data
PUT /v2/client /profile– the method assigns the specified data to the participant (by token)
Queries to determine the values of the id_city and id_region parameters
GET /v2/client/geo/{country}/regions - returns all regions and their IDs
{country} - country ID
GET /v2/client/geo/{country}/{city}/search-city - search by part of the city name, returns cities (regions, countries) of the given country, max = 10pcs
{country} - country ID
{city} - part of the city name
{country} - Specify the country ID in the query by default and do not display it in the user interface for selection.
For example, country ID Kazakhstan = 81
Other methods related to geolocation:
GET /v2/client/geo/{id}/get-country - returns country ID and country name
GET /v2/client/geo/{id}/get-region - returns country ID, country name, region ID, region name
GET /v2/client/geo/{id}/get-city - returns country id, country name, region id, region name, city id, city name
GET /v2/client/geo/countries - returns all countries and their IDs
Assign a card to a program member
POST /v2/partner/card/card-update (described in Section 5.3)
Authorization by phone number (with SMS)
Request for authorization by phone number
POST /v2.1/client/phone-auth
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
phone | string | Mobile phone number in the format380######### |
An example of a response, with a successful request:
{
"success": true,
"status": 201,
"data": {
"phone": "380504222530",
"sms_id": 249,
"timeout": 60
}
}
SMS verification request
POST /v2.1/client/phone-auth-confirm
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
code | string | Password from sms that will be sent to the program participant | |
sms_id | integer | This parameter is returned in the methodPOST /client/action/auth-phone |
An example of a response, with a successful request:
{
"success": true,
"status": 201,
"data": {
"phone": "380504222530",
"token": "d4538090-60d0-42bc-87e9-a6141f4d6f37",
"token_expired": 1518426222
}
}
Loyalty program member information
Request for information about a loyalty program member and card by card number
GET /partner/operation/user/{token}/card-user-info
{token}- card number for which information is requested
The method returns info on the card + info on the PL participant, if the card is linked to the account.
An example of a response, with a successful request:
{
"success": true,
"status": 200,
"data": {
"token": "63", //Card number
"user_data": {
"guid": “533a7a29-6928-4aad-a1b3-051bb1717af4”,
"mobile": "380631024903", // phone number
"email": "Alyonahavrylenko@gmail.com", // email address
"first_name": "Helen", //Name
"middle_name": "", //Surname
"last_name": "Teacher", //Last name
"created": 1578488728, // registration date;
"birth_day": "1999-08-08",//Date of birth
"gender": 2, //Pol
"sms_notify": 1, // consent to SMS-mailing (0 - disagree; 1 - agree);
"email_notify": 1, // consent to the email newsletter (0 - disagree; 1 - agree);
"id_region": 86, //region id
"id_city": 1116, //city id
"address": "Peremogy Avenue 12",// Address
"blocked": 0 //Number of member locks
},
"user_status": [],
"profile": {
"work_status": 3,
"children": 0,
"has_auto": 1,
"family_stat": 2
},
"accounts_data": [
{
"account": 2620020401, // wallet number;
"currency": "GOOD", // name of loyalty currency;
"balance": 0, // number of bonuses on the account;
"avialable": 0 // number of available bonuses on the account;
}
],
"cards_data": [
{
"number": "2020000000259", // card number;
"status": 3, // card status (0 - new; 1 - not filled; 2 - blocked; 3 - payment);
"created": 1579167842, // date of map creation (generation);
"date_activated": 1580741547, // activation date (date of the first operation on the card or date of linking the card to the wallet);
"issue_date": null, // card issue date;
"issue_branch": null, // outlet where the card was issued;
"date_blocked": 0, // date of transfer of the card to the "blocked" status;
"type": 1 // card type (1 - main card, 2 - key fob);
},
{
"number": "63",
"status": 3,
"created": 1579166828,
"date_activated": 1579178912,
"issue_date": null,
"issue_branch": null,
"date_blocked": 0,
"type": 1
},
{
"number": "67",
"status": 2,
"created": 1579166828,
"date_activated": 1579167114,
"issue_date": null,
"issue_branch": null,
"date_blocked": 1579167187,
"type": 1
},
{
"number": "2020-80477",
"status": 3,
"created": 1578498242,
"date_activated": 1578910691,
"issue_date": null,
"issue_branch": null,
"date_blocked": 0,
"type": 1
}
],
"gift_bonuses": [ //Information on gift bonuses
{
"id": 268, //Operation ID
"name": "For books",//Name of accrual
"bonus": 1000, //Number of accrued bonuses
"opened_at": 1581948299 // Bonus activation date
}
],
"card_statuses": {
"0": "New",
"1": "Active",
"3": "Payment",
"2": "Blocked"
},
"card_types": {
"1": "Main",
"2": "Slave"
},
"total_amount_spent": 13398 // total amount of participant's purchases.
"groups": [ //list of groups in which the UPL participates
"Kabyldaeva",
"0555409355",
"filter",
"Chui regional mailing group",
"testoce2",
"All clients",
"omurbekov test 2",
"Test 2",
"Sparrow M, two shops, quarter",
"Men are all",
"Except 996701037770",
"Havrylenko test",
"Ivan Ivanov",
"men 20 to 30",
"titan test",
"To send Push",
"\t0000001433663",
"0684607869",
"For_Task_2",
"Titanium men 2 stores",
"Doctor test",
"Women Driving",
"Chui constructor",
"Titan all clients",
"Lucky Look 1",
"1010109147909",
"F 20-30, MP_Horobets",
"men on assignment",
"Biscuits by weight",
"men under 30",
"Valeria",
"5% discount"
]
}
}
Recommendation:
If the response received the status of the card"2": "Blocked", then carry out the sale as an unidentified buyer (do not transfer the card number in the guest bill)
Request information about a member of the loyalty program by phone number
GET /partner/operation/user/{type}/{token}/user-info
{type} - card или phone
{token} - if {type} - card, then fill in with the value of the card number, if {type} - phone, then fill in with the value of the PL member's phone number
An example of a response, with a successful request:
{
"success": true,
"status": 200,
"data": {
"token": "63", //Card number
"user_data": {
"guid": “533a7a29-6928-4aad-a1b3-051bb1717af4”,
"mobile": "380631024903", // phone number
"email": "Alyonahavrylenko@gmail.com", // email address
"first_name": "Helen", //Name
"middle_name": "", //Surname
"last_name": "Teacher", //Last name
"created": 1578488728, // registration date;
"birth_day": "1999-08-08",//Date of birth
"gender": 2, //Pol
"sms_notify": 1, // consent to SMS-mailing (0 - disagree; 1 - agree);
"email_notify": 1, // consent to the email newsletter (0 - disagree; 1 - agree);
"id_region": 86, //region id
"id_city": 1116, //city id
"address": "Peremogy Avenue 12",// Address
"blocked": 0 //Number of member locks
},
"user_status": [],
"profile": {
"work_status": 3,
"children": 0,
"has_auto": 1,
"family_stat": 2
},
"accounts_data": [
{
"account": 2620020401, // wallet number;
"currency": "GOOD", // name of loyalty currency;
"balance": 0, // number of bonuses on the account;
"avialable": 0 // number of available bonuses on the account;
}
],
"cards_data": [
{
"number": "2020000000259", // card number;
"status": 3, // card status (0 - new; 1 - not filled; 2 - blocked; 3 - payment);
"created": 1579167842, // date of map creation (generation);
"date_activated": 1580741547, // activation date (date of the first operation on the card or date of linking the card to the wallet);
"issue_date": null, // card issue date;
"issue_branch": null, // outlet where the card was issued;
"date_blocked": 0, // date of transfer of the card to the "blocked" status;
"type": 1 // card type (1 - main card, 2 - key fob);
},
{
"number": "63",
"status": 3,
"created": 1579166828,
"date_activated": 1579178912,
"issue_date": null,
"issue_branch": null,
"date_blocked": 0,
"type": 1
},
{
"number": "67",
"status": 2,
"created": 1579166828,
"date_activated": 1579167114,
"issue_date": null,
"issue_branch": null,
"date_blocked": 1579167187,
"type": 1
},
{
"number": "2020-80477",
"status": 3,
"created": 1578498242,
"date_activated": 1578910691,
"issue_date": null,
"issue_branch": null,
"date_blocked": 0,
"type": 1
}
],
"gift_bonuses": [ //Information on gift bonuses
{
"id": 268, //Operation ID
"name": "For books",//Name of accrual
"bonus": 1000, //Number of accrued bonuses
"opened_at": 1581948299 // Bonus activation date
}
],
"card_statuses": {
"0": "New",
"1": "Active",
"3": "Payment",
"2": "Blocked"
},
"card_types": {
"1": "Main",
"2": "Slave"
},
"total_amount_spent": 13398 // total amount of participant's purchases. }
}
- Request for changing information about a member of the loyalty program (editing personal data)
PUT /partner/operation/user/{type}/{token}/user-info
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
phone | string | Mobile phone number in the format380######### | |
first_name | string | PL Member Name | |
middle_name | string | Middle name of the participant of the submarine | |
last_name | string | Surname of the PL participant | |
birth_day | string | Date of birth of the participant in the PL in the format 1989-03-17 | |
id_region | integer | Global directory of region of residence | |
id_city | integer | The global directory of the city of residence, linked to the region. | |
gender | integer | Gender: 1 - man 2- woman | |
sms_notify | integer | Subscribe to SMS newsletter: 1-I agree 0-disagree | |
email_notify | integer | Subscribe to email newsletter: 1-I agree 0-disagree | |
string | Email in the format abm@abmcloud.com |
An example of a response, with a successful request:
{
"success": true,
"status": 200,
"data": {
"guid": “77f8f2d6-afad-4123-bd52-0db68df28e74”,
"mobile": "380931000013",
"email": "titkin1@ua-2.com",
"first_name": "Arthur",
"middle_name": "Ivanovich",
"last_name": "I investigated",
"created": 1521451738,//Date of creation
"birth_day": "1979-04-28",
"gender": "2",
"sms_notify": "0",
"email_notify": "0",
"id_region": "91",
"id_city": "1586",
"blocked": 1 //Number of card locks
}
}
Loyalty Program Membership Card Information
Request for information about the card of a member of the loyalty program by card number
GET /partner/operation/user/{token}/card-user-info
{token} - card number for which information is requested
The method returns info on the card + info on the PL participant, if the card is linked to the account.
An example of a response, in case of a successful request, is presented in the Loyalty program member information section.
Request for information about the card of a member of the loyalty program by card number
GET /partner/operation/card/{token}/card-info
{token} - card number for which information is requested
The method returns information on the map
An example of a response, in case of a successful request, is presented in the Loyalty program member information section.
{
"success": true,
"status": 200,
"data": {
"token": "2208801711684",// Card number
"card_data": {
"number": "2208801711684",// Card number
"status": 0, //Map status
"created": 1563365120,// Creation date (map generation in the system)
"date_activated": 0,// Date of activation of the card (transition of the card to the status "Not filled")
"date_blocked": 0,// Date of blocking the card (transferring the card to the status "Blocked")
"user_guid": "Not found",// Guid of the program member who owns the card
"type": 1,// Card type (1-main, 2-trinket)
"main_card_number": "", // Number of the main card if there are key cards
"slave_card_number": "", // Keylock card number, if any.
"card_guid": null,// GUID of the card itself
"issue_date": null,// Date of issue of the card to the program participant
"issue_branch": null// Shop for issuing a card to a program participant
},
"statuses": { // Status is old
"0": "New",// New (the card does not have a bonus account; when it is first sold to such a card, it will automatically switch to the status)
"1": "Active", //The card has a bonus account, but has not yet been fully registered. Can only accumulate bonuses, but not write off
"2": "Blocked", // Blocked. Cannot accumulate or write off bonuses.
"3": "Payment" // Payment. Can accumulate and write off bonuses.
},
"types": { //Card types:
"1": "Main",// Main
"2": "Slave"// Keycard map tied to the main map.
}
}
}
Changing the status of the card at the checkout
The request updates the map data:
- Sets/changes the map status;
- Sets/changes the issue date;
- Sets/changes the issue point;
- Assigns a card to an existing program member.
POST /v2/partner/card/card-update
List of parameters in the request:
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
card_issue_branch | string | Code of the point of sale where the card was issued | |
card_issue_date | integer | Date and time of card issue, transmitted in unix time format | |
card_number | string | Submarine membership card number for which data is updated | |
card_status | integer | Status Card: 1 - Active / New 2 - Blocked 3 - Payment | |
user_card | string | PL membership card number Used to bind an additional card | Identifier of the PL participant, to be used if it is necessary to link a new card to an existing participant. You need to pass one of these parameters |
user_phone | string | The phone number of the PL participant to which the card will be linked, specified in the card_number parameter |
An example of a response, with a successful request:
{
"success": true,
"status": 200,
"data": {
"card_number": "10000009"
}}
Sale
Request pre-calculation by check
POST /v2/partner/operation/pre-check
If the user is a member of the loyalty program, you must fill in the value in the card or phone field. If the user is not a member of the loyalty program, do not transfer card or phone data.
The data received in pre-check must be cached for further receipt printing and sending sales data to the client's accounting system.
The data of the meta parameter in receipt_details corresponds to the value of the product details description customer .
- checks for the presence of a coupon in the system, belonging to a partner
- the possibility of its redemption by a given user at a given time
- associates the coupon code with the number of the transaction to which the coupon will be applied
- pre-calculates the check taking into account the coupon (for a discount coupon)
The request must fill in an existing parameter"coupon"
List of parameters in the request:
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
branch_id | string | Code (id) of the outlet Must first be created in CRM Loyalty | |
card | integer | PL membership card number | |
coupon | string | Coupon code, if there are several coupons, they must be separated by commas | |
offline | boolean | Specifies the operation mode: 1 - offline, 0 - online It is impossible to write off bonuses offline | |
operator_id | string | Cashier code Must first be created in CRM Loyalty | |
phone | string | PL member's phone number | |
receipt_bonus_amount | number | Number of bonuses per checkthat the buyer wants to write off. | |
receipt_currency | string | Bonus currency | Pass BON value |
receipt_datetime | Integer (type: 1470825537) | Date and time of purchase by UTC (GMT) вformat UNIX time | |
receipt_description | string | Purchase Type Description | Normal sale |
receipt_details | string | Purchase details (full list of products and their properties in the receipt) as a JSON array. "position" - position in the receipt. "prod_cat" - product group code. "prod_code" - SKU code. "prod_name" is the full name of the product. "prod_price" - the price of the product. "prod_amount" - the amount of goods. "prod_sum" - the total cost of the product (usually equal to prod_amount * prod_price). bonus_restrict - exclude position from bonus calculation, not required,external_discount - size (in money) of external discount "meta":"{\"parameter1\":\"value\", \"parameter2\":\"value\"}" | |
session_id | integer | Session code | |
terminal_id | string | Checkout code | |
variables | string | Add. product properties as a JSON array Example: {"key1":1, "key2":1} |
Important!!!:
1.bonus_restrict - If the product is sold with a promotion configured in the accounting or cash system, pass 1 to the bonus_restrict parameter so that loyalty mechanics for this product do not work. Do not pass this parameter in other positions.
2. If a discount is triggered on a product, bonuses for this product are not credited and are not written off.
Response example, in case of a successful request (the value in the "pre_check_id" parameter must be saved in order to be passed to the sale confirmation operation)
{
"success": true,
"status": 201,
"data": {
"pre_check": {
"pre_check_id": "1548149007.104900.03",// id that will need to be confirmed using the check-confirm method
"payment": {
"money": 899.03, // "net" amount payable (how much money the user needs to pay, minus discount and bonus discounts
"bonus_redeemed": 1, // how many bonuses were used to pay for the purchase
"discount": 0// discount amount in money
},
"currency": "GOOD",// currency of bonus accrual
"coupon": [
{
"code": "3863NUM6",
"success": false,
"message": "Coupon configuration is not active"
},
{
"code": "6556PRE",// coupon number
"success": true,
"message": "",
"reward_type": "1"
}
], // coupon usedny with this check
"branch_id": "001", // outlet id
"terminal_id": "terminal_1",// checkout id
"operator_id": "operator_1",// cashier id
"session_id": null, // session id
"receipt_amount": 900.03, // total check amount
"payment_bonus": 63.86, // total bonuses accrued by check
"base_bonus": 63.86, //base bonus size (cashback)
"receipt_description": "Precheck test",// description of the check
"birthday_bonus": 0, // birthday bonus
"userStatusFixBonus": 0, // status bonus (only fixed reward amount, not %)
"receipt_details": [
{
"position": 1, // position number in the check
"prod_cat": "20316",// product category (if the product is not in CRM, it is returned as "0")
"prod_code": "13997",// the product sku
"prod_name": "CONF WEIGHT ASSORTED",// product name (if the product is not in CRM, it is returned as "no name product")
"prod_price": "100.01",// product price
"prod_amount": "3",// product quantity (pcs)
"prod_sum": 300.03, // total cost by product item
"bonus_restrict": "ok",
"discount_limit": 300.03, // maximum possible discount for a position
"discount": 0, // size of the applied discount for the position
"parameters": [],// additional position parameters set in the product settings (price, MRP, restrictions on accrual and write-off of bonuses)
"discount_success": [],// information on successfully applied discount promotions
"discount_bonus": 0, // discount amount provided by bonuses in money
"bonus": 0, // number of bonuses accrued per position
"bonus_success": []// detailed information on bonus accruals per position
},
{
"position": 2,
"prod_cat": "20316",
"prod_code": "86163",
"prod_name": "Tekila Patron silver 0.5",
"prod_price": "100",
"prod_amount": "2",
"prod_sum": 200,
"discount_limit": 0,
"discount": 0,
"parameters": {
"price": 100,
"mrp": null,
"discount": 0,
"max_calculation_bonus": 4,
"max_payment_bonus": 0
},
"discount_success": [ // detailed information ondiscounts to position
{
"rule": "coupon",// accrual type, party
"action_id": 0, // share id (for accrual for a share)
"action_title": "",//share name
"info": "6556PRE",
"discount": 7.11, // discount amount in money
"priority": 1// share priority
}
],
"discount_bonus": 0,
"bonus": 4,
"bonus_success": [
{
"rule": "cashback",
"action_id": 0,
"action_title": "",
"bonus": 4,
"priority": 999998
}
]
},
{
"position": 3,
"prod_cat": "20316",
"prod_code": "77765",
"prod_name": "MIKE PACKAGE FIRM ELISEY 12KG",
"prod_price": "100",
"prod_amount": "2",
"prod_sum": 200,
"discount_limit": 200,
"discount": 0,
"parameters": [],
"discount_success": [],
"discount_bonus": 0.5,
"bonus": 29.93,
"bonus_success": [
{
"rule": "cashback",
"action_id": 0,
"action_title": "",
"bonus": 29.93,
"priority": 999998
}
]
},
{
"position": 4,
"prod_cat": "20316",
"prod_code": "13997",
"prod_name": "CONF WEIGHT ASSORTED",
"prod_price": "100",
"prod_amount": "2",
"prod_sum": 200,
"discount_limit": 200,
"discount": 0,
"parameters": {
"price": 100,
"mrp": 95,
"discount": 0,
"max_calculation_bonus": 200,
"max_payment_bonus": 200
},
"discount_success": [],
"discount_bonus": 0.5,
"bonus": 29.93,
"bonus_success": [
{
"rule": "cashback",
"action_id": 0,
"action_title": "",
"bonus": 29.93,
"priority": 999998
}
]
}
],
"sms_id": 6756,
"max_payment_bonus_check": 2264.5, // maximum number of bonuses to write off (in bonuses)
"max_payment_money_check": 226.45, // the maximum number of bonuses to write off (in a monetary unit with a transfer coefficient of 1 bonus = 10 kopecks, it may differ for you)
"balance_available": 100 , //available bonuses on the account in the PL participant
"discount_fail": [],//information on discount promotions that have not been applied (the promotion is active, but the condition for its operation is not met in the check)
"bonus_fail": []//information on unapplied bonus promotions
}
}
}
Recommendation:
- parameters received in response to pre_check "max_payment_bonus_check" and
- "balance_available" display the minimum of them at the checkout as "Maximum possible number of bonuses to write off:"
- "sms_id": 6756, - SMS identifier for confirmation of debiting bonuses by code from SMS
- pre_check_id - valid for 10 days
Examples of responses from ABM when using coupons in a receipt:
Loyalty Response Example | Meaning |
---|---|
"coupon": [ { "code": "1000896246", "success": true, "message": "", "template_name": "Titan Bonus Coupon", "reward_type": 0 } ] | This coupon is valid and can be used on this receipt |
"coupon": [ { "code": "1000110027", "success": false, "message": "Coupon redeemed" } ] | This coupon has already been redeemed. |
"coupon": [ { "code": "1000358936", "success": false, "message": "Coupon configuration is not active" } ] | The specified coupon has expired |
"coupon": [ { "code": "1000303888", "success": false, "message": "Wrong user", "template_name": "Discount Coupon" } ] | This coupon does not belong to the specified user |
"coupon": [ { "code": "1000572007", "success": false, "message": "Coupon is out of date" } ] | This coupon has not yet expired |
"coupon":[ { "code":"CUP20416079", "success":false, "message":"Condition Order sum is not met" } ] | The coupon conditions for the check amount are not met (the check amount is less than specified in the coupon conditions) |
Sales Confirmation Request
POST /v2/partner/operation/check-confirm
- confirms the execution of the check, write-off and accrual of bonuses (pre_check_id - valid for 10 days)
- applies the coupon (puts a mark on the use)
List of parameters in the request:
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
box | number | The amount of money that will be transferred to bonuses according to the write-off ratio. The piggy bank functionality should be implemented. | |
check_number | integer | Check number Sales operation code. When forming, it must be unique in the context of a partner | Format: Check_number_+_Purchase_date |
payment_type | string | Array with payment types. Example: [{"type":1,"sum":899},{"type":2,"sum":0.00}] | |
pre_check_id | string | Code (ID) of the operation received in response to the POST request /v2/partner/operation/pre-check |
Sample response, upon successful request
{
"success": true,
"status": 201,
"data": {
"pre_check_id": "1548149007.104900.03", // identifier of the confirmed check
"check_number": "100110", // check number sent by the cashier
"box_bonus": 0.07, // bonuses transferred to the piggy bank
"bonus_accrued": 63.93, // accrued bonuses
"bonus_redeemed": 1, // written off bonuses, as payment
"bonus_balance": 288, // user's bonus balance after check payment
"c2b_result": { // information on journal operations
"success": true, // operation status
"errorDescription": "", // description in case of error
"processing_transaction_datetime": 1548150560, // operation time in unixtime
"c2b_check_number": "C2B-100110"// operation id
},
"b2c_result": { // information on journal operations
"success": true, // operation status
"errorDescription": "", // description in case of error
"processing_transaction_datetime": 1548150560, // operation time in unixtime
"b2c_check_number": "B2C-100110" // operation id
},
"coupon": [ // coupon information
{
"code": "6067PRECHECK",
"success": true,
"message": "",
"options": {
"received_discount": "16.85",
"redemption_count": 1
},
"reward_type": "1"
}
]
}
}
Purchase returns
POST /partner/operation/check-return
List of parameters in the request:
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
branch_id | string | Code (id) of the outlet | |
check_number | string | Return receipt number | |
operator_id | number | Cashier code | |
return_check_number | string | Number of the sale (receipt) to be returned | |
return_datetime | integer (type: 1550478564) | Date and time of return | |
return_details | string | List of codes of goods and their quantities that are subject to return. Example: [{"prod_code":"139974","prod_amount":1}] | |
terminal_id | number | Checkout code |
Sample response, upon successful request
#Response for loyalty program particiiant
{
"success": true,
"status": 201,
"data": {
"return_check_number": "471", // number of the sales receipt from which the return was made
"check_number": "4587", // return receipt number
"branch_id": "001", // outlet id
"terminal_id": null, // checkout id
"operator_id": null, // cashier id
"b2c_returned": 15, // number of bonuses returned to the partner's account
"b2c_transaction_id": 471, // transaction id for returning bonuses to the partner's account
"c2b_returned": 0.5, // number of bonuses returned to the client's account
"c2b_transaction_id": 470, // transaction id for returning bonuses to the client's account
"message": "b2c - all bonuses cleared" // message about the returned bonuses to the partner's account (whether it was possible to return the bonuses, if yes, then all the bonuses or only a part)
}
}
#Response for anonymous client
{
"success": true,
"status": 201,
"data": {
"return_check_number": "CN-1570437820-db", // number of the sales receipt from which the return was made
"check_number": "CN-1570437820-ret", // return receipt number
"branch_id": "1", // outlet id
"terminal_id": null, // checkout id
"operator_id": null, // cashier id
"b2c_returned": 0, // number of bonuses returned to the partner's account
"b2c_transaction_id": null, // transaction id for returning bonuses to the partner's account
"c2b_returned": 0, // number of bonuses returned to the client's account
"c2b_transaction_id": null, // transaction id for returning bonuses to the client's account
"message": "Does not require transaction execution" // message about the returned bonuses to the partner's account (whether it was possible to return the bonuses, if yes, then all the bonuses or only a part)
}
}
Offline mode
If it is not possible to send data to the Loyalty CRM, then it is necessary to store this data in a separate storage and upload it according to the regulations, it is recommended 1-2 times a day
The timetable is flexible so that the client himself can change the time if necessary.
It is impossible to display the state of the cashier at the checkout - online / offline - it is impossible to write off bonuses.
List of operations in offline mode
- sales operations
Data on sales of anonymous buyers and PL participants is accumulated at the checkout, when accessing loyalty, data on the purchase is sent andcool bonuses. Write off bonuses offlineimpossible – display a dialog box at the checkout: “The checkout is in offline mode. It is impossible to write off bonuses.” In the method
POST /v2/partner/operation/pre-check transfer to the offline parameter - 1 (offline), then apply the method POST /v2/partner/operation/check-confirm
- return operations
Data on the returns of anonymous buyers and PL participants are accumulated at the checkout, when accessing loyalty, data on the return with the deduction of accrued bonuses and the accrual of deducted bonuses are sent.
POST /partner/operation/check-return
Recommendation
To be able to identify an offline transaction in the system reports, we recommend adding the word ”off” to the check number.
Example for POST /v2/partner/operation/check-confirm
check_number | integer | Check number Sales operation code. When forming, it must be unique in the context of a partner | off+Receipt_number_+_Date_of_purchase |
---|
Example for POST /partner/operation/check-return
check_number | string | Return receipt number | off+Check_number |
---|
Referral program
POST /partner/referral/link
Participation in the RP is not required. Part of the loyalty program participants may be in the RP, while the other part of the participants may be ordinary loyalty card holders.
There is no permanent binding of the Referral to the Referrer. The Referral-Referrer ratio may vary from operation to operation.
Several referrals can be linked to one referrer. The referral can change his referrer, while the old connection is not deleted, but goes into an inactive status.
Referee (referrer) – PL participant, on the recommendation of which referrals make transactions.
Referral (referee) – an LP participant who performs an operation on the recommendation of another participant.
RP – referral program
The link referral -> referrer can be created in two ways:
- when registering, if the future PL participant has indicated the referrer ID and the event is being executedRegistration.
- after registration, if the PL participant indicated the referrer ID, while the eventRegistration is not performed.
The referrer ID can be changed by the referral at any time. In this case, a new connection referrer -> referral is created in the system, and the old connection is deactivated (we save it for history and reporting).
EventRegistration considered completed if the PL participant has filled in all the required fields of the questionnaire and indicated the identifier of his referrer (the link of the referrer is indicated at the time when the user is given the registration date in rtl_users.start_day). After that, the referrer -> referral connection is created in the system and the event is recordedRegistration.
Algorithm:
- Creating a user in the system
- Creating a referrer -> referral link using the /partner/referral/link method
- Completion of registration (filling in all required fields of the questionnaire)
EventPurchase considered completed if at the time of purchase the PL participant is a referral (there is an active connection referrer -> referral in the system). After that, an event is recorded in the systemPurchase.
Algorithm:
- Pre-calculation by check using the pre-check method
- Creating a referrer -> referral link using the /partner/referral/link method
- Check confirmation using the check-confirm method
Or
- Creating a referrer -> referral link using the /partner/referral/link method
- Pre-calculation by check using the pre-check method
- Check confirmation using the check-confirm method
Algorithm:
- Creating a user in the system
- Creating a referrer -> referral link using the /partner/referral/link method
- Completion of registration (filling in all required fields of the questionnaire)
Name | Data type | Description | Corresponds to the value in the Client |
---|---|---|---|
refereeToken | string | Token (card/phone number of the person making the sale) | |
refereeType | string | Treferee identification type (card/phone) | |
referToken | string | Token (card/phone numberon whose recommendation the operation takes place) | |
refererType | string | Referrer identification type (card/phone) |
Example of a successful response:
{
"success": true,
"status": 201,
"data": {
"refererType": "card",
"referToken": "20000000001",
"refereeType": "card",
"refereeToken": "20000000001"
}
}
Mistakes
Error code | Response text from ABM server | Reason |
---|---|---|
pre-check (Sales) | ||
401 | "name": "Unauthorized", "message": "Your request was made with invalid credentials.", | Authorisation Error. Invalid token specified. |
404 | "name": "Not Found","message": "Page not found.", | There was a mistake in the server address |
422 | "field": "receipt_details", "message": "Receipt Details cannot be blank." | An error was made in the receipt details (separator, parameters, etc.) |
422 | "field": "branch_id","message": "Partner branch not found" | An outlet with this Id was not found |
422 | "field": "variables", "message": "Invalid variables format" | Variable syntax error for stock |
422 | "field": "card","message": "Card not found" | The specified card is not in the loyalty program |
422 | "field": "errors","message": "User not found" | The specified user is not in loyalty |
422 | "field": "receipt_bonus_amount", "message": "Maximum 330 bonuses" | Bonus redemption limit exceeded |
422 | "field": "phone", "message": "User is blocked" | If the user is blocked |
422 | "field": "terminal_id","message": "Terminal not found" | Checkout with this Id was not found |
422 | "field": "operator_id", "message": "Operator not found" | Cashier with this ID was not found |
500 | "Internal Server Error" | External Server Error |
check-confirm(Sale) | ||
422 | "field": "payment_type", "message": "The amount of the check does not match and the amount transferred in the payment_type." | Payment amount does not match |
422 | "field": "payment_type", "message": "Wrong payment type." | Syntax error in "payment_type" |
422 | "field": "pre_check_id", "message": "Pre check not found." | pre_check_id not found |
422 | "field": "pre_check_id","message": "Pre Check Id cannot be blank." | "pre_check_id" not passed |
422 | "field": "check_number", "message": "Such check number already exists" | This check_number is already taken |
422 | "field": "payment_type","message": "Payment Type cannot be blank." | "payment_type" not passed |
422 | "field": "pre_check_id", "message": "This check has already been confirmed." | pre_check_id is invalid or was previously validated |
500 | "Internal Server Error" | External Server Error |
check-return (Return) | ||
422 | "field":"return_details","message":"Unable to return product 1930612 | It is not possible to return a product with this code, it is not in the specified receipt, or this product has already been returned |
422 | "field":"return_check_number","message":"Check not found" | The specified refund receipt was not found in the loyalty program |
500 | "Internal Server Error" | External Server Error |