@spree/docs 0.1.302 → 0.1.304
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/dist/api-reference/admin-api/monetary-amounts.md +21 -5
- package/dist/api-reference/store-api/monetary-amounts.md +16 -7
- package/dist/api-reference/store.yaml +625 -598
- package/dist/developer/create-spree-app/quickstart.md +1 -0
- package/dist/developer/upgrades/5.6-to-6.0.md +29 -1
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ sidebarTitle: "Monetary Amounts"
|
|
|
4
4
|
description: "How the Admin API represents money as decimal strings, why JSON numbers are avoided, and how to send prices, costs, and amounts safely in requests."
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
All monetary values in the Admin API are **canonical decimal strings** (
|
|
7
|
+
All monetary values in the Admin API are **canonical decimal strings** (period decimal, no thousands grouping), both in responses and in request bodies. Responses write each amount with exactly its currency's decimal places — `"29.99"` in USD, `"1.500"` in Kuwaiti dinar, `"1000"` in yen — and unit prices (`price`, `amount` on a price, `compare_at_amount`, `cost_price`, `unit_cost`) with up to four (`"0.0125"`). A currency's decimal places are its `decimal_places`, from ISO 4217. Strings preserve decimal precision and avoid the floating-point rounding issues common with JSON numbers — critical when an admin is setting prices and costs. The format is the same regardless of locale; localized formatting is a presentation concern handled by the client (see [Canonical format](#canonical-format-not-localized)).
|
|
8
8
|
|
|
9
9
|
## Reading
|
|
10
10
|
|
|
@@ -19,7 +19,7 @@ Every monetary field is returned as a string, alongside a `display_` companion t
|
|
|
19
19
|
}
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Use `display_*` for rendering and the raw string fields for calculations
|
|
22
|
+
Use `display_*` for rendering and the raw string fields for calculations, with a decimal library rather than `parseFloat`. The SDK exports `sumMoney`, `subtractMoney`, `multiplyMoney`, `compareMoney` and `isZeroMoney`, which work on the strings exactly.
|
|
23
23
|
|
|
24
24
|
## Writing
|
|
25
25
|
|
|
@@ -38,13 +38,25 @@ spree api post /products -d '{"name":"Classic Tee","prices":[{"currency":"USD","
|
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
Only strings are accepted. A JSON number (`"amount": 29.99`), a localized or grouped string (`"1.234,56"`, `"1,234.56"`), or more decimals than the field holds (`"19.999"` in USD, `"100.5"` in yen; unit prices allow four) is refused with `422` and the error code `invalid_money_format`, naming the field:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"error": {
|
|
46
|
+
"code": "invalid_money_format",
|
|
47
|
+
"message": "amount must be a decimal string like \"19.99\"",
|
|
48
|
+
"details": { "amount": ["must be a decimal string like \"19.99\""] }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
A `null` clears the value.
|
|
42
54
|
|
|
43
55
|
### Canonical format — not localized
|
|
44
56
|
|
|
45
57
|
Amounts are **canonical**: a period decimal separator and no thousands grouping (`"1234.56"`), independent of any locale. The Admin API does **not** parse locale-specific formats — do not send `"1.234,56"` or `"1,234.56"`.
|
|
46
58
|
|
|
47
|
-
If you are taking input from a merchant in a localized format, normalize it to canonical form **before** sending. The Spree dashboard does this in the browser:
|
|
59
|
+
If you are taking input from a merchant in a localized format, normalize it to canonical form **before** sending. The Spree dashboard does this in the browser, in the number format of the person using it: an admin who writes German types `1.234,56`, in any currency, and `1234.56` goes on the wire. This matches how other commerce APIs handle money (canonical decimal or minor-unit integers; localization is a presentation concern).
|
|
48
60
|
|
|
49
61
|
## Affected types
|
|
50
62
|
|
|
@@ -75,4 +87,8 @@ Calculators and some promotion rules carry their amounts inside an untyped `pref
|
|
|
75
87
|
| **Calculator** `flat_rate` (shipping) | `amount`, `minimum_item_total`, `maximum_item_total` |
|
|
76
88
|
| **Promotion Rule** `item_total` | `amount_min`, `amount_max` |
|
|
77
89
|
|
|
78
|
-
Percentage keys (`percent`, `flat_percent`, `base_percent`),
|
|
90
|
+
Percentage keys (`percent`, `flat_percent`, `base_percent`) are rates: decimal strings too (`"10"`), with no fixed number of decimals. Weights (`minimum_weight`, `maximum_weight`) and quantities (`max_items`, `min_quantity`) are not money and stay numbers. Promotion actions (`create_adjustment`, `create_item_adjustments`) hold their money inside a nested `calculator.preferences`, per the calculator rows above.
|
|
91
|
+
|
|
92
|
+
## Rates and percentages
|
|
93
|
+
|
|
94
|
+
Rates and percentages are decimal strings without trailing zeros, on read and write. A field ending in `_percent` or `_percentage` holds 0–100 (`"23"`); a field named `rate` or ending in `_rate` holds a fraction (`"0.23"`). A tax rate has both: `rate` and `rate_percent`, and accepts either on write.
|
|
@@ -4,7 +4,7 @@ sidebarTitle: "Monetary Amounts"
|
|
|
4
4
|
description: "How monetary values are represented in API responses"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
All monetary values in the Store API are returned as **strings
|
|
7
|
+
All monetary values in the Store API are returned as **decimal strings**, never JSON numbers, written with exactly the decimal places of their currency: `"29.99"` in USD, `"1.500"` in Kuwaiti dinar, `"1000"` in yen. Unit prices may carry up to four decimals (`"0.0125"`). This preserves decimal precision and avoids the rounding errors of JSON numbers. A currency's decimal places are its `decimal_places` (see [below](#currency-decimal-places)).
|
|
8
8
|
|
|
9
9
|
## Response Format
|
|
10
10
|
|
|
@@ -35,7 +35,13 @@ This convention applies to all monetary fields across all resources:
|
|
|
35
35
|
| **Payment** | `amount` |
|
|
36
36
|
| **Gift Card** | `amount`, `amount_used`, `amount_authorized`, `amount_remaining` |
|
|
37
37
|
| **Store Credit** | `amount`, `amount_used`, `amount_remaining` |
|
|
38
|
-
| **Price** | `amount`, `compare_at_amount` |
|
|
38
|
+
| **Price** | `amount`, `compare_at_amount` (unit prices, up to four decimals) |
|
|
39
|
+
|
|
40
|
+
Rates, such as a tax line's `rate`, are decimal strings too, without trailing zeros (`"0.23"`).
|
|
41
|
+
|
|
42
|
+
## Currency decimal places
|
|
43
|
+
|
|
44
|
+
Each currency the store sells in (`GET /api/v3/store/currencies`) carries `decimal_places`, from ISO 4217: `2` for USD and EUR, `0` for JPY, `3` for KWD. Every amount in that currency is written with that many decimals.
|
|
39
45
|
|
|
40
46
|
## Working with Amounts
|
|
41
47
|
|
|
@@ -43,12 +49,15 @@ This convention applies to all monetary fields across all resources:
|
|
|
43
49
|
```typescript SDK
|
|
44
50
|
const order = await client.orders.get('or_abc123', {}, { token });
|
|
45
51
|
|
|
52
|
+
import { compareMoney, sumMoney } from '@spree/sdk'
|
|
53
|
+
|
|
46
54
|
// Raw string values
|
|
47
55
|
order.total; // "129.99"
|
|
48
56
|
order.display_total; // "$129.99"
|
|
49
57
|
|
|
50
|
-
//
|
|
51
|
-
const
|
|
58
|
+
// Calculate on the strings, exactly
|
|
59
|
+
const subtotal = sumMoney(order.items.map((item) => item.total), order.currency); // "129.99"
|
|
60
|
+
const isFree = compareMoney(order.total, '0') === 0;
|
|
52
61
|
```
|
|
53
62
|
|
|
54
63
|
```javascript JavaScript
|
|
@@ -57,9 +66,9 @@ const data = await response.json();
|
|
|
57
66
|
// Use display fields for rendering
|
|
58
67
|
element.textContent = data.display_total; // "$129.99"
|
|
59
68
|
|
|
60
|
-
//
|
|
61
|
-
|
|
69
|
+
// Calculate on the raw strings with a decimal library, never parseFloat:
|
|
70
|
+
// 0.1 + 0.2 is 0.30000000000000004 as a JSON number.
|
|
62
71
|
```
|
|
63
72
|
|
|
64
73
|
|
|
65
|
-
> **TIP:** Use `display_*` fields for rendering prices in the UI — they are pre-formatted with the correct currency symbol and decimal places based on the order's currency.
|
|
74
|
+
> **TIP:** Use `display_*` fields for rendering prices in the UI — they are pre-formatted with the correct currency symbol and decimal places based on the order's currency. Calculate on the raw strings with the SDK's `sumMoney`, `subtractMoney`, `multiplyMoney` and `compareMoney`, which work on decimal strings exactly.
|