Manage orders and charge payments programmatically through the Spark CRM REST API.
The order lifecycle is split into distinct steps:
- Create an order — records the customer, campaign, and products. No payment is attempted.
- Create a transaction — attempts the payment immediately against an existing order.
- Complete the order — fires the normal completion logic, including any applicable auto responders.
Authentication
All endpoints require a Bearer token and return JSON. See API Tokens.
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"| Endpoint | Method | Permission |
|---|---|---|
| List orders | GET /v1/orders |
api:orders.view_any |
| Retrieve order | GET /v1/orders/{order_number} |
api:orders.view |
| Create order | POST /v1/orders |
api:orders.create |
| Update order | PATCH /v1/orders/{order_number} |
api:orders.update |
| Merge custom fields | PATCH /v1/orders/{order_number}/custom-fields |
api:orders.update |
| Complete order | POST /v1/orders/{order_number}/complete |
api:orders.complete |
| Create transaction | POST /v1/transactions |
api:transactions.create |
Create an Order
Creates an order in pending status. No payment is attempted — use the transactions endpoint to charge it.
POST /v1/ordersRequest:
curl -X POST "https://api.sparkcrm.io/v1/orders" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"campaign_id": "1024",
"currency": "USD",
"customer": {
"email": "customer@example.com",
"first_name": "Jane",
"last_name": "Doe",
"phone": "+15551234567"
},
"shipping": {
"address1": "123 Main St",
"city": "Austin",
"state": "TX",
"postal_code": "78701",
"country": "US"
},
"products": [
{ "offer_id": "5001", "quantity": 2 }
]
}'campaign_idandoffer_idare the campaign’s / offer’sinternal_id.shippingis optional; when omitted the order is flagged for QA until an address is provided.
Response (201 Created):
{
"success": true,
"message": "Order created successfully",
"data": {
"order_number": "ORD-260708-00042",
"campaign_id": 1024,
"status": "pending",
"currency": "USD",
"cart": {
"items": [
{ "id": 5001, "type": "offer", "quantity": 2, "unit_price": "49.00", "subtotal": 98 }
],
"subtotal": "98.00",
"shipping": "0.00",
"tax": "0.00",
"total": "98.00"
}
}
}Only the cart-level subtotal, shipping, tax, and total are returned as fixed 2-decimal strings. Item-level money is returned as-stored: unit_price and shipping_price are decimal strings, subtotal and tax are JSON numbers.
Retrieve an Order
GET /v1/orders/{order_number}Request:
curl -X GET "https://api.sparkcrm.io/v1/orders/ORD-260708-00042" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Response (200 OK):
{
"success": true,
"data": {
"order_number": "ORD-260708-00042",
"status": "pending",
"currency": "USD",
"cart": { "total": "98.00" },
"transactions": []
}
}To list orders, call GET /v1/orders with optional status, customer_id, campaign_id, date_from, date_to, search, and per_page filters. The response includes a pagination object.
Update an Order
Updates an order while it has not settled (e.g. pending). Once an order is paid or otherwise settled — completed, processing, refunded, voided, canceled, or in dispute — PATCH /v1/orders/{order_number} is rejected in full with 422 Order can no longer be edited; no field is applied, including custom_fields, utm_*, and affiliate. Custom fields can still be merged on a settled order via PATCH /v1/orders/{order_number}/custom-fields.
PATCH /v1/orders/{order_number}Request:
curl -X PATCH "https://api.sparkcrm.io/v1/orders/ORD-260708-00042" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"products": [
{ "offer_id": "5001", "quantity": 3 }
],
"custom_fields": { "source": "phone" }
}'Response (200 OK):
{
"success": true,
"message": "Order updated successfully",
"data": {
"order_number": "ORD-260708-00042",
"status": "pending",
"cart": { "total": "147.00" }
}
}Create a Transaction (charge)
Creating a transaction attempts the payment immediately — it is not a draft. The charge follows the campaign’s configured payment routing: its payment orchestrator when one is assigned (the orchestrator picks the MID), otherwise its default gateway. A gateway_id override takes precedence over both. A campaign with neither an orchestrator nor a default gateway returns 422 Configuration Error with errors.no_gateway_available set to No payment gateway available for this order.
The order’s payment status is reflected (processing on an approved sale, declined on failure), but the order is not completed here. Completion and auto responders are handled by the complete endpoint.
POST /v1/transactionsRequest:
curl -X POST "https://api.sparkcrm.io/v1/transactions" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"order_number": "ORD-260708-00042",
"payment": {
"method": "card",
"card_number": "4111111111111111",
"card_exp_month": "12",
"card_exp_year": "2030",
"card_cvv": "123"
}
}'amountis optional; it defaults to the order’s cart total.gateway_id(optional) overrides the campaign’s payment routing — both its orchestrator and its default gateway — with an active gateway’sinternal_id. An unknown or inactive gateway returns422.
Response (201 Created, approved):
{
"success": true,
"message": "Transaction processed successfully",
"data": {
"transaction_number": "TXN-260708-000173",
"status": "completed",
"amount": "147.00",
"currency": "USD",
"gateway_id": 12,
"gateway_name": "Primary Gateway",
"card_brand": "visa",
"card_last_four": "1111"
}
}Response (201 Created, declined):
{
"success": false,
"message": "Transaction was not approved",
"data": {
"transaction_number": "TXN-260708-000174",
"status": "declined",
"gateway_response": "Insufficient Funds"
}
}Complete an Order
Marks the order as completed and fires the normal completion logic, including any applicable auto responders (order confirmation emails), fulfillment, affiliate postbacks, and outbound webhooks. The call is idempotent.
POST /v1/orders/{order_number}/completeRequest:
curl -X POST "https://api.sparkcrm.io/v1/orders/ORD-260708-00042/complete" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Response (200 OK):
{
"success": true,
"message": "Order marked as completed successfully",
"data": {
"order_number": "ORD-260708-00042",
"status": "completed"
}
}Related Topics
- API Tokens - Authentication and permissions
- Coupons - Discount codes applied to orders
- Webhooks - Event notifications on order completion

