Orders
Orders represent one-time purchases. Creating an order immediately processes payment through the EPD Gateway — there is no separate "charge" step.
Order Lifecycle
POST /orders → pending → succeeded ✓
→ failed ✗
After a successful order, you can issue full or partial refunds:
POST /orders/:id/refund → partially_refunded → refunded
Important: Orders are immutable financial records. There are no update or delete endpoints. All modifications happen through refunds.
/orders Create an order
Creates a new order and immediately processes payment through the EPD Gateway. There is no separate "charge" step — creating the order is the charge.
How It Works
- Validate customer and payment method exist
- Look up product prices from the database (prevents price manipulation)
- Create order record with status
pending - Submit payment to EPD Gateway
- Update order status to
succeededorfailed - Return the complete order with inline transaction details
Price Security
The price field is not accepted in order items. Prices are always resolved from the product catalog to prevent client-side price manipulation. If you need custom pricing, create a product with the desired price first.
Idempotency
This endpoint requires an idempotency key (X-EPD-Idempotency-Key header). If the same key is sent again within 24 hours, the original order is returned without creating a duplicate charge.
Tip: Always use idempotency keys for order creation. Network timeouts can leave you uncertain whether the payment went through — replaying with the same key safely returns the original result.
Header parameters
string"2026-02-11"string (uuid)"550e8400-e29b-41d4-a716-446655440000"Request body required
string"550e8400-e29b-41d4-a716-446655440000"string"6ba7b815-9dad-11d1-80b4-00c04fd430c8"array[object]string"usd"string"Premium coaching bundle purchase"string (uuid)"6ba7b818-9dad-11d1-80b4-00c04fd430c8"objectstring"John"string"Doe"string"123 Main St"string"Suite 100"string"San Francisco"string"CA"string"94105"string"US"string"+14155551234"Metadatastring"SAVE10"Code samples
curl -X POST https://api.epd.com/v1/orders \
-H "Authorization: Bearer epd_test_sk_xxxx" \
-H "Content-Type: application/json" \
-H "EPD-Version: 2026-02-11" \
-H "X-EPD-Idempotency-Key: $(uuidgen)" \
-d '{
"customer_id": "550e8400-e29b-41d4-a716-446655440000",
"payment_method_id": "6ba7b815-9dad-11d1-80b4-00c04fd430c8",
"items": [
{ "product_id": "6ba7b810-9dad-11d1-80b4-00c04fd430d1", "quantity": 2 }
],
"currency": "usd",
"metadata": { "campaign": "summer_sale" }
}' const response = await fetch('https://api.epd.com/v1/orders', {
method: 'POST',
headers: {
'Authorization': 'Bearer epd_test_sk_xxxx',
'Content-Type': 'application/json',
'EPD-Version': '2026-02-11',
'X-EPD-Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
customer_id: '550e8400-e29b-41d4-a716-446655440000',
payment_method_id: '6ba7b815-9dad-11d1-80b4-00c04fd430c8',
items: [
{ product_id: '6ba7b810-9dad-11d1-80b4-00c04fd430d1', quantity: 2 },
],
currency: 'usd',
}),
});
const order = await response.json();
console.log(order.status); // "succeeded" or "failed" import uuid
import requests
response = requests.post(
'https://api.epd.com/v1/orders',
headers={
'Authorization': 'Bearer epd_test_sk_xxxx',
'EPD-Version': '2026-02-11',
'X-EPD-Idempotency-Key': str(uuid.uuid4()),
},
json={
'customer_id': '550e8400-e29b-41d4-a716-446655440000',
'payment_method_id': '6ba7b815-9dad-11d1-80b4-00c04fd430c8',
'items': [
{'product_id': '6ba7b810-9dad-11d1-80b4-00c04fd430d1', 'quantity': 2},
],
'currency': 'usd',
}
)
order = response.json()
print(order['status']) # "succeeded" or "failed" $ch = curl_init('https://api.epd.com/v1/orders');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer epd_test_sk_xxxx',
'Content-Type: application/json',
'EPD-Version: 2026-02-11',
'X-EPD-Idempotency-Key: ' . wp_generate_uuid4(),
],
CURLOPT_POSTFIELDS => json_encode([
'customer_id' => '550e8400-e29b-41d4-a716-446655440000',
'payment_method_id' => '6ba7b815-9dad-11d1-80b4-00c04fd430c8',
'items' => [
['product_id' => '6ba7b810-9dad-11d1-80b4-00c04fd430d1', 'quantity' => 2],
],
'currency' => 'usd',
]),
]);
$order = json_decode(curl_exec($ch), true);
echo $order['status']; // "succeeded" or "failed" Responses
string"6ba7b811-9dad-11d1-80b4-00c04fd430c8"string"1A2B3C4D"string"550e8400-e29b-41d4-a716-446655440002"enumpendingsucceededfailedvoidedpartially_refundedrefundedrefund_failedchargebackchargeback_acceptedchargeback_dismissed"succeeded"array[OrderItem]integer5998integer600integer5398string"usd"stringobjectstring (uuid)"6ba7b820-9dad-11d1-80b4-00c04fd430c8"string"SAVE10"string"Holiday Promo"enumgeneratedpromo"promo"number10integernullinteger500string"usd"enumoncerepeatingforever"once"integernullinteger600objectstring"6ba7b815-9dad-11d1-80b4-00c04fd430d3"string"4242"string"visa"array[OrderTransaction]objectstring (uuid)stringstringstringstringstringstringstringstringstringMetadatastringstring (date-time)"2024-01-15T10:30:00.000Z"string (date-time)"2024-01-15T10:30:00.000Z"objectenuminvalid_request_errorauthentication_errorauthorization_errorrate_limit_erroridempotency_errorprocessing_errorwebhook_errorstring"validation_error"string"Request validation failed"string"email"string"req_a1b2c3d4e5f67890abcdef0123456789"array[object]objectenuminvalid_request_errorauthentication_errorauthorization_errorrate_limit_erroridempotency_errorprocessing_errorwebhook_errorstring"validation_error"string"Request validation failed"string"email"string"req_a1b2c3d4e5f67890abcdef0123456789"array[object]objectenuminvalid_request_errorauthentication_errorauthorization_errorrate_limit_erroridempotency_errorprocessing_errorwebhook_errorstring"validation_error"string"Request validation failed"string"email"string"req_a1b2c3d4e5f67890abcdef0123456789"array[object]objectenuminvalid_request_errorauthentication_errorauthorization_errorrate_limit_erroridempotency_errorprocessing_errorwebhook_errorstring"validation_error"string"Request validation failed"string"email"string"req_a1b2c3d4e5f67890abcdef0123456789"array[object]/orders List all orders
Returns a paginated list of orders sorted by creation date (newest first). Supports filtering by customer, status, date range, and amount range.
Common Queries
| Use Case | Query |
|---|---|
| All successful orders | ?status=succeeded |
| Orders for a customer | ?customer_id=550e8400-e29b-41d4-a716-446655440000 |
| Orders this month | ?created_at[gte]=2024-02-01&created_at[lt]=2024-03-01 |
| High-value orders | ?total[gte]=10000 (orders $100+) |
| Refunded orders | ?status=refunded,partially_refunded |
Query parameters
integer10string"550e8400-e29b-41d4-a716-446655440000"string"550e8400-e29b-41d4-a716-446655440001"string"created_at[desc]"string"550e8400-e29b-41d4-a716-446655440000"string"succeeded"string"2024-01-01"string"2024-02-01"integer1000integer100000string"customer"string"id,status,total,created"Header parameters
string"2026-02-11"Code samples
# All successful orders this month
curl "https://api.epd.com/v1/orders?status=succeeded&created_at[gte]=2024-02-01" \
-H "Authorization: Bearer epd_test_sk_xxxx"
# Orders for a specific customer
curl "https://api.epd.com/v1/orders?customer_id=550e8400-e29b-41d4-a716-446655440000&limit=50" \
-H "Authorization: Bearer epd_test_sk_xxxx" // List successful orders with expanded customer
const params = new URLSearchParams({
status: 'succeeded',
'created_at[gte]': '2024-02-01',
expand: 'customer',
limit: '50',
});
const response = await fetch(
`https://api.epd.com/v1/orders?${params}`,
{ headers: { 'Authorization': 'Bearer epd_test_sk_xxxx' } }
);
const { data: orders, has_more } = await response.json(); Responses
array[Order]any"/v1/orders"objectenuminvalid_request_errorauthentication_errorauthorization_errorrate_limit_erroridempotency_errorprocessing_errorwebhook_errorstring"validation_error"string"Request validation failed"string"email"string"req_a1b2c3d4e5f67890abcdef0123456789"array[object]/orders/{id} Retrieve an order
Retrieves the full details of an order including line items, payment method, and transaction history. Use expand to include the customer object inline.
Path parameters
string"6ba7b811-9dad-11d1-80b4-00c04fd430c8"Query parameters
stringHeader parameters
string"2026-02-11"Code samples
curl https://api.epd.com/v1/orders/6ba7b811-9dad-11d1-80b4-00c04fd430c8 \
-H "Authorization: Bearer epd_test_sk_xxxx" const response = await fetch(
'https://api.epd.com/v1/orders/6ba7b811-9dad-11d1-80b4-00c04fd430c8?expand=customer',
{ headers: { 'Authorization': 'Bearer epd_test_sk_xxxx' } }
);
const order = await response.json();
console.log(order.status); // "succeeded"
console.log(order.total / 100); // 59.98 Responses
string"6ba7b811-9dad-11d1-80b4-00c04fd430c8"string"1A2B3C4D"string"550e8400-e29b-41d4-a716-446655440002"enumpendingsucceededfailedvoidedpartially_refundedrefundedrefund_failedchargebackchargeback_acceptedchargeback_dismissed"succeeded"array[OrderItem]integer5998integer600integer5398string"usd"stringobjectstring (uuid)"6ba7b820-9dad-11d1-80b4-00c04fd430c8"string"SAVE10"string"Holiday Promo"enumgeneratedpromo"promo"number10integernullinteger500string"usd"enumoncerepeatingforever"once"integernullinteger600objectstring"6ba7b815-9dad-11d1-80b4-00c04fd430d3"string"4242"string"visa"array[OrderTransaction]objectstring (uuid)stringstringstringstringstringstringstringstringstringMetadatastringstring (date-time)"2024-01-15T10:30:00.000Z"string (date-time)"2024-01-15T10:30:00.000Z"objectenuminvalid_request_errorauthentication_errorauthorization_errorrate_limit_erroridempotency_errorprocessing_errorwebhook_errorstring"validation_error"string"Request validation failed"string"email"string"req_a1b2c3d4e5f67890abcdef0123456789"array[object]/orders/{id}/refund Refund an order
Processes a refund for an order through the EPD Gateway. Supports both full and partial refunds.
Refund Types
| Type | How | Result |
|---|---|---|
| Full refund | Omit amount |
Refunds entire remaining balance, status → refunded |
| Partial refund | Provide amount in cents |
Refunds specified amount, status → partially_refunded |
Multiple Partial Refunds
You can issue multiple partial refunds on the same order. The total of all refunds cannot exceed the original order amount.
Eligible Orders
Only orders with status succeeded or partially_refunded can be refunded. Attempting to refund an order in any other status returns a 400 error.
Tip: The response includes the full order with an updated
transactionsarray showing the refund transaction. Checktransactionsfor the refund'sprocessor_transaction_idfor reconciliation.
Path parameters
string"6ba7b811-9dad-11d1-80b4-00c04fd430c8"Header parameters
string"2026-02-11"string (uuid)"550e8400-e29b-41d4-a716-446655440000"Request body
integer2999Code samples
# Full refund
curl -X POST https://api.epd.com/v1/orders/6ba7b811-9dad-11d1-80b4-00c04fd430c8/refund \
-H "Authorization: Bearer epd_test_sk_xxxx" \
-H "Content-Type: application/json" \
-H "EPD-Version: 2026-02-11" \
-H "X-EPD-Idempotency-Key: $(uuidgen)"
# Partial refund ($29.99)
curl -X POST https://api.epd.com/v1/orders/6ba7b811-9dad-11d1-80b4-00c04fd430c8/refund \
-H "Authorization: Bearer epd_test_sk_xxxx" \
-H "Content-Type: application/json" \
-H "EPD-Version: 2026-02-11" \
-H "X-EPD-Idempotency-Key: $(uuidgen)" \
-d '{ "amount": 2999 }' // Full refund
const response = await fetch('https://api.epd.com/v1/orders/6ba7b811-9dad-11d1-80b4-00c04fd430c8/refund', {
method: 'POST',
headers: {
'Authorization': 'Bearer epd_test_sk_xxxx',
'Content-Type': 'application/json',
'EPD-Version': '2026-02-11',
'X-EPD-Idempotency-Key': crypto.randomUUID(),
},
});
const order = await response.json();
console.log(order.status); // "refunded"
// Partial refund ($29.99)
const partial = await fetch('https://api.epd.com/v1/orders/6ba7b811-9dad-11d1-80b4-00c04fd430d0/refund', {
method: 'POST',
headers: {
'Authorization': 'Bearer epd_test_sk_xxxx',
'Content-Type': 'application/json',
'X-EPD-Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({ amount: 2999 }),
}); import uuid
import requests
# Full refund
response = requests.post(
'https://api.epd.com/v1/orders/6ba7b811-9dad-11d1-80b4-00c04fd430c8/refund',
headers={
'Authorization': 'Bearer epd_test_sk_xxxx',
'EPD-Version': '2026-02-11',
'X-EPD-Idempotency-Key': str(uuid.uuid4()),
}
)
order = response.json()
print(order['status']) # "refunded"
# Partial refund ($29.99)
response = requests.post(
'https://api.epd.com/v1/orders/6ba7b811-9dad-11d1-80b4-00c04fd430d0/refund',
headers={
'Authorization': 'Bearer epd_test_sk_xxxx',
'X-EPD-Idempotency-Key': str(uuid.uuid4()),
},
json={'amount': 2999}
) Responses
string"6ba7b811-9dad-11d1-80b4-00c04fd430c8"string"1A2B3C4D"string"550e8400-e29b-41d4-a716-446655440002"enumpendingsucceededfailedvoidedpartially_refundedrefundedrefund_failedchargebackchargeback_acceptedchargeback_dismissed"succeeded"array[OrderItem]integer5998integer600integer5398string"usd"stringobjectstring (uuid)"6ba7b820-9dad-11d1-80b4-00c04fd430c8"string"SAVE10"string"Holiday Promo"enumgeneratedpromo"promo"number10integernullinteger500string"usd"enumoncerepeatingforever"once"integernullinteger600objectstring"6ba7b815-9dad-11d1-80b4-00c04fd430d3"string"4242"string"visa"array[OrderTransaction]objectstring (uuid)stringstringstringstringstringstringstringstringstringMetadatastringstring (date-time)"2024-01-15T10:30:00.000Z"string (date-time)"2024-01-15T10:30:00.000Z"objectenuminvalid_request_errorauthentication_errorauthorization_errorrate_limit_erroridempotency_errorprocessing_errorwebhook_errorstring"validation_error"string"Request validation failed"string"email"string"req_a1b2c3d4e5f67890abcdef0123456789"array[object]objectenuminvalid_request_errorauthentication_errorauthorization_errorrate_limit_erroridempotency_errorprocessing_errorwebhook_errorstring"validation_error"string"Request validation failed"string"email"string"req_a1b2c3d4e5f67890abcdef0123456789"array[object]objectenuminvalid_request_errorauthentication_errorauthorization_errorrate_limit_erroridempotency_errorprocessing_errorwebhook_errorstring"validation_error"string"Request validation failed"string"email"string"req_a1b2c3d4e5f67890abcdef0123456789"array[object]