Core concepts

Wallets & Points

Every customer has a wallet that tracks their loyalty point balance. The wallet is backed by an append-only ledger that records every point movement with a full audit trail.


Wallet overview

FieldDescription
idUnique wallet ID
customer_idThe customer this wallet belongs to
balanceCurrent point balance (integer)
expiring_soonPoints expiring in the near future

A wallet is automatically created when a customer is registered. There is exactly one wallet per customer.


Ledger entries

The ledger is an immutable, append-only record of every point movement. Each entry contains:

FieldDescription
typeThe type of movement: earn, adjust, redeem, or expire
amountSigned integer: positive for credits, negative for debits
running_balanceThe wallet balance after this entry
reasonHuman-readable explanation
causer_typeWhat triggered this entry (e.g., transaction, admin user)
causer_idID of the triggering entity
transaction_idAssociated transaction (for earn entries)
created_atTimestamp of the entry

Entry types

TypeDirectionTriggered by
earnPositiveTransaction submitted. Points calculated from earn rules
adjustPositive or negativeManual balance adjustment by admin or API
redeemNegativeCustomer redeems a reward
expireNegativePoints expired under the vendor's expiration policy

Immutable ledger

Ledger entries are never updated or deleted. The running_balance field on each entry provides a verifiable audit trail. To correct a mistake, create a new adjustment entry rather than modifying existing entries.


Point batches and expiration

When a vendor has point expiration enabled, earned points are tracked in batches. Each batch records:

FieldDescription
amountPoints in this batch
consumedPoints already used from this batch
expires_atWhen the remaining points in this batch expire

Points are consumed from the oldest batches first (FIFO). When a batch expires, any remaining points are deducted from the wallet and recorded as an expire ledger entry.

How expiration works

  1. Vendor enables expiration and sets expiration_months (e.g., 12 months)
  2. Each time points are earned, a batch is created with expires_at set to the earn date + expiration months
  3. When points are redeemed or adjusted, the oldest batches are consumed first
  4. A background job periodically checks for expired batches and creates expire entries

Manual adjustments

Administrators can manually adjust a wallet balance through the admin portal or the API. Adjustments create a new ledger entry with type adjust:

POST /api/v1/customers/{customer}/wallet/adjust
{
    "amount": 500,
    "reason": "Compensation for service issue",
    "idempotency_key": "goodwill-2024-0042"
}

Positive amounts add points; negative amounts deduct points. The idempotency_key makes the call safe to retry: re-sending the same key for the same customer returns the original ledger entry instead of moving the balance twice.

See Wallet endpoints for the complete API reference.

Previous
Customers