Build with WalletD wallet infrastructure

From Points to Perks: Build a Loyalty System with WalletD

Use WalletD reward rules to turn captured payments into loyalty points and wallet credit, with practical guidance on rounding, retries, refunds, and launch checks.

Purchase receipt sending loyalty points into a wallet and onward to a gift reward, illustrating a WalletD loyalty system.

A customer pays for lunch, earns points, and returns next week to use them. The experience should feel simple. Behind it, your application needs to answer harder questions: Did the payment actually complete? Has this purchase already earned a reward? What happens if the customer returns it after spending the points?

WalletD can provide the rewards foundation for that journey through payment-triggered points accrual, cashback rules, and explicit conversion from points to wallet cash. Your application still owns the program’s customer experience, commercial policy, and any features beyond those primitives.

This guide covers WalletD at walletd.io, using its rewards API. The examples describe a restaurant program in a USD tenant: one point per dollar of qualifying captured payment, followed by conversion into wallet credit. They assume an existing sandbox tenant, a funded test user, and a registered merchant. They are integration examples, not a complete environment setup.

1. Decide what a point means before creating a rule

Start with a program specification that support, finance, and engineering can all explain.

Decision Example policy for this guide
Eligible purchase A captured WalletD payment to a merchant categorized as restaurants
Earning rate One point per USD 1.00 captured, rounded down per qualifying payment
Conversion value One point converts into one US cent of wallet cash
Minimum conversion 500 points
Expiry No point expiry in this first version
Refund behavior A launch requirement to define and test, including rewards already converted

Under these rules, a USD 25.00 payment earns 25 points. A customer who has accumulated 500 points can convert them into USD 5.00 of wallet credit. Before caps, refunds, and operating costs, the conversion value represents 1% of qualifying spend.

That arithmetic is an illustrative program design, not a WalletD default. It also depends on the tenant currency: one major unit is not always 100 minor units. Use integer minor units for cash and integer quantities for points throughout the integration.

Be precise about the earning base. The example uses the captured payment amount. It does not automatically subtract tax, tips, or delivery charges. If your program promises points on a different subtotal, verify a supported way to express that policy before publishing the promise.

2. Separate the rewards engine from the loyalty experience

WalletD distinguishes three rule kinds: cashback, accrual, and conversion. Accrual credits a separate POINTS commodity; conversion defines how those points become wallet cash. The API also exposes balances and reward history. See the money model and rewards guide.

Use those building blocks deliberately:

Responsibility Where it belongs
Evaluate matching rules after capture WalletD reward processing
Record points and cash separately WalletD’s ledger-backed account model
Execute points-to-cash conversion WalletD conversion API
Display progress toward the next reward Your customer application
Explain eligibility and refund terms Your program policy and customer experience
Gift fulfillment, referral qualification, or loyalty tiers Additional application behavior unless your deployed version explicitly supports it

The flow is straightforward:

Customer checkout → WalletD payment capture
                  → reward evaluation → points balance

Customer chooses conversion → your backend → WalletD conversion
                                          → wallet cash balance

This matters when integrating an existing store. A purchase recorded only in another checkout system is not automatically a captured WalletD payment. Do not invent a generic “award points” call or create a second payment merely to trigger rewards. Confirm the supported integration path for external purchases first.

Likewise, converting points to wallet cash does not itself deliver a gift or apply a discount in an unrelated checkout. Those require their own fulfillment or payment integration.

3. Configure a points accrual rule

Run administrative calls from a trusted backend or sandbox terminal. Configure WALLETD_API with your sandbox API origin and supply WALLETD_API_KEY through your normal secret handling. Never put a tenant key in frontend JavaScript. The authentication guide documents the available credentials and reward scopes.

Create the restaurant rule once:

curl --fail-with-body -sS -X POST "$WALLETD_API/v1/reward_rules" \
  -H "Authorization: Bearer $WALLETD_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "kind": "accrual",
    "params": {"rate_bps": 100},
    "scope": {"categories": ["restaurants"]}
  }'

Record the returned rule ID with the campaign configuration. Do not recreate the rule every time a service starts. Inspect existing rules before creating another, because overlapping matching rules can change what a purchase earns.

For this accrual rule, the calculation before caps is:

points = floor(captured_minor_units × rate_bps / 10,000)

With rate_bps: 100, USD 25.00 is 2,500 minor units and earns 25 points. USD 25.99 earns 25 points too. The fractional amount does not automatically carry over to the next purchase.

This is why “one point per dollar” needs a rounding policy. Two separate USD 0.60 purchases earn zero points under this rule, even though their combined value exceeds a dollar.

For a live campaign, also choose applicable caps and a start/end window using the supported rule configuration. Treat caps as part of the reward design and test their units and boundary behavior. A rule’s end time ends eligibility for future purchases; it should not be presented as expiry of points already earned.

4. Earn points through a captured payment

For the sandbox example, USER_ID is an existing funded user and MERCHANT_ID is a registered merchant with the restaurants category. Create one USD 25.00 instant payment:

curl --fail-with-body -sS -X POST "$WALLETD_API/v1/payments" \
  -H "Authorization: Bearer $WALLETD_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: loyalty-demo-payment-order-1001" \
  --data "{
    \"payer_user_id\": \"$USER_ID\",
    \"merchant_id\": \"$MERCHANT_ID\",
    \"amount\": 2500,
    \"mode\": \"instant\"
  }"

An authorization that merely reserves funds is different from a capture. Choose the payment mode according to the actual checkout lifecycle; see payments and refunds.

Reward evaluation follows capture asynchronously. A successful payment response therefore does not prove that the points are already visible. Let the interface show “payment complete” separately from the updated reward balance.

Read the authoritative balances and grant history:

curl --fail-with-body -sS "$WALLETD_API/v1/users/$USER_ID/balances" \
  -H "Authorization: Bearer $WALLETD_API_KEY"

curl --fail-with-body -sS "$WALLETD_API/v1/users/$USER_ID/rewards" \
  -H "Authorization: Bearer $WALLETD_API_KEY"

For a user starting at zero points, the expected result after processing is 25 points, assuming this is the only matching accrual rule and no cap reduces the grant. Verify the POINTS account and the corresponding grant rather than deriving the displayed balance from the latest purchase alone.

Use bounded polling or the relevant reward event to refresh the interface. For webhook integrations, verify signatures and tolerate duplicate delivery according to the webhook documentation.

5. Turn accumulated points into wallet credit

Configure the conversion policy separately from earning:

curl --fail-with-body -sS -X POST "$WALLETD_API/v1/reward_rules" \
  -H "Authorization: Bearer $WALLETD_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "kind": "conversion",
    "params": {"minor_per_point": 1, "min_points": 500}
  }'

Now consider the same customer later, after they have accumulated 650 points through qualifying payments. The single USD 25.00 purchase above is insufficient to reach that balance. The customer chooses to convert 500 points:

curl --fail-with-body -sS -X POST "$WALLETD_API/v1/rewards/convert" \
  -H "Authorization: Bearer $WALLETD_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: loyalty-demo-conversion-request-2001" \
  --data "{\"user_id\": \"$USER_ID\", \"points\": 500}"

With this rule, a successful conversion leaves 150 points and adds 500 USD minor units, or USD 5.00, to wallet cash. WalletD’s conversion operation performs the linked points debit and cash credit; your application should not implement them as two unrelated balance updates.

Store the returned conversion identifier against your own redemption request. Refresh balances after confirmation, and make the customer-facing wording explicit: “Convert 500 points to USD 5.00 wallet credit.”

Cashback and conversion also need a funding policy. Decide who bears the reward cost and how funding is monitored. WalletD documents client-funded cashback separately from tenant-funded rewards; do not assume every reward type draws from the same merchant budget.

6. Make retries safe and outcomes explainable

For each payment or conversion, create a durable business operation ID and persist its idempotency key before sending the request. Reuse the same key and body if a timeout leaves the outcome unknown.

The sample keys above identify one sandbox operation each. Replace them for new business operations; retain them for retries of the original operation. Generating a fresh key on every attempt defeats the protection.

WalletD documents an idempotency_key_reuse conflict when a key is reused with different parameters. Treat that as a request-identity problem to investigate. For transient failures, follow the documented retry policy with backoff and the original key. See idempotency.

Also test independent concurrent requests. If a customer with 650 points submits two different 500-point conversions, your launch test should demonstrate that only one can spend those points. A disabled button improves the interface, but the balance constraint must hold at the service boundary.

For support, preserve the chain from order ID to payment ID, reward grant, conversion request, and final outcome. A customer asking “Where did my points go?” should receive an explanation tied to transactions.

7. Treat refunds as a separate acceptance test

A returned purchase can affect both the payment and its reward. Those effects become harder to explain after the reward has been converted or spent.

The rewards guide describes proportional cashback reversal on refunds. Do not extend that statement into an assumption that every points scenario, converted reward, or external refund is handled identically. Verify the exact behavior of the deployed version before making promises to customers.

Work through at least three cases:

Case Decision and evidence needed
Refund before reward processing finishes Show that asynchronous processing produces the agreed final entitlement.
Partial refund while points remain available Define the adjusted earning base and rounding, then verify the actual balance and grant history.
Refund after points have been converted or spent Specify how the program treats the shortfall and prove the supported recovery path.

For illustration, if your policy recalculates earning on net eligible spend, a USD 10.00 refund against the USD 25.00 example leaves USD 15.00 eligible and an entitlement of 15 points. That is a policy expectation to test, not a claim that a specific WalletD refund automatically removes ten points.

Do not patch discrepancies by directly editing balances. Use supported operations and retain the audit trail; unresolved behavior is a reason to constrain the launch scope or improve the integration.

8. Add tiers and expiry after the core loop works

An initial program can be useful with just earning, conversion, and a transparent history. Avoid advertising sophisticated features before their lifecycle is defined.

For example, a “Gold” customer tier might depend on qualifying spend over the previous twelve months. That requires a policy for the time window, refunds, qualification, and downgrade timing. It is not equivalent to a payment limit tier or the current spendable points balance.

Point expiry needs equally careful modeling. A single total does not tell you which grant expires next, which points a redemption consumed, or how a later refund affects that allocation. Confirm native support or design the additional grant-level state and supported adjustment operations before promising expiry.

The same applies to referrals and physical rewards: earning eligibility, fulfillment, and reversal are application workflows that need explicit ownership.

9. Use a launch checklist with observable outcomes

  • The eligible merchant and payment scope match the published program terms.
  • Currency units, accrual rounding, and conversion value match the worked examples.
  • A captured qualifying payment produces the expected grant after processing.
  • Replaying the same payment or conversion request produces no duplicate economic effect.
  • Concurrent conversions cannot overspend the available points.
  • Campaign boundaries and overlapping rules behave as intended.
  • Delayed reward processing is visible and recoverable without duplicate grants.
  • Full and partial refunds pass the agreed before-and-after-conversion scenarios.
  • Customer credentials cannot manage rules or access another customer’s rewards.
  • Support can reconcile a customer balance to its underlying transactions.

Monitor the delay between capture and grant, failed reward jobs, conversion failures, duplicate-event handling, and reconciliation differences. Set response thresholds around the customer experience your program promises.

For teams already using WalletD payments, this approach keeps earning and redemption close to the underlying transaction flow. Teams needing a ready-made campaign builder, referral suite, or omnichannel rewards catalog should compare those requirements with a dedicated loyalty product before committing to custom development.

WalletD wallet infrastructure gives teams a ledger-backed foundation for this flow. Bring your checkout flow, expected transaction volume, reward rules, and refund policy to the WalletD demo. Those inputs make it possible to plan the failure handling and operational ownership before customers depend on the program.

وصول مبكر

كن شريك تصميم.

نعمل مع عدد محدود من الفرق التي تبني منتجات محافظ وأموال على WalletD. إن كنت منهم، فلنتحدّث. ستحصل على وصول مباشر إلى من بنوا المنصة.