PyCommerce API Documentation

Welcome to the PyCommerce API documentation. This documentation provides information about the available endpoints and how to interact with the PyCommerce platform programmatically.

Overview

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.

Authentication

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.

Endpoints

GET /api/health

Check if the API is operational. This endpoint does not require authentication.

Response

{
  "status": "ok",
  "version": "1.0.0",
  "message": "PyCommerce API is running"
}
POST /stripe-demo/create-checkout-session-json

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.

Request Body

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

Example Request

{
  "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"
}

Response

{
  "checkout_url": "https://checkout.stripe.com/pay/cs_test_a1b2c3...",
  "session_id": "cs_test_a1b2c3..."
}

Error Response

{
  "error": "Detailed error message describing the issue"
}

Client-Side Implementation Example

// 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 /api/tenants

Get a list of all tenants in the system.

Response

{
  "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 /api/products

Get products for a specific tenant with optional filtering.

Parameters

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

Response

{
  "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 /api/orders

Get orders for a specific tenant with optional filtering.

Parameters

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

Response

{
  "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 /api/orders/{order_id}

Get details of a specific order.

Path Parameters

Name Type Description Required
order_id string The ID of the order to retrieve Yes

Response

{
  "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"
}
POST /api/orders

Create a new order.

Request Body

{
  "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"
}

Response

{
  "id": "e8f9a0b1-c2d3-4e4f-9a5b-6c7d8e9f0a1b",
  "status": "pending",
  "message": "Order created successfully"
}
GET /api/categories

Get categories for a specific tenant.

Parameters

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

Response

{
  "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
}

Errors

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 Response Format

{
  "error": {
    "code": "resource_not_found",
    "message": "The requested resource was not found.",
    "details": "Order with ID '12345' does not exist."
  }
}

Examples

Retrieving Products

curl -X GET \
  'https://api.pycommerce.org/api/products?tenant=tech&category=Audio' \
  -H 'Authorization: Bearer YOUR_JWT_TOKEN'

Creating an Order

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"
  }'