Welcome to the PyCommerce API documentation. This documentation provides information about the available endpoints and how to interact with the PyCommerce platform programmatically.
The PyCommerce API is organized around REST principles. It accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.
All API requests must be made over HTTPS. Calls made over plain HTTP will be rejected.
The PyCommerce API uses JWT bearer tokens for authentication. To authenticate an API request, you should provide your API key in the Authorization header.
Authorization: Bearer YOUR_JWT_TOKEN
You can obtain a JWT token by authenticating through the /api/auth/login endpoint.
Check if the API is operational. This endpoint does not require authentication.
{
"status": "ok",
"version": "1.0.0",
"message": "PyCommerce API is running"
}
Create a Stripe checkout session and return a JSON response with the checkout URL. This endpoint is designed for client-side JavaScript applications using fetch API and resolves browser content decoding issues that could occur with form submissions.
| Name | Type | Description | Required |
|---|---|---|---|
| items | array | Array of items to be purchased, including id, name, price, and quantity | Yes |
| order_id | string | Unique identifier for the order | Yes |
{
"items": [
{
"id": "prod_1",
"name": "Premium Headphones",
"price": 149.99,
"quantity": 1
},
{
"id": "prod_2",
"name": "Wireless Speaker",
"price": 79.99,
"quantity": 2
}
],
"order_id": "order-123-abc"
}
{
"checkout_url": "https://checkout.stripe.com/pay/cs_test_a1b2c3...",
"session_id": "cs_test_a1b2c3..."
}
{
"error": "Detailed error message describing the issue"
}
// JavaScript fetch implementation
async function handleCheckout() {
try {
const response = await fetch('/stripe-demo/create-checkout-session-json', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
items: cartItems,
order_id: orderId
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.error || 'Unknown error');
}
const data = await response.json();
// Redirect to Stripe checkout page in a new tab
if (data.checkout_url) {
window.open(data.checkout_url, '_blank');
}
} catch (error) {
console.error('Checkout error:', error);
}
}
Get a list of all tenants in the system.
{
"tenants": [
{
"id": "ea6c4bc0-d5aa-4f5c-b769-c51c812a5037",
"name": "Tech Gadgets",
"slug": "tech",
"domain": "tech.pycommerce.org",
"active": true
},
{
"id": "f8a7b6c5-e4d3-4c2b-a1b0-9f8e7d6c5b4a",
"name": "Outdoor Adventures",
"slug": "outdoor",
"domain": "outdoor.pycommerce.org",
"active": true
}
],
"count": 2
}
Get products for a specific tenant with optional filtering.
| Name | Type | Description | Required |
|---|---|---|---|
| tenant | string | The tenant slug (e.g., "tech", "outdoor") | Yes |
| category | string | Filter products by category | No |
| min_price | number | Filter products by minimum price | No |
| max_price | number | Filter products by maximum price | No |
| in_stock | boolean | Filter products by stock availability | No |
{
"products": [
{
"id": "b5c6d7e8-f9a0-4b1c-8d2e-3f4a5b6c7d8e",
"name": "Wireless Headphones",
"description": "Premium wireless headphones with noise cancellation",
"price": 129.99,
"sku": "WH-001",
"stock": 25,
"categories": ["Electronics", "Audio"]
},
{
"id": "c6d7e8f9-a0b1-4c2d-8e3f-4a5b6c7d8e9f",
"name": "Bluetooth Speaker",
"description": "Waterproof portable Bluetooth speaker",
"price": 79.99,
"sku": "BS-002",
"stock": 42,
"categories": ["Electronics", "Audio"]
}
],
"tenant": "tech",
"count": 2,
"filters": {
"category": "Audio",
"min_price": null,
"max_price": null,
"in_stock": true
}
}
Get orders for a specific tenant with optional filtering.
| Name | Type | Description | Required |
|---|---|---|---|
| tenant | string | The tenant slug (e.g., "tech", "outdoor") | Yes |
| status | string | Filter orders by status (e.g., "pending", "completed") | No |
| customer_id | string | Filter orders by customer ID | No |
{
"orders": [
{
"id": "d7e8f9a0-b1c2-4d3e-8f4a-5b6c7d8e9f0a",
"customer_name": "Jane Smith",
"customer_email": "jane.smith@example.com",
"status": "completed",
"total": 209.98,
"created_at": "2025-03-15T10:30:00Z",
"items_count": 2,
"shipping_method": "standard"
},
{
"id": "e8f9a0b1-c2d3-4e4f-9a5b-6c7d8e9f0a1b",
"customer_name": "John Doe",
"customer_email": "john.doe@example.com",
"status": "pending",
"total": 129.99,
"created_at": "2025-03-16T14:45:00Z",
"items_count": 1,
"shipping_method": "express"
}
],
"tenant": "tech",
"count": 2,
"filters": {
"status": null,
"customer_id": null
}
}
Get details of a specific order.
| Name | Type | Description | Required |
|---|---|---|---|
| order_id | string | The ID of the order to retrieve | Yes |
{
"id": "d7e8f9a0-b1c2-4d3e-8f4a-5b6c7d8e9f0a",
"customer": {
"id": "f9a0b1c2-d3e4-4f5a-9b6c-7d8e9f0a1b2c",
"name": "Jane Smith",
"email": "jane.smith@example.com",
"phone": "+1234567890"
},
"status": "completed",
"total": 209.98,
"subtotal": 189.98,
"tax": 10.00,
"shipping_cost": 10.00,
"created_at": "2025-03-15T10:30:00Z",
"updated_at": "2025-03-15T14:20:00Z",
"shipping_address": {
"line1": "123 Main St",
"line2": "Apt 4B",
"city": "Metropolis",
"state": "NY",
"postal_code": "10001",
"country": "USA"
},
"billing_address": {
"line1": "123 Main St",
"line2": "Apt 4B",
"city": "Metropolis",
"state": "NY",
"postal_code": "10001",
"country": "USA"
},
"shipping_method": "standard",
"payment_method": "credit_card",
"payment_status": "paid",
"notes": "Please leave at front door",
"items": [
{
"id": "a0b1c2d3-e4f5-4a6b-9c7d-8e9f0a1b2c3d",
"product_id": "b5c6d7e8-f9a0-4b1c-8d2e-3f4a5b6c7d8e",
"name": "Wireless Headphones",
"quantity": 1,
"unit_price": 129.99,
"total_price": 129.99
},
{
"id": "b1c2d3e4-f5a6-4b7c-9d8e-9f0a1b2c3d4e",
"product_id": "c6d7e8f9-a0b1-4c2d-8e3f-4a5b6c7d8e9f",
"name": "Bluetooth Speaker",
"quantity": 1,
"unit_price": 79.99,
"total_price": 79.99
}
],
"tenant_id": "ea6c4bc0-d5aa-4f5c-b769-c51c812a5037"
}
Create a new order.
{
"tenant_id": "ea6c4bc0-d5aa-4f5c-b769-c51c812a5037",
"customer": {
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "+1987654321"
},
"shipping_address": {
"line1": "456 Park Ave",
"line2": "",
"city": "Metropolis",
"state": "NY",
"postal_code": "10002",
"country": "USA"
},
"billing_address": {
"line1": "456 Park Ave",
"line2": "",
"city": "Metropolis",
"state": "NY",
"postal_code": "10002",
"country": "USA"
},
"items": [
{
"product_id": "b5c6d7e8-f9a0-4b1c-8d2e-3f4a5b6c7d8e",
"quantity": 1
}
],
"shipping_method": "express",
"payment_method": "credit_card",
"notes": "Please call before delivery"
}
{
"id": "e8f9a0b1-c2d3-4e4f-9a5b-6c7d8e9f0a1b",
"status": "pending",
"message": "Order created successfully"
}
Get categories for a specific tenant.
| Name | Type | Description | Required |
|---|---|---|---|
| tenant | string | The tenant slug (e.g., "tech", "outdoor") | Yes |
| parent_id | string | Filter categories by parent ID for subcategories | No |
{
"categories": [
{
"id": "a1b2c3d4-e5f6-4a7b-9c8d-9e0f1a2b3c4d",
"name": "Electronics",
"description": "Electronic devices and gadgets",
"slug": "electronics",
"parent_id": null
},
{
"id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Audio",
"description": "Audio devices and accessories",
"slug": "audio",
"parent_id": "a1b2c3d4-e5f6-4a7b-9c8d-9e0f1a2b3c4d"
}
],
"tenant": "tech",
"count": 2
}
The PyCommerce API uses conventional HTTP response codes to indicate the success or failure of an API request. In general, codes in the 2xx range indicate success, codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted), and codes in the 5xx range indicate an error with the PyCommerce servers.
| Code | Description |
|---|---|
| 200 - OK | Everything worked as expected. |
| 201 - Created | A new resource was successfully created. |
| 400 - Bad Request | The request was unacceptable, often due to missing a required parameter. |
| 401 - Unauthorized | No valid API key provided. |
| 403 - Forbidden | The API key doesn't have permissions to perform the request. |
| 404 - Not Found | The requested resource doesn't exist. |
| 409 - Conflict | The request conflicts with another request. |
| 429 - Too Many Requests | Too many requests hit the API too quickly. |
| 500, 502, 503, 504 - Server Errors | Something went wrong on the PyCommerce server. |
{
"error": {
"code": "resource_not_found",
"message": "The requested resource was not found.",
"details": "Order with ID '12345' does not exist."
}
}
curl -X GET \
'https://api.pycommerce.org/api/products?tenant=tech&category=Audio' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN'
curl -X POST \
'https://api.pycommerce.org/api/orders' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"tenant_id": "ea6c4bc0-d5aa-4f5c-b769-c51c812a5037",
"customer": {
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "+1987654321"
},
"shipping_address": {
"line1": "456 Park Ave",
"city": "Metropolis",
"state": "NY",
"postal_code": "10002",
"country": "USA"
},
"items": [
{
"product_id": "b5c6d7e8-f9a0-4b1c-8d2e-3f4a5b6c7d8e",
"quantity": 1
}
],
"shipping_method": "express",
"payment_method": "credit_card"
}'