@dukkan.one/app-sdk/commerce
Money in minor units with each value's own decimals, order status transitions, totals reconciliation, unfulfilled lines, refundable amounts, and sync by updated_at.
- الحزمة
@dukkan.one/app-sdk@0.3.0- مراجعة الواجهة
2026-09-10- الاستيراد
import { … } from "@dukkan.one/app-sdk/commerce"
في هذه الصفحة
- الدوال
- addMoney
- allowedNextStatuses
- buildCreateOrderLines
- canTransition
- compareMoney
- convertLinePrice
- convertMinorAmount
- exchangeRateFor
- formatMoney
- isCustomLine
- isFullyFulfilled
- isSettableStatus
- isZeroMoney
- money
- moneyFromDecimalString
- moneyToDecimalString
- reconcileOrderTotals
- refundableAmount
- subtractMoney
- sumMoney
- syncByUpdatedAt
- syncOrders
- syncProducts
- unfulfilledLines
- الواجهات
- ConvertedLine
- CurrencyExponent
- PricedLine
- ReconciliationResult
- ScaledRate
- SyncOptions
- SyncResult
- UnfulfilledLine
- الأنواع
- CreateOrderItem
- Fulfillment
- Money
- Order
- OrderDetail
- OrderItem
- Store
الدوال
addMoney#
Adds two amounts of the same currency and exponent; throws on a mismatch so mixed currencies never add silently.
allowedNextStatuses#
Transitions an app may request from from (the server's matrix, settable subset).
buildCreateOrderLines#
Builds CreateOrderRequest.items from lines priced in the pricing
currency. With a rate, every unit price is converted per unit like
checkout; with rate: null (order in the pricing currency) the prices
pass through unchanged.
canTransition#
True when the platform's status matrix allows a PATCH /orders/{id}/status from from to to.
compareMoney#
Compares two amounts of the same currency: -1, 0 or 1.
convertLinePrice#
Prices one line in the order currency the way checkout does: round the UNIT price first, then multiply by the quantity. Converting the line total instead can differ by a minor unit, and then the app's quote and the storefront would disagree on the same basket.
convertMinorAmount#
Converts ONE minor amount from the pricing currency to the order currency
with the platform's { scaled, scale } rate, rounding half up to the
target's decimals (what checkout's roundByCurrency does to a unit
price). Exact integer arithmetic: no float drift at the .5 boundary.
exchangeRateFor#
The exchange_rate to send with POST /orders for currency, from the
store's FX table: null when the order is in the pricing currency (the
platform rejects a rate there), the store-adjusted rate otherwise, or
undefined when the store has no rate for that currency.
formatMoney#
Locale-aware formatting through Intl using the value's own exponent.
ar yields Arabic script digits by default; pass numberingSystem: "latn"
for Western digits, which Dukkan's admin uses for technical values.
isCustomLine#
True for a line with no catalog link (kind: "custom", variant_id: null): never touches inventory, refunds by amount only.
isFullyFulfilled#
True when every order line has been fulfilled in full.
isSettableStatus#
True when a string is one of the statuses an app may set through the API.
isZeroMoney#
True when the amount is exactly zero.
money#
Money helpers over the platform's { amount_minor, currency, decimals }.
Every function scales by the value's OWN decimals (SYP is zero-decimal on
Dukkan, which no ISO table knows) and refuses to mix currencies.
moneyFromDecimalString#
Parses a major-unit string the merchant typed ("12.5") into minor units for the given exponent.
moneyToDecimalString#
Major-unit decimal string ("2500", "12.50") without float arithmetic.
reconcileOrderTotals#
Checks the two accounting identities the platform guarantees
(docs/apps/money): line totals against the subtotal according to
line_pricing, and subtotal - discount + shipping + tax = total. Use it in
cash-book and reporting apps instead of your own sum. Custom lines
(kind: "custom", variant_id: null) count like any other line: they carry
their own total.
refundableAmount#
Captured funds still refundable: paid minus refunded (what the platform gates refunds on).
subtractMoney#
Subtracts b from a in the same currency; the result may be negative.
sumMoney#
Adds a list of amounts starting from zero (which fixes the currency and exponent of an empty list).
syncByUpdatedAt#
Pages through a list endpoint ordered by updated_at from a high-water mark, handing every page of changed records to onPage, and returns the new mark. Rerunnable: an interrupted run resumes from the last mark you saved.
syncOrders#
syncByUpdatedAt over client.orders.
syncProducts#
syncByUpdatedAt over client.products.
unfulfilledLines#
Quantities not yet covered by a live fulfillment (cancelled ones release their lines), mirroring the server's over-fulfilment check.
الواجهات
ConvertedLine#
A converted line: the unit price rounded in the order currency, and quantity × unit.
| الاسم | النوع | الوصف |
|---|---|---|
unit_price_minorمطلوب | number | |
total_minorمطلوب | number |
CurrencyExponent#
A currency's minor-unit exponent on Dukkan (SYP 0, USD 2, JOD 3); read it from GET /store or a Money value, never from an ISO table.
| الاسم | النوع | الوصف |
|---|---|---|
decimalsمطلوب | number |
PricedLine#
One quoted line in the PRICING currency: a catalog variant or a custom line with a name.
| الاسم | النوع | الوصف |
|---|---|---|
variant_idمطلوب | string | null | |
name | string | undefined | |
quantityمطلوب | number | |
unit_price_minorمطلوب | number | Unit price in minor units of the pricing currency. |
ReconciliationResult#
Outcome of reconcileOrderTotals: whether the lines, discounts, shipping and total agree, and by how much they differ.
| الاسم | النوع | الوصف |
|---|---|---|
okمطلوب | boolean | |
problemsمطلوب | Array<{ rule: "lines_vs_subtotal" | "totals_identity"; expected: Money; actual: Money; }> | Which identity failed, with the two sides, when |
ScaledRate#
An FX rate as the platform carries it: rate = scaled / 10^scale, oriented 1 pricing-currency unit = rate order-currency units.
| الاسم | النوع | الوصف |
|---|---|---|
scaledمطلوب | number | |
scaleمطلوب | number |
SyncOptions#
Incremental sync (docs/apps/webhooks#reconcile): webhooks are at-least-once
and can lag; a periodic walk of updated_at_min catches what a receiver
missed. The high-water mark is the newest updated_at seen, minus a small
overlap so a write that committed at the same second is never skipped.
| الاسم | النوع | الوصف |
|---|---|---|
since | string | null | undefined | RFC 3339 instant of the last completed sync; omit for a full walk. |
overlapSeconds | number | undefined | Seconds subtracted from |
onPageمطلوب | (items: T[], page: Page<T>) => Promise<boolean | void> | boolean | void | Called per page; return false to stop early. |
limit | number | undefined |
SyncResult#
What a sync run reports: records seen and the high-water mark to persist for the next run.
| الاسم | النوع | الوصف |
|---|---|---|
highWaterMarkمطلوب | string | null | Store this as |
itemsمطلوب | number | |
pagesمطلوب | number |
UnfulfilledLine#
An order line and the quantity of it that still awaits a fulfillment.
| الاسم | النوع | الوصف |
|---|---|---|
order_item_idمطلوب | string | |
orderedمطلوب | number | |
fulfilledمطلوب | number | |
remainingمطلوب | number |