Beta Release
This is pre-release documentation for an API in public beta and is subject to change.
Loyalty API: Walkthrough 1

Step 4: Redeem Points

Now that the buyer has 12 points in the loyalty account, the walkthrough explores how the buyer can use these points to get the reward (a 10% discount for 10 points). In this step, you follow a typical application flow:

  • The buyer places an order.

  • You offer the buyer the reward option.

    In a real application, you compare the point balance in the buyer's account with the points required to get a reward. You do this comparison on the client side. If the buyer qualifies for the discount, you offer the reward.

  • Suppose the buyer agrees to pay points for the reward. You then create a reward using CreateLoyaltyReward.

  • Take the payment for the order using CreatePayment. The following happens:

    • The reward status is automatically set to REDEEMED, a terminal state (the reward points are permanently removed from the loyalty account).

    • If the order qualifies to earn points, you add points to the buyer's account by calling AccumulateLoyaltyPoints.

Step 4.1: Create an order Permalink Get a link to this section

  1. Call CreateOrder to order a $10 item:

    Create Order
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    curl https://connect.squareupsandbox.com/v2/orders \
      -X POST \
      -H 'Square-Version: 2021-03-17' \
      -H 'Authorization: Bearer {ACCESS_TOKEN}' \
      -H 'Content-Type: application/json' \
      -d '{
        "order": {
          "line_items": [
            {
              "name": "a non-catalog-item-order#2",
              "quantity": "1",
              "base_price_money": {
                "amount": 1000,
                "currency": "USD"
              }
            }
          ],
          "location_id": "{LOCATION_ID}"
        },
        "idempotency_key": "{UNIQUE_KEY}"
      }'
  2. Note the order ID in the response. The following is an example response:

    {
       "order":{
          "id":"Dwirgyyg2GjIc5dBoX5rRexample",
          "location_id":"S8GWD5example",
          "line_items":[
             {
                "uid":"to4gxMoxYW3ERQYexample",
                "quantity":"1",
                "name":"a non-catalog-item-order-#2",
                "base_price_money":{
                   "amount":1000,
                   "currency":"USD"
                },
                "gross_sales_money":{
                   "amount":1000,
                   "currency":"USD"
                },
                "total_tax_money":{
                   "amount":0,
                   "currency":"USD"
                },
                "total_discount_money":{
                   "amount":0,
                   "currency":"USD"
                },
                "total_money":{
                   "amount":1000,
                   "currency":"USD"
                },
                "variation_total_price_money":{
                   "amount":1000,
                   "currency":"USD"
                }
             }
          ],
          "created_at":"2020-04-01T03:37:26.446Z",
          "updated_at":"2020-04-01T03:37:26.446Z",
          "state":"OPEN",
          "version":1,
          "total_tax_money":{
             "amount":0,
             "currency":"USD"
          },
          "total_discount_money":{
             "amount":0,
             "currency":"USD"
          },
          "total_tip_money":{
             "amount":0,
             "currency":"USD"
          },
          "total_money":{
             "amount":1000,
             "currency":"USD"
          },
          "total_service_charge_money":{
             "amount":0,
             "currency":"USD"
          },
          "net_amounts":{
             "total_money":{
                "amount":1000,
                "currency":"USD"
             },
             "tax_money":{
                "amount":0,
                "currency":"USD"
             },
             "discount_money":{
                "amount":0,
                "currency":"USD"
             },
             "tip_money":{
                "amount":0,
                "currency":"USD"
             },
             "service_charge_money":{
                "amount":0,
                "currency":"USD"
             }
          },
          "source":{
             "name":"Sandbox for sq0idp-MJ1Sr5Iim0hGGvAexample"
          }
       }
    }
    

Step 4.2: Show the reward options to the buyer Permalink Get a link to this section

The application does the following to determine whether the buyer qualifies for the reward (a 10% discount on the entire order for 10 points):

  • Retrieve the loyalty account, which provides the point balance.

  • Retrieve the loyalty program, which includes the reward tier information.

  • Compare the point balance and reward tier. If the buyer has sufficient points for the discount, offer the reward.

Retrieve a buyer's loyalty account Permalink Get a link to this section

Call RetrieveLoyaltyAccount to retrieve the loyalty account of the buyer. Provide the LOYALTY_ACCOUNT_ID in the endpoint URL.

Retrieve Loyalty Account
  • 1
  • 2
  • 3
  • 4
curl https://connect.squareupsandbox.com/v2/loyalty/accounts/{account_id} \
  -H 'Square-Version: 2021-03-17' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json'

The following is an example response. The balance shows the available point balance.

{
   "loyalty_account":{
      "id":"716cefbc-3d71-4d7c-bdc8-9c78fexample",
      "mappings":[
         {
            "id":"b0e8a407-4305-4cc3-b170-0d4dCexample",
            "type":"PHONE",
            "value":"+14255551111",
            "created_at":"2020-03-24T20:47:15Z"
         }
      ],
      "program_id":"ba293138-8fbd-425d-860b-18ab3example",
      "balance":12,
      "lifetime_points":12,
      "customer_id":"REK96J96AS5AN2Y8Z4Hexample",
      "created_at":"2020-01-30T00:11:58Z",
      "updated_at":"2020-01-30T00:11:58Z"
   }
}

Retrieve the loyalty program Permalink Get a link to this section

Call ListLoyaltyPrograms to retrieve the loyalty program. In the current implementation, only one loyalty program is supported in a seller account. Therefore, the endpoint can only return one loyalty program.

List Loyalty Programs
  • 1
  • 2
  • 3
  • 4
curl https://connect.squareupsandbox.com/v2/loyalty/programs \
  -H 'Square-Version: 2021-03-17' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json'

The following is an example response, which includes a list of the reward tiers the program offers:

{
   "programs":[
      {
         "id":"ba293138-8fbd-425d-860b-18ab3example",
         "status":"ACTIVE",
         "reward_tiers":[
            {
               "id":"681fbe5c-64c6-4417-9860-a6b56example",
               "points":10,
               "name":"10% off entire sale",
               "definition":{
                  "scope":"ORDER",
                  "discount_type":"FIXED_PERCENTAGE",
                  "percentage_discount":"10"
               },
               "created_at":"2020-03-29T20:23:17Z",
               "pricing_rule_reference": {
                 "object_id": "NJD4FBM6LYUSPOFQDexample",
                 "catalog_version": "08732example"
               }
            }
         ],
         "terminology":{
            "one":"Point",
            "other":"Points"
         },
         "location_ids":[
            "S8GWD5example"
         ],
         "created_at":"2020-01-28T04:32:01Z",
         "updated_at":"2020-03-29T20:23:18Z",
         "accrual_rules":[
            {
               "accrual_type":"SPEND",
               "points":1,
               "spend_amount_money":{
                  "amount":100
               }
            }
         ]
      }
   ]
}

Determine the reward tiers to show the buyer Permalink Get a link to this section

Your application can now compare the point balance with the program's reward tiers and present applicable reward tiers to the buyer. In this example, the balance of 12 points in the loyalty account qualifies for the reward tier (redeem 10 points for 10% off your entire sale). Therefore, you need to get information about the reward tier discount.

To get the discount details, use the object_id and catalog_version from the pricing_rule_reference to call the RetrieveCatalogObject endpoint in the Catalog API. Make sure to set include_related_objects to true to return all of the catalog objects that define discount details. You might also need to call the Catalog API to get current product information. For more information, see Get discount details for the reward.

Note

The ListLoyaltyPrograms response currently also includes the deprecated definition field, which is replaced by the pricing_rule_reference field. Square recommends that you use pricing_rule_reference.

Show the reward offer to the buyer Permalink Get a link to this section

Your application can show the reward offer to the buyer. Assume that the buyer chooses to claim the reward.

Step 4.3: Create a reward Permalink Get a link to this section

  1. Call CreateLoyaltyReward to apply the reward tier. In the request:

    • reward_tier_id identifies the reward tier to apply.

    • order_id identifies the order to update.

    • loyalty_account_id identifies the buyer's loyalty account from which to take loyalty points.

    Create Loyalty Reward
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    curl https://connect.squareupsandbox.com/v2/loyalty/rewards \
      -X POST \
      -H 'Square-Version: 2021-03-17' \
      -H 'Authorization: Bearer {ACCESS_TOKEN}' \
      -H 'Content-Type: application/json' \
      -d '{
        "reward": {
          "loyalty_account_id": "{ACCOUNT_ID}",
          "reward_tier_id": "{REWARD_TIER_ID}",
          "order_id": "{ORDER_ID}"
        },
        "idempotency_key": "{UNIQUE_KEY}"
      }'

    The endpoint does the following:

    • Creates a reward object. Creating a reward reserves a certain number of points from the loyalty account of the buyer. These points cannot be used to redeem any other reward unless and until you delete the reward. For more information, see Loyalty rewards.

    • Updates the order as follows:

      • Adds the reward to the order (the rewards property).

      • Adds the relevant discount to the order (the discounts property) and applies the discount to line items that qualify (the applied_discounts property).

      • Updates the order amount to reflect the discount.

    In response, the endpoint returns the reward created. The following is an example response:

    {
       "reward":{
          "id":"45d8d201-50b9-3dc8-97f3-ff5d0example",
          "status":"ISSUED",
          "loyalty_account_id":"716cefbc-3d71-4d7c-bdc8-9c78fexample",
          "reward_tier_id":"681fbe5c-64c6-4417-9860-a6b56example",
          "points":10,
          "order_id":"Dwirgyyg2GjIc5dBoX5rRexample",
          "created_at":"2020-05-07T23:32:19Z",
          "updated_at":"2020-05-07T23:32:19Z"
       }
    }
    
  2. Call RetrieveOrder to retrieve the updated order and show your buyer the updates in your application UI:

    Retrieve Order
    • 1
    • 2
    • 3
    • 4
    curl https://connect.squareupsandbox.com/v2/orders/{order_id} \
      -H 'Square-Version: 2021-03-17' \
      -H 'Authorization: Bearer {ACCESS_TOKEN}' \
      -H 'Content-Type: application/json'

    This is the response:

    {
      "order": {
        "id": "Dwirgyyg2GjIc5dBoX5rRexample",
        "location_id": "S8GWD5example",
        "line_items": [
          {
            "uid": "to4gxMoxYW3ERQYexample",
            "quantity": "1",
            "name": "a non-catalog item #2",
            "base_price_money": {
              "amount": 1000,
              "currency": "USD"
            },
            "gross_sales_money": {
              "amount": 1000,
              "currency": "USD"
            },
            "total_tax_money": {
              "amount": 0,
              "currency": "USD"
            },
            "total_discount_money": {
              "amount": 100,
              "currency": "USD"
            },
            "total_money": {
              "amount": 900,
              "currency": "USD"
            },
            "variation_total_price_money": {
              "amount": 1000,
              "currency": "USD"
            },
            "applied_discounts": [
              {
                "uid": "eOdEOTVqcLD1ab3example",
                "discount_uid": "pFv6PyLSsBkLiGVexample",
                "applied_money": {
                  "amount": 100,
                  "currency": "USD"
                }
              }
            ]
          }
        ],
        "discounts": [
          {
            "uid": "pFv6PyLSsBkLiGVexample",
            "catalog_object_id": "DE6EOJ2H7E62Q4BZVexample",
            "name": "10% off entire sale",
            "percentage": "10.0",
            "applied_money": {
              "amount": 100,
              "currency": "USD"
            },
            "type": "FIXED_PERCENTAGE",
            "scope": "LINE_ITEM",
            "reward_ids": [
              "45d8d201-50b9-3dc8-97f3-ff5d0example"
            ],
            "pricing_rule_id": "NJD4FBM6LYUSPOFQDexample"
          }
        ],
        "created_at": "2020-05-12T22:41:08.475Z",
        "updated_at": "2020-05-12T22:48:39.118Z",
        "state": "OPEN",
        "version": 2,
        "total_tax_money": {
          "amount": 0,
          "currency": "USD"
        },
        "total_discount_money": {
          "amount": 100,
          "currency": "USD"
        },
        "total_tip_money": {
          "amount": 0,
          "currency": "USD"
        },
        "total_money": {
          "amount": 900,
          "currency": "USD"
        },
        "total_service_charge_money": {
          "amount": 0,
          "currency": "USD"
        },
        "net_amounts": {
          "total_money": {
            "amount": 900,
            "currency": "USD"
          },
          "tax_money": {
            "amount": 0,
            "currency": "USD"
          },
          "discount_money": {
            "amount": 100,
            "currency": "USD"
          },
          "tip_money": {
            "amount": 0,
            "currency": "USD"
          },
          "service_charge_money": {
            "amount": 0,
            "currency": "USD"
          }
        },
        "source": {
          "name": "Sandbox for sq0idp-MJ1Sr5Iim0hGGvAexample"
        },
        "rewards": [
          {
            "id": "45d8d201-50b9-3dc8-97f3-ff5d0example",
            "reward_tier_id": "681fbe5c-64c6-4417-9860-a6b56example"
          }
        ]
      }
    }
    

    Note the following order updates:

    • The line item (line_items[]) field shows:

      • total_discount_money. Shows a $1 discount (10% of the total sale).

      • total_money. Shows a decrease from $10 to $9.

      • applied_discounts. Shows the discount applied to the line item. It matches the applied_discounts.discount_uid match the uid of one of the discounts in the top-level discounts[] list (which identifies the list of all the discounts for the order).

    • discounts[]. At the top level, shows a list of discounts added for the order. In this example, there is one discount that maps the loyalty reward you created.

The presence of the discount indicates the reward was applied to the order. It is possible that you create a reward that does not get applied to the order. For example, you might create a reward for a free coffee, but the coffee is not in the order and the discount cannot be applied. After the order reaches the terminal state (for example the order is paid or canceled), Square deletes the reward and returns the points to the buyer's loyalty account.

Step 4.4: Take a payment Permalink Get a link to this section

Call CreatePayment to take a payment from the order.

Create Payment
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
curl https://connect.squareupsandbox.com/v2/payments \
  -X POST \
  -H 'Square-Version: 2021-03-17' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "source_id": "cnon:card-nonce-ok",
    "amount_money": {
      "amount": 900,
      "currency": "USD"
    },
    "order_id": "{ORDER_ID}",
    "idempotency_key": "{UNIQUE_KEY}"
  }'

Step 4.5: Give buyer points for the purchase Permalink Get a link to this section

The buyer paid for the order and therefore qualifies for loyalty points. Call AccumulateLoyaltyPoints to add the points to the buyer's account. In the request:

  • loyalty_account_id identifies the loyalty account of the buyer.

  • order_id is the order for which the buyer is getting points. The endpoint uses the information in the order to compute the loyalty points.

Accumulate Loyalty Points
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
curl https://connect.squareupsandbox.com/v2/loyalty/accounts/{account_id}/accumulate \
  -X POST \
  -H 'Square-Version: 2021-03-17' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "accumulate_points": {
      "order_id": "{ORDER_ID}"
    },
    "location_id": "{LOCATION_ID}",
    "idempotency_key": "{UNIQUE_KEY}"
  }'

The buyer got a 10% discount and paid $9 for the order. The loyalty program gives the buyer one point for every dollar spent. Therefore, the buyer gets 9 points for this purchase. You do not have to do any calculations. You provide the order ID in your AccumulateLoyaltyPoints request and the API uses the order to determine the loyalty points.

{
   "event":{
      "id":"efc9fc89-60e5-360a-9002-d3904example",
      "type":"ACCUMULATE_POINTS",
      "created_at":"2020-05-12T00:05:29Z",
      "accumulate_points":{
         "loyalty_program_id":"ba293138-8fbd-425d-860b-18ab3example",
         "points":9,
         "order_id":"Dwirgyyg2GjIc5dBoX5rRexample"
      },
      "loyalty_account_id":"716cefbc-3d71-4d7c-bdc8-9c78fexample",
      "location_id":"S8GWD5example",
      "source":"LOYALTY_API"
   }
}