Checkout Page
Create a secure, customizable checkout page session to capture payments with cards, bank transfers, and other payment methods. Supports 3D Secure authentication, cards storage for recurring billing, order management, customer creation, and webhook notifications.
Request
Request to get a checkout page session with URL
Path
POST /checkout/page
Request Body (Basic example)
Basic example to create a payment link with all the required fields
{
"mode": "ONE_TIME", // RECURRING or SAVE
"amount": "1200.00"
// or create a new order
"order": {
"description": "Monthly plan + setup"
}
}
Request Body (Save card)
Create a link to save the customer's card for future recurring payments or as a backup card. A R2 will be charged to verify that the card is valid.
{
"mode": "SAVE"
// if no customer object or customer_id passed then a form will show on the payment link to create a customer. Add the customer_fields parameter to specify what fields should be captured.
}
Request Body (Advanced example)
Advanced example with all the fields
{
"mode": "ONE_TIME", // RECURRING or SAVE
"amount": "1200.00",
"currency": "ZA",
// [options for order records]
// [option 1: use the order_id of an existing order record]
"order_id": "ord_12345",
// [option 2: use the order.description field to create an order, if no order.reference passed then one will be created]
"order": {
"reference": "ORD0045",
"description": "Monthly plan + setup",
"amount_subtotal": "1100.00",
"amount_discount": "0.00",
"amount_shipping": "0.00",
"amount_tax": "100.00",
"amount_total": "1200.00",
"items": [
{
"sku": "SKU00567",
"name": "Pro Plan (Monthly)",
"quantity": 1,
"unit_amount": "1200.00",
"tax_amount": 0,
"discount_amount": 0,
"currency": "ZA",
"metadata": {
"custom_field_1": "custom data 1",
"custom_field_2": "custom data 2"
}
}
]
},
// [options for customer records]
// [option 1: use the customer_id of an existing customer record]
"customer_id": "cus_abc123...",
// [option 2: if no customer id or customer object is passed then a form will show, here you can specify the fields to capture, name and surname will always show]
"customer_fields": "reference,id_number,email,contact_number,billing,shipping",
// [option 3: create a new customer]
"customer": {
"reference": "CLN240919000001",
"company_name": null,
"person_name": "John",
"person_surname": "Doe",
"client_type": "RESIDENT_INDIVIDUAL", // [optional]
"id_type": "SAID",
"id_number": "900112....",
"email": "johndoe@mail.com",
"contact_number": "+27831234567",
"billing_address": {
"line1": "1 Loop Street",
"line2": "Floor 5",
"city_or_town": "Cape Town",
"province_or_state": "Western Cape",
"postal_or_zip_code": "8001",
"country": "ZA"
},
"shipping": {
"contact_name": "Jane Doe",
"contact_number": "+27820000000",
"address": {
"line1": "1 Loop Street",
"line2": "Floor 5",
"city_or_town": "Cape Town",
"province_or_state": "Western Cape",
"postal_or_zip_code": "8001",
"country": "ZA"
},
},
"metadata": {
"custom_field_1": "custom data 1",
"custom_field_2": "custom data 2"
},
},
"redirects": {
"success_url": "https://merchant.example/success?order=ord_12345",
"cancel_url": "https://merchant.example/cancel?order=ord_12345",
"notify_url": "https://merchant.example/webhooks/payments"
},
"payment": {
"payment_methods": ["CARD", "ZAPPER"], // [optional: populate to specify payment methods to show else all will show]
"payment_type": "DB" // [optional: Direct Debit (DB) or Pre-Authorization PA, defaults to DB
},
"cards": {
"save_cards": true, // [optional: save cards for recurring or on click checkouts]
"show_cards": true // [optional: show previous saved cards for use to select from]
},
"notifications": {
"send_invoice": true,
"send_confirmation_email": true,
"confirmation_email_override": "accounts@example.com"
},
"customization": {
"locale": "EN_ZA",
"theme": "LIGHT",
"type": "PAGE", // or EMBED
"display_cancel_button": true,
"display_total": true,
"display_cart": true,
"brand": {
"primary": "#00DC82",
}
}
}
Request Parameters
Field | Required | Type | Description | Example |
|---|---|---|---|---|
| mode | Y | ENUM | Payment mode (ONE_TIME, RECURRING, SAVE) | ONE_TIME |
| amount | Y | String | Payment amount | 1200.00 |
| currency | N | String(3) | ISO 4217 currency code | ZAR |
| order_id | C | String(32) | Either pass order_id OR order object of existing order, see orders | ord_abc123... |
| order.reference | C | String(35) | Order reference identifier | ORD0045 |
| order.description | C | String | Description of the order | Monthly plan + setup |
| order.amount_subtotal | N | String | Subtotal amount before tax, shipping, and discounts | 1100.00 |
| order.amount_discount | N | String | Total discount amount applied | 0.00 |
| order.amount_shipping | N | String | Shipping cost amount | 0.00 |
| order.amount_tax | N | String | Tax amount applied | 100.00 |
| order.amount_total | N | String | Total order amount including all fees | 1200.00 |
| order.items.sku | C | String | Product SKU | SKU00567 |
| order.items.name | C | String | Product name | Pro Plan (Monthly) |
| order.items.quantity | C | Integer | Item quantity | 1 |
| order.items.unit_amount | C | String | Unit price | 1200.00 |
| order.items.tax_amount | N | Number | Tax amount | 0 |
| order.items.discount_amount | N | Number | Discount amount | 0 |
| order.items.currency | N | String(2) | ISO 4217 currency code | ZAR |
| order.items.metadata | N | Object | Additional metadata for this item, only 30 object entries allowed and max key length is 128 characters, max value length is 1024 characters | {"custom_field_1": "custom data 1"} |
| customer_fields | N | String | Comma-separated list of customer fields to capture in form (if no customer_id or customer object is specified) | reference,id_number,email,contact_number,billing,shipping |
| customer_id | C | String(32) | Either pass customer_id OR customer object of existing customer, see customers | cus_abc123... |
| customer.reference | C | String(35) | Reference to identify a specific customer | CLN240919000001 |
| customer.company_name | C | String(64) | Company name if the customer is a company | null |
| customer.person_name | C | String(32) | Customer's first name | John |
| customer.person_surname | C | String(32) | Customer's surname | Doe |
| customer.client_type | N | ENUM | Client type (RESIDENT_INDIVIDUAL, NON_RESIDENT_INDIVIDUAL, DOMESTIC_COMPANY, FOREIGN_COMPANY, FINANCIAL_INSTITUTION) | RESIDENT_INDIVIDUAL |
| customer.id_type | N | ENUM | ID type (SAID, PASSPORT, TEMPORARY_RESIDENCE, COMPANY_REGISTRATION_NUMBER) | SAID |
| customer.id_number | N | String(13) | ID number | 900112.... |
| customer.email | C | String(128) | Customer email address | johndoe@mail.com |
| customer.contact_number | C | String(16) | Customer contact number | +27831234567 |
| customer.billing_address.line1 | N | String | Billing address line 1 | 1 Loop Street |
| customer.billing_address.line2 | N | String | Billing address line 2 | Floor 5 |
| customer.billing_address.city_or_town | N | String | Billing city | Cape Town |
| customer.billing_address.province_or_state | N | String | Billing province/state | Western Cape |
| customer.billing_address.postal_or_zip_code | N | String | Postal code | 8001 |
| customer.billing_address.country | N | String(2) | ISO 3166-1 alpha-2 country code | ZA |
| customer.shipping.contact_name | N | String | Shipping contact name | Jane Doe |
| customer.shipping.contact_number | N | String(16) | Shipping contact number | +27820000000 |
| customer.shipping.address.line1 | N | String | Shipping address line 1 | 1 Loop Street |
| customer.shipping.address.line2 | N | String | Shipping address line 2 | Floor 5 |
| customer.shipping.address.city_or_town | N | String | Shipping city | Cape Town |
| customer.shipping.address.province_or_state | N | String | Shipping province/state | Western Cape |
| customer.shipping.address.postal_or_zip_code | N | String | Shipping postal code | 8001 |
| customer.shipping.address.country | N | String(2) | ISO 3166-1 alpha-2 | ZA |
| customer.metadata | N | Object | Additional customer metadata, only 30 object entries allowed and max key length is 128 characters, max value length is 1024 characters | {"custom_field_1": "custom data 1"} |
| redirects.success_url | N | String | URL to redirect on successful payment | https://merchant.example/success?order=ord_12345 |
| redirects.cancel_url | N | String | URL to redirect on cancelled payment | https://merchant.example/cancel?order=ord_12345 |
| redirects.notify_url | N | String | Webhook URL for payment notifications | https://merchant.example/webhooks/payments |
| payment.payment_methods | N | Array | Array of allowed payment methods: (CARD, ZAPPER, SNAPSCAN, APPLE_PAY, GOOGLE_PAY, SCAN_TO_PAY, 1VOUCHER, SCODE, MONEY_BADGER) | [CARD, ZAPPER] |
| payment.payment_type | N | String(2) | Direct Debit (DB) or Pre-Authorization (PA), defaults to DB | DB |
| cards.save_cards | N | Boolean | Save cards for recurring or on click checkouts | true |
| cards.show_cards | N | Boolean | Show previous saved cards for user to select from | true |
| notifications.send_invoice | N | Boolean | Whether to send invoice | true |
| notifications.send_confirmation_email | N | Boolean | Whether to send confirmation email | true |
| notifications.confirmation_email_override | N | String | Override email for confirmations | accounts@example.com |
| customization.locale | N | ENUM | UI locale | EN_ZA |
| customization.theme | N | ENUM | UI theme: (LIGHT or DARK) | LIGHT |
| customization.type | N | ENUM | Display type: (PAGE or EMBED) | PAGE |
| customization.display_cancel_button | N | Boolean | Whether to display the cancel button | true |
| customization.display_total | N | Boolean | Whether to display the total amount | true |
| customization.display_cart | N | Boolean | Whether to display the cart/order items | true |
| customization.brand.primary | N | String | Primary brand color in hex format | #00DC82 |
Response Body
{
"status": true,
"result": {
"id": "chk_abc123...",
"session_id": "ses_abc123...",
"amount": "1200.00",
"currency": "ZA",
"order_id": "ord_12345",
"customer_id": "cus_abc123...",
"page_url": "https://pay.kwik.co.za/checkout/cs_test_a1b2c3",
"expires_at": "2025-09-13T12:30:00Z"
}
}
Response Parameters
Field | Type | Description | Example |
|---|---|---|---|
| status | Boolean | Indicates if the request was successful | true |
| result.id | String | Unique checkout session identifier | chk_abc123... |
| result.session_id | String | Session identifier for the checkout | ses_abc123... |
| result.amount | String | Checkout amount | 1200.00 |
| result.currency | String(32) | ISO 4217 currency code | ZAR |
| result.order_id | String(32) | Associated order ID | ord_12345 |
| result.customer_id | String(32) | Associated customer ID | cus_abc123... |
| result.page_url | String | URL to redirect user to complete checkout | https://pay.kwik.co.za/checkout/cs_test_a1b2c3 |
| result.expires_at | String | ISO timestamp when the checkout session expires | 2025-09-13T12:30:00Z |
Webhook
When a checkout session is completed, updated, or expires, a webhook notification is sent to the notify_url specified in the request.
Webhook Payload
{
"event": "checkout.completed", // checkout.expired, checkout.failed
"data": [{
"checkout": {
"id": "chk_abc123...",
"session_id": "ses_abc123...",
"amount": "1200.00",
"currency": "ZA",
"order_id": "ord_12345",
"customer_id": "cus_abc123...",
"card_id": "crd_abc123...", // return a card id if a card payment was made
"transaction_id": "tra_abc123...",
"transaction_status": "RUNNING",
"expires_at": "2025-09-13T12:30:00Z",
"completed_at": "2025-09-13T10:15:30Z"
},
// return a payment only if a recurring payment was created
"payment": {
"id": "pay_abc123...",
"amount": "1200.00",
"currency": "ZA",
"payment_status": "COMPLETED",
"payment_method": "CARD",
"payment_method_id": "pam_abc123...",
"created_at": "2025-09-13T10:15:30Z"
}
}],
"created_at": "2025-09-13T10:15:30Z"
}
Webhook Payload Parameters
Field | Type | Description | Example |
|---|---|---|---|
| event | String | Type of webhook event that occurred | checkout.completed |
| data | Array | Array containing checkout and payment data | ... |
| data.checkout.id | String | Unique checkout session identifier | chk_abc123... |
| data.checkout.session_id | String | Session identifier for the checkout | ses_abc123... |
| data.checkout.amount | String | Checkout amount | 1200.00 |
| data.checkout.currency | String(3) | ISO 4217 currency code | ZAR |
| data.checkout.order_id | String(32) | Associated order ID | ord_12345 |
| data.checkout.customer_id | String(32) | Associated customer ID | cus_abc123... |
| data.checkout.card.token | String | Card token if card was saved | 60d678e2465b5b6c4fd5e847ef39c70c4b0c22d1b826f39eb80a107b3b8433ad |
| data.checkout.transaction_id | String | Transaction identifier | tra_abc123... |
| data.checkout.transaction_status | ENUM | Transaction status, see lookups | RUNNING |
| data.checkout.expires_at | String | ISO timestamp when checkout session expires | 2025-09-13T12:30:00Z |
| data.checkout.completed_at | String | ISO timestamp when checkout was completed | 2025-09-13T10:15:30Z |
| data.payment.id | String | Payment identifier | pay_abc123... |
| data.payment.amount | String | Payment amount | 1200.00 |
| data.payment.currency | String(3) | ISO 4217 currency code | ZAR |
| data.payment.status | ENUM | Payment status, see lookups | RUNNING |
| data.payment.status | String | Payment status | paid |
| data.payment.payment_method | String | Payment method used | CARD |
| data.payment.payment_method_id | String | Payment method id used | pam_abc123... |
| data.payment.created_at | String | ISO timestamp when payment was created | 2025-09-13T10:15:30Z |
| created_at | String | ISO timestamp when webhook was created | 2025-09-13T10:15:30Z |
Webhook Events
| Event | Description | Trigger Condition | Data Included |
|---|---|---|---|
checkout.completed | Checkout session was successfully completed with payment | When customer completes payment successfully | Checkout details, payment information, transaction data |
checkout.expired | Checkout session expired without completion | When checkout session reaches expiry time without payment | Checkout details only, no payment data |
checkout.failed | Checkout session failed due to payment failure | When payment processing fails (declined card, insufficient funds, etc.) | Checkout details, failed payment attempt, error information |
checkout.abandoned | Customer abandoned the checkout process | When customer leaves checkout page without completing | Checkout details, abandonment timestamp |
checkout.pending | Payment is pending additional verification | When payment requires manual review or 3DS authentication | Checkout details, pending payment status |
checkout.cancelled | Checkout was cancelled by customer or system | When cancel button is used or system cancels due to fraud | Checkout details, cancellation reason |
Webhook Security
All webhooks are sent with the following headers for verification:
X-Signature: HMAC-SHA256 signature of the payloadX-Timestamp: Unix timestamp of when the webhook was sentUser-Agent:Kwik-Webhooks/1.0
Webhook Response
Your endpoint should respond with a 200 status code to acknowledge receipt. Failed webhooks will be retried up to 3 times with exponential backoff.
Orders
Manage order records including product details, pricing, discounts, taxes, and line items. Create, update, retrieve, and delete orders for payment processing and checkout sessions.
Checkout Form
HTML form-based integration for creating secure checkout sessions without JavaScript. Supports order management, customer creation, payment customization, and redirect handling with simple form submissions.