Technical brief · reference 1.0.0 UCP v2026-08-25 Synthetic data

Mapping a Shopify points program onto the UCP loyalty extension

What maps cleanly, what does not, and four questions we could not answer from the released spec. Written for UCP contributors and implementers; useful whether or not you ever evaluate StabileRewards.

  1. Version and sources
  2. Scenario declaration
  3. Field mapping
  4. Public and authorized data
  5. Observations
  6. Reward lifecycle (not UCP)
  7. Known gaps
  8. Our /.well-known/ucp
  9. Downloads and changelog

1. Version and sources

Everything here is mapped against the released UCP v2026-08-25 loyalty extension, merged in PR #340.

Every loyalty object in the fixtures validates against that schema with a full JSON Schema 2020-12 validator; the warning and info messages validate against the released message schemas.

2. Scenario declaration

All data is synthetic. Harbor & Pine Tea (harborpine.example, a reserved TLD) is invented. No real merchant, shopper, balance, code, or order appears anywhere in this reference.

Program5 points per $1 · $35 minimum to earn · 150-point first-order bonus · 500 points → $5 off, 900 → $12 off · 180-day expiry
Loyalty keyexample.harborpine.rewards
Cart ALoose-leaf tea sampler $48.00 + ceramic mug $24.00 = $72.00
Cart BSingle-origin tea tin $28.00 (under the minimum)
MemberSynthetic returning member, three prior orders, masked ****4821
Math sourceThe same functions StabileRewards serves to shopping agents today (buildProgramVisibility, buildRewardOptions). Changing that math without regenerating the fixtures fails our test suite.

3. Field mapping

“Released UCP” means the field exists in the released schema and the fixture value validates. “Stabile-specific” means there is no released representation.

Loading mapping…

4. Public and authorized data

The anonymous projection answers with provisional: true and no display_id. The authorized projection resolves membership from an authenticated identity and returns provisional: false with a masked id. Available points and reward codes appear in neither.

Public Cart A, anonymous

…

Buyer-authorized Cart A, member

…

The authorized example is a controlled synthetic scenario. It is not evidence of completed production identity linking.

5. Observations

Questions and edge cases we hit while mapping. We would value maintainer and implementer views on each.

6. Reward lifecycle Not standardized

The released extension explicitly leaves redeemable balances to a payment instrument or a future redemption capability. This is how StabileRewards handles it today on Shopify, published as implementation evidence. Point movements are shown as deltas; codes are redacted.

Loading lifecycle…

7. Known gaps

  • Balance. Available points are Stabile operational state, not loyalty-extension output.
  • Redemption. Turning points into a discount code has no released UCP operation.
  • Discount stacking. Follows each Shopify discount's combination settings; not modeled here.
  • Settlement. Points settle when the order is created; see the lifecycle gaps below.

    8. Our /.well-known/ucp

    The loyalty extension decorates a business's catalog, cart, and checkout responses, and a business that advertises dev.ucp.common.loyalty must also serve those parent capabilities. StabileRewards is a loyalty provider to Shopify merchants, not a store, so our profile does not advertise the loyalty extension or any shopping capability. It declares one vendor-namespaced service, com.stabilerewards.loyalty, pointing at our merchant-scoped REST quote API and our MCP server, with no payment handlers.

    UCP has no participant type for a loyalty provider yet. That is the subject of issue #384, and our reason for publishing this reference.

    9. Downloads and changelog

    1.0.0 — 2026-09-23

    • First public reference against UCP v2026-08-25.
    • Synthetic merchant, $72.00 and $28.00 carts, one synthetic member.
    • Three fixtures, field mapping, four observations.

    Fixtures are regenerated from StabileRewards' program code, checked against the released schema and a privacy denylist, and versioned. A schema change in a future UCP release gets a new fixture version, not a silent edit.

    Questions or corrections: info@stabilerewards.com. Merchants can request a pilot.