POS Validation API
Introduction
The POS API allows retailers to automatically redeem coupons through their POS.
General principles
Background
Through the POS integration, retailer can redeem coupon codes from Liquid Barcodes. The process is a two step process. Step 1 is Reserve, Step 2 is Validate or Cancel.
Nomenclature
In order to maintain consistency throughout the description the following terms have been used. To avoid ambiguity they are defined here:
Name
|
Description
|
---|---|
Barcode | Graphical, scannable / machine-readable, representation of code (including prefix). |
Cancellation | The cancellation of a reservation whose conditions were not met. |
Code | A code given to the customer representing an offer given to the same customer. |
Coupon | A coupon (image or text) containing a code (see above). |
Internal reference ID | An unique reference that uniquely identifies this transaction from the perspective of the POS. If more than one parameter is used, the field takes the format “parameter1:parameter2:parameter3“ |
LIQUID | A short hand reference to Liquid Barcodes and this API. |
LiquidReference | An unique reference used by LIQUID to keep track of the transaction. |
Normal reservation | The normal mode for reservations. One or more codes are specified, which are then reserved. |
One-Scan | A special reservation mode where all codes owned by a user are reserved. Can be initiated either by specifying the user or by specifying a code owned by the user. |
Prefix | The code (see above) may need a prefix, for example to route the reservation to LIQUID Barcodes’ systems. |
Rebate Handling | Tender Exchange/ Cash Equivalent /Rebate |
Redemptions | See validation below. |
Reservation | Singular, unique offer that corresponds to the particular use of a code (see above). |
User | A person that is the intended recipient of (a) coupon(s) |
UserReference/UserRef | A unique reference to the User that can be used to uniquely identify the User. Most commonly their phone number (MSN), but can also be membership IDs or other unique identifiers |
Validation | The confirmation of a reservation whose conditions were met. |
Coupon elements
The coupon is built up from certain elements:
The main elements of a coupon are:
- Code, this is the actual code that carries the real value of the discount. There is no limitation on the length of the code, nor is the code limited to digits only. However in practical implementations this code is 8 digits. This parameter is also known as UniqueCode
- Barcode, this a representation of the code in a form that is easy to scan. In order for the POS to identify the barcode as originating with Liquid Barcodes the content of the Barcode normally takes a form of ‘Prefix + Code’. The prefix part of the configuration for each retailer. The barcode is constructed in one of three ways (of which the first is the predominant structure)
- Prefix + UniqueCode. In total 12 digits.
- Prefix + UniqueCode + Control digit. This is only used when the barcode has to be of type EAN-13, where the last digit is a control digit.
- Prefix + ’01’ + CampaignCode + ’21’ + UniqueCode.
Process for validating coupons
The basic concept is that when a coupon/code is scanned/entered manually the system returns the corresponding reservation with conditions. This reservation is unique and subsequent uses of the same code/coupon will result in a new reservation with conditions that may or may not be identical to the first. Once the sale is completed, the reservation is either validated (the conditions have been met) or the reservation is cancelled/freed (the reservation’s conditions have NOT been met).
We use the term coupon or code as the representation of the offer to the consumer, and reservation as the singular, unique offer that corresponds to a particular use of the coupon. A coupon/code may in other words trigger multiple reservations with separate conditions.
The process of validation is done in two stages. Once the coupon is scanned or the coupon code is manually entered at the POS, a reservation request is sent from the POS to LIQUID (RESERVE function). Upon receipt of the RESERVE message LIQUID will respond with an acknowledgement message and this message may be positive (the coupon exists and can be used) or negative (the coupon doesn’t exist, is not valid, or has already been used). If the RESERVE response is negative an appropriate message to the cashier/consumer should be displayed, according to the error types described in this document.
A positive RESERVE response, called a reservation, will also contain conditions that need to be fulfilled before the rebate can be given to the consumer. Typical conditions are what products need to be on the receipt, the size and type of the rebate, a minimum total sale etc. A successful reservation will mark the coupon as reserved in LIQUIDs system, and this particular use of the coupon is locked until the reservation is either cancelled or validated. If the coupon can be used more than once, each use requires a separate reservation request, as the conditions for the rebate may change for each use of the coupon (an example would be a coupon that gives 5 % rebate for the first use, 10 % for the second, 15 % for the third, etc…). Once the sum of unconfirmed reservations and previous validations of a coupon/code equals the maximum number of validations it will no longer be possible to reserve the same code, unless one or more of the reservations are cancelled.
When the sale has been concluded, the POS has to determine whether the conditions for the reservation has been met (i.e. the required products are present on the receipt). When receiving payment from the consumer the POS must send a final confirmation to LIQUID containing whether the consumer received the rebate. This is done through the validation request (VALIDATE function), as a confirmation or a cancellation. LIQUID will respond by sending VALIDATE response to confirm that it has received the validation. If no VALIDATE response is received the POS should retry at least 3 times.
If the rebate/coupon is removed from the receipt or the conditions have not been met, the POS should send a VALIDATE message and indicate that this reservation was cancelled. This will free the code for later use.
Cancelling reservations and clean up
Since coupons can be multi-use and each reservation can have different conditions the sequence of which reservations takes precedence is important. For reservations that belongs to the same coupon/code the reservations should be cancelled in the order of the most recent reservation first. As an illustration, a coupon has been reserved three times that gives 5, 10, 15 % rebate respectively on product A and 3 product A is present on the receipt. There are now two situations that needs to be handled properly:
- The cashier removes one of the product As from the receipt (irrespective of which of the three A’s is cancelled). In this case the last reservation (15 % discount) no longer holds, but both 5 and 10 % discount is still valid
- The cashier removes one of the reservations themselves (if made possible by the POS implementation). Regardless of which reservation that is removed, the most recent reservation should be cancelled (15 % discount)
System clean-up and parking the receipt
As a fail-safe in case the POS is unable to validate a reservation (by validating or cancelling), to prevent reservations from lasting indefinitely and to prevent that consumer is unable to use the coupon at a later stage, all reservations are automatically cleaned up 15 minutes after the reservation is made. If this occurs it is no longer possible to complete the validation (by validating or cancelling).
In the case where the receipt is intentionally parked/paused one risks that the clean-up happens while it’s parked. There are multiple alternative ways to handle this. The preferred option is the first one, however, depending on POS architecture and other factors, this may not always be ideal and the alternative implementation may be a better solution.
- Cancel all reservations when unparking the receipt and immediately reserve them again.
If the coupon has been used on another order in the mean time the reservation will fail, if not the reservation will go through. - Trying to make it before time-out.
When the receipt is unparked the reservations can be in the following states and the POS will have to consider what to do with them.- Before the reservations time-out. The rebate is given and the validations will still go through, however, the time before validations must happen is reduced by the time the receipt was parked.
- After the reservations time-out. When finalizing the purchase the validations will fail, and this should be handled by either replaying reservations. Alternatively, allowing the user scan his/her coupons again before finalizing the sale.
- Cancel all reservations when parking the receipt.
The user must be notified that the coupons will have to be scanned again.
Additional receipts
This API allows for additional receipts being printed which contains additional coupons. Note that these additional coupons will be issued on the basis of the initial transaction, and can hence not be used in the original transaction. As such this is a mechanism to get people to revisit your stores. There are two ways to invoke additional receipts and only one should be used per transaction:
- LIQUID Barcodes will add additional receipts to the transaction as a field on the VALIDATE response.This implies that there has been at least one coupon present during the transaction (note that the coupon may not give a discount in itself, but represent a membership card). The rules for which offer(s) to trigger for the additional coupons are then set up in LIQUID Barcodes system entirely, and conditions can span several purchases.
- The POS will during the finishing phase of the transaction query LIQUID Barcodes with the complete receipt for the transaction and an additional receipt may be returned based on either the total value in the purchase or which individual products were present. Note that this may issue coupon to any customer that has not already used a LIQUID Barcodes coupon in the transaction. To activate this functionality the POS needs to call the Receipt function call that is detailed below. If the user has used some LIQUID Barcodes coupon on the transaction, this function should not be called.
It should be noted that based on the configuration of the campaigns, and what information is available for the individual consumer, a receipt coupon may be distributed to the consumer through a different distribution channel. E.g. If the mobile number of the consumer is known to LIQUID Barcodes the system will distribute the coupon on SMS directly to the consumer. If the mobile number is not known the same coupon would be returned as an extra receipt to be printed by the receipt printer. The configuration of distribution channels is a property of the LIQUID Barcodes system.
Receipt text format
The format is a minimalist XML format. There is no XML-header used in the format and there is no XSD available.
Receipt texts are only used in the context of the Validation API and as such the enclosing HTTP response headers define the character set for this content.
Supported tags
<RECEIPTS>
This is the container tag for all additional receipts. There will be only one of this tag.
<RECEIPT>
This is the container tag for one additional receipt.
Supported attributes (default values underlined):
- reservationid=” X “
If this receipt was created from a validation, this value references the reservation ID for the reservation+validation that triggered it.
Optional attribute.
<BARCODE>
A barcode to add to the receipt. The value of the barcode is given as content for the tag.
Supported attributes (default values underlined):
- type=” datamatrix | ean13 “
Format of the barcode. Required attribute.
<IMAGE>
An image to add to the receipt. The binary data of the image is given as content for the tag. Any whitespace characters should be removed from the content before decoding, as the content may have been chunked.
- format=” image/png “
The image format used in the enclosed binary data. Required attribute.
Currently the only supported format is image/png. - encoding=” base64 “
The encoding used on the enclosed binary data. Required attribute.
Currently the only supported encoding is base64.
<TEXT>
A text paragraph, optionally formatted (see level four tags), to add to the receipt. All text content should be trimmed for any leading/trailing whitespaces. Multiple consequtive whitespaces should be treated as one whitespace. Linebreaks should be treated as spaces, as linebreaks are explicitly defines by BR tags.
Supported attributes (default values underlined):
- align=” left | center | right “
Text alignment. Optional attribute. - color=” #rrggbb ”
Text color in hexadecimal red (rr), green (gg) and blue (bb) components. Optional attribute.
<B> for bold
The content of this tag should be formatted as bold text.
<I> for italic
The content of this tag should be formatted as italic text.
<SMALLER>
The content of this tag should be formatted slightly smaller than other text.
<BIGGER>
The content of this tag should be formatted slightly bigger than other text.
<BR>
Line break. Whitespaces before and after the linebreak should be trimmed.
<COLOR>
Supported attributes (default values underlined):
- color=” #rrggbb ”
Text color in hexadecimal red (rr), green (gg) and blue (bb) components. Required attribute.
PoS Bandwidth and Latency Requirements
The amount of data transmitted through the API is quite limited with a typical payload of less than 1 kB (but it can be larger). In theory it means that the data can be transmitted over very low bandwidth networks. However the limiting factor is typically not the bandwidth but the latency as the network latency can significantly increase the time the consumer has to wait by the PoS for the transaction to finish. Additionally, as this service requires the PoS to be online at all times, the stability of the open connection is very important for the consumer experience at the PoS. A model for the time constraints related to processing of a reserve can be expressed as:
TReserve = TScan + TNetworkLatency + TTransfer + TLiquidBarcodesProcessing + TNetworkLatency + TTransfer + TPoSProcessing
= TScan + 2 * TNetworkLatency + 2 * TTransfer + TLiquidBarcodesProcessing + TPoSProcessing
where
- TScan is the time taken from the coupon has been scanned to the request from the PoS to Liquid Barcodes is initiated
- TNetworkLatency is the latency of the network in question. This may vary significantly depending on the network configuration, and also includes the routing through the internet to the Liquid Barcodes servers
- TTransfer is the actual transfer speed of the data packet. Given the small size of the payload this component would be ~150 ms for a 1kB packet over a 64kbit/s ISDN
- TLiquidBarcodesProcessing is the time it takes for Liquid Barcodes to process the incoming request and send the response. Typically this is processed in 100 to 300 ms
- TPoSProcessing is the time the PoS requires to process the incoming conditions from LB and align with the current transaction at the PoS
Additionally there is a second Validate function call that happens when you close the bill on the PoS which has the following time constraints
TValidate = TClosingBill + TNetworkLatency + TTransfer + TLiquidBarcodesProcessing + TNetworkLatency + TTransfer + TPoSProcessing
= TClosingBill + 2 * TNetworkLatency + 2 * TTransfer + TLiquidBarcodesProcessing + TPoSProcessing
where
- TClosingBill is the time taken from the cashier closes the sale until the request to Liquid Barcodes is initiated
- TNetworkLatency is the latency of the network in question. This may vary significantly depending on the network configuration, and also includes the routing through the internet to the Liquid Barcodes servers
- TTransfer is the actual transferspeed of the data packet. Given the small size of the payload this component would be ~150 ms for a 1kB packet over a 64kbit/s ISDN
- TLiquidBarcodesProcessing is the time it takes for Liquid Barcodes to process the incoming request and send the response. Typically this is processed in 100 to 300 ms
- TPoSProcessing is the time the PoS requires to process the incoming conditions from LB and align with the current transaction at the PoS. Given that there is very little to process at this stage, the PoSProcessing step should be fairly insignificant.
Our recommendation is to have sufficient available bandwidth in order to minimise the latency. In the end the service will work with high latency too, but the wait for the consumer will at some point be unacceptable. We do however recommend to have a 500 kbit/s line from PoS to the internet (provided that the line is shared with other services), but as a minimum our service can operate reasonably well on a dedicated symmetric 64kbits/s line (that is always connected)
General notes for using the services
The API is available through a secure web service exposed at https://validator.api.barcodes.no/v3 . The client can expect a signed, valid SSL certificate for this endpoint.
Some standard HTTP response statuses are used to indicate success or failure. See Responses section below.
Authentication, timestamp and signatures are required for all services and are submitted as headers. See Requests section below.
All dates and times must be formatted as a ISO-8601 timestamp, for example 2014-03-06T13:11:04+03:00.
The unique coupon codes should not be added to the printed receipts, as it would allow a third party that gets access to the receipt to use another person’s coupons.
REQUESTS
All services require:
- Authentication via the HTTP header Authorization. We use the BASIC authentication mechanism. Username and password are provided by LIQUID.
- A timestamp via the HTTP header X-Liquid-Timestamp. It should be set to the current time when the client sends a request and must be formatted as a ISO-8601 timestamp, for example 2014-03-06T13:11:04+03:00.
The services will reject any request where the time deviates more than 10 minutes from our current time. - A signature via the HTTP header X-Liquid-Signature. See the section below on Calculation of the signature.
The services will reject any request where the signature cannot be verified.
RESPONSES
The HTTP response code will identify the outcome of any request.
- 200 (success): The request was successfull.
- 400 (bad request): A value in the request was considered wrong and caused the processing to stop. One typical value is the signature.
- 401 (unauthorized): There was a authentication problem (username and password is provided by LIQUID, contact support).
- 500 (internal server error): There was an unexpected problem (contact support).
Note that these codes are response-level status codes (as in one response, as a whole). In other words a 200 / success response may well contain rejected reservations / validations / cancellations. These can be identified by inspecting the nested RejectCode and RejectMessage fields. Furthermore a non-200 / unsuccessfull response code means the whole request has been rejected, with the exception of 500-errors which means something unexpected has occurred and the state is uncertain.
Unless another format is specified in the Accept header of the request, the format of the response body is JSON. The format of the response body can always be found in the Content-Typeheader.
Signature
In addition to authentication the services use a signature to further validate the customer and the authenticity of the request.
The signature is calculated from the following parts concatenated to a string (without any separator between the parts):
- The exact value of the X-Liquid-Timestamp header
- The content of the request (which fields and their order is specified in each services specification below).
- The secret salt provided to you by LIQUID.
The correct signature is the hexadecimal upper-cased SHA1 hash value from this content.
Example
Given the following:
- The customer salt is 123SALT123.
- The username is demouser.
- The password is demopassword.
- We want to reserve the UniqueCode 78907890.
The following is an example of a valid Reserve request:
POST https://validator.api.barcodes.no/v3/reserve HTTP/1.1 Accept: application/json X-Liquid-Timestamp: 2015-02-10T22:53:44Z X-Liquid-Signature: 25EC3D52BE0E728D4BF50A452B98E3E393C610AD Content-Type: application/json Host: validator.api.barcodes.no:443 Authorization: Basic ZGVtb3VzZXI6ZGVtb3Bhc3N3b3Jk { "RetryCounter":0, "StoreRef":"MYSTORE001", "PosRef":"MYPOS002", "OperatorRef":"MYOPER003", "TransRef":"MYTRANS004", "InternalPosRef":"MYINTPOS005", "UserRef":"MYUSER006", "Codes":[ { "UniqueCode":"12341234", "CampaignCode":"9876543210123" } ] }
Notice:
- Authorization header for basic HTTP auth.
BASE64(“demouser:demopassword”) = ZGVtb3VzZXI6ZGVtb3Bhc3N3b3Jk - X-Liquid-Timestamp header format in ISO-8601 format.
- X-Liquid-Signature see detailed calculation explained below.
Looking at the Service specification in the next chapter you can see that signature source for the Reserve service is made concatenating the following data:
- StoreRef + PosRef + OperatorRef + TransRef + InternalPosRef
- All Codes items concatenated (no separator). Each item consisting of the following values:
- UniqueCode
- CampaignCode
- UserRef + RetryCounter
Which yields the same signature you can see in the requests X-Liquid-Signature:
modelsource = "MYSTORE001" + "MYPOS002" + "MYOPER003" + "MYTRANS004" + "MYINTPOS005" + "12341234" + "9876543210123" + "MYUSER006" + "0" // modelsource is "MYSTORE001MYPOS002MYOPER003MYTRANS004MYINTPOS005123412349876543210123MYUSER0060" source = "2015-02-10T22:53:44Z" + modelsource + "123SALT123" // source is "2015-02-10T22:53:44ZMYSTORE001MYPOS002MYOPER003MYTRANS004MYINTPOS005123412349876543210123MYUSER0060123SALT123" signature = UPPERCASE(HEX(SHA1(UTF8(source)))) // signature is "767778229A2A91E63BADA993AB79BE90F69E7AA9"
Disclaimer
This document describes the process flow and protocol for validating coupons issued by LIQUID Barcodes on behalf of the stores. In order to utilize this interface there must be a commercial agreement with LIQUID Barcodes in place, and a technical verification that the implementation has been implemented correctly. In all circumstances the intellectual property rights (IPR) of the interface resides with LIQUID Barcodes. LIQUID Barcodes reserves the right to change this interface at any moment. Any implementation that utilizes this interface is the sole responsibility of the implementor, and under no circumstances should the issuing of this document be construed to signify that LIQUID Barcodes will participate with the implementation, testing, verification of the implementation, unless otherwise agreed.
Standard POS Integration
Introduction
Liquid Barcodes POS Integration ensures quick and efficient customer experience in store. The member discount calculation is performed by Liquid Barcodes. This simplifies the POS integration.
Main steps are:
- Customer identifies once in store. POS caches this ID.
- When all products have been added to the transaction, POS sends POST /applicator/sale request to Liquid Barcodes with:
- list of products (ProductLines). Link products to rebate lines if applicable. Disaggregate products that are linked to rebate lines.
- list of general rebates (RebateLines)
- customer identification (ShopperIdentifiers)
- Liquid Barcodes applies personal discounts and replies to the /applicator/sale request with adjusted transaction list.
- POS receives list of products and updated prices. POS makes new check to add general discounts.
- When customer has paid and transaction has been closed, POS sends finalizing request POST /applicator/sale/{SaleId}/finalization to Liquid Barcodes. If customer wants to add products or on unsuccessful payment, POS sends cancel request to Liquid Barcodes, also using POST /applicator/sale/{SaleId}/finalization and Cancel = TRUE.
The Standard POS integration uses the Applicator services – POST /applicator/sale and POST /applicator/sale/{SaleId}/finalization.
Applicator service – Sale
Definitions:
- General rebate: a discount applied by POS that is available to all shoppers.
- Personal rebate: a discount applied by Liquid Barcodes that is available to registered members.
This service accepts the details of a sale from a POS, including products, general rebates and Liquid Barcodes identifiers, and applies all qualified Liquid Barcodes personal rebates to it.
The main flow is that the POS submits all details for its current sale, then uses the response to change or replace the sale.
The service can be called multiple times during sales process or just once when the sale is about to complete.
POST /applicator/sale
REQUEST
Fieldname | Description | ||
---|---|---|---|
Origin | Details of where this sale originated from. Mandatory for POST, not used for PUT. | ||
StoreRef | The store reference is the unique identifier for the store of that retailer. Will be allocated by LIQUID, and will only change if the cash register is physically moved to another location. | ||
PosRef | Optional. The reference of the particular POS used in the transaction. If used this ID is at the discretion of the store. This ID will NOT change upon a change of owner of the store. | ||
InternalPosRef | Optional. Parameter that maps the transaction to the internal cash register reference ID. If more than one parameter is used, the field takes the format “parameter1:parameter2:parameter3”. | ||
OperatorRef | Optional. An anonymous identifier for the cashier using the cash register. If used this ID is at the discretion of the store. | ||
LegalEntity | Optional. An identifier that identifies the legal entity that owns the store. This will change upon a change of owner of the store. If not blank the value in this field will appear in the validation report for this validation. | ||
Sale | |||
Id | Unique sale ID. Must be unqiue for the customer. This may be a temporary ID if the POS does not obtain it’s transaction/sale ID before finalizing the sale. | ||
ProductLines | List of sales line objects. NOTE: Lines are processed in the order they are sent. | ||
Id | Unique ID for the line. Needs only be unique within this sale. A sequential numbering may be used, for example. | ||
ProductCode | Optional. Product code / identifier. These are the identifiers matches by campaign conditions. Required if the line is a sold item. For rebate lines added by the applicator service, the ProductCode will be LB-REBATE or LB-TENDER. |
||
ProductCodePrefix | Optional: Prefix that will be added in front of ProductCode when searching for products. | ||
Barcode | Optional. Scanned article number. | ||
Title | Optional. Text displayed in the POS. | ||
Price | Full price per unit on this line. Default 0. | ||
Tax | Tax amount per item on this line. Default 0. | ||
Quantity | Quantity of units sold. Default 0. Product lines Quantity should be split so that the full quantity of a line is either not discounted, or discounted by the same rebate (see RebatedBy). When we consider replacing rebates, the full Quantity of the is included by the rebate. |
||
Unit | Unit name, for example pieces, liters, kilograms. Default: Pieces. | ||
RebatedBy | Optional. Rebate reference. If this line is rebated point to the Id of the associated rebate line. |
||
OnlyQualifiesRebate | Optional: When set to true, it means this product line has qualified a rebate, but not been rebated itself. If a rebate has products that are only-qualifying and varying tax-rates, the TaxTotal calculation may be wrong unless this property is set. |
||
RebateLines | List of rebate line objects. NOTE: Lines are processed in the order they are sent. | ||
Id | Unique ID for the line. Needs only be unique within this sale. A sequential numbering may be used, for example. | ||
Title | Optional. Text displayed in the POS. | ||
Rebate | Optional. Rebate amount given (in total, not per unit). | ||
Tender | Optional. Tender amount given (in total, not per unit). The tender amount is a rebate that is still eligble for tax/VAT (because the seller is compensated). |
||
Irreplacable | When set to true, the rebate cannot be replaced during price minification. Default: false. | ||
ShopperIdentifiers | List of ShopperIdentifiers such as coupon ids, Userid. NOTE: Lines are processed in the order they are sent. | ||
Id | Unique ID for the line. Needs only be unique within this sale. A sequential numbering may be used, for example. | ||
Identifier | The code that identifies the shopper or the coupon, eg. a UserReference or scanned barcode. | ||
Type | Specifies what the Identifier field above contains and the processing mode: – Owner: initiates a one-scan for the owner given in Identifier. – Code: initiates a one-scan for the owner of the code in Identifier. – SingleCode: initiaties a single reservation of the code given in Identifier. – ExternalIdentifier: resolves the external identifier and initiates a one-scan for the owner found. |
||
TaxTotal | The total taxes for this sale. | ||
Total | The total for this sale, taxes added and rebates deducted. | ||
TransientData | Free-to-use field which will be forwarded to the response.Can be used to send and keep additional data about the sale through this service, rather than persisting it on the POS side. This field is processed as a string and the content must be escaped as a valid JSON string. The content is otherwise decided by the client. |
||
Nonce | A unique one-time value. All requests must use a unique nonce, however if the POS needs to re-send a request it must use the same nonce. If we have already processed that nonce, it will be rejected and duplicate processing is avoided. |
||
Decimals | Optional: If decimal rounding is desired, send the number of decimals to keep here. |
Signature
The signature source consists of the common header/salt data (see Calculation of the signature) and the following concatenated fields from this service:
- Nonce
- Origin.StoreRef
- Sale.Id
- Sale.TaxTotal (invariant culture)
- Sale.Total (invariant culture)
- For each Sale.ProductLines concatenate:
- Id
- ProductCode
- Barcode
- Title
- Price (invariant culture)
- Tax (invariant culture)
- Quantity (invariant culture)
- Unit
- RebatedBy
- For each Sale.RebateLines concatenate:
- Id
- Rebate (invariant culture)
- Tender (invariant culture)
- For each Sale.ShopperIdentifiers concatenate:
- Id
- Identifier
RESPONSE
Fieldname | Description | |||
---|---|---|---|---|
LiquidLogRef | A reference to LIQUIDs internal logs. | |||
Sale | Updated sale with campaigns applied. | |||
Id | Unique sale ID. | |||
ProductLines | List of sales line objects (same model as in request). | |||
RebateLines | List of rebate line objects (same model as in request). | |||
AccountingTags | Defined on the LB campaign and forwarded here. | |||
TaxTotal | The total tax for this sale. | |||
Total | The total for this sale, tax deducted. | |||
TransientData | Transient data forwarded from the request. | |||
Changes | List of changes done to the sale for this request. | |||
Action | One of: AddRebate, RemoveRebate… | |||
Id | Optional. The Id from the affected line. | |||
Warnings | List of warnings that the POS may want to show the user. | |||
Code | Possible warning codes: InvalidExternalIdentifier – a shopper identifier of type ExternalIdentifier was used, but we failed to find it. |
|||
Message | Optional.Readable message with further details. |
Request example:
POST /v3/applicator/sale HTTP/1.1 Host: validator.123.barcodes.no Content-Type: application/json X-Liquid-Timestamp: 2019-06-13T12:42:35+02:00 X-Liquid-Signature: 7835280A88C9E2626AC0F75B18DBCFC1BD57B736 Authorization: Basic ZGVtb3VzZXI6ZGVtb3Bhc3N3b3Jk cache-control: no-cache { "Origin": { "StoreRef": "ST0001", "PosRef": "POS0001", "InternalPosRef": "IPOS0001", "OperatorRef": "OP0001", "LegalEntity": "LE0001" }, "Sale": { "Id": "355f2bd4-4b06-41c3-b40d-e7a8bbc8ffe3", "ProductLines": [ { "Id": "f3faeb2a-c578-4e32-8299-eab37539a2e9", "ProductCode": "COFFEE", "Barcode": "111122223333", "Title": "Cup of black coffee", "Price": 20, "Tax": 5, "Quantity": 2, "Unit": "pieces", "RebatedBy": "" } ], "RebateLines": [ { "Id": "7e5a388d-7200-4c5b-b1b1-d81df0fe25e9", "Title": "Example Rebate", "Rebate": 0, "Tender": 0, "Irreplacable": false } ], "ShopperIdentifiers": [ { "Id": "1", "Identifier": "TDULC5BK133FEF1D74E1D9F2E4E84CAED1439", "Type": "Owner" } ], "TaxTotal": 10, "Total": 36.43, "TransientData": "" }, "Nonce": "b397912a-b6f9-4a36-8577-2fbf839e5ed9" }
Response example:
{ "LiquidLogRef": 1043405020, "Sale": { "Id": "355f2bd4-4b06-41c3-b40d-e7a8bbc8ffe3", "ProductLines": [ { "Id": "f3faeb2a-c578-4e32-8299-eab37539a2e9", "ProductCode": "COFFEE", "Barcode": "111122223333", "Title": "Cup of black coffee", "Price": 20, "Tax": 5, "Quantity": 2, "Unit": "pieces", "RebatedBy": "" } ], "RebateLines": [ { "Id": "7e5a388d-7200-4c5b-b1b1-d81df0fe25e9", "Title": "Example Rebate", "Rebate": 0, "Tender": 0, "Irreplacable": false }, { "Id": "b59621d3-e4cc-4606-8e51-74dc326ca646", "Rebate": 1.23, "Tender": 2.34, "Irreplacable": false } ], "TaxTotal": 10, "Total": 36.43, "TransientData": "" }, "Changes": [ { "Action": "AddRebate", "Id": "b59621d3-e4cc-4606-8e51-74dc326ca646" } ] }
Applicator service – Sale finalization
Finalizing request
POST /applicator/sale/{SaleId}/finalization
REQUEST
Fieldname | Description | ||
---|---|---|---|
SaleId | ID of the sale to finalize. This may be a temporary ID if the POS does not obtain it’s transaction/sale ID before finalizing the sale. | ||
FinalSaleId | Optional. ID of the sale. If the POS does not obtain it’s transaction/sale ID before finalizing the sale, a temporary SaleId has been used up till now. The actual sale ID should then be set here. It will replace the temporary SaleId on our end. | ||
Cancel | When true, cancel the sale instead of completing it. |
RESPONSE
If the request is correct, the endpoint will return HTTP 204 with an empty body.
Request example:
POST /v3/applicator/sale/355f2bd4-4b06-41c3-b40d-e7a8bbc8ffe3/finalization HTTP/1.1 Host: validator.123.barcodes.no Content-Type: application/json X-Liquid-Timestamp: 2019-06-13T13:19:59+02:00 X-Liquid-Signature: 4BF8116117404E1E858B8DD07E79A55BEE36ABED Authorization: Basic ZGVtb3VzZXI6ZGVtb3Bhc3N3b3Jk cache-control: no-cache { "SaleId": "355f2bd4-4b06-41c3-b40d-e7a8bbc8ffe3", "FinalSaleId": "bd0f6ee6-02ce-487c-b4b1-f8c4850a04ac", "Cancel": false }
Signature calculation example:
Timestamp: 2019-06-13T15:06:40+02:00 SaleId: 355f2bd4-4b06-41c3-b40d-e7a8bbc8ffe3 FinalSaleId: bd0f6ee6-02ce-487c-b4b1-f8c4850a04ac Cancel: 0 (1 means true, 0 means false) Salt: exampleSalt SignatureString = Timestamp + SaleId + FinalSaleId + Cancel + Salt = 2019-06-13T15:06:40+02:00355f2bd4-4b06-41c3-b40d-e7a8bbc8ffe3 bd0f6ee6-02ce-487c-b4b1-f8c4850a04ac0exampleSalt LowerCaseSignature = SHA1(SignatureString) = 371c1f119b4a169d4e1615f73da34414dd8900f5 Signature = UpperCase(lowerCaseSignature) = 371C1F119B4A169D4E1615F73DA34414DD8900F5
Cancel rebate request
This service allows the POS to delete one rebate line at a time. The service only deletes the rebate and the related coupon reservation(s), it does not trigger recalculation of personal rebates for the entire basket.
DELETE /applicator/rebate/{RebateId}
Signature
The signature source consists of the common header/salt data (see Calculation of the signature) and the following concatenated fields from this service:
RebateId
Alternative POS integration methods
Integration alternatives
Liquid Barcodes offers multiple alternative POS integration methods.
In store handling
- Handle one coupon at a time
- Multi-use
- Identify once per transaction
How to communciate the offer conditions to the POS
- Promotion ID
- Conditions
The options are summarized and described in this table:
Identify once
Customer only registers once per transaction.
The API allows for the usage of unique User IDs instead of scanning individual coupons. The typical use case is that the consumer is identified by his membership number or registered payment method (eg. credit card) and will receive all the offers he is entitled to without having to scan multiple coupons. Note that the process of identifying the user ID from credit cards and translating from the credit card details to the unique user reference is not handled by LIQUID.
Once the user is identified, the POS can send a RESERVE request to LIQUID with the unique User ID in place of a coupon code. A successful reservation will return the collected results of a reservation for all of the users available coupons. That is, it will return the first available reservation for each coupon that the user is eligible for. Once the conditions for a reservation is met (and the corresponding coupon can be used several times) the POS must automatically fetch the next reservation for that coupon (see multi-use above).
Once the sale is completed and the products are paid for, all the reservations can be validated/cancelled in a single VALIDATE request.
Multi-use
This is a hybrid between the “One coupon at a time” and “Identify once” POS integration methods.
When scanning multiuse coupons, such as loyalty cards, POS automatically makes a new reservation when the offer conditions matches the product(s) on the receipt.
One attribute of a coupon is that it may be used more than once, e.g. three times, 5 times or unlimited numbers of times. The conditions for the rebate may differ for each subsequent reservation. To prevent that the consumer has to scan the coupon multiple times to use it multiple times on the same receipt, the POS should automatically reserve the coupon/code given that certain conditions are met.
When the conditions for a reservation is met, the coupon has more remaining validations and the coupon can be used more than once per sale, the POS should automatically reserve the coupon again and receive a new set of conditions. An example would be a coupon that can be used 3 times, and give a rebate when buying a particular product (A), The rebate given is 5 % discount first usage, 10 % discount second usage, and 15 % discount on the third and final usage. A consumer then scans the coupon at the POS (this initiates the first reservation), and adds product B, C and D on the receipt (which will not meet the conditions for the reservation). The consumer then adds product A, and the conditions for the first reservation is met. As the coupon can be used multiple times on the same sale and have remaining uses, the POS automatically reserves the coupon a second time and receives the second set of conditions. The consumer adds another product A, and the conditions for the second use has also been met, which triggers the third reservation. When the consumer adds the third product A the conditions for the third reservation is met, but as there are no further uses left the POS doesn’t reserve a fourth time.
In the example above, if at any time one of the product A’s is removed from the receipt, the rebate associated with the most recent reservation must be undone (the 15 % discount)
To simplify the process, all outstanding reservations can be validated/cancelled in a single VALIDATE request.
One coupon at a time
Shopper must register each coupon she wants to use one time per usage. Say for example she has bought two loyalty card products. She must scan her loyalty card two times to get two stamps on the loyalty card.
On each scan, Liquid Barcodes makes a reservation on the coupon code and replies with correct rebate conditions.
When transaction is complete, POS must validate the reservations that have been used.
If shopper scans too many times, POS must automatically cancel unused reservations.
This is a basic POS integration. It is easier to implement in the POS than the other integrations. The disadvantage is that it takes more time in store.
Offers based on Promotion ID
On reservation, Liquid Barcodes replies with Promotion IDs for the shopper’s personal offers.
The Promotion IDs are discount triggers that have been created in the POS before campaign start.
POS only applies Promomtion ID from each reservation once. To obtain additional Promotion IDs, new reservation must be made.
The advantage of using Promotion IDs is that discounts can be determined using POS existing rebate engine. The disadvantage is that the marketeer must maintain two systems – the coupon campaigns and the Promotion IDs.
The Promomtion IDs will be sent to POS using the ExternalParamater field in the Reservation response.
Offers based on Conditions
On reservation, Liquid Barcodes replies with rebate conditions for the shopper’s personal offers.
The rebate conditions define in detail the requirements for this particular rebate to apply and the value of the rebate.
POS only applies Conditions from each reservation once. To obtain additional Conditions, new reservation must be made.
The advantage of using Conditions is that the marketeer only needs to maintain one system. The disadvantage is that discounts must be calculated using a custom rebate engine in the POS.
The Conditions will be sent to POS using the Conditions field in the Reservation response.
Reserve
POST https://validator.api.barcodes.no/v3/reserve
REQUEST
Fieldname | Title | Description | ||
---|---|---|---|---|
StoreRef | Store reference | The store reference is the unique identifier for the store of that retailer. Will be allocated by LIQUID, and will only change if the cash register is physically moved to another location. | ||
PosRef | Cash register reference | The reference of the particular POS used in the transaction. If used this ID is at the discretion of the store. This ID will NOT change upon a change of owner of the store | ||
OperatorRef | Cashier reference | Optional. An anonymous identifier for the cashier using the cash register. If used this ID is at the discretion of the store. | ||
TransRef | Transaction reference | Unique identifier for the particular transaction on the cash register. Has the same value across the whole receipt, and is unique across all stores. The TransRef uniquely identifies one and only one receipt in all the transactions of the retailer. | ||
LegalEntity | Legal entity | Optional. An identifier that identifies the legal entity that owns the store. This will change upon a change of owner of the store. If not blank the value in this field will appear in the validation report for this validation. | ||
InternalPosRef | Internal reference ID | Optional. Parameter that maps the transaction to the internal cash register reference ID. If more than one parameter is used, the field takes the format “parameter1:parameter2:parameter3” May optionally be left blank. | ||
RetryCounter | Retry counter | Initially this value is always 0. In case the POS needs to retry the request the value should be increased by 1 per attempt.
It is used to handle network issues or other issues where the POS does not know whether a request was successfully submitted. |
||
UserRef | Unique user reference | Optional. For normal reservation mode this field should be blank. To enter one-scan mode this can be set to:
|
||
Codes | Array of codes to reserve. This array should be empty if UserRef is present | |||
CampaignCode | Campaign code | Optional. Campaign code in the barcode of the coupon. If UniqueCode is manually entered this field is not used. | ||
UniqueCode | Unique coupon code | If the coupon code is manually entered this field contains the printed digits below the barcode. | ||
BalanceOffset | Optional. Requested giftcard balance change. Negative amount means balance deduction. Positive amount means balance increase / top-up. For giftcard reservations that do not specify a value here 0 is used. |
|||
Position | Optional. An attempt to acquire geographical location. Should be set whenever an attempt to acquire location was made. In this object you must set either Position or ErrorCode+Error. |
|||
Position | Optional. Must be set when the attempt to acquire geographical location succeeded. The position will be used to attempt identification of which store performed the reservation. Position is given as decimal degrees (DD). Conversion from sexagesimal (DMS): With degrees, add minutes as /60 fractions, add seconds as /3600 fractions. |
|||
Longitude | Longitude / meridian. Range from -180.0 (180 degrees west) to 180.0 degrees (180 degrees east). | |||
Latitude | Latitude / parallel. Range from -90.0 (south pole) to 90.0 degrees (north pole). | |||
Accuracy | Optional. The accuracy for the position in meters. | |||
Altitude | Optional. Altitude in meters, relative to sea level. | |||
AltitudeAccuracy | Optional. The accuracy for the altitude in meters. | |||
Speed | Optional. Current velocity of the device in meters per second. | |||
Heading | Optional. Current heading in degrees of clockwise deviation from heading true north (which means that 0, 90, 180, 270 degrees is north, east, south and west, respectively). | |||
ErrorCode | Optional. Must be set when the attempt to acquire geographical location failed. Error classification. One of: PermissionDenied, Unavailable, Timeout, NotSupported, Unknown. |
|||
Error | Optional. Must be set when the attempt to acquire geographical location failed. Error message / details. May be a blank string if there are no further details that ErrorCode. |
Signature
The signature source consists of the common header/salt data (see Calculation of the signature) and the following concatenated fields from this service:
- StoreRef + PosRef + OperatorRef + TransRef + LegalEntity + InternalPosRef
- All Codes items concatenated (no separator). Each item consisting of the following values:
- UniqueCode
- CampaignCode
- UserRef + RetryCounter
RESPONSE
Fieldname | Title | Description | |||
---|---|---|---|---|---|
LiquidLogRef | Log reference | A reference to LIQUIDs internal logs. | |||
Reservations | Array of reservation | ||||
ReservationId | Reservation reference | A reference to this reservation. It will be formatted either as a number or a GUID (i.e. it should always be treated as a string). This value is the relation between reservation and validation / cancellation (see the Validate service). |
|||
UniqueCode | Unique coupon code | The reserved unique coupon code. | |||
CampaignCode | Campaign code | Only present if CampaignCode was used in Reserve request. | |||
Timestamp | Reservation timestamp | The date and time when the reservation was completed. | |||
Campaign | |||||
Id | Campaign ID | The ID of the campaign associated with the unique code. | |||
Description | Campaign description | Optional: Short description of the campaign to be displayed in the POS and/or printed on the recipt. | |||
Type | Campaign Type | The campaign type. Currently the only values in use are “Rebate”, “Giftcard”. | |||
Start | Campaign Start | Timestamp for campaign start. This is the earliest possible time to reserve coupons for this campaign. The timestamp should be used only for informational purposes, not to decline a reservation. | |||
End | Campaign End | Timestamp for campaign end. This is the latest possible time to reserve coupons for this campaign. The timestamp should be used only for informational purposes, not to decline a reservation. | |||
CouponExpires | Coupon expiry timestamp | Timestamp for last possible reservation of this coupon. This value can not be later than Campaign.End. | |||
Rebate | Optional but either Rebate, Tender or both must be set. | ||||
Type | Rebate type | Possible values are:
If this field is FixedPrice then some products to rebate will be specified in the ProductGroups. |
|||
Value | Rebate value | The value of the rebate, see related field Rebate.Type. This field may be zero. Also the value of this field may be negative, in this case the consumer is not getting a rebate, but have to pay for the use of the coupon. Negative rebate is primarily used for prepaid/top-up cards, where the first usage of coupon allows the user to buy x rebated products for later. | |||
MinimumValue | Minimum rebate value | Optional. Minimum value of the total rebate in the case where the rebate value is undetermined. | |||
MaximumValue | Maximum rebate value | Optional. Maximum value of the total rebate in the case where the rebate value is undetermined. This occurs when the product in question has different sale price in the different shops where the coupon can be redeemed | |||
Tender | Optional but either Rebate, Tender or both must be set. | ||||
Type | Tender type | Possible values are:
|
|||
Value | Tender value | The value of the tender, see related field Tender.Type. This field may be zero. Also the value of this field may be negative, in this case the consumer is not getting a rebate, but have to pay for the use of the coupon. Negative rebate is primarily used for prepaid/top-up cards, where the first usage of coupon allows the user to buy x rebated products for later. This field may have a value in combination with Rebate.
If the campaign type is of type CashCard this value represents the amount of the cashcard that has been reserved
|
|||
RemainingRedemptions | Number of remaining redemptions | Number of remaining redemptions excluding this transaction. A value of zero means that there are no remaining redemptions for this coupon (except this one). A value of ‘-1’ means that there are no limits to the number of remaining redemptions. | |||
ExtParam | External parameter | Optional. A list of parameter names and values that can be used by the cash register. An example would be to indicate the PLU to be inserted as a result of an redemption. | |||
ReceiptText | Receipt text | Optional. Parameter that the POS can choose to print on the receipt for each reservation. | |||
Giftcard | Optional. Giftcard specific fields. Only supplied when Campaign.Type is Giftcard. | ||||
NewBalance | The current balance of the giftcard after Reserve.Codes.BalanceOffset has been applied. The actual balance offset that was applied is available in Tender.Value. | ||||
MaxBalanceOffset | This is the maximum value that is permitted to top-up this giftcard with (i.e. maximum Reserve.Codes.BalanceOffset). If value = 0 or parameter is not present then it is not allowed to top-up this giftcard. | ||||
RejectCode | Per reservation reject code | Optional. A code that can be used to programatically recognize the cause of a rejection. If this field is set it means that the reservation has failed, all other values for this reservation must be disregarded.
The following values can occur:
|
|||
RejectMessage | Per reservation reject message | Optional. A human readable cause of rejection message in case a rejection occurred. Only set when RejectCode is set. | |||
RejectCode | Reject code | Optional. A code that can be used to programatically recognize the cause of a rejection.
The following values can occur:
|
|||
RejectMessage | Reject message | Optional. A human readable cause of rejection message in case a rejection occurred. Only set when RejectCode is set. |
Validate
This is the second part of the validation process. This is call is initiated in the following circumstances:
- The conditions for the reservation has been met and the customer is about to be given his rebate. This call is initiated after the customer has paid, but before the transaction has been completed.
- The conditions for the reservation have not been met so the reservation must be released.
- The transaction was aborted by cashier or customer so the reservation must be released.
POST https://validator.api.barcodes.no/v3/validate
REQUEST
Fieldname | Title | Description | |||
---|---|---|---|---|---|
Validations | List of confirmed / approved validations. | ||||
ReservationId | Reservation reference | A reference to this reservation. It will be formatted either as a number or a GUID (i.e. it should always be treated as a string). This value is the relation between reservation and validation / cancellation (see the Reserve service). |
|||
RebateValue | Rebate value | This is the actual rebate that was given. Should be the monetary value (not percentage). If the rebate type is percentage this value will vary depending on the basket of goods to rebate. If the rebate type is units this value is the number of units given. Should not include the TenderValue. | |||
TenderValue | Tender value | This is the actual tender that was given. Should be the monetary value (not percentage). Should not include the RebateValue. | |||
Cancellations | |||||
ReservationId | Reservation reference | A reference to this reservation. It will be formatted either as a number or a GUID (i.e. it should always be treated as a string). This value is the releation between reservation and validation / cancellation (see the Reserve service). |
|||
TotalValue | Total value | The gross total of the receipt (i.e. the total before the deduction of the above rebate/tender). | |||
OptParams | Additional data | Optional. A list of parameter names and values that can be set by the cash register. This field can be used to further detail the transaction. | |||
RetryCount | Retry counter | Initially this value is always 0. In case the POS needs to retry the request the value should be increased by 1 per attempt. It is used to handle network issues or other issues where the POS does not know whether a request was successfully submitted. |
|||
Receipt | |||||
Format | Receipt format, always use Liquid/1.0 for this field. The format is detailed below | ||||
Receipt | Receipt |
Optional. A JSON representation of the whole receipt for the complete transaction, including the unique ReceiptID, EAN codes, Product price, rebate values, total sum etc. The JSON should take the following format: Expand source
Note: The JSON code must be escaped so that the Receipt field is just a regular string. |
|||
TransRef | Transaction reference | Optional: Unique identifier for the particular transaction on the cash register. Has the same value across the whole receipt, and is unique across all stores. The TransRef uniquely identifies one and only one receipt in all the transactions of the retailer.The TransRef should only be used in the Validate call if for some reason the final receipt ID is not available before the POS ends the transaction. In this case the POS should use a temporary TransRef for all reservations in this transaction. If you also send the receipt in this transaction, the TransRef value should be identical to the ReceiptId in the Receipt block. |
Signature
The signature source consists of the common header/salt data (see Calculation of the signature) and the following concatenated fields from this service:
- RetryCount
- All Validations items concatenated (no separator). Each item consisting of the following values:
- ReservationId + RebateValue + TenderValue
- All Cancellations items concatenated (no separator). Each item consisting of the following values:
- ReservationId
- TotalValue
- Format
- Receipt
- All OptParams items concatenated (no separator between key/value, no separator between items).
RESPONSE
Fieldname | Title | Description | |
---|---|---|---|
LiquidLogRef | Log reference | A reference to LIQUIDs internal logs. | |
Results | |||
ReservationId | Reservation reference | A reference to the submitted validation or cancellation with the same ReservationId. | |
Receipts | Receipts | Information / coupons may be provided for printing on the receipt. See Receipt format. | |
RejectCode | Reject code | Optional .A code that can be used to programatically recognize the cause of a rejection. If this field is set it means that the validation / cancellation has failed, all other values for this validation / cancellation must be disregarded.
The following values can occurr:
|
|
RejectMessage | Reject message | Optional. A human readable cause of rejection message in case an error occurred. Only set when RejectCode is set. |
Sales service
Introduction
This provides the POS with a mechanism to get additional coupons to print on the receipt. Based on sales rules configured in LIQUIDs platform the user may get additional coupon(s).
Since the validation service (see previous chapter) implicitly will trigger any sales-rule coupons too, this function should only be used when the validation service has not been called. If both the sale service and the validation services are used, the user would effectively get twice the amount of coupons he has qualified for.
POST /sale
Request
Fieldname | Title | Description | |
---|---|---|---|
StoreRef | Store reference | The store reference is the unique identifier for the store of that retailer. Will be allocated by LIQUID, and will only change if the cash register is physically moved to another location. | |
PosRef | Cash register reference | The reference of the particular POS used in the transaction. If used this ID is at the discretion of the store. | |
OperatorRef | Cashier reference | Optional. An anonymous identifier for the cashier using the cash register. If used this ID is at the discretion of the store. | |
TransRef | Transaction reference | Unique identifier for the particular transaction on the cash register. Has the same value across the whole receipt, and is unique across all stores. The TransRef uniquely identifies one and only one receipt in all the transactions of the retailer. | |
LegalEntity | Legal entity | Optional. An identifier that identifies the legal entity that owns the store. This will change upon a change of owner of the store. If not blank the value in this field will appear in the validation report for this validation. | |
InternalPosRef | Internal reference ID | Optional. Parameter that maps the transaction to the internal cash register reference ID. If more than one parameter is used, the field takes the format "parameter1:parameter2:parameter3" May optionally be left blank. | |
RetryCounter | Retry counter | Initially this value is always 0. In case the POS needs to retry the request the value should be increased by 1 per attempt.
It is used to handle network issues or other issues where the POS does not know whether a request was successfully submitted. |
|
UserRef | Unique user reference | Optional: The unique reference to the user. | |
TotalValue | Total value | The gross total of the receipt (i.e. the total before the deduction of the above rebate/tender). | |
Receipt | |||
Format | Receipt format, always use Liquid/1.0 for this field. | ||
Receipt |
Optional: A JSON representation of the whole receipt for the complete transaction. The model definition is described under Model definitions, Receipt format, Liquid/1.0. Note: This field is a string containing JSON, meaning the JSON must be escaped so that the value is only a string. |
Signature
The signature source consists of the common header/salt data (see Calculation of the signature) and the following concatenated fields from this service:
- StoreRef + PosRef + OperatorRef + TransRef + LegalEntity + InternalPosRef + UserRef + TotalValue + Format + Receipt
Response
Fieldname | Title | Description | |
---|---|---|---|
LiquidLogRef | Log reference | A reference to LIQUIDs internal logs. | |
Receipt | Receipt text | If any coupons were triggered they will be included here in the format outlined in Receipt text format. It should be printed as a separate receipt for the consumer. When no coupons were triggered this field will be blank. Nothing should be printed in this case. |