{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://uip.dev/schemas/ucp/shopping/loyalty.json",
  "name": "dev.uip.shopping.loyalty",
  "version": "2026-01-23",
  "title": "Loyalty Extension Response",
  "description": "Extends Checkout with Loyalty support, detailing memberships, programs, wallets, tiers, and earnings.",
  "$defs": {
    "allocation": {
      "type": "object",
      "description": "Breakdown of how the earning was allocated to a specific target.",
      "required": [
        "path",
        "amount"
      ],
      "properties": {
        "path": {
          "type": "string",
          "description": "JSONPath to the allocation target (e.g., '$.line_items[0]')."
        },
        "amount": {
          "type": "integer",
          "minimum": 0,
          "description": "Amount of points/value allocated to this target in minor units (1/100)."
        }
      },
      "examples": [
        {
          "path": "$.line_items[0]",
          "amount": 200
        }
      ]
    },
    "membership": {
      "type": "object",
      "description": "An identifier for the entity involved in the loyalty program.",
      "required": [
        "type",
        "id"
      ],
      "properties": {
        "type": {
          "type": "string",
          "enum": ["profile", "card"],
          "description": "The type of membership identifier."
        },
        "id": {
          "type": "string",
          "description": "The unique identifier string."
        }
      },
      "examples": [
        {
          "type": "profile",
          "id": "cd9105a3-078f-4c27-a6e1-6f26b51011ae"
        },
        {
          "type": "card",
          "id": "4686969062356430"
        }
      ]
    },
    "amount_breakdown": {
      "type": "object",
      "description": "Breakdown of points or value by status.",
      "required": [
        "active",
        "pending",
        "total"
      ],
      "properties": {
        "active": {
          "type": "integer",
          "description": "Immediately available balance in minor units (1/100)."
        },
        "pending": {
          "type": "integer",
          "description": "Balance awaiting confirmation or activation in minor units (1/100)."
        },
        "total": {
          "type": "integer",
          "description": "Sum of active and pending balances in minor units (1/100)."
        }
      },
      "examples": [
        {
          "active": 1250,
          "pending": 500,
          "total": 1750
        }
      ]
    },
    "tier": {
      "type": "object",
      "required": [
        "id",
        "name"
      ],
      "properties": {
        "id": {
          "type": "string",
          "description": "Internal ID of the tier."
        },
        "name": {
          "type": "string",
          "description": "Human-readable tier name."
        }
      },
      "examples": [
        {
          "id": "tier_gold",
          "name": "Gold Tier"
        }
      ]
    },
    "tier_info": {
      "type": "object",
      "description": "Current tier status and progression.",
      "required": [
        "current"
      ],
      "properties": {
        "current": {
          "$ref": "https://uip.dev/schemas/ucp/shopping/loyalty.json#/$defs/tier"
        },
        "next": {
          "$ref": "https://uip.dev/schemas/ucp/shopping/loyalty.json#/$defs/tier"
        },
        "units_to_next": {
          "type": "integer",
          "minimum": 0,
          "description": "Points/units required to reach the next tier in minor units (1/100)."
        }
      },
      "examples": [
        {
          "current": {
            "id": "tier_silver",
            "name": "Silver"
          },
          "next": {
            "id": "tier_gold",
            "name": "Gold"
          },
          "units_to_next": 250
        }
      ]
    },
    "wallet": {
      "type": "object",
      "description": "A specific container of value (points, money, stamps. etc.) within a program.",
      "required": [
        "id",
        "unit",
        "balances"
      ],
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique identifier for the wallet."
        },
        "unit": {
          "type": "string",
          "description": "The unit of measure ('points', 'stamps', 'USD', etc.)."
        },
        "balances": {
          "$ref": "https://uip.dev/schemas/ucp/shopping/loyalty.json#/$defs/amount_breakdown",
          "description": "Current state of the wallet before this transaction."
        },
        "earnings": {
          "$ref": "https://uip.dev/schemas/ucp/shopping/loyalty.json#/$defs/amount_breakdown",
          "description": "Impact of the current transaction on this wallet. Contains amounts expected to be earned at transaction completion, or that have been earned if this transaction is already completed."
        },
        "tier": {
          "$ref": "https://uip.dev/schemas/ucp/shopping/loyalty.json#/$defs/tier_info"
        }
      },
      "examples": [
        {
          "id": "main_wallet",
          "unit": "points",
          "balances": {
            "active": 1250,
            "pending": 500,
            "total": 1750
          },
          "earnings": {
            "active": 100,
            "pending": 0,
            "total": 100
          },
          "tier": {
            "current": {
              "id": "tier_silver",
              "name": "Silver"
            },
            "next": {
              "id": "tier_gold",
              "name": "Gold"
            },
            "units_to_next": 250
          }
        }
      ]
    },
    "program": {
      "type": "object",
      "description": "A loyalty program associated with a membership.",
      "required": [
        "id",
        "name",
        "membership",
        "wallets"
      ],
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique identifier for the program."
        },
        "name": {
          "type": "string",
          "description": "Human-readable name of the program."
        },
        "membership": {
          "type": "string",
          "description": "JSONPath reference to the membership (e.g., '$.loyalty.memberships[0]')."
        },
        "wallets": {
          "type": "array",
          "items": {
            "$ref": "https://uip.dev/schemas/ucp/shopping/loyalty.json#/$defs/wallet"
          },
          "minItems": 1
        }
      },
      "examples": [
        {
          "id": "f94c586c-af6f-47c9-9194-e3cf3550a1a2",
          "name": "The Loyalty Club",
          "membership": "$.loyalty.memberships[0]",
          "wallets": [
            {
              "id": "main_wallet",
              "unit": "points",
              "balances": {
                "active": 1250,
                "pending": 500,
                "total": 1750
              },
              "earnings": {
                "active": 100,
                "pending": 0,
                "total": 100
              }
            }
          ]
        }
      ]
    },
    "earning": {
      "type": "object",
      "description": "Details of points or value expected to be earned.",
      "required": [
        "title",
        "target",
        "amount",
        "wallet"
      ],
      "properties": {
        "title": {
          "type": "string",
          "description": "Human-readable description of the earning."
        },
        "target": {
          "type": "string",
          "enum": [
            "session",
            "items",
            "bundle"
          ],
          "description": "What the earning is applied to."
        },
        "method": {
          "type": "string",
          "enum": ["each", "across"],
          "description": "How the earning is calculated/distributed for item/bundle targets."
        },
        "amount": {
          "type": "integer",
          "minimum": 0,
          "description": "The total amount expected to be earned at transaction completion, or that has been earned if this transaction is already completed. Represented in minor units (1/100)."
        },
        "wallet": {
          "type": "string",
          "description": "JSONPath reference to the specific wallet receiving the earnings (e.g., '$.loyalty.programs[0].wallets[0]')."
        },
        "active_from": {
          "type": "string",
          "format": "date-time",
          "description": "RFC-3339 timestamp indicating when these points become active."
        },
        "allocations": {
          "type": "array",
          "items": {
            "$ref": "https://uip.dev/schemas/ucp/shopping/loyalty.json#/$defs/allocation"
          },
          "description": "Breakdown of where this earning was allocated."
        }
      },
      "examples": [
        {
          "title": "20 Points on the session",
          "target": "session",
          "amount": 200,
          "wallet": "$.loyalty.programs[0].wallets[0]"
        }
      ]
    },
    "loyalty_object": {
      "type": "object",
      "description": "Container for all loyalty-related data.",
      "properties": {
        "memberships": {
          "type": "array",
          "items": {
            "$ref": "https://uip.dev/schemas/ucp/shopping/loyalty.json#/$defs/membership"
          },
          "description": "List of profiles or cards identified."
        },
        "programs": {
          "type": "array",
          "readOnly": true,
          "items": {
            "$ref": "https://uip.dev/schemas/ucp/shopping/loyalty.json#/$defs/program"
          },
          "description": "State of loyalty programs and wallets."
        },
        "earnings": {
          "type": "array",
          "readOnly": true,
          "items": {
            "$ref": "https://uip.dev/schemas/ucp/shopping/loyalty.json#/$defs/earning"
          },
          "description": "List of specific earnings triggered by the transaction."
        }
      }
    },
    "checkout": {
      "title": "Checkout with Loyalty Response",
      "description": "Checkout extended with loyalty capability.",
      "allOf": [
        {
          "$ref": "https://ucp.dev/schemas/shopping/checkout.json"
        },
        {
          "type": "object",
          "properties": {
            "loyalty": {
              "$ref": "https://uip.dev/schemas/ucp/shopping/loyalty.json#/$defs/loyalty_object"
            }
          }
        }
      ]
    }
  }
}