POST
/payment
Create a payment session
Creates a payment request for the current tenant and stores a pending order row for later webhook updates.
Headers
| Header | Required | Notes |
|---|---|---|
X-Tenant-ID | required | Tenant that owns the payment |
Content-Type | required | application/json |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
packageId | number | required | Credit package to purchase |
customerName | string | optional | Customer display name |
customerEmail | string | optional | Customer email address |
Example Request
POST /payment
Content-Type: application/json
X-Tenant-ID: TENANT_ABC
{
"packageId": 4,
"customerName": "Test Customer",
"customerEmail": "customer@example.com"
}
Responses
// 200 OK
{
"data": {
"paymentId": 32,
"redirectUrl": "https://..."
}
}
Response format
| Field | Type | Notes |
|---|---|---|
data.paymentId | number | Internal payment reference |
data.redirectUrl | string | Checkout redirect URL |
POST
/payment/webhook
Receive payment webhook events
Receives payment status updates from the provider and updates the matching order row.
Headers
| Header | Required | Notes |
|---|---|---|
Content-Type | required | application/json |
Payload
| Field | Type | Required | Description |
|---|---|---|---|
event | string | required | Webhook event name |
payment | object | required | Payment details from the provider |
original | object | optional | Original provider payload |
Example Payload
{
"event": "payment.succeeded",
"payment": {
"id": 123,
"externalId": "ORD-123",
"tenantId": "TENANT_ABC",
"status": "succeeded",
"amount": 157.5,
"currency": "ZAR"
}
}
Persistence
CREATE TABLE IF NOT EXISTS orders (
id INT AUTO_INCREMENT PRIMARY KEY,
tenant_id VARCHAR(100) NOT NULL,
order_id VARCHAR(255) NOT NULL,
payment_id INT NULL,
status VARCHAR(50) NOT NULL DEFAULT 'pending',
amount DECIMAL(10,2) NOT NULL DEFAULT 0.00,
currency CHAR(3) NOT NULL DEFAULT 'ZAR',
metadata JSON NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uq_order (tenant_id, order_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS orders_webhook (
id INT AUTO_INCREMENT PRIMARY KEY,
tenant_id VARCHAR(100) NULL,
event VARCHAR(100) NULL,
status VARCHAR(50) NULL,
message TEXT NOT NULL,
errors TEXT NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Response format
| Field | Type | Notes |
|---|---|---|
data | object | Webhook acknowledgement payload |
data.message | string | Status message |