mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-24 20:09:02 +00:00
docs(commerce): add Orders, Customers, Inventory, Promotions, Store pages
Flesh out the Commerce service section under the 10-category services taxonomy: five hand-authored reference pages for the per-org commerce surface (api.hanzo.ai/v1/commerce/*) — order lifecycle (returns, exchanges, edits), guest/registered customers + groups, multi-location inventory, rule-based promotions, and store settings (regions, currencies, sales channels, publishable keys). meta.json groups them into Products / Orders / Payments / Marketing / Store sections; validated as JSON with every slug resolving to a page.
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
---
|
||||
title: Customers
|
||||
description: Manage guest and registered customers, addresses, and customer groups for targeted pricing and promotions.
|
||||
---
|
||||
|
||||
# Customers
|
||||
|
||||
The Customers API stores and organizes the people who buy from your store — both guest and registered — and groups them so you can target pricing, promotions, and communications.
|
||||
|
||||
**Base URL:** `https://api.hanzo.ai/v1/commerce/customers`
|
||||
|
||||
## Customer object
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `id` | string | Unique customer identifier (`cus_...`) |
|
||||
| `email` | string | Contact email (unique per store) |
|
||||
| `first_name` | string | Given name |
|
||||
| `last_name` | string | Family name |
|
||||
| `has_account` | boolean | `true` for registered customers, `false` for guests |
|
||||
| `phone` | string | Optional phone number |
|
||||
| `addresses` | array | Saved shipping and billing addresses |
|
||||
| `groups` | array | Customer groups this customer belongs to |
|
||||
| `metadata` | object | Arbitrary key/value data you attach |
|
||||
|
||||
## Guest vs. registered customers
|
||||
|
||||
A **guest** is created automatically at checkout from the email provided. A **registered** customer has an authenticated account (`has_account: true`) and can sign in to view order history and manage saved addresses. Promote a guest to registered by attaching an identity from [Hanzo IAM](/docs/services/iam).
|
||||
|
||||
```typescript
|
||||
import { HanzoCommerce } from '@hanzo/commerce'
|
||||
|
||||
const commerce = new HanzoCommerce({ apiKey: process.env.HANZO_API_KEY })
|
||||
|
||||
const customer = await commerce.customers.create({
|
||||
email: '[email protected]',
|
||||
first_name: 'Ada',
|
||||
last_name: 'Lovelace'
|
||||
})
|
||||
```
|
||||
|
||||
## Addresses
|
||||
|
||||
Customers can store multiple addresses; mark one shipping and one billing address as default.
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.hanzo.ai/v1/commerce/customers/cus_123/addresses \
|
||||
-H "Authorization: Bearer $HANZO_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"address_1": "1 Market St",
|
||||
"city": "San Francisco",
|
||||
"province": "CA",
|
||||
"postal_code": "94105",
|
||||
"country_code": "us",
|
||||
"is_default_shipping": true
|
||||
}'
|
||||
```
|
||||
|
||||
## Customer groups
|
||||
|
||||
Groups organize customers for use cases like wholesale tiers, VIP pricing, or region-specific offers. A [promotion](/docs/services/commerce/promotions) or price list can be scoped to one or more groups.
|
||||
|
||||
```typescript
|
||||
// Create a group and add members
|
||||
const vip = await commerce.customers.createGroup({ name: 'VIP' })
|
||||
|
||||
await commerce.customers.addToGroup(vip.id, {
|
||||
customer_ids: ['cus_123', 'cus_456']
|
||||
})
|
||||
```
|
||||
|
||||
```bash
|
||||
# List members of a group
|
||||
curl "https://api.hanzo.ai/v1/commerce/customers?group_id=cusgroup_vip" \
|
||||
-H "Authorization: Bearer $HANZO_API_KEY"
|
||||
```
|
||||
|
||||
<Callout type="info">
|
||||
Customer groups are the join key between customers and pricing rules. Assigning a group-scoped price list or promotion applies automatically to every current and future member — no per-customer configuration.
|
||||
</Callout>
|
||||
|
||||
## Endpoints
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| `GET` | `/customers` | List customers (filter by `group_id`, `email`, `has_account`) |
|
||||
| `POST` | `/customers` | Create a customer |
|
||||
| `GET` | `/customers/:id` | Retrieve a customer |
|
||||
| `PATCH` | `/customers/:id` | Update a customer |
|
||||
| `DELETE` | `/customers/:id` | Delete a customer |
|
||||
| `POST` | `/customers/:id/addresses` | Add an address |
|
||||
| `PATCH` | `/customers/:id/addresses/:aid` | Update an address |
|
||||
| `DELETE` | `/customers/:id/addresses/:aid` | Remove an address |
|
||||
| `POST` | `/customers/groups` | Create a customer group |
|
||||
| `POST` | `/customers/groups/:gid/customers` | Add customers to a group |
|
||||
| `DELETE` | `/customers/groups/:gid/customers/:id` | Remove a customer from a group |
|
||||
|
||||
## Next steps
|
||||
|
||||
<Cards>
|
||||
<Card title="Promotions" href="/docs/services/commerce/promotions">
|
||||
Target discounts at specific customer groups
|
||||
</Card>
|
||||
<Card title="Orders" href="/docs/services/commerce/orders">
|
||||
View a customer's order history
|
||||
</Card>
|
||||
<Card title="IAM" href="/docs/services/iam">
|
||||
Back registered customers with Hanzo identities
|
||||
</Card>
|
||||
</Cards>
|
||||
@@ -0,0 +1,124 @@
|
||||
---
|
||||
title: Inventory
|
||||
description: Track stock across locations with inventory items, levels, reservations, and availability checks.
|
||||
---
|
||||
|
||||
# Inventory
|
||||
|
||||
The Inventory API tracks the physical stock behind your catalog: how much of each item you have, where it lives, and how much is reserved for in-flight orders. It keeps *available* quantity accurate so you never oversell.
|
||||
|
||||
**Base URL:** `https://api.hanzo.ai/v1/commerce/inventory`
|
||||
|
||||
## Model
|
||||
|
||||
```
|
||||
InventoryItem ──< InventoryLevel >── StockLocation
|
||||
│ │
|
||||
│ └── stocked / reserved / available
|
||||
└──< Reservation (holds quantity at a location for an order)
|
||||
```
|
||||
|
||||
- **Inventory item** — a stock-kept unit, typically linked to a product variant.
|
||||
- **Stock location** — a warehouse, store, or fulfillment center.
|
||||
- **Inventory level** — the quantity of one item at one location, split into `stocked`, `reserved`, and computed `available` (`stocked − reserved`).
|
||||
- **Reservation** — a hold placed on `available` quantity when an order is placed, released or converted on fulfillment.
|
||||
|
||||
## Inventory item object
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `id` | string | Inventory item id (`iitem_...`) |
|
||||
| `sku` | string | Stock keeping unit |
|
||||
| `requires_shipping` | boolean | Whether the item ships physically |
|
||||
| `levels` | array | Per-location stock levels |
|
||||
| `reserved_quantity` | integer | Total reserved across all locations |
|
||||
| `stocked_quantity` | integer | Total on hand across all locations |
|
||||
|
||||
## Manage stock levels
|
||||
|
||||
```typescript
|
||||
import { HanzoCommerce } from '@hanzo/commerce'
|
||||
|
||||
const commerce = new HanzoCommerce({ apiKey: process.env.HANZO_API_KEY })
|
||||
|
||||
// Set the on-hand quantity for an item at a location
|
||||
await commerce.inventory.setLevel({
|
||||
inventory_item_id: 'iitem_1',
|
||||
location_id: 'sloc_warehouse_sf',
|
||||
stocked_quantity: 500
|
||||
})
|
||||
```
|
||||
|
||||
```bash
|
||||
# Read levels for an item across every location
|
||||
curl https://api.hanzo.ai/v1/commerce/inventory/iitem_1/levels \
|
||||
-H "Authorization: Bearer $HANZO_API_KEY"
|
||||
```
|
||||
|
||||
## Reservations
|
||||
|
||||
Reservations hold `available` quantity so concurrent checkouts can't oversell. Create one when an order is placed; release it on cancellation or convert it on fulfillment.
|
||||
|
||||
```typescript
|
||||
const reservation = await commerce.inventory.reserve({
|
||||
inventory_item_id: 'iitem_1',
|
||||
location_id: 'sloc_warehouse_sf',
|
||||
quantity: 2,
|
||||
order_id: 'order_123'
|
||||
})
|
||||
```
|
||||
|
||||
## Check availability
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.hanzo.ai/v1/commerce/inventory/availability \
|
||||
-H "Authorization: Bearer $HANZO_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"inventory_item_id": "iitem_1",
|
||||
"location_ids": ["sloc_warehouse_sf", "sloc_store_nyc"],
|
||||
"quantity": 2
|
||||
}'
|
||||
# → { "available": true, "available_quantity": 498 }
|
||||
```
|
||||
|
||||
<Callout type="info">
|
||||
`available = stocked − reserved`. Always check availability against the specific locations a [sales channel](/docs/services/commerce/storefront) can fulfill from — an item can be in stock globally but unavailable to a given storefront.
|
||||
</Callout>
|
||||
|
||||
## Stock locations
|
||||
|
||||
```typescript
|
||||
const sf = await commerce.inventory.createLocation({
|
||||
name: 'San Francisco Warehouse',
|
||||
address: { city: 'San Francisco', country_code: 'us' }
|
||||
})
|
||||
```
|
||||
|
||||
## Endpoints
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| `GET` | `/inventory` | List inventory items |
|
||||
| `POST` | `/inventory` | Create an inventory item |
|
||||
| `GET` | `/inventory/:id/levels` | List levels for an item |
|
||||
| `POST` | `/inventory/levels` | Set/update a level at a location |
|
||||
| `POST` | `/inventory/availability` | Check availability across locations |
|
||||
| `POST` | `/inventory/reservations` | Reserve quantity for an order |
|
||||
| `DELETE` | `/inventory/reservations/:rid` | Release a reservation |
|
||||
| `GET` | `/inventory/locations` | List stock locations |
|
||||
| `POST` | `/inventory/locations` | Create a stock location |
|
||||
|
||||
## Next steps
|
||||
|
||||
<Cards>
|
||||
<Card title="Products" href="/docs/services/commerce/products">
|
||||
Link inventory items to product variants
|
||||
</Card>
|
||||
<Card title="Orders" href="/docs/services/commerce/orders">
|
||||
Reservations are created and released along the order lifecycle
|
||||
</Card>
|
||||
<Card title="Store settings" href="/docs/services/commerce/storefront">
|
||||
Control which locations each sales channel fulfills from
|
||||
</Card>
|
||||
</Cards>
|
||||
@@ -6,10 +6,18 @@
|
||||
"quickstart",
|
||||
"---Products---",
|
||||
"products",
|
||||
"inventory",
|
||||
"subscriptions",
|
||||
"---Orders---",
|
||||
"orders",
|
||||
"customers",
|
||||
"---Payments---",
|
||||
"payments",
|
||||
"webhooks",
|
||||
"---Marketing---",
|
||||
"promotions",
|
||||
"---Store---",
|
||||
"storefront",
|
||||
"---Reference---",
|
||||
"api",
|
||||
"configuration"
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
---
|
||||
title: Orders
|
||||
description: Manage the full order lifecycle — orders, draft orders, fulfillments, returns, exchanges, and edits.
|
||||
---
|
||||
|
||||
# Orders
|
||||
|
||||
The Orders API manages the complete lifecycle of a purchase: from cart capture through fulfillment, and every post-purchase change — returns, exchanges, claims, and edits — with a versioned timeline so every mutation is auditable.
|
||||
|
||||
**Base URL:** `https://api.hanzo.ai/v1/commerce/orders`
|
||||
|
||||
## Order lifecycle
|
||||
|
||||
```
|
||||
draft ──▶ pending ──▶ completed
|
||||
│
|
||||
├──▶ canceled
|
||||
│
|
||||
├──▶ return ──▶ refunded
|
||||
├──▶ exchange ──▶ new fulfillment
|
||||
└──▶ edit ──▶ new version
|
||||
```
|
||||
|
||||
An order moves through **pending** once payment is authorized, and **completed** once every fulfillment is delivered. Post-purchase operations (returns, exchanges, edits) create *order changes* that append a new version to the order's timeline rather than mutating history.
|
||||
|
||||
## Order object
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `id` | string | Unique order identifier (`order_...`) |
|
||||
| `status` | enum | `draft`, `pending`, `completed`, `canceled` |
|
||||
| `customer_id` | string | Customer who placed the order |
|
||||
| `email` | string | Contact email (guest or registered) |
|
||||
| `currency` | string | ISO 4217 currency code |
|
||||
| `items` | array | Line items with quantity, unit price, and adjustments |
|
||||
| `shipping_methods` | array | Selected shipping options with tax and promotion adjustments |
|
||||
| `payment_status` | enum | `not_paid`, `authorized`, `captured`, `partially_refunded`, `refunded` |
|
||||
| `fulfillment_status` | enum | `not_fulfilled`, `partially_fulfilled`, `fulfilled`, `delivered` |
|
||||
| `total` | number | Order grand total after tax and discounts |
|
||||
| `version` | integer | Current timeline version |
|
||||
|
||||
## List and retrieve orders
|
||||
|
||||
```bash
|
||||
# List orders (paginated, filterable by status/customer/date)
|
||||
curl "https://api.hanzo.ai/v1/commerce/orders?status=pending&limit=20" \
|
||||
-H "Authorization: Bearer $HANZO_API_KEY"
|
||||
|
||||
# Retrieve a single order
|
||||
curl https://api.hanzo.ai/v1/commerce/orders/order_123 \
|
||||
-H "Authorization: Bearer $HANZO_API_KEY"
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { HanzoCommerce } from '@hanzo/commerce'
|
||||
|
||||
const commerce = new HanzoCommerce({ apiKey: process.env.HANZO_API_KEY })
|
||||
|
||||
const orders = await commerce.orders.list({ status: 'pending', limit: 20 })
|
||||
const order = await commerce.orders.retrieve('order_123')
|
||||
```
|
||||
|
||||
## Draft orders
|
||||
|
||||
Draft orders let a merchant build an order on behalf of a customer — quotes, phone sales, or B2B — then convert it to a live order when the customer confirms.
|
||||
|
||||
```typescript
|
||||
const draft = await commerce.orders.createDraft({
|
||||
email: '[email protected]',
|
||||
currency: 'USD',
|
||||
items: [{ variant_id: 'variant_1', quantity: 2, unit_price: 2500 }],
|
||||
shipping_methods: [{ option_id: 'so_standard' }]
|
||||
})
|
||||
|
||||
// Convert the draft to a pending order once the customer confirms
|
||||
const order = await commerce.orders.completeDraft(draft.id)
|
||||
```
|
||||
|
||||
## Fulfillments
|
||||
|
||||
Create a fulfillment to ship all or part of an order. Each fulfillment tracks the items, shipping location, and delivery state.
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.hanzo.ai/v1/commerce/orders/order_123/fulfillments \
|
||||
-H "Authorization: Bearer $HANZO_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"location_id": "sloc_warehouse_sf",
|
||||
"items": [{ "item_id": "item_1", "quantity": 1 }]
|
||||
}'
|
||||
```
|
||||
|
||||
Mark a fulfillment as shipped or delivered to advance the order's `fulfillment_status`:
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.hanzo.ai/v1/commerce/orders/order_123/fulfillments/ful_1/ship \
|
||||
-H "Authorization: Bearer $HANZO_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{ "tracking_numbers": ["1Z999AA10123456784"] }'
|
||||
```
|
||||
|
||||
## Returns, exchanges, and claims
|
||||
|
||||
Post-purchase changes are modeled as **order changes**. Each creates a new order version so the timeline is fully auditable.
|
||||
|
||||
| Operation | Endpoint | Effect |
|
||||
|-----------|----------|--------|
|
||||
| Return | `POST /orders/:id/returns` | Customer sends items back; issues a refund on receipt |
|
||||
| Exchange | `POST /orders/:id/exchanges` | Return items and ship replacements in one flow |
|
||||
| Claim | `POST /orders/:id/claims` | Resolve damaged/incorrect items (refund or replace) |
|
||||
| Edit | `POST /orders/:id/edits` | Add, remove, or re-price items after purchase |
|
||||
|
||||
```typescript
|
||||
// Request a return with a refund on receipt
|
||||
const ret = await commerce.orders.createReturn('order_123', {
|
||||
items: [{ item_id: 'item_1', quantity: 1, reason: 'wrong_size' }],
|
||||
refund_on_receive: true
|
||||
})
|
||||
```
|
||||
|
||||
<Callout type="info">
|
||||
Every return, exchange, edit, and claim appends a new `version` to the order. Fetch `GET /orders/:id/changes` to render the full timeline of who changed what and when.
|
||||
</Callout>
|
||||
|
||||
## Refunds
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.hanzo.ai/v1/commerce/orders/order_123/refund \
|
||||
-H "Authorization: Bearer $HANZO_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{ "amount": 2500, "reason": "return_accepted" }'
|
||||
```
|
||||
|
||||
## Endpoints
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| `GET` | `/orders` | List orders |
|
||||
| `GET` | `/orders/:id` | Retrieve an order |
|
||||
| `POST` | `/orders/draft` | Create a draft order |
|
||||
| `POST` | `/orders/:id/complete` | Complete a draft into a pending order |
|
||||
| `POST` | `/orders/:id/fulfillments` | Create a fulfillment |
|
||||
| `POST` | `/orders/:id/fulfillments/:fid/ship` | Mark shipped |
|
||||
| `POST` | `/orders/:id/returns` | Request a return |
|
||||
| `POST` | `/orders/:id/exchanges` | Create an exchange |
|
||||
| `POST` | `/orders/:id/claims` | File a claim |
|
||||
| `POST` | `/orders/:id/edits` | Edit order items |
|
||||
| `POST` | `/orders/:id/refund` | Refund all or part of an order |
|
||||
| `POST` | `/orders/:id/cancel` | Cancel an order |
|
||||
| `GET` | `/orders/:id/changes` | Retrieve the versioned change timeline |
|
||||
|
||||
## Next steps
|
||||
|
||||
<Cards>
|
||||
<Card title="Customers" href="/docs/services/commerce/customers">
|
||||
Attach orders to customers and customer groups
|
||||
</Card>
|
||||
<Card title="Inventory" href="/docs/services/commerce/inventory">
|
||||
Reserve and deduct stock as orders are placed and fulfilled
|
||||
</Card>
|
||||
<Card title="Payments" href="/docs/services/commerce/payments">
|
||||
Authorize, capture, and refund order payments
|
||||
</Card>
|
||||
</Cards>
|
||||
@@ -0,0 +1,120 @@
|
||||
---
|
||||
title: Promotions
|
||||
description: Build discounts with flexible rules, promotion codes, and budgeted campaigns.
|
||||
---
|
||||
|
||||
# Promotions
|
||||
|
||||
The Promotions API discounts an amount or percentage off a cart's items, its shipping, or the entire order — governed by rules that decide *when* the discount applies and grouped into *campaigns* that cap spend and set a schedule.
|
||||
|
||||
**Base URL:** `https://api.hanzo.ai/v1/commerce/promotions`
|
||||
|
||||
## Promotion types
|
||||
|
||||
| Type | Behavior |
|
||||
|------|----------|
|
||||
| `standard` | Applies a discount when the cart matches the rules |
|
||||
| `buyget` | "Buy X, get Y" — discounts target items when required items are present |
|
||||
|
||||
## Application method
|
||||
|
||||
Every promotion has an **application method** describing the discount:
|
||||
|
||||
| Field | Values | Description |
|
||||
|-------|--------|-------------|
|
||||
| `type` | `fixed`, `percentage` | Fixed amount off, or a percentage |
|
||||
| `target_type` | `items`, `shipping_methods`, `order` | What the discount reduces |
|
||||
| `value` | number | Amount (minor units) or percent |
|
||||
| `allocation` | `each`, `across` | Apply per matching item, or spread across the target |
|
||||
|
||||
```typescript
|
||||
import { HanzoCommerce } from '@hanzo/commerce'
|
||||
|
||||
const commerce = new HanzoCommerce({ apiKey: process.env.HANZO_API_KEY })
|
||||
|
||||
const promo = await commerce.promotions.create({
|
||||
code: 'WELCOME10',
|
||||
type: 'standard',
|
||||
application_method: {
|
||||
type: 'percentage',
|
||||
target_type: 'items',
|
||||
value: 10,
|
||||
allocation: 'each'
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Flexible rules
|
||||
|
||||
Rules restrict when a promotion is applied by matching attributes of the cart, its items, or the customer. Combine multiple rules — all must pass.
|
||||
|
||||
```json
|
||||
{
|
||||
"rules": [
|
||||
{ "attribute": "customer.groups.id", "operator": "in", "values": ["cusgroup_vip"] },
|
||||
{ "attribute": "items.product.collection", "operator": "eq", "values": ["col_outerwear"] },
|
||||
{ "attribute": "currency_code", "operator": "eq", "values": ["usd"] }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Supported operators: `eq`, `ne`, `in`, `not_in`, `gt`, `gte`, `lt`, `lte`.
|
||||
|
||||
<Callout type="info">
|
||||
Target a promotion at a [customer group](/docs/services/commerce/customers) with a `customer.groups.id` rule to run tiered or member-only pricing without touching individual customers.
|
||||
</Callout>
|
||||
|
||||
## Promotion codes
|
||||
|
||||
A promotion can be automatic (applies with no code) or gated behind a `code` the shopper enters. Generate many unique codes for a single promotion when you need per-recipient tracking.
|
||||
|
||||
```bash
|
||||
# Apply a code to a cart
|
||||
curl -X POST https://api.hanzo.ai/v1/commerce/carts/cart_1/promotions \
|
||||
-H "Authorization: Bearer $HANZO_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{ "code": "WELCOME10" }'
|
||||
```
|
||||
|
||||
## Campaigns
|
||||
|
||||
A campaign groups promotions under a shared schedule and budget. When the budget is spent or the window closes, its promotions stop applying automatically.
|
||||
|
||||
```typescript
|
||||
const campaign = await commerce.promotions.createCampaign({
|
||||
name: 'Spring Sale',
|
||||
starts_at: '2026-03-01T00:00:00Z',
|
||||
ends_at: '2026-03-31T23:59:59Z',
|
||||
budget: { type: 'spend', limit: 100000, currency: 'USD' },
|
||||
promotion_ids: [promo.id]
|
||||
})
|
||||
```
|
||||
|
||||
Budget types: `spend` (cap total discount value) or `usage` (cap number of redemptions).
|
||||
|
||||
## Endpoints
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| `GET` | `/promotions` | List promotions |
|
||||
| `POST` | `/promotions` | Create a promotion |
|
||||
| `GET` | `/promotions/:id` | Retrieve a promotion |
|
||||
| `PATCH` | `/promotions/:id` | Update a promotion or its rules |
|
||||
| `DELETE` | `/promotions/:id` | Delete a promotion |
|
||||
| `POST` | `/promotions/:id/rules` | Add rules |
|
||||
| `POST` | `/promotions/campaigns` | Create a campaign |
|
||||
| `PATCH` | `/promotions/campaigns/:cid` | Update a campaign budget/schedule |
|
||||
|
||||
## Next steps
|
||||
|
||||
<Cards>
|
||||
<Card title="Customers" href="/docs/services/commerce/customers">
|
||||
Scope promotions to customer groups
|
||||
</Card>
|
||||
<Card title="Orders" href="/docs/services/commerce/orders">
|
||||
Promotion adjustments are recorded on order line items
|
||||
</Card>
|
||||
<Card title="Products" href="/docs/services/commerce/products">
|
||||
Match promotions against product attributes and collections
|
||||
</Card>
|
||||
</Cards>
|
||||
@@ -0,0 +1,103 @@
|
||||
---
|
||||
title: Store settings
|
||||
description: Configure your store — regions, currencies, sales channels, and publishable keys that power each storefront.
|
||||
---
|
||||
|
||||
# Store settings
|
||||
|
||||
Store settings define the commercial context every cart and order runs in: which **regions** you sell to, which **currencies** you price in, and which **sales channels** (storefronts) expose which products. One backend can drive many storefronts.
|
||||
|
||||
**Base URL:** `https://api.hanzo.ai/v1/commerce/store`
|
||||
|
||||
## Regions
|
||||
|
||||
A region groups countries that share a currency, tax behavior, and set of payment and fulfillment options. Carts and orders always belong to a region, which fixes their currency and tax rules.
|
||||
|
||||
```typescript
|
||||
import { HanzoCommerce } from '@hanzo/commerce'
|
||||
|
||||
const commerce = new HanzoCommerce({ apiKey: process.env.HANZO_API_KEY })
|
||||
|
||||
const region = await commerce.store.createRegion({
|
||||
name: 'North America',
|
||||
currency_code: 'usd',
|
||||
countries: ['us', 'ca'],
|
||||
automatic_taxes: true
|
||||
})
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `id` | string | Region id (`reg_...`) |
|
||||
| `currency_code` | string | ISO 4217 currency for all prices in the region |
|
||||
| `countries` | array | ISO country codes served |
|
||||
| `automatic_taxes` | boolean | Calculate tax at checkout |
|
||||
| `payment_providers` | array | Enabled payment providers |
|
||||
|
||||
## Currencies
|
||||
|
||||
Enable the currencies your store prices in. Each region pins exactly one currency; products carry a price per enabled currency.
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.hanzo.ai/v1/commerce/store/currencies \
|
||||
-H "Authorization: Bearer $HANZO_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{ "codes": ["usd", "eur", "gbp"], "default": "usd" }'
|
||||
```
|
||||
|
||||
## Sales channels
|
||||
|
||||
A sales channel is a storefront — web, mobile, marketplace, or point of sale. Products are published per channel, and each channel fulfills from a specific set of [stock locations](/docs/services/commerce/inventory), so a product can be sold on one channel and hidden on another.
|
||||
|
||||
```typescript
|
||||
const web = await commerce.store.createSalesChannel({ name: 'Web Store' })
|
||||
|
||||
// Publish products to the channel
|
||||
await commerce.store.publishProducts(web.id, {
|
||||
product_ids: ['prod_1', 'prod_2']
|
||||
})
|
||||
```
|
||||
|
||||
## Publishable API keys
|
||||
|
||||
A publishable key is a client-safe key that scopes storefront requests to one or more sales channels. Use it in browser and mobile clients; use a secret `Bearer` key only on your server.
|
||||
|
||||
```bash
|
||||
curl -X POST https://api.hanzo.ai/v1/commerce/store/publishable-keys \
|
||||
-H "Authorization: Bearer $HANZO_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{ "title": "Web Store", "sales_channel_ids": ["sc_web"] }'
|
||||
# → { "id": "pk_...", "token": "pk_live_..." }
|
||||
```
|
||||
|
||||
<Callout type="info">
|
||||
Never ship a secret key to a browser. Publishable keys are scoped to sales channels and safe to embed in client code; secret keys authorize the full admin surface and belong only on your server or in [Hanzo KMS](/docs/services/kms).
|
||||
</Callout>
|
||||
|
||||
## Endpoints
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| `GET` | `/store` | Retrieve store configuration |
|
||||
| `PATCH` | `/store` | Update store settings |
|
||||
| `GET` | `/store/regions` | List regions |
|
||||
| `POST` | `/store/regions` | Create a region |
|
||||
| `POST` | `/store/currencies` | Enable currencies |
|
||||
| `GET` | `/store/sales-channels` | List sales channels |
|
||||
| `POST` | `/store/sales-channels` | Create a sales channel |
|
||||
| `POST` | `/store/sales-channels/:id/products` | Publish products to a channel |
|
||||
| `POST` | `/store/publishable-keys` | Create a publishable key |
|
||||
|
||||
## Next steps
|
||||
|
||||
<Cards>
|
||||
<Card title="Products" href="/docs/services/commerce/products">
|
||||
Publish products to sales channels and price per currency
|
||||
</Card>
|
||||
<Card title="Inventory" href="/docs/services/commerce/inventory">
|
||||
Map sales channels to fulfillment locations
|
||||
</Card>
|
||||
<Card title="KMS" href="/docs/services/kms">
|
||||
Store secret commerce keys securely
|
||||
</Card>
|
||||
</Cards>
|
||||
Reference in New Issue
Block a user