This document provides comprehensive documentation for the Commercify e-commerce backend API.
https://api.commercify.com/api
All API endpoints are prefixed with /api unless otherwise specified.
The API uses JWT (JSON Web Token) authentication. Include the token in the Authorization header:
Authorization: Bearer <your-jwt-token>
All API responses follow a consistent format:
{
"success": boolean,
"message": "string (optional)",
"data": object | array | null,
"error": "string (optional)",
"pagination": {
"page": number,
"page_size": number,
"total": number
}
}200 OK: Request successful201 Created: Resource created successfully400 Bad Request: Invalid request data401 Unauthorized: Authentication required403 Forbidden: Insufficient permissions404 Not Found: Resource not found409 Conflict: Resource already exists or conflict500 Internal Server Error: Server error
GET /health
Health check endpoint for load balancers and monitoring.
Response:
{
"status": "healthy",
"timestamp": "2025-07-07T10:30:45Z",
"services": {
"database": "healthy"
}
}POST /api/auth/register
Register a new user account.
Request Body:
{
"email": "user@example.com",
"password": "Password123!",
"first_name": "John",
"last_name": "Smith"
}Response:
{
"success": true,
"data": {
"user": {
"id": 1,
"email": "user@example.com",
"first_name": "John",
"last_name": "Smith",
"role": "user",
"created_at": "2025-07-07T10:30:45Z",
"updated_at": "2025-07-07T10:30:45Z"
},
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "",
"expires_in": 3600
}
}POST /api/auth/signin
Authenticate a user and retrieve a JWT token.
Request Body:
{
"email": "user@example.com",
"password": "Password123!"
}Response:
{
"success": true,
"data": {
"user": {
"id": 1,
"email": "user@example.com",
"first_name": "John",
"last_name": "Smith",
"role": "user",
"created_at": "2025-07-07T10:30:45Z",
"updated_at": "2025-07-07T10:30:45Z"
},
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "",
"expires_in": 3600
}
}GET /api/products/{productId}
Get a product by ID.
Response:
{
"success": true,
"data": {
"id": 1,
"name": "Product Name",
"description": "Product description",
"currency": "USD",
"price": 99.99,
"sku": "PROD-001",
"total_stock": 100,
"category": "Electronics",
"category_id": 1,
"images": ["https://example.com/image1.jpg"],
"has_variants": true,
"active": true,
"variants": [
{
"id": 1,
"product_id": 1,
"variant_name": "Size L",
"sku": "PROD-001-L",
"stock": 50,
"attributes": {
"size": "L",
"color": "blue"
},
"images": ["https://example.com/variant1.jpg"],
"is_default": true,
"weight": 0.5,
"price": 99.99,
"currency": "USD",
"created_at": "2025-07-07T10:30:45Z",
"updated_at": "2025-07-07T10:30:45Z"
}
],
"created_at": "2025-07-07T10:30:45Z",
"updated_at": "2025-07-07T10:30:45Z"
}
}GET /api/products/search
Search for products with optional filters.
Query Parameters:
query(string, optional): Search termcategory_id(number, optional): Filter by category IDmin_price(number, optional): Minimum price filtermax_price(number, optional): Maximum price filtercurrency(string, optional): Currency codeactive_only(boolean, optional): Show only active productspage(number, optional): Page number (default: 1)page_size(number, optional): Items per page (default: 10)
GET /api/categories
Get all categories.
GET /api/categories/{id}
Get a category by ID.
GET /api/categories/{id}/children
Get child categories of a parent category.
GET /api/payment/providers
Get available payment providers.
POST /api/discounts/validate
Validate a discount code.
Request Body:
{
"discount_code": "SUMMER2025"
}GET /api/currencies
Get all enabled currencies.
GET /api/currencies/default
Get the default currency.
POST /api/currencies/convert
Convert amount between currencies.
Request Body:
{
"amount": 100.0,
"from_currency": "USD",
"to_currency": "EUR"
}POST /api/shipping/options
Calculate available shipping options.
Request Body:
{
"address": {
"address_line1": "123 Main St",
"address_line2": "",
"city": "New York",
"state": "NY",
"postal_code": "10001",
"country": "US"
},
"order_value": 150.0,
"order_weight": 2.5
}GET /api/checkout
Get current checkout session.
POST /api/checkout/items
Add item to checkout.
Request Body:
{
"sku": "PROD-001-L",
"quantity": 2,
"currency": "USD"
}PUT /api/checkout/items/{sku}
Update checkout item quantity.
Request Body:
{
"quantity": 3
}DELETE /api/checkout/items/{sku}
Remove item from checkout.
DELETE /api/checkout
Clear entire checkout.
PUT /api/checkout/shipping-address
Set checkout shipping address.
Request Body:
{
"address_line1": "123 Main St",
"address_line2": "Apt 4B",
"city": "New York",
"state": "NY",
"postal_code": "10001",
"country": "US"
}PUT /api/checkout/billing-address
Set checkout billing address.
PUT /api/checkout/customer-details
Set customer information.
Request Body:
{
"email": "customer@example.com",
"phone": "+1234567890",
"full_name": "John Smith"
}PUT /api/checkout/shipping-method
Set shipping method.
Request Body:
{
"shipping_method_id": 1
}PUT /api/checkout/currency
Set checkout currency.
Request Body:
{
"currency": "EUR"
}POST /api/checkout/discount
Apply discount code to checkout.
Request Body:
{
"discount_code": "SUMMER2025"
}DELETE /api/checkout/discount
Remove applied discount from checkout.
POST /api/checkout/complete
Complete checkout and create order.
Request Body:
{
"payment_provider": "stripe",
"payment_data": {
"card_details": {
"card_number": "4242424242424242",
"expiry_month": 12,
"expiry_year": 2025,
"cvv": "123",
"cardholder_name": "John Smith"
}
}
}GET /api/users/me
Get authenticated user's profile.
PUT /api/users/me
Update authenticated user's profile.
Request Body:
{
"first_name": "John",
"last_name": "Smith"
}PUT /api/users/me/password
Change user password.
Request Body:
{
"current_password": "oldPassword123!",
"new_password": "newPassword123!"
}GET /api/orders
List orders for authenticated user.
Query Parameters:
page(number, optional): Page numberpageSize(number, optional): Items per page
GET /api/orders/{orderId}
Get order by ID (accessible by order owner or via checkout session).
All admin endpoints require authentication and admin role.
GET /api/admin/users
List all users (admin only).
Query Parameters:
page(number, optional): Page numberpage_size(number, optional): Items per page
GET /api/admin/orders
List all orders (admin only).
Query Parameters:
page(number, optional): Page numberpageSize(number, optional): Items per pagestatus(string, optional): Filter by order status
PUT /api/admin/orders/{orderId}/status
Update order status (admin only).
Request Body:
{
"status": "shipped"
}Response Body:
{
"id": 1,
"order_number": "ORD-001",
"currency": "USD",
"user_id": 1,
"total_amount": 9999,
"status": "shipped",
"payment_status": "captured",
"created_at": "2025-07-10T10:00:00Z",
"updated_at": "2025-07-10T11:00:00Z"
}Status Codes:
200 OK: Order status updated successfully400 Bad Request: Invalid request body or status401 Unauthorized: Not authenticated403 Forbidden: Not authorized (not an admin)404 Not Found: Order not found
Valid Order Statuses:
pending: Order is pendingpaid: Order has been paidshipped: Order has been shipped (triggers shipment email)cancelled: Order has been cancelledcompleted: Order is completed
PUT /api/admin/orders/{orderId}/status-with-tracking
Update order status with optional tracking information (admin only). When updating status to "shipped" with tracking information, an enhanced shipment email will be sent to the customer.
Request Body:
{
"status": "shipped",
"tracking_number": "1Z999AA1234567890",
"tracking_url": "https://www.ups.com/track?loc=en_US&tracknum=1Z999AA1234567890"
}Response Body:
{
"id": 1,
"order_number": "ORD-001",
"currency": "USD",
"user_id": 1,
"total_amount": 9999,
"status": "shipped",
"payment_status": "captured",
"created_at": "2025-07-10T10:00:00Z",
"updated_at": "2025-07-10T11:00:00Z"
}Status Codes:
200 OK: Order status updated successfully400 Bad Request: Invalid request body or status401 Unauthorized: Not authenticated403 Forbidden: Not authorized (not an admin)404 Not Found: Order not found
Note: When an order status is changed to "shipped", an email notification is automatically sent to the customer. If tracking information is provided, it will be included in the email with a tracking link.
GET /api/admin/checkouts
List all checkouts (admin only).
GET /api/admin/checkouts/{checkoutId}
Get checkout by ID (admin only).
DELETE /api/admin/checkouts/{checkoutId}
Delete checkout (admin only).
GET /api/admin/currencies/all
List all currencies including disabled ones (admin only).
POST /api/admin/currencies
Create new currency (admin only).
Request Body:
{
"code": "EUR",
"name": "Euro",
"symbol": "€",
"exchange_rate": 0.85,
"is_enabled": true,
"is_default": false
}PUT /api/admin/currencies
Update currency (admin only).
DELETE /api/admin/currencies
Delete currency (admin only).
PUT /api/admin/currencies/default
Set default currency (admin only).
POST /api/admin/categories
Create new category (admin only).
Request Body:
{
"name": "Electronics",
"description": "Electronic devices and accessories",
"parent_id": 1
}PUT /api/admin/categories/{id}
Update category (admin only).
DELETE /api/admin/categories/{id}
Delete category (admin only).
Status Codes:
200 OK: Category deleted successfully400 Bad Request: Cannot delete category with child categories or products401 Unauthorized: Not authenticated403 Forbidden: Not authorized (not an admin)404 Not Found: Category not found500 Internal Server Error: Server error
GET /api/admin/products
List all products (admin only).
Query Parameters:
page(number, optional): Page numberpage_size(number, optional): Items per pagequery(string, optional): Search termcategory_id(number, optional): Filter by categorymin_price(number, optional): Minimum pricemax_price(number, optional): Maximum pricecurrency(string, optional): Currency codeactive_only(boolean, optional): Show only active products
POST /api/admin/products
Create new product (admin only).
Request Body:
{
"name": "Product Name",
"description": "Product description",
"currency": "USD",
"category_id": 1,
"images": ["https://example.com/image1.jpg"],
"active": true,
"variants": [
{
"sku": "PROD-001-L",
"stock": 100,
"attributes": [
{ "name": "size", "value": "L" },
{ "name": "color", "value": "blue" }
],
"images": ["https://example.com/variant1.jpg"],
"is_default": true,
"weight": 0.5,
"price": 99.99
}
]
}PUT /api/admin/products/{productId}
Update product (admin only).
DELETE /api/admin/products/{productId}
Delete product (admin only).
POST /api/admin/products/{productId}/variants
Add variant to product (admin only).
PUT /api/admin/products/{productId}/variants/{variantId}
Update product variant (admin only).
DELETE /api/admin/products/{productId}/variants/{variantId}
Delete product variant (admin only).
POST /api/admin/shipping/methods
Create new shipping method (admin only).
Request Body:
{
"name": "Standard Shipping",
"description": "5-7 business days",
"estimated_delivery_days": 7
}POST /api/admin/shipping/zones
Create new shipping zone (admin only).
Request Body:
{
"name": "US Zone",
"description": "United States shipping zone",
"countries": ["US"],
"states": ["NY", "CA", "TX"],
"zip_codes": ["10001", "90210"]
}POST /api/admin/shipping/rates
Create new shipping rate (admin only).
Request Body:
{
"shipping_method_id": 1,
"shipping_zone_id": 1,
"base_rate": 9.99,
"min_order_value": 0,
"free_shipping_threshold": 100.0,
"active": true
}POST /api/admin/shipping/rates/weight
Create weight-based shipping rate (admin only).
Request Body:
{
"shipping_rate_id": 1,
"min_weight": 0,
"max_weight": 5.0,
"rate": 5.99
}POST /api/admin/shipping/rates/value
Create value-based shipping rate (admin only).
Request Body:
{
"shipping_rate_id": 1,
"min_order_value": 0,
"max_order_value": 50.0,
"rate": 9.99
}POST /api/admin/discounts
Create new discount (admin only).
Request Body:
{
"code": "SUMMER2025",
"type": "basket",
"method": "percentage",
"value": 15.0,
"min_order_value": 50.0,
"max_discount_value": 30.0,
"product_ids": [],
"category_ids": [],
"start_date": "2025-05-01T00:00:00Z",
"end_date": "2025-08-31T23:59:59Z",
"usage_limit": 500
}GET /api/admin/discounts/{discountId}
Get discount by ID (admin only).
PUT /api/admin/discounts/{discountId}
Update discount (admin only).
DELETE /api/admin/discounts/{discountId}
Delete discount (admin only).
GET /api/admin/discounts
List all discounts (admin only).
GET /api/admin/discounts/active
List active discounts (admin only).
POST /api/admin/discounts/apply/{orderId}
Apply discount to order (admin only).
DELETE /api/admin/discounts/remove/{orderId}
Remove discount from order (admin only).
POST /api/admin/payments/{paymentId}/capture
Capture authorized payment (admin only).
POST /api/admin/payments/{paymentId}/cancel
Cancel payment (admin only).
POST /api/admin/payments/{paymentId}/refund
Refund payment (admin only).
POST /api/admin/payments/{paymentId}/force-approve
Force approve MobilePay payment (admin only).
GET /api/admin/payment-providers
Get all payment providers (admin only).
GET /api/admin/payment-providers/enabled
Get enabled payment providers (admin only).
PUT /api/admin/payment-providers/{providerType}/enable
Enable/disable payment provider (admin only).
Request Body:
{
"enabled": true
}PUT /api/admin/payment-providers/{providerType}/configuration
Update payment provider configuration (admin only).
POST /api/admin/payment-providers/{providerType}/webhook
Register webhook for payment provider (admin only).
DELETE /api/admin/payment-providers/{providerType}/webhook
Delete webhook for payment provider (admin only).
GET /api/admin/payment-providers/{providerType}/webhook
Get webhook information for payment provider (admin only).
POST /api/admin/test/email
Send test order confirmation and notification emails to a specified email address (admin only).
Request Body:
{
"email": "test@example.com"
}Query Parameters:
email(optional): Email address to send test emails to. Can be provided as query parameter instead of request body.
Response Body (Success):
{
"success": true,
"message": "Both order confirmation and notification emails sent successfully",
"details": {
"target_email": "test@example.com",
"order_id": "12345"
}
}Response Body (Error):
{
"success": false,
"errors": ["Invalid email format"]
}Status Codes:
200 OK: Test emails sent successfully400 Bad Request: Invalid email format401 Unauthorized: Not authenticated403 Forbidden: Not authorized (not an admin)500 Internal Server Error: Failed to send one or more emails
POST /api/webhooks/stripe
Stripe webhook endpoint for payment events.
POST /api/webhooks/mobilepay
MobilePay webhook endpoint for payment events.
All error responses follow this format:
{
"success": false,
"error": "Error message describing what went wrong"
}Common error scenarios:
- Authentication required (401)
- Insufficient permissions (403)
- Resource not found (404)
- Validation errors (400)
- Server errors (500)