Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 10 Next »

Contents

Currently, personalized offers are not supported by NCR.

Overview

Personalised offers (also called config offers) are a specific type of offer that is only available to selected guests. These need to be handled slightly different to systemwide offers, and those details are covered in this document.

Please make sure that you understand Listing offers and rewards on kiosks before reading this document.

Data structure

All offers, regardless of their type, are stored in our Loyalty Platform. We also use a CMS platform called Sanity, where our team and the franchisee can set up marketing materials such as the offer's name, description, and images. Additionally, they can define within Sanity how the offer works, including rules for redemption, limitations, any requirements, and some other miscellaneous aspects of each offer.

It’s important to understand that both of these systems store and handle data separately from each other, some data gets synced between platforms, and some data does not. Sanity for example has all the images for any given offer, whereas the Loyalty Platform does not. The same is true in the other direction, the Loyalty Platform contains the records for Personalized offers, whereas Sanity does not.

The way we like to think about it is, that for any content displayed to the final user, we want to usually use the data from Sanity. For any business rules and logic, like which offer should be displayed to which user we want to use the data from the Loyalty Platform.

Also, please keep in mind that personalized offers will only come from the Loyalty Platform, and their Sanity ID will point to a Configuration Offer, like a Many-to-One relationship.

Retrieving personalised offers

This is an example Sanity GraphQL query that returns personalized offers:

query getSanityOffers {
	LoyaltyOffersUI(id: "feature-loyalty-offers-ui-singleton") {
	# Available for all users.
	# You can use these to lookup assets from global.
    sortedSystemwideOffers {
      _id
      loyaltyEngineId
      name {
        enRaw
      }
    }
    # These are config. offers (templates).
    # You should use these only to display content (images, names, etc).
    # You can use these to lookup assets from the actual Personalized offers.
    liveConfigOffers {
      _id
      loyaltyEngineId
      name {
        enRaw
      }
    }
  }
}

Processing personalized offers

This section explains how the Loyalty API endpoints must be used to process orders that contain personalized offers.

Identify (POST)

Use Case: Successfully identify the Loyalty user along with any potential rewards/offers that they had pre-selected within the app.

Endpoint URL: https://{reg}-{env}-{brand}-loyalty-middleware.rbictg.com/loyalty/identify

Expected Request Payload:

{
    "identifier": "$6digitCode or $loyaltyId",
     "posVendor": {
        "matchingId": "$smgCode",
        "operator": "$operatorId",
        "posType": "$posVendorName",
        "storeId": "$rbiStoreId",
        "supportingPos": "POS vendor name (optional field)", // vendor to return plu for
        "terminal": "$terminalNumber",
        "transactionId": "$posTransactionId"
    }
}

Expected Response Payload:

{
    "balances": [
        {
            "amount": 14464,
            "currency": "points"
        }
    ],
    "loyaltyUser": {
        "created": "2021-08-10T12:18:39.180Z",
        "id": "$loyaltyUserId",
        "name": "$loyaltyUserName"
    },
    "order": [
        {
            "incentiveId": "$rewardSanityId",
            "loyaltyEngineId": "$rewardLoyaltyEngineId",
            "price": 0,
            "productId": "$rewardPlu",
            "productType": "REWARD",
            "quantity": 1,
            "referenceId": "01" // unique line id
        },
        {
            "incentiveId": "$offerSanityId",
            "loyaltyEngineId": "$offerLoyaltyEngineId",
            "productId": "$offerPlu",
            "productType": "OFFER",
            "quantity": 1,
            "referenceId": "02" // unique line id
        }
    ],
    "transactionId": "$loyaltyTransactionId"
}

Transaction Validation (POST)

Use Case: Kiosk sends the Loyalty API a preliminary version of the user’s order so that the Loyalty Platform can evaluate the order and determine if the user meets eligibility requirements of any included incentives (Rewards or Offers). This request should be an exact mirror of what the POS expects to send when they actually claim the transaction.

Endpoint URL: https://{reg}-{env}-{brand}-loyalty-middleware.rbictg.com/loyalty/transaction/pos/validate/{loyaltyTransactionId}

Expected Request Payload:

{
    "channel": "Restaurant",
    "created": "2021-05-04T13:39:47Z",
    "loyaltyId": "$loyaltyUserId",
    "serviceMode": "$serviceMode",
    "status": "PENDING or CLAIMED",
    "transactionDetails": {
        "currency": "USD",
        "order": [
            {
                "name": "med whopper combo",
                "price": 5.00,
                "productId": "$plu",
                "productType": "combo",
                "quantity": 1,
                "referenceId": "1", // line id
                "tax": 0
            },
            {
                "name": "whopper",
                "parentReferenceId"?: "1", // line id of parent (for children elements)
                "price": 0,
                "productId": "$plu",
                "productType": "item",
                "quantity": 1,
                "referenceId": "2", // line id
                "tax": 0
            },
            {
                "name": "med fries",
                "parentReferenceId"?: "1", // line id of parent (for children elements)
                "price": 0,
                "productId": "$plu",
                "productType": "item",
                "quantity": 1,
                "referenceId": "3", // line id
                "tax": 0
            },
            {
                "incentiveId": "$sanityRewardId",
                "name": "free drink reward",
                "price": 0,
                "productId": "$rewardPlu",
                "productType": "REWARD",
                "quantity": 1,
                "referenceId": "4", // line id
                "tax": 0
            },
            {
                "incentiveId": "$sanityOfferId",
                "loyaltyEngineId": "$offerLoyaltyEngineId", // (Optional) Use this field for all Offers if supporting Personalized Offers
                "name": "$2.99 chicken sandwich meal",
                "price": 2.99,
                "productId": "$offerPlu",
                "productType": "OFFER",
                "quantity": 1,
                "referenceId": "5", // line id
                "tax": 0.50
            }
        ],
        "payments": [
            {
                "amount": 500,
                "type": "$paymentMethod",
                "ccToken"?: "$panToken"
            }
        ],
        "posVendor": {
            "matchingId": "$smgCode",
            "operator": "$operatorId",
            "posType": "$posVendorName",
            "storeId": "$rbiStoreId",
            "supportingPos": "POS vendor name (optional field)", // vendor to return plu for
            "terminal": "$terminalNumber",
            "transactionId": "$posTransactionId"
        }
    },
    "transactionId": "$loyaltyTransactionId"
}

Expected Response Payload:

{
    "loyaltyId": "$loyaltyUserId",
    "points": 14464,
    "pointsEarned": 50,
    "pointsRedeemed": 750,
    "transactionId": "$loyaltyTransactionId"
}

Expected Error Response:

{
  "code": "RulesError",
  "details": {
    "ruleEvaluation": [
      {
        "code": "insufficient-point-balance", // reason for rule failure
        "currentValue": 0, // what value was provided
        "message": "User does not have sufficient funds to redeem reward",
        "ruleId": "point-balance", // name of the rule
        "targetValue": 250 // what value is needed
      }
    ]
  },
  "message": "Rule evaluation failed"
}

 

Transaction Update (PUT) - Claim / Commit

Use Case: Kiosk sends this transaction request with the order details to update the loyalty transaction. If the Kiosk states this transaction should be claimed, this will result in the user earning and redeeming eligible points.

Endpoint URL: https://{reg}-{env}-{brand}-loyalty-middleware.rbictg.com/loyalty/transaction/pos/{loyaltyTransactionId}

Expected Request Payload:

{
    "channel": "Restaurant",
    "created": "2021-05-04T13:39:47Z",
    "loyaltyId": "$loyaltyUserId",
    "serviceMode": "$serviceMode",
    "status": "PENDING or CLAIMED",
    "transactionDetails": {
        "currency": "USD",
        "order": [
            {
                "name": "med whopper combo",
                "price": 5.00,
                "productId": "$plu",
                "productType": "combo",
                "quantity": 1,
                "referenceId": "1", // line id
                "tax": 0
            },
            {
                "name": "whopper",
                "parentReferenceId"?: "1", // line id of parent (for children elements)
                "price": 0,
                "productId": "$plu",
                "productType": "item",
                "quantity": 1,
                "referenceId": "2", // line id
                "tax": 0
            },
            {
                "name": "med fries",
                "parentReferenceId"?: "1", // line id of parent (for children elements)
                "price": 0,
                "productId": "$plu",
                "productType": "item",
                "quantity": 1,
                "referenceId": "3", // line id
                "tax": 0
            },
            {
                "incentiveId": "$sanityRewardId",
                "name": "free drink reward",
                "price": 0,
                "productId": "$rewardPlu",
                "productType": "REWARD",
                "quantity": 1,
                "referenceId": "4", // line id
                "tax": 0
            },
            {
                "incentiveId": "$sanityOfferReward", // (Optional) Don't send this field for Personalized Offer, should send loyaltyEngineId
                "loyaltyEngineId": "$offerLoyaltyEngineId", // (Optional) Use this field for all Offers if supporting Personalized Offers
                "name": "$2.99 chicken sandwich meal",
                "price": 2.99,
                "productId": "$offerPlu",
                "productType": "OFFER",
                "quantity": 1,
                "referenceId": "5", // line id
                "tax": 0.50
            }
        ],
        "payments": [
            {
                "amount": 500,
                "type": "$paymentMethod",
                "ccToken"?: "$panToken"
            }
        ],
        "posVendor": {
            "matchingId": "$smgCode",
            "operator": "$operatorId",
            "posType": "$posVendorName",
            "storeId": "$rbiStoreId",
            "supportingPos": "POS vendor name (optional field)", // vendor to return plu for
            "terminal": "$terminalNumber",
            "transactionId": "$posTransactionId"
        }
    },
    "transactionId": "$loyaltyTransactionId"
}

Expected Response Payload:

{
    "loyaltyId": "$loyaltyUserId",
    "points": 14464,
    "pointsEarned": 50,
    "pointsRedeemed": 750,
    "transactionId": "$loyaltyTransactionId"
}

 

Unclaimed Transaction (POST)

Use Case: Kiosk sends a request to Loyalty even when a user does not identify w/ the Loyalty program. This allows us to still create a transaction for the purpose of metrics, analytics, and potentially receipt code claiming

Endpoint URL: https://{reg}-{env}-{brand}-loyalty-middleware.rbictg.com/loyalty/transaction/pos

Expected Request Payload:

{
    "channel": "Restaurant",
    "created": "2021-05-04T13:39:47Z",
    "serviceMode": "$serviceMode",
    "status": "CLAIMED",
    "transactionDetails": {
        "currency": "USD",
        "order": [
            {
                "name": "some incentive name",
                "price": 5.00,
                "productId": "$incentivePlu",
                "productType": "offer",
                "quantity": 1,
                "referenceId": "1",
                "tax": 0
            },
            {
                "name": "med whopper combo",
                "price": 5.00,
                "productId": "$plu",
                "productType": "combo",
                "quantity": 1,
                "referenceId": "1",
                "tax": 0
            },
            {
                "name": "whopper",
                "parentReferenceId"?: "1",
                "price": 0,
                "productId": "$plu",
                "productType": "item",
                "quantity": 1,
                "referenceId": "2",
                "tax": 0
            },
            {
                "name": "med fries",
                "parentReferenceId"?: "1",
                "price": 0,
                "productId": "$plu",
                "productType": "item",
                "quantity": 1,
                "referenceId": "3",
                "tax": 0
            }
        ],
        "payments": [
            {
                "amount": 500,
                "type": "$paymentMethod",
                "ccToken"?: "$panToken"
            }
        ],
        "posVendor": {
            "matchingId": "$smgCode",
            "operator": "$operatorId",
            "posType": "$posVendorName",
            "storeId": "$rbiStoreId",
            "terminal": "$terminalNumber",
            "transactionId": "$posTransactionId"
        }
    }
}

Expected Response Payload:

{
  "presentation": {
    "footer": "receipt footer",
    "header": "receipt header",
    "marketing": "receipt marketing promo",
    "identifier": "Transaction ID: "$loyaltyTransactionId"
  },
  "transactionId": "$loyaltyTransactionId"
}

 

Void Transaction (PUT)

Use Case: Loyalty transaction needs to be voided/refunded.

Endpoint URL: https://{reg}-{env}-{brand}-loyalty-middleware.rbictg.com/loyalty/transaction/pos/{loyaltyTransactionId}/void

Order information does not need to be included in the Void Transaction Request

Expected Request Payload:

{
    "channel": "Restaurant",
    "created": "2021-05-04T13:39:47Z",
    "serviceMode": "$serviceMode",
    "status": "PENDING or CLAIMED",
    "transactionDetails": {
        "currency": "USD",
        "order": [
            {
                "name": "some incentive name",
                "price": 5.00,
                "productId": "$incentivePlu",
                "productType": "offer",
                "quantity": 1,
                "referenceId": "1",
                "tax": 0
            },
            {
                "name": "med whopper combo",
                "price": 5.00,
                "productId": "$plu",
                "productType": "combo",
                "quantity": 1,
                "referenceId": "1",
                "tax": 0
            },
            {
                "name": "whopper",
                "parentReferenceId"?: "1",
                "price": 0,
                "productId": "$plu",
                "productType": "item",
                "quantity": 1,
                "referenceId": "2",
                "tax": 0
            },
            {
                "name": "med fries",
                "parentReferenceId"?: "1",
                "price": 0,
                "productId": "$plu",
                "productType": "item",
                "quantity": 1,
                "referenceId": "3",
                "tax": 0
            }
        ],
        "payments": [
            {
                "amount": 500,
                "type": "$paymentMethod",
                "ccToken"?: "$panToken"
            }
        ],
        "posVendor": {
            "matchingId": "$smgCode",
            "operator": "$operatorId",
            "posType": "$posVendorName",
            "storeId": "$rbiStoreId",
            "terminal": "$terminalNumber",
            "transactionId": "$posTransactionId"
        }
    }
}

Expected Response Payload:

{
  "transactionId": "$loyaltyTransactionId"
}

 

  • No labels