Shop Orders
Manage artist shop orders, track fulfillment, and issue refunds for sold products.
Endpoints
List Artist Orders
Endpoint: GET /wp-json/extrachill/v1/shop/orders
Purpose: Retrieve paginated list of orders containing products from a specific artist.
Permission: Requires logged-in user who can manage the artist
Parameters:
artist_id(integer, required) – The artist profile IDstatus(string, optional) – Filter by status:all(default),needs_fulfillment, orcompletedpage(integer, optional) – Page number (default: 1)per_page(integer, optional) – Results per page (default: 20, max: 100)
Response (HTTP 200):
{
"orders": [
{
"id": 12345,
"number": "#12345",
"status": "processing",
"date_created": "2025-01-15T10:30:00Z",
"customer": {
"name": "Fan Name",
"email": "[email protected]",
"address": {
"address_1": "123 Main St",
"address_2": "",
"city": "Los Angeles",
"state": "CA",
"postcode": "90001",
"country": "US"
}
},
"items": [
{
"product_id": 456,
"name": "Album CD",
"quantity": 1,
"total": 14.99
}
],
"artist_payout": 7.50,
"order_total": 14.99,
"ships_free_only": false,
"tracking_number": ""
}
],
"total": 42,
"total_pages": 3,
"page": 1,
"per_page": 20,
"needs_fulfillment_count": 5
}
Error Responses:
400– Missing artist_id401– User not logged in403– User cannot manage the artist500– Shop site not configured or WooCommerce unavailable
Update Order Status
Endpoint: PUT /wp-json/extrachill/v1/shop/orders/{id}/status
Purpose: Mark an order as shipped or completed.
Permission: Requires logged-in user who can manage the artist
Parameters:
id(integer, required, in URL) – Order IDartist_id(integer, required) – The artist profile IDstatus(string, required) – Status value:completed(marks order as shipped)tracking_number(string, optional) – Shipping tracking number
Request Example:
{
"artist_id": 123,
"status": "completed",
"tracking_number": "1Z999AA10123456784"
}
Response (HTTP 200):
{
"id": 12345,
"number": "#12345",
"status": "completed",
"date_created": "2025-01-15T10:30:00Z",
"customer": { /* ... */ },
"items": [ /* ... */ ],
"artist_payout": 7.50,
"order_total": 14.99,
"tracking_number": "1Z999AA10123456784"
}
Error Responses:
400– Invalid parameters or invalid artist401– User not logged in403– User cannot manage the artist or order doesn’t contain artist’s products404– Order not found500– WooCommerce unavailable
Issue Refund
Endpoint: POST /wp-json/extrachill/v1/shop/orders/{id}/refund
Purpose: Issue a full refund for the artist’s portion of an order via Stripe.
Permission: Requires logged-in user who can manage the artist
Parameters:
id(integer, required, in URL) – Order IDartist_id(integer, required) – The artist profile ID
Request Example:
{
"artist_id": 123
}
Response (HTTP 200):
{
"success": true,
"order_id": 12345,
"refund_amount": 7.50
}
Error Responses:
400– Invalid parameters or invalid refund amount401– User not logged in403– User cannot manage the artist404– Order not found500– WooCommerce, Stripe, or payment intent service unavailable
Implementation Details:
- Orders stored on shop site (Blog ID 3)
- Each order contains
_artist_payoutsmeta with per-artist totals - Refunds processed via Stripe using stored payment intent ID
- Order status changes to "refunded" after successful refund
- Tracks artist-specific shipping info via
_artist_tracking_{artist_id}meta
File: inc/routes/shop/orders.php
Usage Examples
Get Pending Orders (JavaScript)
async function getPendingOrders(artistId) {
const response = await fetch(
`/wp-json/extrachill/v1/shop/orders?artist_id=${artistId}&status=needs_fulfillment`,
{
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('access_token')
}
}
);
const data = await response.json();
console.log(`${data.needs_fulfillment_count} orders need fulfillment`);
return data.orders;
}
Mark Order Shipped
async function shipOrder(orderId, artistId, trackingNumber) {
const response = await fetch(
`/wp-json/extrachill/v1/shop/orders/${orderId}/status`,
{
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem('access_token')
},
body: JSON.stringify({
artist_id: artistId,
status: 'completed',
tracking_number: trackingNumber
})
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.message);
}
const order = await response.json();
console.log(`Order ${order.number} marked as shipped`);
return order;
}
Issue Refund
async function refundOrder(orderId, artistId) {
const response = await fetch(
`/wp-json/extrachill/v1/shop/orders/${orderId}/refund`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem('access_token')
},
body: JSON.stringify({
artist_id: artistId
})
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(`Refund failed: ${error.message}`);
}
const result = await response.json();
console.log(`Refund issued: $${result.refund_amount}`);
return result;
}
Order Fulfillment Dashboard
async function loadOrderDashboard(artistId) {
// Get all orders
const response = await fetch(
`/wp-json/extrachill/v1/shop/orders?artist_id=${artistId}&per_page=50`,
{
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('access_token')
}
}
);
const data = await response.json();
// Display pending orders
const pending = data.orders.filter(o =>
o.status === 'processing' || o.status === 'on-hold'
);
return {
total_orders: data.total,
pending_count: data.needs_fulfillment_count,
pending_orders: pending
};
}
Usage Notes
Order Status Values:
processing– Awaiting shipment (needs fulfillment)on-hold– On hold, needs fulfillmentcompleted– Marked as shipped by artistrefunded– Full refund issuedfailed– Payment failed
Fulfillment Workflow:
- Artist receives notification of new order
- Call GET endpoint to view pending orders
- Ship order and get tracking number
- Call PUT endpoint to mark as completed with tracking
- Customer receives shipping notification
Refunds:
- Only full refunds supported (for artist’s portion)
- Requires valid Stripe payment intent
- Automatically changes order status to "refunded"
- Cannot be undone via API (must be handled in Stripe dashboard)
Artist Payout:
artist_payoutfield shows artist’s earnings from order- Calculated based on product prices and commission structure
- May be less than
order_totalif platform takes commission
Related Endpoints:
- Shop Products – Manage product listings
- Stripe Connect – Configure payment processing
- User Artists – Manage artist profiles