Skip to main content

Order Fulfillment

Scottsdale Mint fulfills orders through a combination of ShipStation (order management) and FedEx (shipping carrier). Physical precious metals require special handling โ€” signature on delivery, high-value insurance, and discreet packaging.


Fulfillment Flowโ€‹

WooCommerce (wc-processing)
โ”‚
โ”‚ ShipStation webhook / API push
โ–ผ
ShipStation
- Creates packing slip
- Assigns to warehouse queue
- Generates FedEx label
- Warehouse packs and ships
โ”‚
โ”‚ ShipStation webhook (shipment.shipped)
โ–ผ
WordPress /wp-json/suma/v1/shipstation-webhook
- Stores tracking number on order
- Updates order status to wc-awaiting-shipment โ†’ wc-completed (or awaiting)
- Sends ShippingConfirmation email to customer
โ”‚
โ–ผ
FedEx delivers package โ†’ Customer signs for delivery

ShipStation Integrationโ€‹

Automatic Order Pushโ€‹

Orders automatically appear in ShipStation when they reach wc-processing. ShipStation polls WooCommerce via the WooCommerce ShipStation Gateway plugin or direct API integration.

Products synced:

  • Product name and SKU
  • Quantity
  • Unit price
  • Customer note (from checkout)

Order Import Rules (ShipStation settings)โ€‹

ShipStation applies import rules to set:

  • Warehouse assignment
  • Shipping service (FedEx Overnight, FedEx 2Day, etc.)
  • Package type (declare value for insurance)
  • Signature confirmation (required for all precious metals shipments)

FedEx Configurationโ€‹

All precious metals orders ship via FedEx:

SettingValue
Default serviceFedEx Overnight (next business day)
SignatureAdult signature required
InsuranceDeclared value = full order amount
PackagingDiscreet plain packaging (no "Scottsdale Mint" on exterior)

FedEx service level available to customer at checkout:

  • FedEx Overnight โ€” standard for most orders
  • FedEx 2Day โ€” lower cost option for lower-value orders
info

All precious metals shipments require adult signature at delivery. Orders cannot be left without a signature.


ShipStation Webhookโ€‹

When ShipStation ships an order, it calls:

POST /wp-json/suma/v1/shipstation-webhook

Webhook payload:

{
"resource_url": "https://ssapi.shipstation.com/shipments?orderNumber=12345",
"resource_type": "SHIP_NOTIFY",
"order_number": "12345",
"tracking_number": "794658749765",
"carrier": "fedex",
"ship_date": "2024-01-15"
}

Webhook handling:

  1. Verify webhook secret token
  2. Fetch full shipment details from ShipStation API (using resource_url)
  3. Update WooCommerce order:
    • Store tracking number in _tracking_number meta
    • Store carrier in _tracking_provider meta
    • Store ship date in _date_shipped meta
  4. Advance order status to wc-awaiting-shipment (if not already wc-completed)
  5. Send ShippingConfirmation email with tracking link

Inventory Managementโ€‹

WooCommerce Inventoryโ€‹

WooCommerce manages product inventory:

  • Inventory count decremented when order is placed
  • Inventory restored if order is cancelled

The suma-patches plugin includes a modification:

// 0001-Feature-Added-Checkbox-for-ignoring-inventory-limits.patch

This adds an admin checkbox to allow backorders for specific products.

NFusion Inventory Syncโ€‹

When an order is shipped, inventory data is pushed to NFusion to keep the catalog accurate:

  • WooCommerce stock โ†’ NFusion catalog availability
  • Exported via the NFusion order export endpoint

Backordered Itemsโ€‹

If a product is backordered:

  1. Admin marks the product to allow backorders
  2. Customer may still purchase
  3. Order is held in wc-processing with an "Expected Ship Date" meta set by admin
  4. Customer tracking page shows expected ship date

Hold Reasonsโ€‹

Orders that cannot be shipped immediately are put "on hold" for:

ReasonStatusRequired Action
ACH pending settlementwc-pending-achWait for iTransact settlement webhook
Wire transfer pendingwc-partially-paidAdmin confirm wire received
Crypto confirmationswc-pending-cryptoWait for blockchain confirmations
KYC requiredwc-kyc-pendingCompliance team reviews documents
Kount reviewwc-on-holdFraud team manually reviews
Inventory shortagewc-on-holdAdmin resolves inventory/ETA

Stock Reduction & Restoration Throughout Order Lifecycleโ€‹

Scottsdale Mint's inventory system automatically manages stock levels as orders move through different statuses. This ensures accurate inventory counts while handling edge cases like payment failures and order recovery.

When Stock is Reducedโ€‹

Stock is reduced at checkout for most orders via the ensure_reduce_stock_meta method:

Trigger: Fires on woocommerce_checkout_order_processed hook (priority 20)

Logic:

  1. Order is created (excludes crypto-canceled, cancelled, refunded, failed, checkout-draft, atc-order)
  2. System checks if stock was already reduced (_order_stock_reduced meta)
  3. If not reduced, calls wc_reduce_stock_levels($order_id)
  4. Marks order with _order_stock_reduced = yes meta
  5. Marks each line item with _reduced_stock = {quantity} meta
  6. Logs "[Stock] Made sure all items were marked as reduced stock"

Example: Customer orders 10 oz Silver Bar โ†’ WooCommerce inventory decreases by 10 immediately at checkout.

Prevention of Double-Reduction

The system uses _order_stock_reduced meta to prevent duplicate reductions. The prevent_duplicate_stock_reduction filter in class-stock.php blocks any attempt to reduce stock again if this meta is already set to yes.

WooCommerce Deposits Integrationโ€‹

For orders with deposits (partial payment), stock reduction timing depends on the Deposits plugin configuration:

Configuration Option: wc_deposits_reduce_stock

  • deposit โ€” Stock reduced at checkout when deposit is paid
  • full โ€” Stock reduced when full payment is completed (not at checkout)

When reduce_stock_on === 'full':

  • ensure_reduce_stock_meta skips stock reduction at checkout
  • Deposits plugin handles stock reduction via payment_complete_reduce_order_stock filter
  • Order note: "[Stock] Skipping stock reduction at checkout - Deposits plugin configured to reduce stock on full payment"

Stock Restoration on Order Failureโ€‹

When an order transitions to failed status, stock is automatically restored via handle_order_status_stock_changes:

Trigger: Fires on woocommerce_order_status_changed hook

Logic (via restore_stock_for_failed_order):

  1. Check if stock was already restored (_stock_restored_on_failure meta) to prevent double-restoration
  2. Verify stock was actually reduced by checking _reduced_stock meta on line items
  3. Call wc_increase_stock_levels($order) to restore inventory
  4. Set _stock_restored_on_failure = yes meta
  5. Set _order_stock_reduced = no meta
  6. Delete _reduced_stock meta from all line items
  7. Log "[Stock] Stock levels restored due to order failure"

Example:

  • Customer orders 5 Gold Eagles โ†’ stock reduced to 95
  • Payment fails โ†’ order status changes to failed
  • Stock automatically restored to 100

Edge Cases:

  • If Deposits plugin manages stock (reduce_stock_on === 'full'), no restoration occurs
  • If stock was never reduced, no restoration occurs

Stock Re-Reduction on Order Recoveryโ€‹

When a failed order recovers to a valid status, stock is re-reduced via re_reduce_stock_for_recovered_order:

Valid Recovery Statuses:

  • pending
  • processing
  • on-hold
  • completed
  • pending-ach
  • crypto-pending
  • partially-paid

Logic:

  1. Only executes if _stock_restored_on_failure = yes (stock was previously restored)
  2. Check if stock is already reduced (_order_stock_reduced = yes) to prevent double-reduction
  3. Call wc_reduce_stock_levels($order_id) to re-reduce inventory
  4. Set _order_stock_reduced = yes meta
  5. Delete _stock_restored_on_failure meta
  6. Re-mark line items with _reduced_stock = {quantity} meta
  7. Log "[Stock] Stock levels re-reduced after order recovery from failed status"

Example:

  • Customer's payment initially fails โ†’ stock restored to 100
  • Customer retries payment and succeeds โ†’ order moves to pending
  • Stock automatically re-reduced to 95

Order Meta Keys for Stock Trackingโ€‹

Meta KeyValuesPurpose
_order_stock_reducedyes / noIndicates if stock has been reduced for this order
_stock_restored_on_failureyes / (absent)Indicates stock was restored when order failed
_reduced_stock{quantity}Stored on each line item; tracks quantity reduced

Stock Change Loggingโ€‹

All stock changes are logged via the stock_change_log method in class-stock.php:

Trigger: Fires on woocommerce_product_set_stock and woocommerce_variation_set_stock hooks

Logged Data:

  • Product ID
  • SKU
  • New quantity
  • Log type: activity_product (sub_type: stock_change)

This creates an audit trail for all inventory movements.