@spree/docs 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -0
- package/dist/api-reference/platform/authentication.md +38 -0
- package/dist/api-reference/store-api/authentication.md +188 -0
- package/dist/api-reference/store-api/errors.md +277 -0
- package/dist/api-reference/store-api/idempotency.md +129 -0
- package/dist/api-reference/store-api/introduction.md +34 -0
- package/dist/api-reference/store-api/localization.md +279 -0
- package/dist/api-reference/store-api/metadata.md +160 -0
- package/dist/api-reference/store-api/monetary-amounts.md +65 -0
- package/dist/api-reference/store-api/querying.md +399 -0
- package/dist/api-reference/store-api/rate-limitting.md +103 -0
- package/dist/api-reference/store-api/relations.md +185 -0
- package/dist/api-reference/storefront/authentication.md +88 -0
- package/dist/api-reference/tutorials/adyen-integration-guide-for-android.md +165 -0
- package/dist/api-reference/tutorials/adyen-integration-guide-for-ios.md +194 -0
- package/dist/api-reference/tutorials/quick-checkout-with-stripe.md +248 -0
- package/dist/api-reference/v2/fetching-multiple-resources.md +26 -0
- package/dist/api-reference/v2/filtering-and-sorting.md +53 -0
- package/dist/api-reference/v2/introduction.md +22 -0
- package/dist/api-reference/v2/pagination.md +37 -0
- package/dist/api-reference/webhooks-events.md +883 -0
- package/dist/developer/admin/admin.md +205 -0
- package/dist/developer/admin/authentication.md +59 -0
- package/dist/developer/admin/components.md +711 -0
- package/dist/developer/admin/custom-css.md +243 -0
- package/dist/developer/admin/custom-javascript.md +116 -0
- package/dist/developer/admin/extending-ui.md +1964 -0
- package/dist/developer/admin/form-builder.md +444 -0
- package/dist/developer/admin/helper-methods.md +531 -0
- package/dist/developer/admin/navigation.md +805 -0
- package/dist/developer/admin/tables.md +491 -0
- package/dist/developer/advanced/adding_spree_to_rails_app.md +106 -0
- package/dist/developer/cli/quickstart.md +137 -0
- package/dist/developer/contributing/creating-an-extension.md +258 -0
- package/dist/developer/contributing/developing-spree.md +339 -0
- package/dist/developer/contributing/quickstart.md +32 -0
- package/dist/developer/contributing/updating-extensions.md +67 -0
- package/dist/developer/core-concepts/addresses.md +265 -0
- package/dist/developer/core-concepts/adjustments.md +107 -0
- package/dist/developer/core-concepts/architecture.md +177 -0
- package/dist/developer/core-concepts/calculators.md +323 -0
- package/dist/developer/core-concepts/customers.md +230 -0
- package/dist/developer/core-concepts/events.md +624 -0
- package/dist/developer/core-concepts/imports-exports.md +698 -0
- package/dist/developer/core-concepts/inventory.md +191 -0
- package/dist/developer/core-concepts/markets.md +250 -0
- package/dist/developer/core-concepts/media.md +167 -0
- package/dist/developer/core-concepts/metafields.md +187 -0
- package/dist/developer/core-concepts/orders.md +328 -0
- package/dist/developer/core-concepts/payments.md +710 -0
- package/dist/developer/core-concepts/pricing.md +163 -0
- package/dist/developer/core-concepts/products.md +360 -0
- package/dist/developer/core-concepts/promotions.md +322 -0
- package/dist/developer/core-concepts/reports.md +206 -0
- package/dist/developer/core-concepts/search-filtering.md +237 -0
- package/dist/developer/core-concepts/shipments.md +212 -0
- package/dist/developer/core-concepts/slugs.md +111 -0
- package/dist/developer/core-concepts/staff-roles.md +123 -0
- package/dist/developer/core-concepts/store-credits-gift-cards.md +317 -0
- package/dist/developer/core-concepts/stores.md +117 -0
- package/dist/developer/core-concepts/taxes.md +135 -0
- package/dist/developer/core-concepts/translations.md +120 -0
- package/dist/developer/core-concepts/users.md +299 -0
- package/dist/developer/core-concepts/webhooks.md +378 -0
- package/dist/developer/create-spree-app/quickstart.md +158 -0
- package/dist/developer/customization/api.md +93 -0
- package/dist/developer/customization/authentication.md +88 -0
- package/dist/developer/customization/checkout.md +204 -0
- package/dist/developer/customization/configuration.md +55 -0
- package/dist/developer/customization/decorators.md +523 -0
- package/dist/developer/customization/dependencies.md +232 -0
- package/dist/developer/customization/emails.md +21 -0
- package/dist/developer/customization/extensions.md +92 -0
- package/dist/developer/customization/metadata.md +236 -0
- package/dist/developer/customization/model-preferences.md +130 -0
- package/dist/developer/customization/permissions.md +265 -0
- package/dist/developer/customization/quickstart.md +229 -0
- package/dist/developer/customization/routes.md +24 -0
- package/dist/developer/customization/v4/admin-panel.md +78 -0
- package/dist/developer/customization/v4/authentication.md +210 -0
- package/dist/developer/customization/v4/checkout.md +212 -0
- package/dist/developer/customization/v4/deface.md +251 -0
- package/dist/developer/customization/v4/images.md +86 -0
- package/dist/developer/customization/v4/storefront.md +450 -0
- package/dist/developer/deployment/assets.md +87 -0
- package/dist/developer/deployment/aws.md +335 -0
- package/dist/developer/deployment/caching.md +27 -0
- package/dist/developer/deployment/cdn.md +39 -0
- package/dist/developer/deployment/database.md +155 -0
- package/dist/developer/deployment/docker.md +128 -0
- package/dist/developer/deployment/emails.md +77 -0
- package/dist/developer/deployment/environment_variables.md +111 -0
- package/dist/developer/deployment/heroku.md +51 -0
- package/dist/developer/deployment/render.md +95 -0
- package/dist/developer/getting-started/quickstart.md +82 -0
- package/dist/developer/how-to/custom-payment-method.md +374 -0
- package/dist/developer/how-to/custom-promotion.md +373 -0
- package/dist/developer/how-to/custom-report.md +387 -0
- package/dist/developer/how-to/custom-search-provider.md +230 -0
- package/dist/developer/multi-store/quickstart.md +71 -0
- package/dist/developer/multi-store/setup.md +38 -0
- package/dist/developer/multi-tenant/configuration.md +41 -0
- package/dist/developer/multi-tenant/core-concepts.md +75 -0
- package/dist/developer/multi-tenant/installation.md +96 -0
- package/dist/developer/multi-tenant/quickstart.md +20 -0
- package/dist/developer/multi-vendor/installation.md +45 -0
- package/dist/developer/multi-vendor/quickstart.md +17 -0
- package/dist/developer/sdk/admin/quickstart.md +22 -0
- package/dist/developer/sdk/authentication.md +89 -0
- package/dist/developer/sdk/configuration.md +225 -0
- package/dist/developer/sdk/quickstart.md +82 -0
- package/dist/developer/sdk/store/account.md +67 -0
- package/dist/developer/sdk/store/cart-checkout.md +140 -0
- package/dist/developer/sdk/store/markets.md +151 -0
- package/dist/developer/sdk/store/payments.md +96 -0
- package/dist/developer/sdk/store/products.md +149 -0
- package/dist/developer/sdk/store/wishlists.md +52 -0
- package/dist/developer/security/pci_compliance.md +15 -0
- package/dist/developer/security/security_policy.md +68 -0
- package/dist/developer/storefront/blocks.md +285 -0
- package/dist/developer/storefront/custom-css.md +260 -0
- package/dist/developer/storefront/custom-javascript.md +166 -0
- package/dist/developer/storefront/helper-methods.md +1288 -0
- package/dist/developer/storefront/links.md +298 -0
- package/dist/developer/storefront/nextjs/architecture.md +150 -0
- package/dist/developer/storefront/nextjs/customization.md +141 -0
- package/dist/developer/storefront/nextjs/deployment.md +180 -0
- package/dist/developer/storefront/nextjs/quickstart.md +92 -0
- package/dist/developer/storefront/nextjs/spree-next-package.md +314 -0
- package/dist/developer/storefront/pages.md +163 -0
- package/dist/developer/storefront/sections.md +569 -0
- package/dist/developer/storefront/storefront.md +56 -0
- package/dist/developer/storefront/themes.md +161 -0
- package/dist/developer/tutorial/admin.md +134 -0
- package/dist/developer/tutorial/extending-models.md +380 -0
- package/dist/developer/tutorial/file-uploads.md +121 -0
- package/dist/developer/tutorial/introduction.md +33 -0
- package/dist/developer/tutorial/model.md +41 -0
- package/dist/developer/tutorial/page-builder.md +487 -0
- package/dist/developer/tutorial/rich-text.md +73 -0
- package/dist/developer/tutorial/seo.md +332 -0
- package/dist/developer/tutorial/storefront.md +352 -0
- package/dist/developer/tutorial/testing.md +558 -0
- package/dist/developer/upgrades/2.0-to-2.1.md +46 -0
- package/dist/developer/upgrades/2.1-to-2.2.md +59 -0
- package/dist/developer/upgrades/2.2-to-2.3.md +44 -0
- package/dist/developer/upgrades/2.3-to-2.4.md +42 -0
- package/dist/developer/upgrades/3.0-to-3.1.md +47 -0
- package/dist/developer/upgrades/3.1-to-3.2.md +34 -0
- package/dist/developer/upgrades/3.2-to-3.3.md +70 -0
- package/dist/developer/upgrades/3.3-to-3.4.md +36 -0
- package/dist/developer/upgrades/3.4-to-3.5.md +44 -0
- package/dist/developer/upgrades/3.5-to-3.6.md +40 -0
- package/dist/developer/upgrades/3.6-to-3.7.md +62 -0
- package/dist/developer/upgrades/3.7-to-4.0.md +152 -0
- package/dist/developer/upgrades/4.0-to-4.1.md +92 -0
- package/dist/developer/upgrades/4.1-to-4.2.md +109 -0
- package/dist/developer/upgrades/4.10-to-5.0.md +129 -0
- package/dist/developer/upgrades/4.2-to-4.3.md +100 -0
- package/dist/developer/upgrades/4.3-to-4.4.md +125 -0
- package/dist/developer/upgrades/4.4-to-4.5.md +94 -0
- package/dist/developer/upgrades/4.5-to-4.6.md +119 -0
- package/dist/developer/upgrades/4.6-to-4.7.md +39 -0
- package/dist/developer/upgrades/4.8-to-4.9.md +24 -0
- package/dist/developer/upgrades/4.9-to-4.10.md +24 -0
- package/dist/developer/upgrades/4.x-to-4.8.md +52 -0
- package/dist/developer/upgrades/5.0-to-5.1.md +28 -0
- package/dist/developer/upgrades/5.1-to-5.2.md +127 -0
- package/dist/developer/upgrades/5.2-to-5.3.md +338 -0
- package/dist/developer/upgrades/5.3-to-5.4.md +248 -0
- package/dist/developer/upgrades/quickstart.md +36 -0
- package/dist/integrations/analytics/google-analytics.md +64 -0
- package/dist/integrations/analytics/google-tag-manager.md +78 -0
- package/dist/integrations/integrations.md +39 -0
- package/dist/integrations/marketing/klaviyo.md +99 -0
- package/dist/integrations/payments/adyen.md +90 -0
- package/dist/integrations/payments/paypal.md +41 -0
- package/dist/integrations/payments/razorpay.md +45 -0
- package/dist/integrations/payments/stripe.md +109 -0
- package/dist/integrations/search/meilisearch.md +236 -0
- package/dist/integrations/sso-mfa-social-login/admin-dashboard.md +57 -0
- package/dist/integrations/sso-mfa-social-login/storefront.md +56 -0
- package/package.json +27 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Addresses
|
|
3
|
+
description: Addresses, countries, states, and zones — how geography drives checkout, taxes, and shipping
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
Geography is central to how Spree handles checkout, pricing, taxes, and shipping. The system works through a chain of related concepts:
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
Markets → Countries → Zones → Tax Rates & Shipping Methods
|
|
12
|
+
↘ States
|
|
13
|
+
↘ Addresses
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
- [**Markets**](/developer/core-concepts/markets) group countries into selling regions with their own currency and locale
|
|
17
|
+
- **Countries** and **States** provide the geographic data for addresses
|
|
18
|
+
- **Zones** group countries or states together to define where tax rates and shipping methods apply
|
|
19
|
+
- **Addresses** tie a customer to a specific location, determining which zones — and therefore which taxes and shipping options — apply to their order
|
|
20
|
+
|
|
21
|
+
## Addresses
|
|
22
|
+
|
|
23
|
+
An address represents a shipping or billing location. Every order has a shipping address and a billing address, and customers can save multiple addresses in their address book.
|
|
24
|
+
|
|
25
|
+
| Field | Description |
|
|
26
|
+
|-------|-------------|
|
|
27
|
+
| `first_name`, `last_name` | Contact name |
|
|
28
|
+
| `address1`, `address2` | Street address |
|
|
29
|
+
| `city` | City |
|
|
30
|
+
| `postal_code` | Postal code (not required for all countries) |
|
|
31
|
+
| `phone` | Phone number |
|
|
32
|
+
| `company` | Company name (optional) |
|
|
33
|
+
| `label` | User-facing label like "Home" or "Office" (optional, unique per customer) |
|
|
34
|
+
| `country_iso` | Country (ISO alpha-2 code, e.g., `US`) |
|
|
35
|
+
| `state_abbr` | State/province abbreviation (required for some countries, e.g., `CA`) |
|
|
36
|
+
|
|
37
|
+
Whether a state or zipcode is required depends on the country. For example, the US requires both, while Hong Kong requires neither. The API returns `states_required` and `zipcode_required` on each country so your frontend can adapt the form dynamically.
|
|
38
|
+
|
|
39
|
+
### Customer Address Book
|
|
40
|
+
|
|
41
|
+
Customers can save multiple addresses and set a default for shipping and billing. When a customer completes checkout, the selected addresses are cloned onto the order — so editing an address later doesn't change past orders.
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
```typescript SDK
|
|
45
|
+
// List addresses
|
|
46
|
+
const { data: addresses } = await client.customer.addresses.list()
|
|
47
|
+
|
|
48
|
+
// Create an address
|
|
49
|
+
const address = await client.customer.addresses.create({
|
|
50
|
+
first_name: 'John',
|
|
51
|
+
last_name: 'Doe',
|
|
52
|
+
address1: '123 Main St',
|
|
53
|
+
city: 'Los Angeles',
|
|
54
|
+
country_iso: 'US',
|
|
55
|
+
state_abbr: 'CA',
|
|
56
|
+
postal_code: '90001',
|
|
57
|
+
phone: '555-0100',
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
// Update an address
|
|
61
|
+
await client.customer.addresses.update('addr_xxx', { city: 'Brooklyn' })
|
|
62
|
+
|
|
63
|
+
// Delete an address
|
|
64
|
+
await client.customer.addresses.delete('addr_xxx')
|
|
65
|
+
|
|
66
|
+
// Set as default shipping or billing address
|
|
67
|
+
await client.customer.addresses.markAsDefault('addr_xxx', 'shipping')
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
```bash cURL
|
|
71
|
+
# List addresses
|
|
72
|
+
curl 'https://api.mystore.com/api/v3/store/customer/addresses' \
|
|
73
|
+
-H 'Authorization: Bearer <jwt_token>'
|
|
74
|
+
|
|
75
|
+
# Create an address
|
|
76
|
+
curl -X POST 'https://api.mystore.com/api/v3/store/customer/addresses' \
|
|
77
|
+
-H 'Authorization: Bearer <jwt_token>' \
|
|
78
|
+
-H 'Content-Type: application/json' \
|
|
79
|
+
-d '{
|
|
80
|
+
"first_name": "John",
|
|
81
|
+
"last_name": "Doe",
|
|
82
|
+
"address1": "123 Main St",
|
|
83
|
+
"city": "Los Angeles",
|
|
84
|
+
"country_iso": "US",
|
|
85
|
+
"state_abbr": "CA",
|
|
86
|
+
"postal_code": "90001",
|
|
87
|
+
"phone": "555-0100"
|
|
88
|
+
}'
|
|
89
|
+
|
|
90
|
+
# Update an address
|
|
91
|
+
curl -X PATCH 'https://api.mystore.com/api/v3/store/customer/addresses/addr_xxx' \
|
|
92
|
+
-H 'Authorization: Bearer <jwt_token>' \
|
|
93
|
+
-H 'Content-Type: application/json' \
|
|
94
|
+
-d '{ "city": "Brooklyn" }'
|
|
95
|
+
|
|
96
|
+
# Delete an address
|
|
97
|
+
curl -X DELETE 'https://api.mystore.com/api/v3/store/customer/addresses/addr_xxx' \
|
|
98
|
+
-H 'Authorization: Bearer <jwt_token>'
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
### Checkout Addresses
|
|
103
|
+
|
|
104
|
+
During checkout, you can either reference a saved address by ID or pass a new address inline:
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
```typescript SDK
|
|
108
|
+
// Use saved addresses
|
|
109
|
+
await client.carts.update(cartId, {
|
|
110
|
+
shipping_address_id: 'addr_xxx',
|
|
111
|
+
billing_address_id: 'addr_yyy',
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
// Or pass new addresses inline
|
|
115
|
+
await client.carts.update(cartId, {
|
|
116
|
+
shipping_address: {
|
|
117
|
+
first_name: 'John',
|
|
118
|
+
last_name: 'Doe',
|
|
119
|
+
address1: '123 Main St',
|
|
120
|
+
city: 'Los Angeles',
|
|
121
|
+
country_iso: 'US',
|
|
122
|
+
state_abbr: 'CA',
|
|
123
|
+
postal_code: '90001',
|
|
124
|
+
phone: '555-0100',
|
|
125
|
+
},
|
|
126
|
+
})
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
```bash cURL
|
|
130
|
+
# Use a saved address
|
|
131
|
+
curl -X PATCH 'https://api.mystore.com/api/v3/store/carts/cart_xxx' \
|
|
132
|
+
-H 'Authorization: Bearer spree_pk_xxx' \
|
|
133
|
+
-H 'X-Spree-Token: order_token' \
|
|
134
|
+
-H 'Content-Type: application/json' \
|
|
135
|
+
-d '{ "shipping_address_id": "addr_xxx", "billing_address_id": "addr_yyy" }'
|
|
136
|
+
|
|
137
|
+
# Or pass a new address inline
|
|
138
|
+
curl -X PATCH 'https://api.mystore.com/api/v3/store/carts/cart_xxx' \
|
|
139
|
+
-H 'Authorization: Bearer spree_pk_xxx' \
|
|
140
|
+
-H 'X-Spree-Token: order_token' \
|
|
141
|
+
-H 'Content-Type: application/json' \
|
|
142
|
+
-d '{
|
|
143
|
+
"shipping_address": {
|
|
144
|
+
"first_name": "John",
|
|
145
|
+
"last_name": "Doe",
|
|
146
|
+
"address1": "123 Main St",
|
|
147
|
+
"city": "Los Angeles",
|
|
148
|
+
"country_iso": "US",
|
|
149
|
+
"state_abbr": "CA",
|
|
150
|
+
"postal_code": "90001",
|
|
151
|
+
"phone": "555-0100"
|
|
152
|
+
}
|
|
153
|
+
}'
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
## Countries
|
|
158
|
+
|
|
159
|
+
Countries are the foundation of Spree's geographic system. They connect to [Markets](/developer/core-concepts/markets), contain states, and belong to zones.
|
|
160
|
+
|
|
161
|
+
Each country includes metadata that drives address form behavior:
|
|
162
|
+
|
|
163
|
+
| Field | Description | Example |
|
|
164
|
+
|-------|-------------|---------|
|
|
165
|
+
| `iso` | ISO 3166-1 alpha-2 code | `US` |
|
|
166
|
+
| `iso3` | ISO 3166-1 alpha-3 code | `USA` |
|
|
167
|
+
| `name` | Country name | `United States` |
|
|
168
|
+
| `states_required` | Whether the address form should show a state/province picker | `true` |
|
|
169
|
+
| `zipcode_required` | Whether the address form should require a postal code | `true` |
|
|
170
|
+
|
|
171
|
+
### Which Countries Are Available?
|
|
172
|
+
|
|
173
|
+
Only countries assigned to a [Market](/developer/core-concepts/markets) are available during checkout. This lets you control exactly where you sell.
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
```typescript SDK
|
|
177
|
+
// List all countries available in this store
|
|
178
|
+
const { data: countries } = await client.countries.list()
|
|
179
|
+
|
|
180
|
+
// Get a country with its states (for address form dropdowns)
|
|
181
|
+
const usa = await client.countries.get('US', { include: 'states' })
|
|
182
|
+
// usa.states => [{ name: "Alabama", abbr: "AL" }, { name: "Alaska", abbr: "AK" }, ...]
|
|
183
|
+
|
|
184
|
+
// Get a country with its market (for currency/locale resolution)
|
|
185
|
+
const germany = await client.countries.get('DE', { include: 'market' })
|
|
186
|
+
// germany.market => { currency: "EUR", default_locale: "de", tax_inclusive: true }
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
```bash cURL
|
|
190
|
+
# List all countries
|
|
191
|
+
curl 'https://api.mystore.com/api/v3/store/countries' \
|
|
192
|
+
-H 'Authorization: Bearer spree_pk_xxx'
|
|
193
|
+
|
|
194
|
+
# Get a country with states
|
|
195
|
+
curl 'https://api.mystore.com/api/v3/store/countries/US?include=states' \
|
|
196
|
+
-H 'Authorization: Bearer spree_pk_xxx'
|
|
197
|
+
|
|
198
|
+
# Get a country with its market
|
|
199
|
+
curl 'https://api.mystore.com/api/v3/store/countries/DE?include=market' \
|
|
200
|
+
-H 'Authorization: Bearer spree_pk_xxx'
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
Use the `states_required` and `zipcode_required` fields to build adaptive address forms — show a state picker only when needed, and skip the zipcode field for countries that don't use them.
|
|
205
|
+
|
|
206
|
+
## States
|
|
207
|
+
|
|
208
|
+
States (provinces, regions) belong to a country and are used for address validation and zone matching. Countries like the US, Canada, Australia, and India have predefined states — for these countries, customers must select a state from the list rather than typing a name.
|
|
209
|
+
|
|
210
|
+
States are fetched via the country endpoint using `?include=states`:
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
```typescript SDK
|
|
214
|
+
const usa = await client.countries.get('US', { include: 'states' })
|
|
215
|
+
|
|
216
|
+
// Build a state picker from the response
|
|
217
|
+
usa.states.forEach(state => {
|
|
218
|
+
console.log(state.abbr, state.name) // "AL", "Alabama"
|
|
219
|
+
})
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
```bash cURL
|
|
223
|
+
curl 'https://api.mystore.com/api/v3/store/countries/US?include=states' \
|
|
224
|
+
-H 'Authorization: Bearer spree_pk_xxx'
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
For countries without predefined states, addresses accept a free-text `state_name` field instead of `state_abbr`.
|
|
229
|
+
|
|
230
|
+
## Zones
|
|
231
|
+
|
|
232
|
+
Zones group countries or states together for [tax](/developer/core-concepts/taxes) and [shipping](/developer/core-concepts/shipments) rules. A zone is either **country-based** or **state-based**.
|
|
233
|
+
|
|
234
|
+
**Examples:**
|
|
235
|
+
- **EU VAT** (country zone) — Germany, France, Italy, Spain, ... → applies EU VAT rates
|
|
236
|
+
- **California** (state zone) — CA → applies California sales tax
|
|
237
|
+
- **Domestic Shipping** (country zone) — US, CA → enables domestic shipping methods
|
|
238
|
+
|
|
239
|
+
When a customer enters their address at checkout, Spree matches it against zones to determine:
|
|
240
|
+
1. Which **tax rates** apply (see [Taxes](/developer/core-concepts/taxes))
|
|
241
|
+
2. Which **shipping methods** are available (see [Shipments](/developer/core-concepts/shipments))
|
|
242
|
+
|
|
243
|
+
Zones are configured in the admin dashboard — storefront developers don't interact with them directly via the API.
|
|
244
|
+
|
|
245
|
+
### Tax Zones and Markets
|
|
246
|
+
|
|
247
|
+
Each [Market](/developer/core-concepts/markets) resolves a tax zone from its default country. This means product prices display the correct tax treatment (inclusive or exclusive) before the customer enters an address — just from knowing their market.
|
|
248
|
+
|
|
249
|
+
## How It All Fits Together
|
|
250
|
+
|
|
251
|
+
Here's how geography flows through a typical checkout:
|
|
252
|
+
|
|
253
|
+
1. **Customer visits the store** — their country is detected (from URL, geolocation, or selection)
|
|
254
|
+
2. **Market resolved** — the country maps to a market, which sets the currency and locale
|
|
255
|
+
3. **Products displayed** — prices use the market's currency and tax zone for correct formatting
|
|
256
|
+
4. **Customer enters address** — the address form adapts based on `states_required` and `zipcode_required`
|
|
257
|
+
5. **Zones matched** — the shipping address determines which tax rates and shipping methods apply
|
|
258
|
+
6. **Order completed** — the address is cloned onto the order for permanent record
|
|
259
|
+
|
|
260
|
+
## Related Documentation
|
|
261
|
+
|
|
262
|
+
- [Markets](/developer/core-concepts/markets) — Multi-region commerce with currency, locale, and country grouping
|
|
263
|
+
- [Taxes](/developer/core-concepts/taxes) — How zones and addresses affect taxation
|
|
264
|
+
- [Shipments](/developer/core-concepts/shipments) — How zones and addresses affect shipping availability
|
|
265
|
+
- [Orders](/developer/core-concepts/orders) — Order billing and shipping addresses
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Adjustments
|
|
3
|
+
description: How taxes, promotions, and other price modifications are applied to orders
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
An Adjustment modifies the price of an [Order](/developer/core-concepts/orders), a [Line Item](/developer/core-concepts/orders#line-items), or a [Shipment](/developer/core-concepts/shipments). Adjustments can be positive (charges) or negative (credits).
|
|
9
|
+
|
|
10
|
+
```mermaid
|
|
11
|
+
erDiagram
|
|
12
|
+
Adjustment {
|
|
13
|
+
decimal amount
|
|
14
|
+
string label
|
|
15
|
+
boolean eligible
|
|
16
|
+
boolean mandatory
|
|
17
|
+
string state
|
|
18
|
+
boolean included
|
|
19
|
+
string source_type
|
|
20
|
+
string adjustable_type
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
Order ||--o{ Adjustment : "has many"
|
|
24
|
+
Order ||--o{ LineItem : "has many"
|
|
25
|
+
Order ||--o{ Shipment : "has many"
|
|
26
|
+
LineItem ||--o{ Adjustment : "has many"
|
|
27
|
+
Shipment ||--o{ Adjustment : "has many"
|
|
28
|
+
TaxRate ||--o{ Adjustment : "creates"
|
|
29
|
+
PromotionAction ||--o{ Adjustment : "creates"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Key relationships:**
|
|
33
|
+
- **Adjustment** modifies prices on orders, line items, or shipments
|
|
34
|
+
- **Source** is where the adjustment comes from ([Tax Rate](/developer/core-concepts/taxes) or [Promotion Action](/developer/core-concepts/promotions))
|
|
35
|
+
- **Adjustable** is what's being adjusted (Order, LineItem, or Shipment)
|
|
36
|
+
- Positive amounts are charges, negative amounts are credits
|
|
37
|
+
|
|
38
|
+
## Adjustment Types
|
|
39
|
+
|
|
40
|
+
### Included vs Additional
|
|
41
|
+
|
|
42
|
+
- **Included** adjustments are part of the item's displayed price (e.g., VAT in European stores)
|
|
43
|
+
- **Additional** adjustments are added on top of the item's price (e.g., US sales tax)
|
|
44
|
+
|
|
45
|
+
### Sources
|
|
46
|
+
|
|
47
|
+
Adjustments are created by two sources:
|
|
48
|
+
|
|
49
|
+
| Source | Example | Typical Amount |
|
|
50
|
+
|--------|---------|----------------|
|
|
51
|
+
| [Tax Rate](/developer/core-concepts/taxes) | Sales tax, VAT | Positive (charge) |
|
|
52
|
+
| [Promotion Action](/developer/core-concepts/promotions) | Coupon discount, free shipping | Negative (credit) |
|
|
53
|
+
|
|
54
|
+
## Adjustment Attributes
|
|
55
|
+
|
|
56
|
+
| Attribute | Description | Example |
|
|
57
|
+
|-----------|-------------|---------|
|
|
58
|
+
| `amount` | The monetary value of the adjustment | `-10.00` |
|
|
59
|
+
| `label` | Human-readable description | `10% off order` |
|
|
60
|
+
| `eligible` | Whether the adjustment currently applies | `true` |
|
|
61
|
+
| `mandatory` | If `true`, always applied regardless of eligibility rules | `false` |
|
|
62
|
+
| `state` | `open` (auto-updated) or `closed` (locked) | `open` |
|
|
63
|
+
| `included` | Whether the amount is included in the item's displayed price | `false` |
|
|
64
|
+
|
|
65
|
+
## Adjustment Lifecycle
|
|
66
|
+
|
|
67
|
+
- **Open** adjustments are recalculated whenever the order is updated (e.g., items added/removed, address changed)
|
|
68
|
+
- **Closed** adjustments are locked and will not be automatically recalculated
|
|
69
|
+
- When a promotion becomes ineligible (e.g., item removed from cart), its adjustments are automatically removed
|
|
70
|
+
|
|
71
|
+
## Store API
|
|
72
|
+
|
|
73
|
+
Adjustments appear in order responses when you expand line items or shipments:
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
```typescript SDK
|
|
77
|
+
const order = await client.orders.get('or_abc123', {
|
|
78
|
+
spreeToken: '<token>',
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
// Line item adjustments (promotions, taxes)
|
|
82
|
+
order.items?.forEach(item => {
|
|
83
|
+
item.adjustment_total // total adjustments on this item
|
|
84
|
+
item.additional_tax_total
|
|
85
|
+
item.included_tax_total
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
// Order-level totals
|
|
89
|
+
order.adjustment_total // total of all adjustments
|
|
90
|
+
order.promo_total // total promotional discounts
|
|
91
|
+
order.additional_tax_total
|
|
92
|
+
order.included_tax_total
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
```bash cURL
|
|
96
|
+
curl 'https://api.mystore.com/api/v3/store/orders/or_abc123?expand=items,shipments' \
|
|
97
|
+
-H 'Authorization: Bearer spree_pk_xxx' \
|
|
98
|
+
-H 'X-Spree-Token: <token>'
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
## Related Documentation
|
|
103
|
+
|
|
104
|
+
- [Promotions](/developer/core-concepts/promotions) — Promotion-based adjustments
|
|
105
|
+
- [Taxes](/developer/core-concepts/taxes) — Tax adjustments
|
|
106
|
+
- [Shipments](/developer/core-concepts/shipments) — Shipping adjustments
|
|
107
|
+
- [Orders](/developer/core-concepts/orders) — How adjustments affect order totals
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Architecture
|
|
3
|
+
description: How Spree's core models, APIs, and packages work together
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
Spree is a commerce engine built around interconnected models that represent the core concepts of commerce: products, orders, payments, and shipments. It adapts to your stack — use it as a headless API for any frontend, embed it into an existing application, or scale it from a single storefront to a global multi-vendor marketplace.
|
|
9
|
+
|
|
10
|
+
> **INFO:** Spree supports PostgreSQL, MySQL, and SQLite. PostgreSQL is recommended for production. [Learn more about database configuration](/developer/deployment/database).
|
|
11
|
+
|
|
12
|
+
## Core Commerce Flow
|
|
13
|
+
|
|
14
|
+
The following diagram shows how the main models interact during a typical customer purchase:
|
|
15
|
+
|
|
16
|
+
```mermaid
|
|
17
|
+
flowchart TB
|
|
18
|
+
subgraph Catalog["Catalog"]
|
|
19
|
+
Product --> Variant
|
|
20
|
+
Variant --> Price
|
|
21
|
+
Variant --> StockItem
|
|
22
|
+
StockItem --> StockLocation
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
subgraph Shopping["Shopping"]
|
|
26
|
+
User --> Order
|
|
27
|
+
Order --> LineItem
|
|
28
|
+
LineItem --> Variant
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
subgraph Checkout["Checkout"]
|
|
32
|
+
Order --> Address
|
|
33
|
+
Order --> Shipment
|
|
34
|
+
Order --> Payment
|
|
35
|
+
Shipment --> ShippingMethod
|
|
36
|
+
Payment --> PaymentMethod
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
subgraph Fulfillment["Fulfillment"]
|
|
40
|
+
Shipment --> InventoryUnit
|
|
41
|
+
InventoryUnit --> Variant
|
|
42
|
+
StockLocation --> Shipment
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
subgraph Pricing["Pricing & Adjustments"]
|
|
46
|
+
Order --> Adjustment
|
|
47
|
+
LineItem --> Adjustment
|
|
48
|
+
Shipment --> Adjustment
|
|
49
|
+
TaxRate --> Adjustment
|
|
50
|
+
Promotion --> Adjustment
|
|
51
|
+
end
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**How it works:**
|
|
55
|
+
|
|
56
|
+
1. **Catalog** — [Products](/developer/core-concepts/products) have [Variants](/developer/core-concepts/products#variants) (SKUs) with prices and inventory tracked at [Stock Locations](/developer/core-concepts/inventory#stock-locations)
|
|
57
|
+
|
|
58
|
+
2. **Shopping** — Customers add Variants to their cart, creating an [Order](/developer/core-concepts/orders) with Line Items
|
|
59
|
+
|
|
60
|
+
3. **Checkout** — The Order collects [Addresses](/developer/core-concepts/addresses), calculates [Shipping](/developer/core-concepts/shipments) options, and processes [Payments](/developer/core-concepts/payments)
|
|
61
|
+
|
|
62
|
+
4. **Fulfillment** — [Shipments](/developer/core-concepts/shipments) are created from Stock Locations, tracking individual [Inventory Units](/developer/core-concepts/inventory#inventory-units)
|
|
63
|
+
|
|
64
|
+
5. **Pricing & Adjustments** — [Taxes](/developer/core-concepts/taxes) and [Promotions](/developer/core-concepts/promotions) create [Adjustments](/developer/core-concepts/adjustments) that modify order totals
|
|
65
|
+
|
|
66
|
+
## Core Model Relationships
|
|
67
|
+
|
|
68
|
+
This diagram shows the key database relationships between Spree's main models:
|
|
69
|
+
|
|
70
|
+
```mermaid
|
|
71
|
+
erDiagram
|
|
72
|
+
Store ||--o{ Order : "has many"
|
|
73
|
+
Store ||--o{ Product : "has many"
|
|
74
|
+
|
|
75
|
+
Product ||--o{ Variant : "has many"
|
|
76
|
+
Product }o--|| TaxCategory : "belongs to"
|
|
77
|
+
Product }o--|| ShippingCategory : "belongs to"
|
|
78
|
+
Product }o--o{ Taxon : "categorized by"
|
|
79
|
+
|
|
80
|
+
Variant ||--o{ Price : "has many"
|
|
81
|
+
Variant ||--o{ StockItem : "has many"
|
|
82
|
+
Variant ||--o{ LineItem : "has many"
|
|
83
|
+
|
|
84
|
+
Order ||--o{ LineItem : "has many"
|
|
85
|
+
Order ||--o{ Shipment : "has many"
|
|
86
|
+
Order ||--o{ Payment : "has many"
|
|
87
|
+
Order ||--o{ Adjustment : "has many"
|
|
88
|
+
Order }o--|| User : "belongs to"
|
|
89
|
+
Order }o--|| Address : "ship address"
|
|
90
|
+
Order }o--|| Address : "bill address"
|
|
91
|
+
|
|
92
|
+
Shipment ||--o{ InventoryUnit : "has many"
|
|
93
|
+
Shipment }o--|| StockLocation : "ships from"
|
|
94
|
+
Shipment }o--|| ShippingMethod : "via"
|
|
95
|
+
|
|
96
|
+
Payment }o--|| PaymentMethod : "via"
|
|
97
|
+
|
|
98
|
+
StockLocation ||--o{ StockItem : "has many"
|
|
99
|
+
|
|
100
|
+
TaxRate }o--|| TaxCategory : "belongs to"
|
|
101
|
+
TaxRate }o--|| Zone : "applies to"
|
|
102
|
+
TaxRate ||--o{ Adjustment : "creates"
|
|
103
|
+
|
|
104
|
+
Promotion ||--o{ Adjustment : "creates"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## APIs
|
|
108
|
+
|
|
109
|
+
Spree exposes two REST APIs, both under API v3:
|
|
110
|
+
|
|
111
|
+
| API | Purpose | Authentication |
|
|
112
|
+
|-----|---------|----------------|
|
|
113
|
+
| [**Store API**](/api-reference/introduction) | Customer-facing — cart, checkout, products, account | Publishable API key + JWT |
|
|
114
|
+
| **Admin API** | Operational — manage products, orders, customers, settings | Secret API key |
|
|
115
|
+
|
|
116
|
+
Both APIs use [prefixed IDs](/api-reference/introduction) (e.g., `prod_86Rf07xd4z`, `or_m3Rp9wXz`), flat JSON request/response structures, and full TypeScript types via the [@spree/sdk](/developer/sdk/quickstart).
|
|
117
|
+
|
|
118
|
+
Events from both APIs can trigger [Webhooks](/developer/core-concepts/webhooks) to notify external systems in real time.
|
|
119
|
+
|
|
120
|
+
## Multi-Store Architecture
|
|
121
|
+
|
|
122
|
+
Spree supports [multiple stores](/developer/multi-store/quickstart) from a single installation. Each Store can have:
|
|
123
|
+
|
|
124
|
+
- Its own domain and branding
|
|
125
|
+
- Different currencies and locales
|
|
126
|
+
- Separate product catalogs
|
|
127
|
+
- Independent payment and shipping methods
|
|
128
|
+
- Isolated orders and customers
|
|
129
|
+
|
|
130
|
+
This makes Spree suitable for multi-brand retailers, international expansion, or B2B/B2C hybrid setups.
|
|
131
|
+
|
|
132
|
+
## Extension Points
|
|
133
|
+
|
|
134
|
+
Spree is designed to be customized without modifying core code. The main extension mechanisms are:
|
|
135
|
+
|
|
136
|
+
| Mechanism | Use Case | Documentation |
|
|
137
|
+
|-----------|----------|---------------|
|
|
138
|
+
| **Events & Subscribers** | React to order completion, payment, shipment events | [Events Guide](/developer/core-concepts/events) |
|
|
139
|
+
| **Webhooks** | Notify external systems of changes | [Webhooks Guide](/developer/core-concepts/webhooks) |
|
|
140
|
+
| **Dependencies** | Swap out services (tax calculation, shipping estimation) | [Dependencies Guide](/developer/customization/dependencies) |
|
|
141
|
+
| **Decorators** | Modify existing model/controller behavior (use sparingly) | [Decorators Guide](/developer/customization/decorators) |
|
|
142
|
+
|
|
143
|
+
> **INFO:** For most customizations, prefer **Events** and **Dependencies** over Decorators. They're easier to maintain and won't break during upgrades.
|
|
144
|
+
|
|
145
|
+
## Packages
|
|
146
|
+
|
|
147
|
+
Spree is distributed as a set of packages:
|
|
148
|
+
|
|
149
|
+
**Core (required):**
|
|
150
|
+
|
|
151
|
+
| Package | Purpose |
|
|
152
|
+
|---------|---------|
|
|
153
|
+
| `spree` | Models, services, business logic, Store API, Admin API, and Webhooks |
|
|
154
|
+
|
|
155
|
+
**Optional:**
|
|
156
|
+
|
|
157
|
+
| Package | Purpose |
|
|
158
|
+
|---------|---------|
|
|
159
|
+
| `spree_admin` | Admin dashboard for managing your store |
|
|
160
|
+
| `spree_emails` | Transactional email templates (order confirmation, shipping, etc.) |
|
|
161
|
+
|
|
162
|
+
**TypeScript packages:**
|
|
163
|
+
|
|
164
|
+
| Package | Purpose |
|
|
165
|
+
|---------|---------|
|
|
166
|
+
| [`@spree/sdk`](/developer/sdk/quickstart) | TypeScript SDK for Store API and Admin API |
|
|
167
|
+
| [`@spree/next`](/developer/storefront/nextjs/spree-next-package) | Next.js integration — server actions, caching, cookie-based auth |
|
|
168
|
+
|
|
169
|
+
> **INFO:** For headless commerce, you only need the `spree` package. Build your customer-facing frontend with any technology (Next.js, Nuxt, mobile apps) using the Store API and SDK.
|
|
170
|
+
|
|
171
|
+
## Related Documentation
|
|
172
|
+
|
|
173
|
+
- [Products](/developer/core-concepts/products) — Product catalog and variants
|
|
174
|
+
- [Orders](/developer/core-concepts/orders) — Order lifecycle and state machine
|
|
175
|
+
- [Payments](/developer/core-concepts/payments) — Payment processing
|
|
176
|
+
- [Shipments](/developer/core-concepts/shipments) — Shipping and fulfillment
|
|
177
|
+
- [Customization Quickstart](/developer/customization/quickstart) — How to extend Spree
|