Send Finalize Transaction
POST/client/users/:correlation_id/activity/finalize/v2
This call sends a finalize activity associated with a user and returns the details regarding earning, redeeming, and offer rewards (point and/or non-point) the user has incurred with the purchase transaction.
Optional Parameter - The callId can be optionally included to further specify the request that was made to the ES Loyalty Platform which flows through to reporting. It should be just as unique as the correlationId. If not provided, a GUID is generated in its place.
In some cases, points can only be awarded after payment or fulfillment of the order have taken place, resulting in delayed transactions. Adding the following object to the end of the call supports a delayed transaction that requires confirmation.
"confirmation": {
"mode": "CART"
}
The response includes information about the confirmation status.
"ConfirmationDetails": {
"confirmed": true,
"mode": "CART"
}
The tender object contains details about payment tender(s). Within the tender object, the tender type and value can be presented as a key:value pair or, if more data is required as with a payment card, in an array. There can also be a mixture of both types within the tender object.
As a key:value pair:
"tender": {
"CASH": "200",
"LOYALTY": 100
}
As an array:
"tender": {
"VISA": [
{
"idType": "LAST_4",
"prefix": "12345",
"suffix": "1235",
"amount": "500"
}
}
}
Note: For a single members or in a household, if a redemption transaction begins, but one or more of the cards are subsequently set to a non-active state such as Suspended, Lost or Stolen, Fraud/Abuse, Cancelled, or Damaged before the redemption transaction is completed, then to prevent fraud, the redemption amount is still withdrawn from the single member or proportionally from all household members who had active cards before the redemption transaction began.
Request
Body
| Attribute | Description | Format | Notes |
|---|---|---|---|
| action | Describes the action carried out by the Finalize request. | String | Required; for example, "PURCHASE" or "NON_POINT_REWARD" |
| channel | Identifies the channel through which the action takes place. | Enum: "STORE", "POS", "WEBSITE", "APP", "PARTNER" | Required. Default is "POS". The client can set this value, but it cannot be null or blank. |
| locale | Locale of the member. | String, values currently supported are: "en-CA", "en-US" and "fr-CA"; "EN" and "FR" can be used as well, but only for the member record (on the account level) | Optional. Priority order: (1) value from the POS system; (2) locale set on the account; (3) environment locale. If locale is not provided or is not a valid value, system default ("en-CA") is used. |
| reservationToken | Uses a token for API requests that include reserved points. | String | Optional. See the Reserve for Redemption request. |
| transactionDate | Timestamp for the transaction (date and time) in ISO-8601 format. | String | Required |
| retailBanner | A store grouping or type. Transactions will default if a single BU or banner exists based on configuration. OAuth takes control of processing. | String | Optional |
| storeNumber | Unique identifier for the store where the purchase transaction took place. | String | Required. Used for targeting, analytics, and support. |
| tillNumber | Unique identifier for the till in the store at which the purchase transaction took place. | Number | Optional. Used for analytics and support. |
| employeeCode | Unique identifier for employee who carried out the transaction. CSR of the transaction. | Number | This attribute is optional for operations but required for analytics. |
| loyaltyId | Unique identifier for each member. | Number | Optional. This can be captured in the Start Session request. |
| externalTransactionID | Unique identifier for transaction used by the client. | String | Optional. |
| priceMatrix | Designates whether the transaction is retail or an employee purchase. | Enum: "R" or "E" | Required. "R" for retail, "E" for employee. |
| locale | Used to change the receipt message language response for this transaction. Defaults to the client's chosen language when not present. | String, values currently supported are: "en-CA" and "fr-CA" as well as "EN" and "FR" | Optional. "en-CA" for English. "fr-CA" for French. |
| callId | Unique request identifier. | String | Optional. Can be auto-generated if none provided. Supports tracking specific calls to be captured within a specific session for analytics. (Secondary Correlation ID). |
| cart | Object containing array of saleLineItems | Object | Required. JSON Object containing array of saleLineItems. |
| saleLineItems | Contains details of one transaction item. | Array | Required. JSON Object containing line items. See saleLineItems Details below this table |
| subCategory | Same subcategory as in Product feed. | Number | Can be blank to force system to grab subcategory from product data. This is an optional attribute. |
| sku | The product identifier scanned at POS. | Number | Required |
| quantity | Measure of product amount sold. | Number; for some clients, may include values confirmed to be as low as 0.000001 | Required. Can be partial value for unit of measure calculations where there is no directly-applicable SKU (for instance, rope sold by the foot). |
| originalSaleAmount | The Manufacturer's Suggested Retail Price for a product. | Number | Required. Single-unit MSRP in pennies. |
| subCategory | Identifier for the sub-category associated with the product. | String | |
| productName | Unique product name. | String | |
| saleAmount | MSRP less the discount, the actual sale price. | Number | Required. MSRP minus item discount in pennies. |
| storeCoupon | Store-based coupon. | Number | Optional. This is informational only, no active discounting occurs in ESL. This attribute is optional. |
| itemDiscount | Amount discounted. | Number | Optional. This attribute is optional. In pennies. |
| mnfCoupon | Manufacturer Coupon. | Number | Optional. This is informational only, no active discounting occurs in ESL. This attribute is optional. |
| promoCoupon | Flyer coupon. | Number | Optional. This is informational only, no active discounting occurs in ESL. This attribute is optional. |
| itemTax | Tax on the item. | Number | Required. Tax on the line item in pennies. |
| finalSaleAmount | Total sale amount for a specific product, the discounted price times the quantity purchased. | Number | Required. quantity * saleAmount |
| tags | To provide additional information | String | Required, but can be empty. |
| rewardTags | To provide additional information about specified rewards. | Object | Required, but can be empty. Contains offer name(s) and associated reward(s) as key:value pairs. |
| itemCost | Total cost for a specific product, the cost per unit times the quantity purchased. | Number | Optional. cost per unit * quantity. This attribute is optional. |
| couponCodes | Purchase-level coupons. | String | Optional. |
| extendedData | Client keys needed for analytics of the transaction. | Optional. Maximum 1KB, 1 level deep, 10 keys maximum. | |
| totalSaleAmount | Total of all items sold on this transaction, including tax. | Number | Required. Summed up, tax included, total of all saleLineItems. In pennies. |
| tender | JSON Object containing transaction tender used. | Object | Required. Contains one or more type of tender and details of each (as required). |
| {tender_type} | Array containing one or more objects for a particular type of tender (such as "VISA" which replaces {tender_type}). | String for tender type name, then array containing an object for each instance of that tender type. | Contains idType to amount below. Possible values for {tender_type}: "CASH", "COUPON" (flyer coupon), "REWARDS" (non-points rewards), "AMEX", "MSTCARD", "VISA", "GWCOUP", "MCOUPON" (manufacturer's coupon), "LOYALTY" (points) |
| idType | Type of the card identifier being passed in. | String | Optional. "TOKEN", "LAST_4", etc. |
| prefix | Prefix of the card identifier. | Number | Optional. Usually the BIN or first 6 digits of the card. Used for partner-based offers. This attribute is optional. |
| suffix | Suffix of the card identifier. | Number | Optional. Usually the last 4 digits. Used for partner-based offers. |
| amount | Total amount of the tender that was spent using this specific card/tender. | Number or String | Required. Total amount of the tender that was spent using this specific card/tender. |
| LOYALTY | Reserved key that denotes in cents the dollars spent by exchanging for loyalty points. | Number | Optional. Used for redemption-based actions. |
| REWARDS | Contains data about non-points rewards. | Object | Contains every non-points reward offer in this transaction. Contains {offer_name} to itemsAdjusted. |
| {offer_name} | Contains details about one non-points reward offer. | String | Shows the quantity of the non-loyalty reward offer in dollars and whether it has been adjusted in the cart. Contains total and itemAdjusted below. |
| total | The total amount of the non-points currency reward associated with the offer in cents. | Number or String | |
| itemsAdjusted | Gives the flexibility to the POS system to selectively choose to adjust the cart for some non-points offers and not for others. | Boolean | If true, the cart/item sale amounts are already adjusted using the non-points rewards amount and no further adjustment is required. The point-based cart evaluation proceeds. If false, promo but did not adjust the cart for that at the time of sending the request. The promo-engine will adjust the cart first and then do further evaluation of the points-based offers. |
saleLineItem Details
-
Original Sale Amount = Original price per Unit
-
Sale Amount = Discounted price per Unit
-
Final Sale Amount = Discounted Price per Unit * Quantity
-
itemCost = Cost per Unit * Quantity
Response
To view the hierarchy, see the example Response.
| Attribute | Definition | Format | Notes |
|---|---|---|---|
| earned | Contains points earned on all applicable programs. | Object | Besides "loyalty," there may be other programs such as a partner program (and related object) with additional points awarded. For instance, may contain "rewards" object. |
| loyalty | Contains points earned on the loyalty program. | Object | |
| base | The number of base rewards earned on the transaction. | Number | Base points = points for any transaction based on spend. |
| bonus | The number of bonus rewards earned on the transaction. | Number | Bonus points = points for completing particular behaviour. |
| targeted | The number of points attributable to targeted offers. | Number | Targeted points = points derived from targeted offer. |
| total | The total of all points earned on the transaction. | Number | = base + bonus + targeted points |
| rewards | Rewards awarded as non-loyalty points (for instance, in dollars). | Object | Contains list of non-loyalty point rewards. |
| DOLLAR | Dollar amount of reward. | Number (in cents) | Optional, can be 0 |
| GAMEPLAY | Contains applicable game offers. | Object | Includes {{gameOfferName}} field(s) |
| {{gameOfferName}} | Name of one game offered. | String | There may be one or more of the game offers and associated game names |
| {{partnerName}} | Contains partner points data. | Object | May contain same attributes as "loyalty" above |
| loyaltyID | Loyalty Card number for the session. | Number | If loyaltyId was not provided in the request, then this is the primary card number on the account |
| pointsRedeemed | The number of points redeemed. | Number | Always 0 for this type of request. To redeem points, use Send Finalize Transaction (with Redemption). |
| pointsEarnedTotal | The total of points earned after redemptions. | Number | total minus pointsRedeemed |
| offerRewards | Contains details of one or more offer rewards. | Array | |
| offerDescription | General description of offer. | String | For instance, "Spend $20 and get 500 points." |
| offerDescription2 | Additional details of offer. | String | For instance, "Offer good through March 22." |
| promotionHeadline | Headline under which offer is promoted. | String | For example: "Spend $20 and get 500 points." |
| offerCode | Unique code identifying offer. | String | |
| pointsEarned | Points earned for this offer. | Number | |
| isTargeted | Flags whether the transaction results from a targeted offer. | Boolean | |
| isDiscretionary | Flags whether the transaction is discretionary. | Boolean | |
| stacking | Used to provide data about reward groups and the winning group for rewards when one or more of the rewards are based on units. | Object | Contains rewardGroups and winningGroup |
| rewardGroups | All possible reward groups for this reward. | Array | Contains one or more reward groups |
| winningGroup | Winning reward group, the one used for this reward. | String | Contains one reward group from the array in rewardGroups |
| currency | Currency used for this offer reward. | String | For instance, if the member is rewarded with game play, this will be "GAMEPLAY" |
| scope | Contains details of one or more offer reward(s). | Object | Contains type attribute and metadata object below |
| type | Type of reward | String | For instance, if the member is rewarded with game play, this will be "GAMEPLAY" |
| metadata | Contains details for the type of offer reward. | Object | For example, for game play, contains gameID and gameProvider below for each game used as reward |
| gameID | Unique identifier for game. | String | |
| gameProvider | Name of vendor providing the game. | String | |
| partnerID | Identification of a partner. | String | Used only with partner offerRewards, if relevant. |
| Cart | Object containing array of saleLineItems; used if configuration allows return of cart details in response. | Object | Required. JSON Object containing array of saleLineItems. |
| saleLineItems | Contains details of one transaction item. | Array | Required. JSON Object containing line items. See saleLineItems Details below this table |
| subcategory | Same subcategory as in Product feed. | Number | Optional. Can be blank to force system to grab subcategory from product data. |
| sku | The product identifier scanned at POS. | Number | Required |
| quantity | Measure of product amount sold. | Number; for some clients, may include values confirmed to be as low as 0.000001 | Required. Can be partial value for unit of measure calculations where there is no directly-applicable SKU (for instance, rope sold by the foot). |
| originalSaleAmount | The Manufacturer's Suggested Retail Price for a product. | Number | Required. Single-unit MSRP in pennies. |
| saleAmount | MSRP less the discount, the actual sale price. | Number | Required. MSRP minus item discount in pennies. |
| subCategory | Identifier for the sub-category associated with the product. | String | |
| productName | Unique product name. | String | |
| storeCoupon | Store-based coupon. | Number | Optional. This is informational only, no active discounting occurs in ESL. This attribute is optional. |
| itemDiscount | Amount discounted. | Number | Optional. This attribute is optional. In pennies. |
| mnfCoupon | Manufacturer Coupon. | Number | Optional. This is informational only, no active discounting occurs in ESL. This attribute is optional. |
| promoCoupon | Flyer coupon. | Number | Optional. This is informational only, no active discounting occurs in ESL. This attribute is optional. |
| itemTax | Tax on the item. | Number | Required. Tax on the line item in pennies. |
| finalSaleAmount | Total sale amount for a specific product, the discounted price times the quantity purchased. | Number | Required. quantity* saleAmount |
| tags | To provide additional information | String | Required, but can be empty. |
| rewardTags | To provide additional information about specified rewards. | Object | Required, but can be empty. Contains offer name(s) and associated reward(s) as key:value pairs. |
| itemCost | Total cost for a specific product, the cost per unit times the quantity purchased. | Number | Optional. cost per unit * quantity. This attribute is optional. |
| totalSaleAmount | Total of all items sold on this transaction, including tax. | Number | Required. Summed up, tax included, total of all saleLineItems. In pennies. |
| couponCodes | Purchase-level coupons. | String | Optional. |
| extendedData | Client keys needed for analytics of the transaction. | Optional. Maximum 1KB, 1 level deep, 10 keys maximum. | |
| tender | JSON Object containing transaction tender used. | Object | Required. Contains one or more type of tender and details of each (as required). |
| {tender_type} | Array containing one or more objects for a particular type of tender (such as "VISA" which replaces {tender_type}). | String for tender type name, then array containing an object for each instance of that tender type. | Contains idType to amount below. Possible values for {tender_type}: "CASH", "COUPON" (flyer coupon), "REWARDS" (non-points rewards), "AMEX", "MSTCARD", "VISA", "GWCOUP", "MCOUPON" (manufacturer's coupon), "LOYALTY" (points) |
| total | Total of the sale transaction. | Object | Contains subTotal, totalSaleAmount, and taxAmount within each sale object type |
| {transaction status type} | Status of transaction. | String | For example, "final"; contains totalSaleAmount, subTotal, and taxAmount below |
| totalSaleAmount | The total amount of the sale including tax. | String | |
| subTotal | The total amount of the sale before tax. | String | |
| taxAmount | The tax generated on the sale. | String | |
| idType | Type of the card identifier being passed in. | String | Optional. "TOKEN", "LAST_4", etc. |
| prefix | Prefix of the card identifier. | Number | Optional. Usually the BIN or first 6 digits of the card. Used for partner-based offers. This attribute is optional. |
| suffix | Suffix of the card identifier. | Number | Optional. Usually the last 4 digits. Used for partner-based offers. |
| amount | Total amount of the tender that was spent using this specific card/tender. | Number or String | Required. Total amount of the tender that was spent using this specific card/tender. |
| LOYALTY | Reserved key that denotes in cents the dollars spent by exchanging for loyalty points. | Number | Optional. Used for redemption-based actions. |
| REWARDS | Contains data about non-points rewards. | Object | Contains every non-points reward offer in this transaction. Contains {offer_name} to itemsAdjusted. |
| {offer_name} | Contains details about one non-points reward offer. | String | Shows the quantity of the non-loyalty reward offer in dollars and whether it has been adjusted in the cart. Contains total and itemAdjusted below. |
| total | The total amount of the non-points currency reward associated with the offer in cents. | Number or String | |
| itemsAdjusted | Gives the flexibility to the POS system to selectively choose to adjust the cart for some non-points offers and not for others. | Boolean | If true, the cart/item sale amounts are already adjusted using the non-points rewards amount and no further adjustment is required. The point-based cart evaluation proceeds. If false, promo but did not adjust the cart for that at the time of sending the request. The promo-engine will adjust the cart first and then do further evaluation of the points-based offers. |
| stacking | Identification of a stacking group showing rewardsGroups associated with the transaction and the highest rewarding offer in that group (winningGroup). | Object | Optional. Contains information about the stacking group for the transaction. |
| rewardsGroups | Identifies the rewards group(s) associated with the transaction. | Array | Contains the name(s) of the rewards group(s). |
| winningGroup | Identifies the reward group that won the highest rewarding offer. | String | Contains the name of the winning group. |
| receiptMessage | Message to show on the receipt. | String | The message may differ depending on points earned, redeemed, both, or neither. It may also be a generic message or specific to the client depending on configuration. |
| message | Details of transaction not shown to consumer. | String | Provides information about the transaction and any redemptions. |
| pointsBalance | Total number of points currently attributed to this account. | Number | Rewards balance in points. |
| redeemableBalance | Maximum balance quantity in currency that can currently be redeemed | Number | An increment of a standard redemption amount. For instance, with a pointsBalance of 120000 and currency rewards of $10 per 25000 points, this value would be 40, or four increments of 10. |
| redeemablePointBalance | Maximum number of points that can currently be redeemed. | Number | An increment of a standard redemption amount. For example, with a pointsBalance of 110000, the user may be able to redeem 100000, or four increments of 25000. |
| household | Object containing information about the household to which the member belongs. | Object | Only returned if the member is a member of a household. |
| id | Unique identifier for the household. | String | |
| role | The member's role in the household. | Enum: "PRIMARY" or "SECONDARY" | |
| balance | Object containing data about the balances available to the household. | Object | |
| totalPointsBalance | The total points balance of the household. | Number | The sum of all member balances. |
| totalDollarBalance | The total dollar balance of the household. | Number | The sum of all member balances. |
| totalAvailablePointBalance | The total points available to the household. | Number | |
| totalAvailableDollarBalance | The total dollars available to the household. | Number | |
| totalRedeemablePointBalance | The total number of points that can currently be redeemed by the household members. | Number | |
| totalRedeemableDollarBalance | The total number of dollars that can currently be redeemed by the household members. | Number | |
| minRedeemPoints | The minimum number of points that can be redeemed by the household. | Number | |
| maxRedeemPoints | The maximum number of points that can be redeemed by the household. | Number | |
| minRedeemDollars | The minimum number of dollars that can be redeemed by the household. | Number | |
| maxRedeemDollars | The maximum number of dollars that can be redeemed by the household. | Number |
Error Responses
| statusCode | errorMessage | errorCode | Definition |
|---|---|---|---|
| 400 Bad Request | Session correlation ID does not exist--create it first. | INVALID_REQUEST | Create session correlation ID before sending this request. |
| 400 Bad Request | Session Closed | INVALID_REQUEST | Cannot process this request because the session is closed. |
| 400 Bad Request | Session Expired | INVALID_REQUEST | Cannot process this request because the session has expired. |
| 400 Bad Request | Cart cannot contain zero-quantity line items | INVALID_REQUEST | Cannot process request when cart includes one or more line items with quantity of zero. |
| 400 Bad Request | Invalid Extended data : Exceeded data size limit for extended data : {dataSize} Bytes | INVALID_REQUEST | When extendedData size exceeds the size limit. See the limit on ConfigType = EXTENDED_DATA, on Platform.DataSizeLimitInKb. |
| 400 Bad Request | Invalid Extended data : Exceeded root level key limit for extended data : {numberOfKeys} keys | INVALID_REQUEST | When extendData exceeds number of attributes/keys limit. See the limit on ConfigType = ‘EXTENDED_DATA’, on Platform.TopLevelKeysLimit. |
| 400 Bad Request | Anonymous users cannot redeem. | INVALID_REQUEST | When session is anonymous and it’s a redemption transaction. Member must be registered for redemption. |
| 400 Bad Request | Invalid confirmation mode. | INVALID_REQUEST | When confirmation is informed on request’s body, but confirmation.mode is different from ‘CART’. |
| 400 Bad Request | This card or user is not eligible for redemption. | INVALID_REQUEST | When it’s a redemption transaction and user is not eligible for redemption. |
| 400 Bad Request | Invalid reservation Token provided. | INVALID_REQUEST | When it’s a redemption transaction and an invalid reservationToken is included in request body. |
| 400 Bad Request | Reservation token has expired. | INVALID_REQUEST | When it’s a redemption transaction and an expired reservationToken is included in request body. |
| 400 Bad Request | Products (or their quantities) do not match the Reservation request. | INVALID_REQUEST | Products used in the reservation request must be the same ones redeemed for. |
| 400 Bad Request | Channel should be a string value. | INVALID_REQUEST | Cannot use data type other than string value for channel attribute. For example, channel attribute value cannot be a Boolean (rue, false, or null). |
| 400 Bad Request | storeNumber is mandatory and required to be non-empty. | MISSING_REQUIRED_FIELDS_ERROR | A required attribute is missing from the request, or a required attribute has an empty value. |
| 409 Conflict | Too many simultaneous requests for the same account. | CONFLICT_REQUEST | Reduce number of simultaneous requests. |
| 500 Unexpected Error | An unexpected error occured. Please report guid: {{GUID}}. | UNKNOWN | An unexpected error has occured. Contact your Exchange Solutions representative with the GUID code above for more information. |
Request
Responses
- 200
- 400
- 409
- 500
200 - Transaction Finalized
Response Headers
Fri, 02 Oct 2020 16:59:12 GMT938keep-alive78159b02-6465-4e38-874c-3e65476ff414no-referrer1;mode=block*max-age=86400max-age=31536000vibrate 'none'; geolocation 'none'sameoriginconnect-src 'none';object-src https://*.cloudfront.net;script-src https://*.cloudfront.netTytfBHRNoAMF99g=no-cache, no-store, must-revalidatenosniffRoot=1-5f775c60-6d481fe94d4d3633480daa9c;Sampled=0400 - Cart Cannot Contain Zero-Quantity Line Items
Response Headers
Thu, 10 Jun 2021 19:14:13 GMT110keep-aliveb86004a4-3eb3-4116-9589-69df12d52f35no-referrer1;mode=block*max-age=86400max-age=31536000vibrate 'none'; geolocation 'none'sameoriginconnect-src 'none';object-src https://*.cloudfront.net;script-src https://*.cloudfront.netAuSkxEn8IAMF8Eg=no-cache, no-store, must-revalidatenosniffRoot=1-60c26484-48ddc5ba39023f56572c2a5a;Sampled=0409 - Too Many Concurrent Requests for the Same Account
Response Headers
Thu, 10 Jun 2021 19:14:13 GMT110keep-aliveb86004a4-3eb3-4116-9589-69df12d52f35no-referrer1;mode=block*max-age=86400max-age=31536000vibrate 'none'; geolocation 'none'sameoriginconnect-src 'none';object-src https://*.cloudfront.net;script-src https://*.cloudfront.netAuSkxEn8IAMF8Eg=no-cache, no-store, must-revalidatenosniffRoot=1-60c26484-48ddc5ba39023f56572c2a5a;Sampled=0500 - Unexpected Error
Response Headers
Thu, 17 Jun 2021 13:47:11 GMT143keep-alive5ca5d5c1-2619-4af0-b04e-552f2981c7ddno-referrer1;mode=block*max-age=86400max-age=31536000vibrate 'none'; geolocation 'none'sameoriginconnect-src 'none';object-src https://*.cloudfront.net;script-src https://*.cloudfront.netBEnOuF4ToAMFXlQ=no-cache, no-store, must-revalidatenosniffRoot=1-60cb525e-474b80a15a24737f4f85fd08;Sampled=0