Price Update Endpoint
The price update endpoint is the inbound channel through which the external Laravel pricing middleware pushes current precious metals prices to WooCommerce every minute.
Endpointโ
POST /wp-json/suma/v1/product/update-prices
Authentication: Bearer token
Handler class: \Suma\Endpoints\Pricing (inc/endpoints/class-pricing.php)
Called by: External Laravel pricing middleware (every 60 seconds)
Request Formatโ
{
"products": [
{
"sku": "SM-1OZ-SILVER-BAR",
"price": 29.95,
"sale_price": null,
"spot_price": 27.50,
"premium": 2.45
},
{
"sku": "SM-1OZ-GOLD-AGE",
"price": 1950.00,
"sale_price": null,
"spot_price": 1880.00,
"premium": 70.00
}
]
}
Response Formatโ
{
"updated": 142,
"skipped": 3,
"errors": [
{ "sku": "SM-DISCONTINUED-ITEM", "error": "Product not found" }
],
"execution_time_ms": 1240
}
Update Logic (PriceUpdater::update_batch())โ
For each product in the payload:
1. Find WC product by SKU (wp_is_post() + sku lookup)
โ If not found: add to errors[], continue
2. Validate the new price is positive and numeric
โ If invalid: add to errors[], continue
3. Update WooCommerce product price fields:
- _price โ new price
- _regular_price โ new price (if not on sale)
- _sale_price โ sale_price from payload (or null)
4. Flush Redis object cache for this product ID
(wp_cache_delete on product and related keys)
5. Mark this product ID for CloudFront invalidation
After loop:
6. Trigger CloudFront cache invalidation for all updated product URLs
7. Update spot price cache in Redis (suma_pricing_cache)
8. Return summary (updated count, skipped, errors)
Performance Requirementsโ
This endpoint runs every 60 seconds. Violating these rules will cause pricing pipeline delays and customer-facing stale prices.
Rules:
- No blocking external API calls in the update loop
- No email sends during batch processing
- Batch database operations where possible โ avoid N+1 queries
- Use
wp_defer_term_counting(true)around the batch to prevent repeatedwp_termslock contention - Total execution time target: < 10 seconds for ~200 products
- Never call
wp_update_post()withwp_after_insert_postactions if they trigger expensive hooks
Sale Management Endpointsโ
POST /wp-json/suma/v1/product/start-salesโ
Starts scheduled product sales. Called by a cron job when date_on_sale_from has been reached.
Logic:
- Query products with
date_on_sale_from <= now AND date_on_sale_to >= now - Set
_price = _sale_pricefor each matching product - Clear caches
POST /wp-json/suma/v1/product/end-expired-salesโ
Ends product sales that have passed their expiry date.
Logic:
- Query products with
date_on_sale_to < now AND _price = _sale_price - Restore
_price = _regular_price - Clear
_sale_price - Clear caches
Cron Configurationโ
These endpoints are called via Ymir's external cron runner (not wp-cron).
From ymir.yml:
cron: 1 # Single cron execution โ Ymir calls WordPress cron every minute
For the price update specifically, the Laravel middleware's own cron calls the WP REST endpoint directly โ it does not go through WordPress's internal cron system.
Spot Price Alert Emailsโ
POST /wp-json/suma/v1/product/spot-price-alert-emailโ
Triggers price alert emails to customers who have registered for spot price notifications at a specific target price.
When triggered: After a successful price update batch, if any product's price has crossed a customer's alert threshold, this endpoint sends the notification email via WooCommerce's email system.
Alert subscriptions are managed via a custom ACF field or meta on user accounts. The alert email uses the standard WooCommerce transactional email system (routed through Mailgun).