DocumentationLoyalty cards

Loyalty Cards

This page describes an extension to the Qerko API for loyalty cards. It allows customers to add their loyalty cards to the Qerko app and enjoy benefits offered by restaurants. The card can work across multiple restaurants.

Usage Perspective

  1. I want to use my loyalty card when I pay with the Qerko app, so I decide to add my loyalty card to the app. I select the brand of my loyalty card from the list of supported cards. The Qerko app asks me for some information about the card, which I fill in and submit.

  2. The Qerko app presents me with the result of my request. It can be:

    1. The card is authorized and I can use it.
    2. The card is unauthorized for some reason, so I need to resolve the problem.
    3. I need to perform some additional action described by a message. For example: “Check your email for the verification link.”
  3. The card is added to the Qerko app and I can use it from now on.

Card Authority Perspective

  1. Qerko sends an authorization request to the authority assigned to the selected brand of the loyalty card. Card info and a list of verified emails are included in the request. Card info can be any set of parameters from the physical loyalty card, or a code generated by restaurant staff. The specific form is configured per card brand.

  2. The authority processes the request and responds. If the response contains the final authorization result, the process ends. If not, Qerko waits for the result. You can use any two-factor authentication method (e.g., email with a verification link). When the result is available, the authority submits it to Qerko, which then notifies the customer.

  3. That’s it. The customer can use their loyalty card from now on.

Customer Perspective

  1. I pick my items and choose to use my previously added loyalty card. The Qerko app shows me my bill, but I can no longer modify items, and there is a form I have to fill in. Alternatively, I can go back and start over or choose not to use my loyalty card.

  2. I submit the required information until there are no more forms to fill in. The Qerko app displays the bill with the applied bonus. It could be a discount or no bonus at all if I opted to receive loyalty points.

  3. I make the swipe gesture to proceed with the payment.

  4. The bill is paid. I can go home now.

POS Perspective

  1. Qerko requests the POS to create a new individual bill with the exact items. The request contains the ID of the source bill, the loyalty card token (result of authorization), and the items. The POS responds with an individual bill structure. It can contain a set of questions that must be answered to proceed.

  2. The customer submits responses, and Qerko forwards them to the POS along with the individual bill ID. The POS responds with a recalculated individual bill, which may contain another set of questions. We call this “the negotiation,” because the customer is negotiating with the POS. This step repeats until the POS returns no additional questions.

  3. The bill is paid like any other bill. If the customer leaves this process before this step, Qerko requests the POS to cancel the individual bill. The POS should, but does not have to, return items to the original bill. The customer is returned to the individual bill (if it exists), the original bill (if it exists), or sees the message “Your bill was closed.”

Authorization and Usage

There are two problems to address for this extension to work:

  1. Authorization of the loyalty card.
  2. Application of the loyalty card.

Methods

Card Authority Methods

A card authority is needed for this step. It can be the POS, an independent component, or another POS instance. If the loyalty card works only in one restaurant, it can be the POS. If the loyalty card works in multiple restaurants, it will probably be an independent component. The card authority verifies the guest and their loyalty card. It also passes the authorization result to Qerko. It is connected to Qerko using a WebSocket or long-polling connection, but it does not have to implement standard POS methods.

authorizeLoyaltyCard

authorizeLoyaltyCard(request: LoyaltyCardAuthorizationRequest): LoyaltyCardAuthorizationResponse

Qerko asks the card authority to authorize a loyalty card. This method returns the AuthorizationResponse structure.

ParameterTypeDescription
requestLoyaltyCardAuthorizationRequestAuthorization request described in the data structures section.

loyaltyCardAuthorizationFinished

loyaltyCardAuthorizationFinished(response: LoyaltyCardAuthorizationResponse): null

REST-API alternative: POST /api/v2/card-authority/loyalty-card-authorization-finished - request body contains the LoyaltyCardAuthorizationResponse structure.

The card authority should call this method when the customer completes the authentication challenge and the authority has the final result. When called with response.result = PENDING, the response is treated as UNAUTHORIZED.

ParameterTypeDescription
responseLoyaltyCardAuthorizationResponseAuthorization response described in the data structures section.
LoyaltyCardAuthorizationResponse

The card authority returns this structure in the authorizeLoyaltyCard method or uses it as an argument for the loyaltyCardAuthorizationFinished method.

It contains the authorization result.

PropertyTypeRequiredDescription
requestIdstringYesIdentifier of this request in GUID v4 format. It was received in the LoyaltyCardAuthorizationRequest.
resultstringYesEnum: AUTHORIZED (final result - successfully authorized), UNAUTHORIZED (final result - unsuccessful authorization), PENDING (final result will be sent in the future)
loyaltyCardTokenstringYesIf result = PENDING or UNAUTHORIZED, token is ignored. If result = AUTHORIZED, token must be a non-empty string. The POS should recognize the customer based on this string. Example: “abc-123-foo-bar”
messagestringYesIf result = PENDING, message contains instructions for the customer. If result = UNAUTHORIZED, message contains the reason why the request is unauthorized. If result = AUTHORIZED, message is ignored. Example: “Check your email for verification link”

Usage of the Added Card

The POS must implement methods that allow Qerko and the POS to negotiate an offer for the customer. The POS can ask the user additional questions. Many loyalty cards offer multiple possibilities, so we need to determine what the customer wants to do with it (e.g., gain loyalty points vs. spend them).

startIndividualBill

startIndividualBill(idBill: string, loyaltyCardToken: string, items: BillItem[], language: string): IndividualBillData

Qerko asks the POS to start a new individual bill from the original bill with the specified loyalty card and items. This method returns an IndividualBillData structure.

ParameterTypeDescription
idBillstringIdentifier of the original non-individual bill
loyaltyCardTokenstringString which identifies the customer. It is the result of the card authorization.
itemsBillItem[]Items to be transferred to the new individual bill. The same structures as in the base document.
languagestringSuggested language for questions in ISO 639-1 format.
Special Error Codes

This section describes string values that can appear in Error.code and have special meaning.

INVALID_LOYALTY_CARD_TOKEN ‒ The Qerko app will announce that the loyalty card is invalid and suggest the customer reauthorize it.

BILL_NOT_CUSTOMIZABLE ‒ The Qerko app will announce that the loyalty card cannot be used with this bill.

updateIndividualBill

updateIndividualBill(idIndividualBill: string, answers: IndividualAnswer[]): IndividualBillData

Qerko has answers for questions from the previous set. The POS should modify the individual bill accordingly and return a new individual bill with or without questions. This method returns an IndividualBillData structure.

ParameterTypeDescription
idIndividualBillstringIdentifier of the individual bill to be modified with the provided answers. Another set of questions may be returned.
answersIndividualAnswer[]A set of answers for the current set of questions.

cancelIndividualBill

cancelIndividualBill(idIndividualBill: string): null

Qerko asks the POS to cancel the individual bill. This is because the customer has left the negotiation session. The POS should return items to the original bill. The POS does not have to cancel the individual bill. After this call, the app checks all bills on the table. If the individual bill is found, the customer is returned to it. If the original bill is found, the customer is returned to the original bill. Otherwise, the app shows a message “Your bill was closed” and the customer is returned to the QR scanning screen.

This covers the situation when Alice starts her individual bill while Bob pays the rest of the original bill. In this case, the original bill is closed, so there is no bill to which individual items should be returned.

ParameterTypeDescription
idIndividualBillstringIdentifier of the individual bill to be cancelled and items to be returned to the original, non-individual bill.

Data Structures

IndividualAnswer

This structure represents an answered question.

PropertyTypeRequiredDescription
idstringYesIdentifier of the question.
booleanbooleanVariesCustomer’s response to the question. Required if dataType of related IndividualQuestion = “boolean”
numbernumberVariesCustomer’s response to the question. Required if dataType of related IndividualQuestion = “number”
stringstringVariesCustomer’s response to the question. Required if dataType of related IndividualQuestion = “string”

IndividualBillData

This structure represents an individual bill. It is a composite of the Bill structure with a description of the offered bonus and a set of questions that need to be answered before payment.

PropertyTypeRequiredDescription
individualBillBillYesBill which contains items. The effect of the loyalty card should be applied.
descriptionstringNoBrief description of the individual offer.
questionsIndividualQuestion[]NoDefault: [] A set of questions that need to be answered before payment.

IndividualQuestion

This structure represents a question to be answered by the customer.

PropertyTypeRequiredDescription
idstringYesIdentifier of the question.
dataTypestringYesAnswer dataType - one of:
* 'boolean'
* 'number'
* 'string'
labelstringYesThe question in human-readable text. Will be used as the label for the form field for the answer.
descriptionstringNoPossible longer text to clarify the question.
optionsIndividualQuestionOption[]NoList of options that the customer can pick as their answer. Use this to create dropdowns.

IndividualQuestionOption

This structure represents a substructure of IndividualQuestion

PropertyTypeRequiredDescription
labelstringYesLabel for this option. Human-readable text for the customer.
booleanbooleanVariesValue for this option if dataType is “boolean”
numbernumberVariesValue for this option if dataType is “number”
stringstringVariesValue for this option if dataType is “string”

LoyaltyCardAuthorizationRequest

Qerko sends this structure to the Loyalty Card Authority. It contains properties needed to authorize the loyalty card.

PropertyTypeRequiredDescription
requestIdstringYesIdentifier of this request in GUIDv4 format.
expirationstringYesExpiration of the request in ISO8601 extended format. If the request results in a PENDING state, this is the timestamp of the request expiration. The result won’t be accepted after this expiration. Example: 2019-04-13T00:22:57+01:00
loyaltyCardInfoobjectYesObject with unspecified properties. Exact properties depend on the configuration for the card brand. It carries data readable from the physical loyalty card. Example: { “number”: “1234 5678 9012” }
emailsstring[]YesA set of known and verified emails of the customer. Lower-cased and hashed using SHA1 for privacy reasons (GDPR).
languagestringYesSuggested language for the message in response. In ISO639-1 format.
hmacKeystringYesA string to be used as the HMAC key for signature. It must not leak to the customer in any form. See below.
callbackUrlstringYesURL where to navigate the customer to successfully finish the request. Example The Loyalty Card Authority must add query parameters token and signature. Signature is SHA1 HMAC in hex encoding. Data is the token, hmacKey is provided. See above. Result url

Need help? If you get stuck or have questions, email us at techsupport@qerko.com—we’re here for you!