Logo PopinaPopina API

Getting Started

Get started with Loyalty API service, acting as a proxy for loyalty operations.

1. Purpose

Loyalty API acts as a centralized proxy between Popina's client applications (like Popina Kiosks and Point of Sale systems) and various external loyalty service providers.

Its primary goal is to abstract the complexity of integrating with multiple third-party loyalty systems. By providing a single, standardized set of endpoints, it allows Popina applications to perform all loyalty-related operations, including searching for customers, awarding points, and redeeming rewards, without needing to know the specific implementation details of each external provider.

This architecture simplifies client-side development, ensures consistency, and makes it easier to add, remove, or switch loyalty providers in the future.

2. Loyalty Providers

The service integrates with several loyalty providers, each at a different stage of development.

ProviderStatusDescription
Hey Pongoβœ… OperationalFully integrated and available for production use.
Como🚧 In ProgressIntegration is currently under development.
Little Bill🚧 In ProgressIntegration is currently under development.
Provider XπŸ—ΊοΈ RoadmapPlanned for a future release.

3. Core Concepts

Understanding these terms is essential for working with the loyalty API.

  • POS (Point of Sale): The system used by merchants to process customer transactions, manage orders, and handle payments in physical retail locations.
  • Kiosk: A self-service terminal that allows customers to browse products, place orders, and make payments without direct assistance from staff.
  • C&C (Click and Collect): An ordering method where customers place orders online or through an app and then pick them up at a physical location at a scheduled time.
  • Loyalty Service: An external third-party platform that manages loyalty programs (e.g., Hey Pongo, Como).
  • Customer: The end-user enrolled in a loyalty program, identified by attributes like an email address or phone number.
  • Benefit: A generic term for any advantage a customer has in their loyalty account. This includes points, available coupons, or a cashback balance.
  • Reward: A specific, redeemable item that a customer can obtain, often by exchanging points (e.g., "Free Coffee" or "10% Off Next Purchase").
  • Points: A virtual currency customers earn with purchases, which can be accumulated and later redeemed for Rewards.
  • Credit: A monetary value credited to a customer's loyalty account after a purchase, which can often be used as a discount on future transactions.
  • Redeem: The action of exchanging points for a specific Reward. For example, a customer redeems 100 points to get a "Free Coffee" coupon.
  • Apply Benefit / Burn Reward: The final action of consuming a benefit on a transaction. This "burns" the reward (marks it as used) and applies its value (e.g., a discount) to the customer's bill.

4. Process Flowcharts

The following diagrams illustrate the two primary user flows managed by the API.

Gaining Points & Benefits

This flow describes how a customer earns points or cashback from a transaction at the POS or Kiosk.

Applying Rewards & Discounts

This flow shows how a customer uses an existing reward or benefit to get a discount.

5. Step-by-Step API Usage

Authentication

All requests to the Loyalty API must be authenticated. There is two ways to use this API:

  • with the consumer key: Authorization: Bearer <CONSUMER_KEY>
  • with a device access token:
    • Authorization: Bearer <DEVICE_ACCESS_TOKEN>
    • Authorization-Client: device

The CONSUMER_KEY is a secret token available in Popina Admin. The DEVICE_ACCESS_TOKEN is generated when a Popina device is connected.

Health Check

To verify that the service is running, make a simple GET request to the health check endpoint.

Request:

curl {API_LOYALTY_URL}/health

Response:

{
  "statusCode": 200,
  "status": "ok"
}

Search or Create a Customer

To find a customer, you can search by their email or phone number. If the customer doesn't exist, some providers may create a new one automatically.

Request: POST {API_LOYALTY_URL}/v1/customers/search

{
  "type": "phone",
  "value": "+33612345678"
}

Response (Customer Found):

{
  "id": "customer_uuid",
  "firstName": "John",
  "lastName": "Doe",
  "email": "john.doe@example.com",
  "phoneNumber": "+33612345678",
  "birthDate": null,
  "externalLoyaltyId": "external-loyalty-id-12345",
}

Retrieve Customer's Benefits

Once you have a customer ID, you can fetch their available benefits.

Request: GET {API_LOYALTY_URL}/v1/benefits/{customerId}

Response:

{
  "points": 450,
  "credit": 45,
  "rewards": [
    {
      "id": "4kOvH4foImPWSa4igbXtIFWJuvAoW469C7yRcjMQ8",
      "type": "AMOUNT",
      "name": "Test free coffee",
      "image":
        "https://services.prod.bcomo.com/GetResource?namespace=location_8270&resourceId=image_medium_747001&version=0",
      "description": "free coffee",
      "couponCode": null,
      "isUsed": false,
      "useable": true,
      "requirement": {
        "expirationDate": "2030-04-24T09:06:26.000Z",
      },
      "value": null,
      "hash": null,
      "receivedAt": null,
      "usedAt": null,
    }
  ]
}

Redeem a Benefit (Buy a Reward)

To redeem a benefit, send the order with the list of rewards we want to redeem. In the reward list we need the reward "id" and if available the "couponCode" value.

The API will "buy" the reward and return the discount to apply for the valid requested rewards. A reward may not be valid if:

  • it is expired by its expiration date
  • it has an minimum amount required for the order
  • it is specific for an item on the order by an SKU

Request: POST /tickets/ticket-xyz-789/apply-benefit

{
  "customerId": "5efdca54-c860-43dc-ba4b-7aff61937b44",
  /* spell-checker: disable */
  "rewards": [
    {
      "rewardId": "rew_3377badde0",
      "couponCode": null,
    },
    {
      "rewardId": "rew_1111badde1",
      "couponCode": "123456",
    },
  ],
  /* spell-checker: enable */
  "order":{
    "totalAmount": 5000,
    "totalTax": 500,
    "products": [
      {
        "id": "3ed0bce3-bf8a-4e46-bd71-994cf4e5c36a",
        "name": "Pants",
        "quantity": 2,
        "unitPrice": 1000,
        "categoryId": "5e380043-0936-46be-a0b7-25d2b0398834",
        "categoryName": "Ergonomic Concrete Computer",
        "sku": "SKU",
      },
      {
        "id": "d1889e80-51a6-42b3-a6ac-1e0f7aca6982",
        "sku": "COFFEE",
        "name": "Coffee",
        "categoryId": "af4a50cc-d694-495a-8e45-c8aba9f05c16",
        "categoryName": "Granite",
        "quantity": 3,
        "unitPrice": 1000,
      },
    ],
  }
}

Response:

{
  "success": true,
  "data": [
    {
      /* cspell: disable-next-line */
      "id": "rew_3377badde0",
      "type": "AMOUNT",
      "name": "popina reward 1",
      "couponCode": null,
      "productSku": null,
      "value": 300,
    },
  ]
}

The POS system is now responsible for applying a €3.00 discount to the order.

Apply benefits (Complete a Transaction)

After a payment is completed on the POS, the api-loyalty create the final ticket to the loyalty API to award points or cashback to the customer. It is all made under the hood, without calling any endpoint from any actor. The requested rewards are burnt and an order is created in the external loyalty service.

The api-loyalty receive the loyalty orderId created when success.

Response:

{
  "success": true,
  "externalOrderId": "loyalty_order_123456"
}