Quick Pay
The Quick Pay endpoint creates a customer, order, order line, and payment in a single API request. It is designed for one-time payments — typically an e-commerce checkout or a face-to-face transaction where the amount is known at the time of the request.
When a customer completes a Quick Pay payment, they are redirected back to the redirect_url you supply. An optional webhook_url can be used to receive real-time status updates (see the Webhooks guide).
Base URL: https://api.wonderful.one
Authentication: All requests require a Authorization: Bearer {YOUR_AUTH_KEY} header. Obtain your token from your dashboard.
Payment flow
- The customer reaches your checkout and chooses "Pay by Bank".
- Your application calls
POST /v2/quick-paywith the amount, a reference, and a redirect URL. - The API returns a
pay_link. Send the customer to that URL. - The customer selects their bank, authorises the payment in their banking app, and is redirected back to your
redirect_urlwith a?wonderful-payment-id=query parameter. - Your application calls
GET /v2/payments/{id}to verify the final status.
You can optionally pre-select a bank by passing a bank_id. If omitted, the customer chooses from a list on a Wonderful-hosted page.
Important for mobile integrations
When redirecting a customer to the pay_link URL, the redirect must happen in the device's native browser — Safari or Chrome on iOS, Chrome on Android. If you are integrating the API within a mobile app, do not use in-app browser views or WebUI panels. The hand-off to the customer's mobile banking app will only work correctly when launched from the native browser. Some Samsung users have also reported issues triggering their banking app when using the default Samsung browser; where possible, direct those customers to Chrome instead.
Fetch supported banks
Before creating a payment, you may want to display a list of supported banks so the customer can choose.
Request
GET /v2/supported-banks
Response
{
"data": [
{
"bank_id": "natwest",
"bank_name": "NatWest",
"status": "available"
},
{
"bank_id": "barclays",
"bank_name": "Barclays",
"status": "available"
}
]
}
Example
curl --request GET \
--get "https://api.wonderful.one/v2/supported-banks" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL("https://api.wonderful.one/v2/supported-banks");
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, { method: "GET", headers })
.then(response => response.json())
.then(data => console.log(data.data));
$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/supported-banks';
$response = $client->get($url, [
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]);
$body = json_decode((string) $response->getBody());
print_r($body->data);
Create a Quick Pay payment
Request
POST /v2/quick-pay
Content-Type: application/json
Body parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | integer | yes | Amount in GB pence (e.g. 1000 = £10.00). Minimum 5. |
merchant_payment_reference | string | yes | Shown on the customer's bank statement. Max 18 characters, A-Z, 0-9, -. |
payment_description | string | no | Description for the order line. |
customer_email_address | string | no | Email address. When provided, the order is linked to (or creates) a customer record. |
redirect_url | string | no | URL to return the customer to after payment. |
webhook_url | string | no | URL to receive POST notifications for payment status changes. |
bank_id | string | no | Pre-select a specific bank (e.g. natwest). |
skip_confirmation | boolean | no | Set to true to skip the Wonderful-hosted confirmation page. |
send_to_tap | string | no | A Tap device ID to push the payment to a Tap terminal. |
Response
{
"data": {
"id": "ed6d3016",
"order_id": "ed6d3016",
"amount": 1000,
"amount_formatted": "£10.00",
"status": "created",
"reference": "ORDER-1234",
"pay_link": "https://api.wonderful.one/pay/AB12",
"created_at": "2024-03-05T11:50:43.000000Z",
"updated_at": "2024-03-05T11:50:43.000000Z"
}
}
Example
curl --request POST \
"https://api.wonderful.one/v2/quick-pay" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{
"amount": 1000,
"merchant_payment_reference": "ORDER-1234",
"payment_description": "Website Order #1234",
"customer_email_address": "[email protected]",
"redirect_url": "https://mysite.com/success",
"webhook_url": "https://mysite.com/webhooks",
"bank_id": "natwest"
}'
const url = new URL("https://api.wonderful.one/v2/quick-pay");
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
const body = {
amount: 1000,
merchant_payment_reference: "ORDER-1234",
payment_description: "Website Order #1234",
customer_email_address: "[email protected]",
redirect_url: "https://mysite.com/success",
webhook_url: "https://mysite.com/webhooks",
bank_id: "natwest",
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
})
.then(response => response.json())
.then(data => {
// Redirect the customer to data.data.pay_link
window.location.href = data.data.pay_link;
});
$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/quick-pay';
$response = $client->post($url, [
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'amount' => 1000,
'merchant_payment_reference' => 'ORDER-1234',
'payment_description' => 'Website Order #1234',
'customer_email_address' => '[email protected]',
'redirect_url' => 'https://mysite.com/success',
'webhook_url' => 'https://mysite.com/webhooks',
'bank_id' => 'natwest',
],
]);
$body = json_decode((string) $response->getBody());
$payLink = $body->data->pay_link;
// Redirect the customer to $payLink
Verify payment status
After the customer is redirected back to your redirect_url, inspect the wonderful-payment-id query parameter and call the API to get the authoritative payment status.
Request
GET /v2/payments/{id}
Response
{
"data": {
"id": "ed6d3016",
"order_id": "ed6d3016",
"amount": 1000,
"amount_formatted": "£10.00",
"status": "completed",
"reference": "ORDER-1234",
"pay_link": "https://api.wonderful.one/pay/AB12",
"created_at": "2024-03-05T11:50:43.000000Z",
"updated_at": "2024-03-05T11:55:00.000000Z"
}
}
Possible status values: created, pending, paid, failed, cancelled, expired, errored.
Example
curl --request GET \
--get "https://api.wonderful.one/v2/payments/ed6d3016" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const paymentId = new URLSearchParams(window.location.search)
.get("wonderful-payment-id");
fetch(`https://api.wonderful.one/v2/payments/${paymentId}`, {
headers: {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
},
})
.then(response => response.json())
.then(data => {
if (data.data.status === "completed") {
// Show success page
}
});
$client = new \GuzzleHttp\Client();
$paymentId = $_GET['wonderful-payment-id'];
$url = "https://api.wonderful.one/v2/payments/{$paymentId}";
$response = $client->get($url, [
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]);
$body = json_decode((string) $response->getBody());
$status = $body->data->status;
if ($status === 'completed') {
// Process the order
}
Error handling
The API returns standard HTTP status codes and a consistent error payload:
{
"error": true,
"message": "Validation failed",
"invalid_fields": {
"amount": ["The amount must be at least 5."]
}
}
| Status | Meaning |
|---|---|
201 | Created successfully |
400 | Validation error |
401 | Invalid or missing API token |
404 | Resource not found |
Next steps
- Reusable payment links (QR Codes) — fixed-amount links for donations or products.
- Orders & refunds — reconcile payments and process refunds.
- Customers — manage your customer records.
- Webhooks — real-time payment status notifications.