Choose one profile for your game store. Each profile is a call sequence and scope set — not a different API product. All profiles use the same Seller API at https://api.avrix.io.
Start here if you are new: 30-minute quickstart and SDK & helpers.
Profile A vs Profile B (pick one)#
| Profile A — Minimal | Profile B — Production | |
|---|---|---|
| Goal | Prove checkout end-to-end quickly | Run a live storefront safely |
| Catalog | Browse GET /products + check allocations | Full sellable sync (syncSellableCatalog + deltas) |
| Checkout | Preview → PSP → POST /orders | Same, plus availability checks and optional soft hold |
| Ops | Manual / light | Webhooks, reconcile by orderReference, low-stock signals |
| When to use | First integration, sandbox certification | Live traffic, multi-SKU catalog, support desk |
Profile C adds hot-drop reserve/commit on top of B for launch-day contention. You do not need C unless allocations use hot-drop mode.
The easy path (all profiles)#
Rules every store must follow:
- Server-to-server only — never put API keys in a browser or mobile app.
- Do not charge unless
canFulfillistrueon preview (or availability withquantity). - POST /orders is all-or-nothing — no partial keys; stock shortfall returns 409 NO_AVAILABLE_KEYS → refund at your PSP.
- Reuse the same
Idempotency-Keywhen retrying the same checkout; use a new key only for a new purchase. - Set
orderReferenceto your store order id on every POST /orders. - Echo
expectedUnitPriceCentsfrom preview on every commercial commit (API business model — territory catalog list price). PreferplaceStoreOrderFromPreview, which also forwardspriceCommitmentTokenwhen preview returns one. - Persist keys from the POST /orders response — webhooks are metadata-only.
- Treat region locks as geo-unverified until
whoami.capabilities.consumerGeoEnforcementEnabledis true — Territory enforcement. - Prefer the reference helper patterns (
createSellerClient,syncSellableCatalog, checkout + webhook consumer) over ad-hoc fetch — Client and helpers.
Profile A — Minimal store#
For: first integration, low traffic, proving checkout end-to-end.
| Step | API | Notes |
|---|---|---|
| 1 | GET /whoami | Confirm scopes, BMA (hasActiveBma), capabilities |
| 2 | GET /products?limit=50 | Pick skuCode from detail if needed |
| 3 | GET /allocations | Keep only rows with sellable: true |
| 4 | POST /orders/preview | Gate Pay on canFulfill |
| 5 | Your PSP | Avrix never charges the buyer — you capture payment |
| 6 | POST /orders | Idempotency-Key + orderReference |
Scopes: seller:products:read, seller:keys:pull (preview accepts seller:orders:preview or seller:keys:pull).
Defer until later: hot-drop, bulk orders, finance reads, checkout hold.
Recipe: Integration recipes — browse-catalog + create-order.
Postman: folder Store profile A — minimal checkout (preview → order).
Code: checkout helpers — see Client and helpers.
Profile B — Production store#
For: live storefronts with catalog sync and operational safety.
Everything in Profile A, plus:
| Addition | API / event | Why |
|---|---|---|
| Sellable catalog sync | syncSellableCatalog + syncCatalogChanges | Snapshot alone ≠ sellable — merge /allocations (Sellable SKU readiness) |
| Cart stock check | GET /availability?skuCode=…&quantity=N | canFulfill without posting preview on every keystroke |
| Catalog push | Webhooks product.updated, allocation.updated, allocation.low_stock, product.delisted | Avoid stale “in stock” UI |
| Fulfillment push | Webhook order.fulfilled / order.reserved / order.failed | Lifecycle/metadata only — persist keys from POST /orders response; use createWebhookConsumer |
| Reconcile | GET /orders?orderReference=… | Support and finance alignment |
| Soft hold | POST /orders/hold → checkoutHoldId on POST /orders | Check whoami.capabilities.checkoutHoldEnabled — Order preview |
Recipe: check-before-pull, webhooks, get-order.
Helpers: checkout helpers — see Client and helpers.
Rehearse the whole profile against the shared sandbox catalog before you point it at live inventory — see Sandbox and environments.
Profile C — Launch / high contention#
For: drop-day traffic on allocations with hot_drop_mode.
Everything in Profile B, plus:
| Step | API | Fallback |
|---|---|---|
| Reserve | POST /orders/reserve | 412 HOT_DROP_NOT_ENABLED → use Profile B (POST /orders only) |
| Commit | POST /orders/commit before TTL expires | Seconds-level window — see OpenAPI for reserve/commit TTL |
Checkout soft-hold is separate from hot-drop: normal allocations use hold; hot-drop allocations use reserve/commit.
Common mistakes#
| Do not | Do instead |
|---|---|
Charge when canFulfill is false | Disable Pay; show out of stock |
Expect partial keys on POST /orders | Treat 409 as zero keys; refund at PSP |
Retry POST /orders with a new idempotency key for the same sale | Same key as first attempt |
Poll GET /products on every page view | Webhooks + updatedSince / snapshot |
Call POST /orders to “get a price” | POST /orders/preview only |
| Skip Profile B sync and list every catalog SKU | Merge allocations (sellable: true) before merchandising |
After payment failure#
If POST /orders returns 409 NO_AVAILABLE_KEYS after the buyer paid:
- Log
X-Request-Id/requestId. - Refund at your PSP (Avrix does not auto-refund external checkouts).
- Read
details.recommendedAction(e.g.refund_customer) — Error playbook.
Next steps#
| Doc | Topic |
|---|---|
| 30-minute quickstart | End-to-end golden path |
| Order preview | Preview fields and price binding |
| Integration recipes | Scopes, call order, idempotency |
| Error playbook | Recovery actions after failed checkout |
| SDK & helpers | Typed client and checkout helpers |