MagicWeave SDK: Player Store (apps/client/client_store)
This guide is for game developers integrating the MagicWeave player store into their game.
The client_store module lets players:
- browse currently redeemable store items
- redeem items using gems
- receive fulfillment output (for example voucher code/pin)
Base URL and Route Prefix
Use one of these deployment styles:
- Split client API deployment:
http://localhost:8001 - Combined deployment:
http://localhost:8000/client
Store routes are under:
/store
Examples:
GET http://localhost:8001/storePOST http://localhost:8001/store/redeem
Required Authentication and Headers
All store endpoints require:
x-client-id: <your_project_client_id>x-client-secret: <your_project_client_secret>Authorization: Bearer <magicweave_access_token>
The authenticated user also needs the client.store permission.
For redemption retries, send:
Idempotency-Key: <stable-unique-key-per-purchase-attempt>
If you do not pass Idempotency-Key, the server generates one automatically, but then retries from your client cannot be safely deduplicated.
Endpoint 1: List Store Items
GET /store
Returns active items that are currently available and in stock.
Filtering rules used by backend:
- item must be
is_active = true available_frommust be null or in the pastavailable_untilmust be null or in the future- item must be in stock
Response shape:
{
"items": [
{
"id": 12,
"name": "Amazon INR 100",
"description": "Gift card",
"item_type": "voucher",
"brand_name": "Amazon",
"image_url": "https://cdn.example.com/amazon-100.png",
"gem_cost": 150,
"is_featured": true,
"available_from": "2026-04-01T00:00:00Z",
"available_until": null,
"stock_remaining": 25,
"in_stock": true
}
]
}
stock_remaining semantics:
- finite integer for limited stock
nullwhen stock is effectively unlimited
Reference: List store items
Endpoint 2: Redeem Store Item
POST /store/redeem
Request body:
{
"store_item_id": 12,
"shipping_address": null
}
shipping_address is required when the item uses webhook/physical fulfillment.
Physical example:
{
"store_item_id": 99,
"shipping_address": {
"name": "Rahul Nema",
"line1": "123 MG Road",
"line2": "Near Metro",
"city": "Bengaluru",
"state": "Karnataka",
"pincode": "560001",
"phone": "+919999999999"
}
}
Response shape:
{
"id": 834,
"status": "fulfilled",
"gem_cost_at_time": 150,
"fulfillment_data": {
"code": "AMZN-XXXX-YYYY",
"pin": "1234"
}
}
Redemption Behavior
When redeeming:
- Server validates item existence and availability window.
- Server checks stock and per-player limit.
- Server checks wallet gems.
- Server deducts gems and records wallet transaction.
- Server creates redemption record.
- Fulfillment output depends on fulfillment strategy:
code_pool: code is claimed immediately, response often returnsstatus = fulfilledwith code/pin- other strategies (for example webhook/provider): response is usually
status = pendinguntil downstream fulfillment
Reference: Redeem store item
Idempotency (Critical for Production)
Use a unique Idempotency-Key per user purchase attempt and reuse the same key for retries of the same attempt.
Behavior:
- same key + same user returns existing redemption (safe retry)
- same key reused by different user returns
409
Recommended key format:
<user-id>:<store-item-id>:<client-order-id>
Common Error Codes
400:- store item not found
- item unavailable (inactive/not yet available/expired)
- sold out
- per-player limit reached
- shipping address missing for webhook item
401: missing/invalid project headers or bearer token402: insufficient gems403: user lacksclient.storepermission409:- idempotency key conflict
- concurrent sellout race (
This item just sold out; please try again)
cURL Examples
List Items
curl -X GET "http://localhost:8001/store" \
-H "x-client-id: <client-id>" \
-H "x-client-secret: <client-secret>" \
-H "Authorization: Bearer <access-token>"
Redeem Voucher
curl -X POST "http://localhost:8001/store/redeem" \
-H "x-client-id: <client-id>" \
-H "x-client-secret: <client-secret>" \
-H "Authorization: Bearer <access-token>" \
-H "Idempotency-Key: user-42:item-12:order-1001" \
-H "Content-Type: application/json" \
-d '{"store_item_id":12}'
Redeem Physical Item
curl -X POST "http://localhost:8001/store/redeem" \
-H "x-client-id: <client-id>" \
-H "x-client-secret: <client-secret>" \
-H "Authorization: Bearer <access-token>" \
-H "Idempotency-Key: user-42:item-99:order-1002" \
-H "Content-Type: application/json" \
-d '{"store_item_id":99,"shipping_address":{"name":"Rahul Nema","line1":"123 MG Road","city":"Bengaluru","state":"Karnataka","pincode":"560001","phone":"+919999999999"}}'
Integration Notes for Game Teams
- Fetch
/storeon store screen open and periodically refresh for stock/time changes. - Always send
Idempotency-Keyfor redeem requests. - Deduct gems in UI only after server confirmation; server is source of truth.
- Handle
402with an upsell flow (earn gems / buy gems / engage in game loops). - For
pendingredemptions, show "processing" state and poll your redemption history endpoint when available.