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.
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.