AMARSoft: connection, pull, reserve, order
Connection, webhook, catalogue, prices, events, jewellery margins, reserve and intake.
Connection
Admin → Settings → Integrations → AMARSoft: use Connect AMARSoft ERP (OAuth) for one-click setup, or Advanced for manual base URL / key / secret / site / company / seller country. Admin values override env when set. Use Test connection or Re-sync on that page.
Auth is Authorization: token key:secret. Envelope is { message }. Methods are dotted: catalogue, prices, availability, reserve, release, order.
Webhook and signed test
URL: https://your-origin/api/erp/availability. Headers: HMAC-SHA256 of the raw body only, a timestamp rejected after five minutes, and the event name. Secrets live on the host (plus a legacy secret during rotation). Body needs event_id and barcode except on test. A repeated event_id is acknowledged and not applied twice. test is log-only and shows in the admin event feed.
Catalogue and prices
Pull drafts from the button or npm run erp:pull-draft. Manual JSON import upserts on barcode. Pieces land as draft. Page size 200, hard max 500. A bad cursor returns 417. Prices every five minutes or Refresh prices. metal_cost is not stored — metal is our live rate.
Stale cost and quote lock
An AMARSoft cost older than the stale threshold (default 900 seconds under Quote rules) refuses the quote as erpCostStale. Cart lock is 600 seconds. Their order intake rejects sealed_at older than 600 seconds. Their reserve TTL is 900 seconds. Our unique-piece hold is 15 minutes. Spot older than 600 seconds also refuses quotes.
Availability events
Sold / invoice / POS: mark sold. Withdrawn / transfer / hide: draft. Reserved: hide unless we already hold it. Available: activate unless already sold. Released: reverse a hide. Sold pieces are never auto-resurrected. The five-minute poll uses the same apply path.
Field names
Contract names are stored as sent (gold_color, item_style, type, category). Semantic maps cover quantity and identity only. type is item form; category is metal category — do not swap them.
Jewellery margins
Category margins settings. Making margin applies to gold/silver making and to diamond/watch selling_price. Metal margin and shop-rate override on that screen do not price the storefront.
Reserve then order
At quote and place, ERP jewellery only: reserve with our order number. Failure fails closed and drops the line. A 10-minute re-price keeps the hold. Cancel, abandon, and card failure: release. After payment confirmed we POST order with sealed amounts (margin is its own field). Their invoice is DRAFT; when they submit, the reservation becomes consumed — we never POST release on paid. Bullion and own-catalogue lines never call ERP.
If they return price_lock_expired, do not drop the paid order. The order detail flags it. Retry after re-seal consent (same paid amounts, new sealed_at).
Go-live gate
Jewellery, diamond, and watch stay draft until JOHAR_JEWELLERY_STOREFRONT_LIVE=1 after they accept a test order.