Step by step guide
This guide takes you through building an iwocaPay ecommerce API integration end to end: getting your credentials, creating an order, sending the customer to checkout, and handling the success and decline outcomes.
For a high-level picture of the flow before you start, read How it works. For full field-level detail on every request and response, see the Endpoints and Webhooks reference.
Before you start building, make sure you’ve completed the following:
- Understand the user journey and our concepts
- Get staging credentials from your Account Manager — see Contact us
Request the following from your Account Manager. See Contact us.
IWOCAPAY_SUPPLIER_ACCESS_TOKEN— your access token, used to authenticate every request.IWOCAPAY_SUPPLIER_UUID— identifies your account in the order endpoint URL.IWOCAPAY_API_URL— the base URL for the environment you’re targeting (see Base URLs).
Store these securely — for example, in a .env file — and never expose them in client-side code:
IWOCAPAY_API_URL=https://stage.iwoca-dev.co.uk/api/lending/edge/IWOCAPAY_SUPPLIER_ACCESS_TOKEN=your-access-tokenIWOCAPAY_SUPPLIER_UUID=your-supplier-uuidiwocaPay’s ecommerce API endpoints are accessible at a base URL. The staging and production environments use different base URLs, and you must use HTTPS for all interactions with our API.
https://stage.iwoca-dev.co.uk/Use the staging environment to develop and test your integration. It behaves identically to production.
https://www.iwoca.co.uk/The production environment must only be used for real loan applications.
All requests require your access token in the Authorization header for bearer authentication.
The following example shows how to authenticate and create an order in Bash, Typescript, Python 3, and PHP.
curl -X POST -H 'Authorization: Bearer SUPPLIER_ACCESS_TOKEN' -H "Content-Type: application/json" -d '{"data": {"amount": 4200, "reference": "#order1"}}' https://stage.iwoca-dev.co.uk/api/lending/edge/ecommerce/seller/SUPPLIER_UUID/order/fetch( "https://stage.iwoca-dev.co.uk/api/lending/edge/ecommerce/seller/SUPPLIER_UUID/order/", { method: "POST", headers: { Authorization: "Bearer SUPPLIER_ACCESS_TOKEN", "Content-Type": "application/json", }, body: JSON.stringify({ data: { amount: 4200, reference: "#order1", }, }), },) .then((response) => response.json()) .then((data) => console.log("Order created:", data)) .catch((error) => console.error("Error creating create-order:", error));import requests
url = "https://stage.iwoca-dev.co.uk/api/lending/edge/ecommerce/seller/SUPPLIER_UUID/order/"headers = { "Authorization": "Bearer SUPPLIER_ACCESS_TOKEN", "Content-Type": "application/json",}data = { "data": { "amount": 4200, "reference": "#order1", }}
response = requests.post(url, headers=headers, json=data)if response.ok: print("Order created:", response.json())else: print("Error creating order:", response.status_code, response.text)<?php
$url = "https://stage.iwoca-dev.co.uk/api/lending/edge/ecommerce/seller/SUPPLIER_UUID/order/";$accessToken = "SUPPLIER_ACCESS_TOKEN";
$data = [ "data" => [ "amount" => 4200, "reference" => "#order1" ]];
$headers = [ "Authorization: Bearer $accessToken", "Content-Type: application/json",];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_POST, true);curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$response = curl_exec($ch);$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($response === false) { echo "Curl error: " . curl_error($ch);} elseif ($httpCode >= 200 && $httpCode < 300) { echo "Order created: " . $response;} else { echo "Error creating order: HTTP $httpCode, " . $response;}
curl_close($ch);
?>When your customer chooses Check out with iwocaPay, create an order by sending a POST request to the order endpoint:
POST /api/lending/edge/ecommerce/seller/<supplier_uuid>/order/A minimal request needs an amount and a reference:
{ "data": { "amount": 12000.0, "reference": "#481", "allowed_payment_terms": ["PAY_LATER"], "webhook_url": "https://example.com/iwocapay/webhooks", "redirect_url": "https://example.com/iwocapay/order-complete" }}The most common parameters are:
| Field | Required | Description |
|---|---|---|
amount | Yes | The order amount in GBP. |
reference | Yes | Your unique reference for the order. Appears in your bank transactions for reconciliation. |
allowed_payment_terms | No | Restrict which payment options the customer sees. Must contain PAY_LATER. Defaults to all enabled terms. |
webhook_url | No | A URL to receive webhooks as the order’s status changes. |
For the full list of fields and validation rules, see Creating an order.
The response contains an order_url and an order id. Save the id against the order in your system — it’s your unique source of truth for reconciliation — then redirect the customer to the order_url to complete their checkout with us.
{ "data": { "id": "aaaa-bbbb-cccc", "amount": 12000.0, "reference": "#481", "order_url": "https://www.iwoca.co.uk/pay/order/abc/landing/", "status": "CREATED", "allowed_payment_terms": ["PAY_LATER", "PAY_NOW"] }}The customer completes the payment process on our self-hosted checkout, then we redirect them back to your site.
redirect_url describes where iwocaPay sends a customer after they’ve checked out and completed an order.
This should be an order confirmation page, or somewhere that represents the end of your transaction process.
redirect_url is defined when we issue your access token and is the same for all orders. (If you need a different destination per order, you can pass a per-order redirect_url in the order creation request — see Creating an order.)
Once the customer finishes (or fails to finish) checkout, your integration needs to react to the order’s final status. You receive these status updates via webhooks.
When the order reaches SUCCESSFUL, the customer has completed checkout and accepted their terms, and iwocaPay sends you the funds (net of any applicable fee). You don’t need to wait for the customer to repay us.
On SUCCESSFUL, your system should:
- Mark the order as paid and reconcile it using your
reference. - Fulfil the order and display confirmation messaging to the customer.
If a customer is declined, the order status is set to UNSUCCESSFUL and the customer is returned to your site via the redirect URL. The same status also covers abandoned, cancelled, and failed orders — the status alone doesn’t distinguish between them.
On UNSUCCESSFUL, your system should:
- Update the order accordingly (cancel it, release any reserved stock).
- Show the customer appropriate messaging and let them try an alternative payment method.
To get live updates as an order’s status changes, supply a webhook_url when you create the order. iwocaPay then sends a POST request with a JSON body to that URL every time the status changes:
{ "data": { "webhook_id": "f0b4c1e2-9a3d-4f5b-8c6e-1d2a3b4c5d6e", "event_type": "ORDER_STATUS_CHANGED", "order_id": "aa8cfc99-3853-4641-8856-3294433b7bb7", "amount": 278.22, "reference": "Service Mjolnir", "status": "CREATED" }}Every webhook includes an X-Iwocapay-Hmac-Sha256 signature header so you can verify it came from iwocaPay and wasn’t tampered with.
Always verify the signature before acting on a webhook.
For the payload fields and signature-verification code samples, see Webhooks.
Your integration is now ready to be tested. Before you go live, test it end to end against the sandbox, then certify it to get your production credentials:
- Test with the sandbox — run through the payment flows using our test customer details.
- Certify your integration — verify the required test cases, then request your production API keys to go live.
You may also want to review the full example implementation in Python, PHP, and TypeScript.