Introduction
One by Wonderful: Public API Documentation
Developer Guides
Step-by-step guides for common integration scenarios:
- Quick Pay — One-time payments via e-commerce checkout
- Reusable Payment Links — Fixed-amount QR codes and payment URLs
- Orders & Refunds — List, inspect, and refund orders
- Customers — Manage customer records
- Webhooks — Real-time payment status notifications
PHP SDK
For PHP and Laravel integrations, we now have an official PHP SDK:
wonderfulpaymentsltd/one-api-sdk-php
This documentation aims to provide all the information you need to work with our API.
Authenticating requests
To authenticate requests, include an Authorization header with the value "Bearer {YOUR_AUTH_KEY}".
All authenticated endpoints are marked with a requires authentication badge in the documentation below.
You can retrieve your token by visiting your dashboard and clicking Generate API token.
Endpoints
Customers
List Customers
requires authentication
List customers for the merchant. Supports basic searching on name and email address, ordering of results, and pagination. Default pagination is 25 results per page.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/customers?search=john.testmore%40example.com&sort=last_name_asc&start_date=2023-07-01&end_date=2023-12-31&per_page=10" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/customers"
);
const params = {
"search": "[email protected]",
"sort": "last_name_asc",
"start_date": "2023-07-01",
"end_date": "2023-12-31",
"per_page": "10",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/customers';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'search' => '[email protected]',
'sort' => 'last_name_asc',
'start_date' => '2023-07-01',
'end_date' => '2023-12-31',
'per_page' => '10',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/customers'
params = {
'search': '[email protected]',
'sort': 'last_name_asc',
'start_date': '2023-07-01',
'end_date': '2023-12-31',
'per_page': '10',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"id": "",
"first_name": "Dina",
"last_name": null,
"full_name": "Dina",
"email": "[email protected]",
"address": "7043 Thiel Creek",
"address_formatted": {
"address_line_1": null,
"address_line_2": null,
"town": null,
"postcode": null
},
"telephone": "507-462-5041",
"marketing_consented_at": null,
"created_at": null,
"updated_at": null
},
{
"id": "",
"first_name": "Newell",
"last_name": null,
"full_name": "Newell",
"email": "[email protected]",
"address": "363 Chelsie Forge Apt. 612",
"address_formatted": {
"address_line_1": null,
"address_line_2": null,
"town": null,
"postcode": null
},
"telephone": "+1-445-707-5865",
"marketing_consented_at": null,
"created_at": null,
"updated_at": null
}
],
"links": {
"first": "/?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "/",
"per_page": "25",
"to": 2
}
}
Example response (200):
{
"data": [
{
"id": "1d368e62",
"first_name": "John",
"last_name": "Testmore",
"full_name": "John Testmore",
"email": "[email protected]",
"address": "1 Test Street, Test Town",
"telephone": "0123456789",
"marketing_consented_at": null,
"created_at": "2023-05-02T22:07:21.000000Z",
"updated_at": "2023-05-02T22:07:21.000000Z"
}
],
"links": {
"first": "https://api.wonderful.one/v2/customers?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "https://api.wonderful.one/v2/customers",
"per_page": 25,
"to": 1
}
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Customer
first_name
string
Customer's first name. Example: John
last_name
string
Customer's last name. Example: Testmore
full_name
string
Customer's full name. Example: John Testmore
address
string
deprecated Customer's address as a single string. Use address_formatted instead. Example: 1 Test Street, Test Town, AB1 2CD
address_formatted
object
Structured address object with individual components.
address_line_1
string
nullable First line of the address. Example: 1 Test Street
address_line_2
string
nullable Second line of the address. Example: Test Area
town
string
nullable Town or city. Example: Test Town
postcode
string
nullable Postal code. Example: AB1 2CD
telephone
string
Customer's telephone number. Example: 0123456789
marketing_consented_at
string
nullable The date and time the Customer last opted in to marketing. Example: 2023-05-02T22:07:21.000000Z
created_at
string
The date and time the Customer was created. Example: 2023-05-02T22:07:21.000000Z
updated_at
string
The date and time the Customer was last updated. Example: 2023-05-02T22:07:21.000000Z
Create Customer
requires authentication
Inserts a new customer record.
Example request:
curl --request POST \
"https://api.wonderful.one/v2/customers" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"first_name\": \"John\",
\"last_name\": \"Smith\",
\"email\": \"[email protected]\",
\"telephone\": \"01234 567890\",
\"marketing_consent\": true,
\"address\": \"123 Some Street, London, SW1A 1AA\"
}"
const url = new URL(
"https://api.wonderful.one/v2/customers"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"first_name": "John",
"last_name": "Smith",
"email": "[email protected]",
"telephone": "01234 567890",
"marketing_consent": true,
"address": "123 Some Street, London, SW1A 1AA"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/customers';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'first_name' => 'John',
'last_name' => 'Smith',
'email' => '[email protected]',
'telephone' => '01234 567890',
'marketing_consent' => true,
'address' => '123 Some Street, London, SW1A 1AA',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/customers'
payload = {
"first_name": "John",
"last_name": "Smith",
"email": "[email protected]",
"telephone": "01234 567890",
"marketing_consent": true,
"address": "123 Some Street, London, SW1A 1AA"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"data": {
"id": "",
"first_name": "Zane",
"last_name": null,
"full_name": "Zane",
"email": "[email protected]",
"address": "9273 Abdul Radial Suite 785",
"address_formatted": {
"address_line_1": null,
"address_line_2": null,
"town": null,
"postcode": null
},
"telephone": "(913) 245-2088",
"marketing_consented_at": null,
"created_at": null,
"updated_at": null
}
}
Example response (201, Created successfully):
{
"data": {
"id": "1d368e62",
"first_name": "John",
"last_name": "Testmore",
"full_name": "John Testmore",
"email": "[email protected]",
"address": "1 Test Street, Test Town",
"telephone": "0123456789",
"marketing_consented_at": null,
"created_at": "2023-05-02T22:07:21.000000Z",
"updated_at": "2023-05-02T22:07:21.000000Z"
}
}
Example response (422, Validation error):
{
"error": true,
"message": "Validation failed",
"invalid_fields": {
"email": [
"The email field is required."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Customer
first_name
string
Customer's first name. Example: John
last_name
string
Customer's last name. Example: Testmore
full_name
string
Customer's full name. Example: John Testmore
address
string
deprecated Customer's address as a single string. Use address_formatted instead. Example: 1 Test Street, Test Town, AB1 2CD
address_formatted
object
Structured address object with individual components.
address_line_1
string
nullable First line of the address. Example: 1 Test Street
address_line_2
string
nullable Second line of the address. Example: Test Area
town
string
nullable Town or city. Example: Test Town
postcode
string
nullable Postal code. Example: AB1 2CD
telephone
string
Customer's telephone number. Example: 0123456789
marketing_consented_at
string
nullable The date and time the Customer last opted in to marketing. Example: 2023-05-02T22:07:21.000000Z
created_at
string
The date and time the Customer was created. Example: 2023-05-02T22:07:21.000000Z
updated_at
string
The date and time the Customer was last updated. Example: 2023-05-02T22:07:21.000000Z
Show Customer
requires authentication
Show the details of a specific customer record. Pass the Public API Hash ID of the customer you want to retrieve on the URL.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/customers/1d368e62" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/customers/1d368e62"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/customers/1d368e62';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/customers/1d368e62'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"data": {
"id": "",
"first_name": "Juliet",
"last_name": null,
"full_name": "Juliet",
"email": "[email protected]",
"address": "60723 Leonie Mountains",
"address_formatted": {
"address_line_1": null,
"address_line_2": null,
"town": null,
"postcode": null
},
"telephone": "531-528-9329",
"marketing_consented_at": null,
"created_at": null,
"updated_at": null
}
}
Example response (200):
{
"data": {
"id": "1d368e62",
"first_name": "John",
"last_name": "Testmore",
"full_name": "John Testmore",
"email": "[email protected]",
"address": "1 Test Street, Test Town",
"telephone": "0123456789",
"marketing_consented_at": null,
"created_at": "2023-05-02T22:07:21.000000Z",
"updated_at": "2023-05-02T22:07:21.000000Z"
}
}
Example response (404, Customer not found):
{
"error": true,
"message": "Customer not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Customer
first_name
string
Customer's first name. Example: John
last_name
string
Customer's last name. Example: Testmore
full_name
string
Customer's full name. Example: John Testmore
address
string
deprecated Customer's address as a single string. Use address_formatted instead. Example: 1 Test Street, Test Town, AB1 2CD
address_formatted
object
Structured address object with individual components.
address_line_1
string
nullable First line of the address. Example: 1 Test Street
address_line_2
string
nullable Second line of the address. Example: Test Area
town
string
nullable Town or city. Example: Test Town
postcode
string
nullable Postal code. Example: AB1 2CD
telephone
string
Customer's telephone number. Example: 0123456789
marketing_consented_at
string
nullable The date and time the Customer last opted in to marketing. Example: 2023-05-02T22:07:21.000000Z
created_at
string
The date and time the Customer was created. Example: 2023-05-02T22:07:21.000000Z
updated_at
string
The date and time the Customer was last updated. Example: 2023-05-02T22:07:21.000000Z
Update Customer
requires authentication
Note: Pushing an update to a customer record will update the entire entity, so you must pass all the fields including those that have not been changed.
Example request:
curl --request PUT \
"https://api.wonderful.one/v2/customers/1d368e62" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"first_name\": \"John\",
\"last_name\": \"Smith\",
\"email\": \"[email protected]\",
\"telephone\": \"01234 567890\",
\"marketing_consent\": true,
\"address\": \"123 Some Street, London, SW1A 1AA\"
}"
const url = new URL(
"https://api.wonderful.one/v2/customers/1d368e62"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"first_name": "John",
"last_name": "Smith",
"email": "[email protected]",
"telephone": "01234 567890",
"marketing_consent": true,
"address": "123 Some Street, London, SW1A 1AA"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/customers/1d368e62';
$response = $client->put(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'first_name' => 'John',
'last_name' => 'Smith',
'email' => '[email protected]',
'telephone' => '01234 567890',
'marketing_consent' => true,
'address' => '123 Some Street, London, SW1A 1AA',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/customers/1d368e62'
payload = {
"first_name": "John",
"last_name": "Smith",
"email": "[email protected]",
"telephone": "01234 567890",
"marketing_consent": true,
"address": "123 Some Street, London, SW1A 1AA"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('PUT', url, headers=headers, json=payload)
response.json()Example response (200):
{
"data": {
"id": "",
"first_name": "Emmie",
"last_name": null,
"full_name": "Emmie",
"email": "[email protected]",
"address": "710 O'Kon Course",
"address_formatted": {
"address_line_1": null,
"address_line_2": null,
"town": null,
"postcode": null
},
"telephone": "+1.727.658.9320",
"marketing_consented_at": null,
"created_at": null,
"updated_at": null
}
}
Example response (200, Updated successfully):
{
"data": {
"id": "1d368e62",
"first_name": "John",
"last_name": "Testmore",
"full_name": "John Testmore",
"email": "[email protected]",
"address": "1 Test Street, Test Town",
"telephone": "0123456789",
"marketing_consented_at": null,
"created_at": "2023-05-02T22:07:21.000000Z",
"updated_at": "2023-05-02T22:07:21.000000Z"
}
}
Example response (422, Validation error):
{
"error": true,
"message": "Validation failed",
"invalid_fields": {
"email": [
"The email field is required."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Customer
first_name
string
Customer's first name. Example: John
last_name
string
Customer's last name. Example: Testmore
full_name
string
Customer's full name. Example: John Testmore
address
string
deprecated Customer's address as a single string. Use address_formatted instead. Example: 1 Test Street, Test Town, AB1 2CD
address_formatted
object
Structured address object with individual components.
address_line_1
string
nullable First line of the address. Example: 1 Test Street
address_line_2
string
nullable Second line of the address. Example: Test Area
town
string
nullable Town or city. Example: Test Town
postcode
string
nullable Postal code. Example: AB1 2CD
telephone
string
Customer's telephone number. Example: 0123456789
marketing_consented_at
string
nullable The date and time the Customer last opted in to marketing. Example: 2023-05-02T22:07:21.000000Z
created_at
string
The date and time the Customer was created. Example: 2023-05-02T22:07:21.000000Z
updated_at
string
The date and time the Customer was last updated. Example: 2023-05-02T22:07:21.000000Z
Delete Customer
requires authentication
The delete customer endpoint will "soft-delete" a customer record. There is no mechanism via the API to restore a deleted record, if you need to restore a previously deleted record you will need to contact the support team.
Note that a successful delete will return a HTTP 204 with an empty response body. Attempting to delete an already deleted record will return a HTTP 404 "not found" response.
Example request:
curl --request DELETE \
"https://api.wonderful.one/v2/customers/1d368e62" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/customers/1d368e62"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/customers/1d368e62';
$response = $client->delete(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/customers/1d368e62'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('DELETE', url, headers=headers)
response.json()Example response (204, Customer deleted):
Empty response
Example response (403, Customer has orders):
{
"error": true,
"message": "Cannot delete customer with orders"
}
Example response (404, Customer not found):
{
"error": true,
"message": "Customer not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Orders
Create an Order Refund
requires authentication
You can create a refund for an existing order. The total of all pending and completed refunds cannot exceed the amount of the original payment on the order.
NOTE: In some cases we might not be able to refund an order. In most cases this is because the customers bank did not provide us with their account details at the time of payment. In this situation the merchant should make arrangements to process the refund offline.
Example request:
curl --request POST \
"https://api.wonderful.one/v2/orders/consequatur/refund" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"refund_amount\": 1234,
\"reference\": \"REFUND-1234\",
\"reason\": \"Item returned, too big.\"
}"
const url = new URL(
"https://api.wonderful.one/v2/orders/consequatur/refund"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"refund_amount": 1234,
"reference": "REFUND-1234",
"reason": "Item returned, too big."
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/orders/consequatur/refund';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'refund_amount' => 1234,
'reference' => 'REFUND-1234',
'reason' => 'Item returned, too big.',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/orders/consequatur/refund'
payload = {
"refund_amount": 1234,
"reference": "REFUND-1234",
"reason": "Item returned, too big."
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"data": {
"id": "ed6d3864",
"order_id": "1d679976",
"refund_amount": 2000,
"refund_amount_formatted": "£20.00",
"status": "created",
"reference": "ORDER-550433-R",
"reason": "Item was damaged, part credit issued.",
"created_at": "2024-04-15T16:43:34.000000Z",
"updated_at": "2024-04-15T16:43:34.000000Z"
}
}
Example response (200, Refund created):
{
"data": {
"id": "3ed6d864",
"order_id": "1d679976",
"refund_amount": 500,
"refund_amount_formatted": "£5.00",
"status": "created",
"reference": "R1712588746",
"reason": "Item returned, too big",
"created_at": "2024-04-08T15:05:46.000000Z",
"updated_at": "2024-04-08T15:05:46.000000Z"
}
}
Example response (400, Validation error):
{
"error": true,
"message": "Validation failed",
"invalid_fields": {
"refund_amount": [
"Refund amount cannot exceed remaining amount refundable"
]
}
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Example response (404, Order not found):
{
"error": true,
"message": "Order not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Refund. Example: 3ed6d864
order_id
string
Public API Hash ID of the Order. Example: 3ed6d864
refund_amount
integer
The refund amount in base currency units (GB Pence). Example: 1000
refund_amount_formatted
string
The refund amount as a formatted currency string. Example: £10.00
status
string
The status of the Refund. Example: paid
reference
string
The reference of the Refund. Example: ONE-3ed6
reason
string
The reason for the Refund (not to be shown to customers!). Example: ONE-3ed6
created_at
string
The date and time the Refund was created. Example: 2024-04-05T14:19:58.000000Z
updated_at
string
The date and time the Refund was last updated. Example: 2024-04-05T14:19:58.000000Z
List Orders
requires authentication
List all orders associated with the merchant. Supports basic searching on customer name and email address, ordering of results, and pagination. Default pagination is 25 results per page.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/orders?search=Smith&sort=amount_desc&payment_status=paid&start_date=2023-01-01&end_date=2023-12-31&per_page=100" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/orders"
);
const params = {
"search": "Smith",
"sort": "amount_desc",
"payment_status": "paid",
"start_date": "2023-01-01",
"end_date": "2023-12-31",
"per_page": "100",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/orders';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'search' => 'Smith',
'sort' => 'amount_desc',
'payment_status' => 'paid',
'start_date' => '2023-01-01',
'end_date' => '2023-12-31',
'per_page' => '100',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/orders'
params = {
'search': 'Smith',
'sort': 'amount_desc',
'payment_status': 'paid',
'start_date': '2023-01-01',
'end_date': '2023-12-31',
'per_page': '100',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"id": "28624076",
"total": 0,
"total_formatted": "£0.00",
"order_status": "pending",
"amount_refundable": 0,
"amount_pending_refund": 0,
"amount_refunded": 0,
"ordered_at": "2026-07-07T23:36:28.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z",
"created_at": "2026-09-15T15:49:44.000000Z",
"refunds": [],
"order_lines": []
},
{
"id": "d9697e36",
"total": 0,
"total_formatted": "£0.00",
"order_status": "pending",
"amount_refundable": 0,
"amount_pending_refund": 0,
"amount_refunded": 0,
"ordered_at": "2026-09-10T22:25:24.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z",
"created_at": "2026-09-15T15:49:44.000000Z",
"refunds": [],
"order_lines": []
}
],
"links": {
"first": "/?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "/",
"per_page": "25",
"to": 2
}
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
The public API hash ID of the Order.
total
integer
The total amount of the Order in base currency units (GB Pence).
total_formatted
string
The total amount of the Order as a formatted currency string.
order_status
string
The status of the Order.
amount_refundable
integer
The total amount of the Order that is refundable in base currency units.
amount_pending_refund
integer
The total amount of the Order currently pending refund in base currency units.
amount_refunded
integer
The total amount of the Order that has been refunded in base currency units.
ordered_at
string
The date and time the Order was ordered.
updated_at
string
The date and time the Order was last updated.
created_at
string
The date and time the Order was created on the system.
customer
object
The Customer record associated with the Order.
payments
object[]
All Payment records associated with the Order.
order_lines
object[]
All OrderLine records associated with the Order.
Create Order
requires authentication
Creates an Order for the merchant with one or more Order Lines. Each line may
reference one of the merchant's Items via item_id; the Item's name, description
and price are snapshotted onto the line unless overridden by the supplied values.
Lines without an item_id must include a name and price.
A Customer may optionally be linked by passing its Public API Hash ID as
customer_id. The Customer must already exist and belong to your account.
Example request:
curl --request POST \
"https://api.wonderful.one/v2/orders" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"customer_id\": \"1d368e62\",
\"description\": \"Website Order 1234\",
\"order_lines\": [
{
\"item_id\": \"4b7f0a91\",
\"quantity\": 2
},
{
\"name\": \"Ad hoc\",
\"description\": \"One off\",
\"price\": 500,
\"quantity\": 1
}
]
}"
const url = new URL(
"https://api.wonderful.one/v2/orders"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"customer_id": "1d368e62",
"description": "Website Order 1234",
"order_lines": [
{
"item_id": "4b7f0a91",
"quantity": 2
},
{
"name": "Ad hoc",
"description": "One off",
"price": 500,
"quantity": 1
}
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/orders';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'customer_id' => '1d368e62',
'description' => 'Website Order 1234',
'order_lines' => [
[
'item_id' => '4b7f0a91',
'quantity' => 2,
],
[
'name' => 'Ad hoc',
'description' => 'One off',
'price' => 500,
'quantity' => 1,
],
],
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/orders'
payload = {
"customer_id": "1d368e62",
"description": "Website Order 1234",
"order_lines": [
{
"item_id": "4b7f0a91",
"quantity": 2
},
{
"name": "Ad hoc",
"description": "One off",
"price": 500,
"quantity": 1
}
]
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"data": {
"id": "89652836",
"total": 0,
"total_formatted": "£0.00",
"order_status": "pending",
"amount_refundable": 0,
"amount_pending_refund": 0,
"amount_refunded": 0,
"ordered_at": "2026-07-07T23:36:28.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z",
"created_at": "2026-09-15T15:49:44.000000Z",
"refunds": [],
"order_lines": []
}
}
Example response (201, Created successfully):
{
"data": {
"id": "ed6d3016",
"total": 1000,
"total_formatted": "£10.00",
"order_status": "pending",
"amount_refundable": 0,
"amount_pending_refund": 0,
"amount_refunded": 0,
"ordered_at": "2024-03-05T11:50:43.000000Z",
"updated_at": "2024-03-05T11:50:43.000000Z",
"created_at": "2024-03-05T11:50:43.000000Z",
"customer": {
"id": "89650465",
"first_name": null,
"last_name": null,
"full_name": "",
"email": "[email protected]",
"address": null,
"telephone": null,
"marketing_consented_at": null,
"created_at": "2024-03-05T11:50:43.000000Z",
"updated_at": "2024-03-05T11:50:43.000000Z"
},
"payments": [],
"order_lines": [
{
"id": "ed6d87e6",
"order_id": "ed6d3016",
"quantity": 2,
"name": "Coffee",
"description": "Freshly ground",
"item_id": "4b7f0a91",
"price": 250,
"price_formatted": "£2.50",
"created_at": "2024-03-05T11:50:43.000000Z",
"updated_at": "2024-03-05T11:50:43.000000Z"
},
{
"id": "ed6d87e7",
"order_id": "ed6d3016",
"quantity": 1,
"name": "Ad hoc",
"description": "One off",
"item_id": null,
"price": 500,
"price_formatted": "£5.00",
"created_at": "2024-03-05T11:50:43.000000Z",
"updated_at": "2024-03-05T11:50:43.000000Z"
}
]
}
}
Example response (400, Validation error):
{
"error": true,
"message": "Validation failed",
"invalid_fields": {
"order_lines": [
"The order lines field is required."
],
"order_lines.0.name": [
"A name is required for an order line that is not linked to an item."
],
"order_lines.0.price": [
"A price is required for an order line that is not linked to an item."
]
}
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
The public API hash ID of the Order.
total
integer
The total amount of the Order in base currency units (GB Pence).
total_formatted
string
The total amount of the Order as a formatted currency string.
order_status
string
The status of the Order.
amount_refundable
integer
The total amount of the Order that is refundable in base currency units.
amount_pending_refund
integer
The total amount of the Order currently pending refund in base currency units.
amount_refunded
integer
The total amount of the Order that has been refunded in base currency units.
ordered_at
string
The date and time the Order was ordered.
updated_at
string
The date and time the Order was last updated.
created_at
string
The date and time the Order was created on the system.
customer
object
The Customer record associated with the Order.
payments
object[]
All Payment records associated with the Order.
order_lines
object[]
All OrderLine records associated with the Order.
Show Order
requires authentication
Shows the specific details for a single order.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/orders/consequatur" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/orders/consequatur"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/orders/consequatur';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/orders/consequatur'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"data": {
"id": "27602726",
"total": 0,
"total_formatted": "£0.00",
"order_status": "pending",
"amount_refundable": 0,
"amount_pending_refund": 0,
"amount_refunded": 0,
"ordered_at": "2026-02-23T02:08:37.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z",
"created_at": "2026-09-15T15:49:44.000000Z",
"refunds": [],
"order_lines": []
}
}
Example response (200, Order found):
{
"data": {
"id": "ed6d3016",
"total": 8957,
"total_formatted": "£89.57",
"order_status": "pending",
"ordered_at": "2024-03-05T11:50:43.000000Z",
"updated_at": "2024-03-05T11:50:43.000000Z",
"created_at": "2024-03-05T11:50:43.000000Z",
"customer": {
"id": "89650465",
"first_name": null,
"last_name": null,
"full_name": "",
"email": "[email protected]",
"address": null,
"telephone": null,
"marketing_consented_at": null,
"created_at": "2024-03-05T11:50:43.000000Z",
"updated_at": "2024-03-05T11:50:43.000000Z"
},
"payments": [
{
"id": "ed6d3016",
"order_id": "ed6d3016",
"amount": 8957,
"amount_formatted": "£89.57",
"status": "created",
"reference": "ORDER-DE81",
"pay_link": "https://api.wonderful.one/pay/DE81",
"created_at": "2024-03-05T11:50:43.000000Z",
"updated_at": "2024-03-05T11:50:43.000000Z"
}
],
"order_lines": [
{
"id": "ed6d87e6",
"order_id": "ed6d3016",
"quantity": 1,
"description": "Gorgeous Fresh Soap",
"price": 8957,
"price_formatted": "£89.57",
"created_at": "2024-03-05T11:50:43.000000Z",
"updated_at": "2024-03-05T11:50:43.000000Z"
}
]
}
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Example response (404, Order not found):
{
"error": true,
"message": "Order not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
The public API hash ID of the Order.
total
integer
The total amount of the Order in base currency units (GB Pence).
total_formatted
string
The total amount of the Order as a formatted currency string.
order_status
string
The status of the Order.
amount_refundable
integer
The total amount of the Order that is refundable in base currency units.
amount_pending_refund
integer
The total amount of the Order currently pending refund in base currency units.
amount_refunded
integer
The total amount of the Order that has been refunded in base currency units.
ordered_at
string
The date and time the Order was ordered.
updated_at
string
The date and time the Order was last updated.
created_at
string
The date and time the Order was created on the system.
customer
object
The Customer record associated with the Order.
payments
object[]
All Payment records associated with the Order.
order_lines
object[]
All OrderLine records associated with the Order.
Payments
Quick Pay
requires authentication
The Quick Pay endpoint allows you to create a customer, order, order line, and payment in one request. The minimum data required is the amount and a merchant payment reference (which is shown on the customer's bank statement). If you also provide a customer email address, the order will be linked to the customer record.
Example request:
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\": 1234,
\"merchant_payment_reference\": \"ORDER-1234\",
\"payment_description\": \"Website Order 1234\",
\"customer_email_address\": \"[email protected]\",
\"redirect_url\": \"https:\\/\\/your-website.example.com\\/success\",
\"webhook_url\": \"https:\\/\\/your-website.example.com\\/webhooks\",
\"bank_id\": \"natwest\",
\"skip_confirmation\": false,
\"send_to_tap\": \"a1b2c3d4\"
}"
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",
};
let body = {
"amount": 1234,
"merchant_payment_reference": "ORDER-1234",
"payment_description": "Website Order 1234",
"customer_email_address": "[email protected]",
"redirect_url": "https:\/\/your-website.example.com\/success",
"webhook_url": "https:\/\/your-website.example.com\/webhooks",
"bank_id": "natwest",
"skip_confirmation": false,
"send_to_tap": "a1b2c3d4"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$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' => 1234,
'merchant_payment_reference' => 'ORDER-1234',
'payment_description' => 'Website Order 1234',
'customer_email_address' => '[email protected]',
'redirect_url' => 'https://your-website.example.com/success',
'webhook_url' => 'https://your-website.example.com/webhooks',
'bank_id' => 'natwest',
'skip_confirmation' => false,
'send_to_tap' => 'a1b2c3d4',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/quick-pay'
payload = {
"amount": 1234,
"merchant_payment_reference": "ORDER-1234",
"payment_description": "Website Order 1234",
"customer_email_address": "[email protected]",
"redirect_url": "https:\/\/your-website.example.com\/success",
"webhook_url": "https:\/\/your-website.example.com\/webhooks",
"bank_id": "natwest",
"skip_confirmation": false,
"send_to_tap": "a1b2c3d4"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"data": {
"id": "2760e996",
"order_id": "d3631506",
"amount": 69754,
"amount_formatted": "£697.54",
"status": "cancelled",
"can_be_refunded": 0,
"reference": "ONE-2322",
"pay_link": "http://wonderful-one.test/pay/2322",
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z",
"cancelled_reason": "aborted"
}
}
Example response (201, Success):
{
"data": {
"id": "ed6d3316",
"order_id": "ed6d3316",
"amount": 6482,
"amount_formatted": "£64.82",
"status": "created",
"reference": "ORDER-585516",
"pay_link": "https://api.wonderful.one/pay/DEE1",
"created_at": "2024-03-05T12:20:47.000000Z",
"updated_at": "2024-03-05T12:20:47.000000Z"
}
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Example response (422, Validation failed):
{
"error": true,
"message": "Validation failed",
"invalid_fields": {
"amount": [
"The amount field is required."
],
"merchant_payment_reference": [
"The merchant payment reference field is required."
]
}
}
Example response (422, Invalid send_to_tap):
{
"error": true,
"message": "Validation failed",
"invalid_fields": {
"send_to_tap": [
"The specified Tap device was not found or is not registered to your account."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Payment. Example: 3ed6d864
order_id
string
Public API Hash ID of the Order. Example: 3ed6d864
amount
integer
The amount in base currency units (GB Pence). Example: 1000
amount_formatted
string
The amount as a formatted currency string. Example: £10.00
status
string
The status of the Payment. Possible values are: created, pending, paid, failed, cancelled, part-refunded, refunded, expired, errored. Example: paid
cancelled_reason
string
Optional. Why the payment is in the cancelled status. Possible values: cancelled (the payment was not authorised, e.g. customer cancelled, expired, or not authed at the bank), aborted (the payment was explicitly stopped before authorisation). Present only when status is cancelled. Example: aborted
can_be_refunded
integer
in Can the payment be refunded. 1 - Yes, 0 - No Example: 1
reference
string
The reference of the Payment. Example: ONE-3ed6
pay_link
string
The URL to redirect the customer to for payment. Example: https://wonderful.one/pay/abc123
created_at
string
The date and time the Payment was created. Example: 2024-04-05T14:19:58.000000Z
updated_at
string
The date and time the Payment was last updated. Example: 2024-04-05T14:19:58.000000Z
latest_payment_id
If the original payment was retried, the latest attempted payment ID. Example: 89a59b26
latest_payment_status
string
If the original payment was retried, the status of the latest attempted Payment. Possible values match the status field. Example: paid
List Payments
requires authentication
Returns a paginated collection of Payment records associated with the authenticated Merchant. The results can be filtered by date and a search term, and sorted by creation date or amount.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/payments?search=ORDER&sort=amount_desc&start_date=2023-01-01&end_date=2023-12-31&per_page=100" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/payments"
);
const params = {
"search": "ORDER",
"sort": "amount_desc",
"start_date": "2023-01-01",
"end_date": "2023-12-31",
"per_page": "100",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/payments';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'search' => 'ORDER',
'sort' => 'amount_desc',
'start_date' => '2023-01-01',
'end_date' => '2023-12-31',
'per_page' => '100',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/payments'
params = {
'search': 'ORDER',
'sort': 'amount_desc',
'start_date': '2023-01-01',
'end_date': '2023-12-31',
'per_page': '100',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"id": "d3633436",
"order_id": "05647446",
"amount": 78709,
"amount_formatted": "£787.09",
"status": "created",
"can_be_refunded": 0,
"reference": "ONE-7121",
"pay_link": "http://wonderful-one.test/pay/7121",
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z"
},
{
"id": "0564d826",
"order_id": "d3681e26",
"amount": 19759,
"amount_formatted": "£197.59",
"status": "pending",
"can_be_refunded": 0,
"reference": "ONE-627D",
"pay_link": "http://wonderful-one.test/pay/627D",
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z"
}
]
}
Example response (200, Filtered search, ordered by descending value):
{
"data": [
{
"id": "ed6d3316",
"order_id": "ed6d3316",
"amount": 6482,
"amount_formatted": "£64.82",
"status": "created",
"reference": "ORDER-585516",
"pay_link": "https://api.wonderful.one/pay/DEE1",
"created_at": "2024-03-05T12:20:47.000000Z",
"updated_at": "2024-03-05T12:20:47.000000Z"
},
{
"id": "e2610086",
"order_id": "e2610086",
"amount": 4765,
"amount_formatted": "£47.65",
"status": "created",
"reference": "ORDER-115103",
"pay_link": "https://api.wonderful.one/pay/8552",
"created_at": "2024-03-05T11:58:24.000000Z",
"updated_at": "2024-03-05T11:58:24.000000Z"
},
{
"id": "05644446",
"order_id": "05644446",
"amount": 3058,
"amount_formatted": "£30.58",
"status": "created",
"reference": "ORDER-314744",
"pay_link": "https://api.wonderful.one/pay/6666",
"created_at": "2024-03-05T11:58:22.000000Z",
"updated_at": "2024-03-05T11:58:22.000000Z"
},
{
"id": "d368ee26",
"order_id": "d368ee26",
"amount": 510,
"amount_formatted": "£5.10",
"status": "created",
"reference": "ORDER-302271",
"pay_link": "https://api.wonderful.one/pay/9887",
"created_at": "2024-03-05T11:58:23.000000Z",
"updated_at": "2024-03-05T11:58:23.000000Z"
}
],
"links": {
"first": "https://api.wonderful.one/v2/payments?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "https://api.wonderful.one/v2/payments",
"per_page": "100",
"to": 4
}
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Payment. Example: 3ed6d864
order_id
string
Public API Hash ID of the Order. Example: 3ed6d864
amount
integer
The amount in base currency units (GB Pence). Example: 1000
amount_formatted
string
The amount as a formatted currency string. Example: £10.00
status
string
The status of the Payment. Possible values are: created, pending, paid, failed, cancelled, part-refunded, refunded, expired, errored. Example: paid
cancelled_reason
string
Optional. Why the payment is in the cancelled status. Possible values: cancelled (the payment was not authorised, e.g. customer cancelled, expired, or not authed at the bank), aborted (the payment was explicitly stopped before authorisation). Present only when status is cancelled. Example: aborted
can_be_refunded
integer
in Can the payment be refunded. 1 - Yes, 0 - No Example: 1
reference
string
The reference of the Payment. Example: ONE-3ed6
pay_link
string
The URL to redirect the customer to for payment. Example: https://wonderful.one/pay/abc123
created_at
string
The date and time the Payment was created. Example: 2024-04-05T14:19:58.000000Z
updated_at
string
The date and time the Payment was last updated. Example: 2024-04-05T14:19:58.000000Z
latest_payment_id
If the original payment was retried, the latest attempted payment ID. Example: 89a59b26
latest_payment_status
string
If the original payment was retried, the status of the latest attempted Payment. Possible values match the status field. Example: paid
Show Payment
requires authentication
Retrieves and displays the details of a specific Payment record, identified by its unique Public API Hash ID.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/payments/consequatur" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/payments/consequatur"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/payments/consequatur';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/payments/consequatur'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"data": {
"id": "d36880d6",
"order_id": "e2615086",
"amount": 92620,
"amount_formatted": "£926.20",
"status": "cancelled",
"can_be_refunded": 0,
"reference": "ONE-9613",
"pay_link": "http://wonderful-one.test/pay/9613",
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z",
"cancelled_reason": "cancelled"
}
}
Example response (200):
{
"data": {
"id": "e2611865",
"order_id": "e2611865",
"amount": 1000,
"amount_formatted": "£10.00",
"status": "created",
"reference": "ONE-0862",
"pay_link": "https://api.wonderful.one/pay/0862",
"created_at": "2023-07-07T08:59:55.000000Z",
"updated_at": "2023-07-07T08:59:55.000000Z"
}
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Payment. Example: 3ed6d864
order_id
string
Public API Hash ID of the Order. Example: 3ed6d864
amount
integer
The amount in base currency units (GB Pence). Example: 1000
amount_formatted
string
The amount as a formatted currency string. Example: £10.00
status
string
The status of the Payment. Possible values are: created, pending, paid, failed, cancelled, part-refunded, refunded, expired, errored. Example: paid
cancelled_reason
string
Optional. Why the payment is in the cancelled status. Possible values: cancelled (the payment was not authorised, e.g. customer cancelled, expired, or not authed at the bank), aborted (the payment was explicitly stopped before authorisation). Present only when status is cancelled. Example: aborted
can_be_refunded
integer
in Can the payment be refunded. 1 - Yes, 0 - No Example: 1
reference
string
The reference of the Payment. Example: ONE-3ed6
pay_link
string
The URL to redirect the customer to for payment. Example: https://wonderful.one/pay/abc123
created_at
string
The date and time the Payment was created. Example: 2024-04-05T14:19:58.000000Z
updated_at
string
The date and time the Payment was last updated. Example: 2024-04-05T14:19:58.000000Z
latest_payment_id
If the original payment was retried, the latest attempted payment ID. Example: 89a59b26
latest_payment_status
string
If the original payment was retried, the status of the latest attempted Payment. Possible values match the status field. Example: paid
Delete Payment
requires authentication
Deletes a specific Payment record from the system. This action is only possible if the payment's status is 'created'. If the payment has been processed or is in any other state, it cannot be deleted.
Example request:
curl --request DELETE \
"https://api.wonderful.one/v2/payments/consequatur" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/payments/consequatur"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/payments/consequatur';
$response = $client->delete(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/payments/consequatur'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('DELETE', url, headers=headers)
response.json()Example response (204, Payment was deleted successfully):
Empty response
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Example response (422, Payment cannot be deleted):
{
"error": true,
"message": "Only payments in the 'created' status can be deleted."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Stop Payment
requires authentication
Stops a Payment that has been started but not yet authorised at the bank, so a stale attempt can be retired and a fresh payment link generated immediately. Only single immediate payments are supported.
On success the payment resource is returned with status: cancelled and cancelled_reason: aborted.
The v2 status enum is unchanged by this endpoint; stopped payments are surfaced as cancelled to
avoid breaking existing v2 consumers, and the optional cancelled_reason lets opt-in consumers
tell a stopped payment apart from any other cancelled one.
Example request:
curl --request POST \
"https://api.wonderful.one/v2/payments/consequatur/stop" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/payments/consequatur/stop"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/payments/consequatur/stop';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/payments/consequatur/stop'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers)
response.json()Example response (200):
{
"data": {
"id": "e2614916",
"order_id": "ed6d4316",
"amount": 92620,
"amount_formatted": "£926.20",
"status": "cancelled",
"can_be_refunded": 0,
"reference": "ONE-8146",
"pay_link": "http://wonderful-one.test/pay/8146",
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z",
"cancelled_reason": "cancelled"
}
}
Example response (200, Payment stopped):
{
"data": {
"id": "e2611865",
"order_id": "e2611865",
"amount": 1000,
"amount_formatted": "£10.00",
"status": "cancelled",
"cancelled_reason": "aborted",
"reference": "ONE-0862",
"pay_link": "https://api.wonderful.one/pay/0862",
"created_at": "2023-07-07T08:59:55.000000Z",
"updated_at": "2023-07-07T08:59:55.000000Z"
}
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Example response (404, Payment not found):
{
"error": true,
"message": "Payment not found"
}
Example response (409, Payment can no longer be stopped):
{
"error": true,
"message": "Payment can no longer be stopped; it has already been authorised or processed."
}
Example response (422, Stopping not supported for this payment type):
{
"error": true,
"message": "Stopping is only supported for single immediate payments."
}
Example response (503, Payment is being processed; retry shortly):
{
"error": true,
"message": "The payment is being processed; please retry shortly."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Payment. Example: 3ed6d864
order_id
string
Public API Hash ID of the Order. Example: 3ed6d864
amount
integer
The amount in base currency units (GB Pence). Example: 1000
amount_formatted
string
The amount as a formatted currency string. Example: £10.00
status
string
The status of the Payment. Possible values are: created, pending, paid, failed, cancelled, part-refunded, refunded, expired, errored. Example: paid
cancelled_reason
string
Optional. Why the payment is in the cancelled status. Possible values: cancelled (the payment was not authorised, e.g. customer cancelled, expired, or not authed at the bank), aborted (the payment was explicitly stopped before authorisation). Present only when status is cancelled. Example: aborted
can_be_refunded
integer
in Can the payment be refunded. 1 - Yes, 0 - No Example: 1
reference
string
The reference of the Payment. Example: ONE-3ed6
pay_link
string
The URL to redirect the customer to for payment. Example: https://wonderful.one/pay/abc123
created_at
string
The date and time the Payment was created. Example: 2024-04-05T14:19:58.000000Z
updated_at
string
The date and time the Payment was last updated. Example: 2024-04-05T14:19:58.000000Z
latest_payment_id
If the original payment was retried, the latest attempted payment ID. Example: 89a59b26
latest_payment_status
string
If the original payment was retried, the status of the latest attempted Payment. Possible values match the status field. Example: paid
WooCommerce Payments
requires authentication
The Woo Pay endpoint allows you to create a customer, order, order line, and payment in one request. The minimum data required is the amount and a merchant payment reference (which is shown on the customer's bank statement) and the selected bank. If you also provide a customer email address, the order will be linked to the customer record.
Example request:
curl --request POST \
"https://api.wonderful.one/v2/woo" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"amount\": 1234,
\"merchant_payment_reference\": \"ORDER-1234\",
\"payment_description\": \"Website Order 1234\",
\"customer_email_address\": \"[email protected]\",
\"redirect_url\": \"https:\\/\\/your-website.example.com\\/success\",
\"webhook_url\": \"https:\\/\\/your-website.example.com\\/webhooks\",
\"bank_id\": \"natwest\",
\"skip_confirmation\": false,
\"send_to_tap\": \"a1b2c3d4\",
\"selected_aspsp\": \"tjqotbhpzwonwlzospqcs\"
}"
const url = new URL(
"https://api.wonderful.one/v2/woo"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"amount": 1234,
"merchant_payment_reference": "ORDER-1234",
"payment_description": "Website Order 1234",
"customer_email_address": "[email protected]",
"redirect_url": "https:\/\/your-website.example.com\/success",
"webhook_url": "https:\/\/your-website.example.com\/webhooks",
"bank_id": "natwest",
"skip_confirmation": false,
"send_to_tap": "a1b2c3d4",
"selected_aspsp": "tjqotbhpzwonwlzospqcs"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/woo';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'amount' => 1234,
'merchant_payment_reference' => 'ORDER-1234',
'payment_description' => 'Website Order 1234',
'customer_email_address' => '[email protected]',
'redirect_url' => 'https://your-website.example.com/success',
'webhook_url' => 'https://your-website.example.com/webhooks',
'bank_id' => 'natwest',
'skip_confirmation' => false,
'send_to_tap' => 'a1b2c3d4',
'selected_aspsp' => 'tjqotbhpzwonwlzospqcs',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/woo'
payload = {
"amount": 1234,
"merchant_payment_reference": "ORDER-1234",
"payment_description": "Website Order 1234",
"customer_email_address": "[email protected]",
"redirect_url": "https:\/\/your-website.example.com\/success",
"webhook_url": "https:\/\/your-website.example.com\/webhooks",
"bank_id": "natwest",
"skip_confirmation": false,
"send_to_tap": "a1b2c3d4",
"selected_aspsp": "tjqotbhpzwonwlzospqcs"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Show method to retrieve payment details from Wonderful Payments service.
requires authentication
This method retrieves the authenticated user's associated merchant, and then returns the response from the Wonderful Payments service for the specified payment ID.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/woo/consequatur" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/woo/consequatur"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/woo/consequatur';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/woo/consequatur'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Generate a reference code for the authenticated merchant.
requires authentication
This method retrieves the authenticated user's associated merchant, generates a hashed reference code using Hashids, and returns it as JSON. If the authenticated user is not a merchant, it returns an error response.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/ref" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/ref"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/ref';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/ref'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
QR Codes
List QR Codes
requires authentication
Lists all QR Codes associated with the Merchant
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/qr-codes" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/qr-codes"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/qr-codes';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/qr-codes'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"data": [
{
"id": "27600476",
"amount": 2404,
"amount_formatted": "£24.04",
"label": "quaerat ipsum earum",
"customer_data_collection": null,
"pay_link": "http://wonderful-one.test/qr-code/3106",
"image_link": "http://wonderful-one.test/qr-code-image/3106",
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z"
},
{
"id": "d363d956",
"amount": 7428,
"amount_formatted": "£74.28",
"label": "dicta accusamus non",
"customer_data_collection": null,
"pay_link": "http://wonderful-one.test/qr-code/912d",
"image_link": "http://wonderful-one.test/qr-code-image/912d",
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z"
}
]
}
Example response (200):
{
"data": [
{
"id": "1d368e62",
"amount": 1000,
"amount_formatted": "£10.00",
"label": "My first QR code",
"pay_link": "https://api.wonderful-one.test/qr-code/e24e",
"image_link": "https://api.wonderful-one.test/qr-code-image/e24e",
"created_at": "2023-07-05T15:03:23.000000Z",
"updated_at": "2023-07-05T15:03:23.000000Z"
},
{
"id": "0e261265",
"amount": 1234,
"amount_formatted": "£12.34",
"label": "My second QR code",
"pay_link": "https://api.wonderful-one.test/qr-code/ed4e",
"image_link": "https://api.wonderful-one.test/qr-code-image/ed4e",
"created_at": "2023-07-05T15:04:05.000000Z",
"updated_at": "2023-07-05T15:04:05.000000Z"
}
]
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the QR Code. Example: 3ed6d864
amount
integer
The amount in base currency units (GB Pence). Example: 1000
amount_formatted
string
The amount as a formatted currency string. Example: £10.00
label
string
The label of the QR Code. Example: Blue Widget
customer_data_collection
string|null
The customer data collection level. One of: "none" (no data collected), "email_only" (email required), "contact_light" (email required, first/last name optional), "contact_full" (email, first/last name required), "billing" (full contact and address details). Example: email_only
pay_link
string
The URL to redirect the customer to for payment. Example: https://api.wonderful.one/qr-code/abc123
image_link
string
Generated QR code image URL that will redirect the customer to the Pay Link. Example: https://api.wonderful.one/qr-code-image/abc123
created_at
string
The date and time the QR Code was created. Example: 2023-05-02T22:07:21.000000Z
updated_at
string
The date and time the QR Code was last updated. Example: 2023-05-02T22:07:21.000000Z
Create QR Code
requires authentication
Inserts a new QR Code record.
Example request:
curl --request POST \
"https://api.wonderful.one/v2/qr-codes" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"amount\": 1234,
\"label\": \"Blue Widget\",
\"customer_data_collection\": \"email_only\"
}"
const url = new URL(
"https://api.wonderful.one/v2/qr-codes"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"amount": 1234,
"label": "Blue Widget",
"customer_data_collection": "email_only"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/qr-codes';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'amount' => 1234,
'label' => 'Blue Widget',
'customer_data_collection' => 'email_only',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/qr-codes'
payload = {
"amount": 1234,
"label": "Blue Widget",
"customer_data_collection": "email_only"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"data": {
"id": "05645056",
"amount": 5045,
"amount_formatted": "£50.45",
"label": "dolor et optio",
"customer_data_collection": null,
"pay_link": "http://wonderful-one.test/qr-code/5080",
"image_link": "http://wonderful-one.test/qr-code-image/5080",
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z"
}
}
Example response (201, Created successfully):
{
"data": {
"id": "0e261265",
"amount": 1000,
"amount_formatted": "£10.00",
"label": "My first QR code",
"pay_link": "https://api.wonderful-one.test/qr-code/ed4e",
"image_link": "https://api.wonderful-one.test/qr-code-image/ed4e",
"created_at": "2023-07-05T15:04:05.000000Z",
"updated_at": "2023-07-05T15:04:05.000000Z"
}
}
Example response (422, Validation error):
{
"error": true,
"message": "Validation failed",
"invalid_fields": {
"amount": [
"The amount field is required."
],
"label": [
"The label field is required."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the QR Code. Example: 3ed6d864
amount
integer
The amount in base currency units (GB Pence). Example: 1000
amount_formatted
string
The amount as a formatted currency string. Example: £10.00
label
string
The label of the QR Code. Example: Blue Widget
customer_data_collection
string|null
The customer data collection level. One of: "none" (no data collected), "email_only" (email required), "contact_light" (email required, first/last name optional), "contact_full" (email, first/last name required), "billing" (full contact and address details). Example: email_only
pay_link
string
The URL to redirect the customer to for payment. Example: https://api.wonderful.one/qr-code/abc123
image_link
string
Generated QR code image URL that will redirect the customer to the Pay Link. Example: https://api.wonderful.one/qr-code-image/abc123
created_at
string
The date and time the QR Code was created. Example: 2023-05-02T22:07:21.000000Z
updated_at
string
The date and time the QR Code was last updated. Example: 2023-05-02T22:07:21.000000Z
Show QR Code
requires authentication
Show the details of a specific QR Code record. Pass the Public API Hash ID of the QR Code you wand to retrieve on the URL.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/qr-codes/0e261265" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/qr-codes/0e261265"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/qr-codes/0e261265';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/qr-codes/0e261265'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"data": {
"id": "d3682776",
"amount": 2404,
"amount_formatted": "£24.04",
"label": "quaerat ipsum earum",
"customer_data_collection": null,
"pay_link": "http://wonderful-one.test/qr-code/2800",
"image_link": "http://wonderful-one.test/qr-code-image/2800",
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z"
}
}
Example response (200):
{
"data": {
"id": "0e261265",
"amount": 1000,
"amount_formatted": "£10.00",
"label": "My first QR code",
"pay_link": "https://api.wonderful-one.test/qr-code/ed4e",
"image_link": "https://api.wonderful-one.test/qr-code-image/ed4e",
"created_at": "2023-07-05T15:04:05.000000Z",
"updated_at": "2023-07-05T15:04:05.000000Z"
}
}
Example response (404, QR code not found):
{
"error": true,
"message": "QR code not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the QR Code. Example: 3ed6d864
amount
integer
The amount in base currency units (GB Pence). Example: 1000
amount_formatted
string
The amount as a formatted currency string. Example: £10.00
label
string
The label of the QR Code. Example: Blue Widget
customer_data_collection
string|null
The customer data collection level. One of: "none" (no data collected), "email_only" (email required), "contact_light" (email required, first/last name optional), "contact_full" (email, first/last name required), "billing" (full contact and address details). Example: email_only
pay_link
string
The URL to redirect the customer to for payment. Example: https://api.wonderful.one/qr-code/abc123
image_link
string
Generated QR code image URL that will redirect the customer to the Pay Link. Example: https://api.wonderful.one/qr-code-image/abc123
created_at
string
The date and time the QR Code was created. Example: 2023-05-02T22:07:21.000000Z
updated_at
string
The date and time the QR Code was last updated. Example: 2023-05-02T22:07:21.000000Z
Update QR Code.
requires authentication
Note: You must pass both the amount and label values even if only one of them has changed.
Example request:
curl --request PUT \
"https://api.wonderful.one/v2/qr-codes/0e261265" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"amount\": 1234,
\"label\": \"Blue Widget\",
\"customer_data_collection\": \"email_only\"
}"
const url = new URL(
"https://api.wonderful.one/v2/qr-codes/0e261265"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"amount": 1234,
"label": "Blue Widget",
"customer_data_collection": "email_only"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/qr-codes/0e261265';
$response = $client->put(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'amount' => 1234,
'label' => 'Blue Widget',
'customer_data_collection' => 'email_only',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/qr-codes/0e261265'
payload = {
"amount": 1234,
"label": "Blue Widget",
"customer_data_collection": "email_only"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('PUT', url, headers=headers, json=payload)
response.json()Example response (200):
{
"data": {
"id": "e26128e6",
"amount": 5045,
"amount_formatted": "£50.45",
"label": "dolor et optio",
"customer_data_collection": null,
"pay_link": "http://wonderful-one.test/qr-code/d4d7",
"image_link": "http://wonderful-one.test/qr-code-image/d4d7",
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z"
}
}
Example response (200, Updated successfully):
{
"data": {
"id": "0e261265",
"amount": 1000,
"amount_formatted": "£10.00",
"label": "My first QR code",
"pay_link": "https://api.wonderful-one.test/qr-code/ed4e",
"image_link": "https://api.wonderful-one.test/qr-code-image/ed4e",
"created_at": "2023-07-05T15:04:05.000000Z",
"updated_at": "2023-07-05T15:04:05.000000Z"
}
}
Example response (422, Validation error):
{
"error": true,
"message": "Validation failed",
"invalid_fields": {
"amount": [
"The amount field is required."
],
"label": [
"The label field is required."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the QR Code. Example: 3ed6d864
amount
integer
The amount in base currency units (GB Pence). Example: 1000
amount_formatted
string
The amount as a formatted currency string. Example: £10.00
label
string
The label of the QR Code. Example: Blue Widget
customer_data_collection
string|null
The customer data collection level. One of: "none" (no data collected), "email_only" (email required), "contact_light" (email required, first/last name optional), "contact_full" (email, first/last name required), "billing" (full contact and address details). Example: email_only
pay_link
string
The URL to redirect the customer to for payment. Example: https://api.wonderful.one/qr-code/abc123
image_link
string
Generated QR code image URL that will redirect the customer to the Pay Link. Example: https://api.wonderful.one/qr-code-image/abc123
created_at
string
The date and time the QR Code was created. Example: 2023-05-02T22:07:21.000000Z
updated_at
string
The date and time the QR Code was last updated. Example: 2023-05-02T22:07:21.000000Z
Delete QR Code
requires authentication
The delete QR code endpoint will "soft-delete" a QR code record. There is no mechanism via the API to restore a deleted record, if you need to restore a previously deleted record you will need to contact the support team.
Note that a successful delete will return a HTTP 204 with an empty response body. Attempting to delete an already deleted record will return a HTTP 404 "not found" response.
Example request:
curl --request DELETE \
"https://api.wonderful.one/v2/qr-codes/0e261265" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/qr-codes/0e261265"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/qr-codes/0e261265';
$response = $client->delete(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/qr-codes/0e261265'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('DELETE', url, headers=headers)
response.json()Example response (204, QR code deleted):
Empty response
Example response (404, QR code not found):
{
"error": true,
"message": "QR code not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Items
List Items
requires authentication
Lists the merchant's Items. Supports basic searching on name and description, ordering of results, and pagination. Default pagination is 25 results per page.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/items?search=coffee&sort=name_asc&per_page=10" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/items"
);
const params = {
"search": "coffee",
"sort": "name_asc",
"per_page": "10",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/items';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'search' => 'coffee',
'sort' => 'name_asc',
'per_page' => '10',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/items'
params = {
'search': 'coffee',
'sort': 'name_asc',
'per_page': '10',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"id": "d363e165",
"name": "consequatur dolor et",
"description": "Rerum quaerat ut fuga non quibusdam itaque ut.",
"price": 618,
"price_formatted": "£6.18",
"is_favourite": false,
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z"
},
{
"id": "05649367",
"name": "voluptatum occaecati nihil",
"description": "Quaerat ipsum earum vel qui itaque voluptatem quis.",
"price": 7428,
"price_formatted": "£74.28",
"is_favourite": false,
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z"
}
],
"links": {
"first": "/?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "/",
"per_page": "25",
"to": 2
}
}
Example response (200):
{
"data": [
{
"id": "1d368e62",
"name": "Coffee",
"description": "Freshly ground",
"price": 250,
"price_formatted": "£2.50",
"is_favourite": false,
"created_at": "2023-05-02T22:07:21.000000Z",
"updated_at": "2023-05-02T22:07:21.000000Z"
}
],
"links": {
"first": "https://api.wonderful.one/v2/items?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "https://api.wonderful.one/v2/items",
"per_page": 25,
"to": 1
}
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Item.
name
string
The name of the Item. Example: Coffee
description
string
nullable The description of the Item. Example: Freshly ground
price
integer
The price of the Item in base currency units (GB Pence). Example: 250
price_formatted
string
The price of the Item as a formatted currency string. Example: £2.50
is_favourite
boolean
Whether the authenticated user has favourited the Item. Example: false
created_at
string
The date and time the Item was created. Example: 2023-05-02T22:07:21.000000Z
updated_at
string
The date and time the Item was last updated. Example: 2023-05-02T22:07:21.000000Z
Create Item
requires authentication
Inserts a new Item record.
Example request:
curl --request POST \
"https://api.wonderful.one/v2/items" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Coffee\",
\"description\": \"Freshly ground\",
\"price\": 250
}"
const url = new URL(
"https://api.wonderful.one/v2/items"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Coffee",
"description": "Freshly ground",
"price": 250
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/items';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'name' => 'Coffee',
'description' => 'Freshly ground',
'price' => 250,
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/items'
payload = {
"name": "Coffee",
"description": "Freshly ground",
"price": 250
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"data": {
"id": "d368de62",
"name": "consequatur dolor et",
"description": "Rerum quaerat ut fuga non quibusdam itaque ut.",
"price": 618,
"price_formatted": "£6.18",
"is_favourite": false,
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z"
}
}
Example response (201, Created successfully):
{
"data": {
"id": "1d368e62",
"name": "Coffee",
"description": "Freshly ground",
"price": 250,
"price_formatted": "£2.50",
"is_favourite": false,
"created_at": "2023-05-02T22:07:21.000000Z",
"updated_at": "2023-05-02T22:07:21.000000Z"
}
}
Example response (422, Validation error):
{
"error": true,
"message": "Validation failed",
"invalid_fields": {
"name": [
"The name field is required."
],
"price": [
"The price field is required."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Item.
name
string
The name of the Item. Example: Coffee
description
string
nullable The description of the Item. Example: Freshly ground
price
integer
The price of the Item in base currency units (GB Pence). Example: 250
price_formatted
string
The price of the Item as a formatted currency string. Example: £2.50
is_favourite
boolean
Whether the authenticated user has favourited the Item. Example: false
created_at
string
The date and time the Item was created. Example: 2023-05-02T22:07:21.000000Z
updated_at
string
The date and time the Item was last updated. Example: 2023-05-02T22:07:21.000000Z
Show Item
requires authentication
Show the details of a specific Item record. Pass the Public API Hash ID of the Item you want to retrieve on the URL.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/items/1d368e62" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/items/1d368e62"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/items/1d368e62';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/items/1d368e62'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"data": {
"id": "e2617265",
"name": "quam quaerat ipsum",
"description": "Vel qui itaque voluptatem quis numquam dicta accusamus.",
"price": 7683,
"price_formatted": "£76.83",
"is_favourite": false,
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z"
}
}
Example response (200):
{
"data": {
"id": "1d368e62",
"name": "Coffee",
"description": "Freshly ground",
"price": 250,
"price_formatted": "£2.50",
"is_favourite": false,
"created_at": "2023-05-02T22:07:21.000000Z",
"updated_at": "2023-05-02T22:07:21.000000Z"
}
}
Example response (404, Item not found):
{
"error": true,
"message": "Item not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Item.
name
string
The name of the Item. Example: Coffee
description
string
nullable The description of the Item. Example: Freshly ground
price
integer
The price of the Item in base currency units (GB Pence). Example: 250
price_formatted
string
The price of the Item as a formatted currency string. Example: £2.50
is_favourite
boolean
Whether the authenticated user has favourited the Item. Example: false
created_at
string
The date and time the Item was created. Example: 2023-05-02T22:07:21.000000Z
updated_at
string
The date and time the Item was last updated. Example: 2023-05-02T22:07:21.000000Z
Update Item
requires authentication
Note: Pushing an update to an item will update the entire entity, so you must pass all the fields including those that have not changed.
Example request:
curl --request PUT \
"https://api.wonderful.one/v2/items/1d368e62" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Coffee\",
\"description\": \"Freshly ground\",
\"price\": 250
}"
const url = new URL(
"https://api.wonderful.one/v2/items/1d368e62"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Coffee",
"description": "Freshly ground",
"price": 250
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/items/1d368e62';
$response = $client->put(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'name' => 'Coffee',
'description' => 'Freshly ground',
'price' => 250,
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/items/1d368e62'
payload = {
"name": "Coffee",
"description": "Freshly ground",
"price": 250
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('PUT', url, headers=headers, json=payload)
response.json()Example response (200):
{
"data": {
"id": "ed6d9864",
"name": "consequatur dolor et",
"description": "Rerum quaerat ut fuga non quibusdam itaque ut.",
"price": 618,
"price_formatted": "£6.18",
"is_favourite": false,
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z"
}
}
Example response (200, Updated successfully):
{
"data": {
"id": "1d368e62",
"name": "Coffee",
"description": "Freshly ground",
"price": 250,
"price_formatted": "£2.50",
"is_favourite": false,
"created_at": "2023-05-02T22:07:21.000000Z",
"updated_at": "2023-05-02T22:07:21.000000Z"
}
}
Example response (422, Validation error):
{
"error": true,
"message": "Validation failed",
"invalid_fields": {
"name": [
"The name field is required."
],
"price": [
"The price field is required."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Item.
name
string
The name of the Item. Example: Coffee
description
string
nullable The description of the Item. Example: Freshly ground
price
integer
The price of the Item in base currency units (GB Pence). Example: 250
price_formatted
string
The price of the Item as a formatted currency string. Example: £2.50
is_favourite
boolean
Whether the authenticated user has favourited the Item. Example: false
created_at
string
The date and time the Item was created. Example: 2023-05-02T22:07:21.000000Z
updated_at
string
The date and time the Item was last updated. Example: 2023-05-02T22:07:21.000000Z
Delete Item
requires authentication
The delete item endpoint will "soft-delete" an item record. There is no mechanism via the API to restore a deleted record, if you need to restore a previously deleted record you will need to contact the support team.
Existing order lines that were created from the item are not affected because their name, description and price are snapshotted.
Note that a successful delete will return a HTTP 204 with an empty response body. Attempting to delete an already deleted record will return a HTTP 404 "not found" response.
Example request:
curl --request DELETE \
"https://api.wonderful.one/v2/items/1d368e62" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/items/1d368e62"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/items/1d368e62';
$response = $client->delete(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/items/1d368e62'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('DELETE', url, headers=headers)
response.json()Example response (204, Item deleted):
Empty response
Example response (404, Item not found):
{
"error": true,
"message": "Item not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Favourites
List Favourites
requires authentication
Lists the authenticated user's favourite Items, in their chosen order. Supports pagination. Default pagination is 25 results per page.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/favourites?per_page=10" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/favourites"
);
const params = {
"per_page": "10",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/favourites';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'per_page' => '10',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/favourites'
params = {
'per_page': '10',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"id": "1d671869",
"name": "fuga non quibusdam",
"description": "Ut quia at quia quibusdam.",
"price": 2688,
"price_formatted": "£26.88",
"is_favourite": true,
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z",
"position": 1
},
{
"id": "8e6e0562",
"name": "itaque voluptatem quis",
"description": "Dicta accusamus non laboriosam ad.",
"price": 4381,
"price_formatted": "£43.81",
"is_favourite": true,
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z",
"position": 1
}
],
"links": {
"first": "/?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "/",
"per_page": "25",
"to": 2
}
}
Example response (200):
{
"data": [
{
"id": "1d368e62",
"name": "Coffee",
"description": "Freshly ground",
"price": 250,
"price_formatted": "£2.50",
"is_favourite": true,
"position": 1,
"created_at": "2023-05-02T22:07:21.000000Z",
"updated_at": "2023-05-02T22:07:21.000000Z"
}
],
"links": {
"first": "https://api.wonderful.one/v2/favourites?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "https://api.wonderful.one/v2/favourites",
"per_page": 25,
"to": 1
}
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Item.
name
string
The name of the Item. Example: Coffee
description
string
nullable The description of the Item. Example: Freshly ground
price
integer
The price of the Item in base currency units (GB Pence). Example: 250
price_formatted
string
The price of the Item as a formatted currency string. Example: £2.50
is_favourite
boolean
Always true for a favourite. Example: true
position
integer
The position of the Item in the user's favourites list. Example: 1
created_at
string
The date and time the Item was created. Example: 2023-05-02T22:07:21.000000Z
updated_at
string
The date and time the Item was last updated. Example: 2023-05-02T22:07:21.000000Z
Add Favourite
requires authentication
Adds an Item to the authenticated user's favourites, appended to the end of the list. Adding an Item that is already a favourite returns HTTP 200 and does not change its position.
Example request:
curl --request POST \
"https://api.wonderful.one/v2/favourites" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"item_id\": \"1d368e62\"
}"
const url = new URL(
"https://api.wonderful.one/v2/favourites"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"item_id": "1d368e62"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/favourites';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'item_id' => '1d368e62',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/favourites'
payload = {
"item_id": "1d368e62"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"data": {
"id": "2862e863",
"name": "accusamus non laboriosam",
"description": "Eius tempore error rerum et autem.",
"price": 1994,
"price_formatted": "£19.94",
"is_favourite": true,
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z",
"position": 1
}
}
Example response (201, Created successfully):
{
"data": {
"id": "1d368e62",
"name": "Coffee",
"description": "Freshly ground",
"price": 250,
"price_formatted": "£2.50",
"is_favourite": true,
"position": 1,
"created_at": "2023-05-02T22:07:21.000000Z",
"updated_at": "2023-05-02T22:07:21.000000Z"
}
}
Example response (400, Validation error):
{
"error": true,
"message": "Validation failed",
"invalid_fields": {
"item_id": [
"The item id field is required."
]
}
}
Example response (404, Item not found):
{
"error": true,
"message": "Item not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Item.
name
string
The name of the Item. Example: Coffee
description
string
nullable The description of the Item. Example: Freshly ground
price
integer
The price of the Item in base currency units (GB Pence). Example: 250
price_formatted
string
The price of the Item as a formatted currency string. Example: £2.50
is_favourite
boolean
Always true for a favourite. Example: true
position
integer
The position of the Item in the user's favourites list. Example: 1
created_at
string
The date and time the Item was created. Example: 2023-05-02T22:07:21.000000Z
updated_at
string
The date and time the Item was last updated. Example: 2023-05-02T22:07:21.000000Z
Reorder Favourites
requires authentication
Persists a new order for the authenticated user's favourites. Every supplied Item must be one of the user's current favourites.
Example request:
curl --request PATCH \
"https://api.wonderful.one/v2/favourites/reorder" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"item_ids\": [
\"consequatur\"
]
}"
const url = new URL(
"https://api.wonderful.one/v2/favourites/reorder"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"item_ids": [
"consequatur"
]
};
fetch(url, {
method: "PATCH",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/favourites/reorder';
$response = $client->patch(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'item_ids' => [
'consequatur',
],
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/favourites/reorder'
payload = {
"item_ids": [
"consequatur"
]
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('PATCH', url, headers=headers, json=payload)
response.json()Example response (200):
{
"data": [
{
"id": "d9693560",
"name": "non quibusdam itaque",
"description": "Quia at quia quibusdam commodi fugiat.",
"price": 9909,
"price_formatted": "£99.09",
"is_favourite": true,
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z",
"position": 1
},
{
"id": "89654465",
"name": "numquam dicta accusamus",
"description": "Laboriosam ad eius tempore error.",
"price": 9970,
"price_formatted": "£99.70",
"is_favourite": true,
"created_at": "2026-09-15T15:49:44.000000Z",
"updated_at": "2026-09-15T15:49:44.000000Z",
"position": 1
}
]
}
Example response (200):
{
"data": [
{
"id": "a1b2c3d4",
"name": "Tea",
"description": "Earl grey",
"price": 300,
"price_formatted": "£3.00",
"is_favourite": true,
"position": 1,
"created_at": "2023-05-02T22:07:21.000000Z",
"updated_at": "2023-05-02T22:07:21.000000Z"
},
{
"id": "1d368e62",
"name": "Coffee",
"description": "Freshly ground",
"price": 250,
"price_formatted": "£2.50",
"is_favourite": true,
"position": 2,
"created_at": "2023-05-02T22:07:21.000000Z",
"updated_at": "2023-05-02T22:07:21.000000Z"
}
]
}
Example response (400, Validation error):
{
"error": true,
"message": "Validation failed",
"invalid_fields": {
"item_ids": [
"The supplied items are not all favourites."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
Public API Hash ID of the Item.
name
string
The name of the Item. Example: Coffee
description
string
nullable The description of the Item. Example: Freshly ground
price
integer
The price of the Item in base currency units (GB Pence). Example: 250
price_formatted
string
The price of the Item as a formatted currency string. Example: £2.50
is_favourite
boolean
Always true for a favourite. Example: true
position
integer
The position of the Item in the user's favourites list. Example: 1
created_at
string
The date and time the Item was created. Example: 2023-05-02T22:07:21.000000Z
updated_at
string
The date and time the Item was last updated. Example: 2023-05-02T22:07:21.000000Z
Remove Favourite
requires authentication
Removes an Item from the authenticated user's favourites. A successful remove returns a HTTP 204 with an empty response body. Removing an Item that is not a favourite returns a HTTP 404.
Example request:
curl --request DELETE \
"https://api.wonderful.one/v2/favourites/1d368e62" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/favourites/1d368e62"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/favourites/1d368e62';
$response = $client->delete(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/favourites/1d368e62'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('DELETE', url, headers=headers)
response.json()Example response (204, Favourite removed):
Empty response
Example response (404, Favourite not found):
{
"error": true,
"message": "Favourite not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Tap Devices
List Tap devices
requires authentication
Lists all registered Tap devices associated with the authenticated merchant.
Tap devices can only be registered via the merchant dashboard interface at this time.
Optionally filter by action type using the action query parameter.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/tap-devices?action[]=merchant_link" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/tap-devices"
);
const params = {
"action[0]": "merchant_link",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/tap-devices';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'action[0]' => 'merchant_link',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/tap-devices'
params = {
'action[0]': 'merchant_link',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"id": "onmw8",
"name": null,
"action": null,
"reusable_link": null,
"registered_at": null,
"tap_url": "http://wonderful-one.test/tap/onmw8"
},
{
"id": "6w5r6",
"name": null,
"action": null,
"reusable_link": null,
"registered_at": null,
"tap_url": "http://wonderful-one.test/tap/6w5r6"
}
]
}
Example response (200):
{
"data": [
{
"id": "a1b2c3d4",
"name": "Front counter",
"action": "tap_payments",
"reusable_link": null,
"registered_at": "2024-06-15T10:30:00.000000Z",
"tap_url": "https://api.wonderful.one/tap/a1b2c3d4"
},
{
"id": "e5f6g7h8",
"name": "Back office",
"action": "reusable_payment",
"reusable_link": "0e261265",
"registered_at": "2024-07-20T14:15:00.000000Z",
"tap_url": "https://api.wonderful.one/tap/e5f6g7h8"
}
]
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
The Tap device hash ID. Example: a1b2c3d4
name
string
The name of the Tap device. Example: Front counter
action
string
The current action type. Example: tap_payments
reusable_link
string|null
The linked QR code public API hash ID, or null. Example: 0e261265
registered_at
string
The registration date. Example: 2024-06-15T10:30:00.000000Z
Notifications
List Notifications
requires authentication
Lists the authenticated user's notifications, newest first. By default only
unread notifications are returned; use the status query parameter to include
read notifications or all notifications. Supports pagination. Default pagination
is 25 results per page.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/notifications?status=unread&per_page=10" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/notifications"
);
const params = {
"status": "unread",
"per_page": "10",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/notifications';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'status' => 'unread',
'per_page' => '10',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/notifications'
params = {
'status': 'unread',
'per_page': '10',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"id": null,
"type": "",
"title": null,
"message": null,
"url": null,
"payload": [],
"read": false,
"read_at": null,
"created_at": null
},
{
"id": null,
"type": "",
"title": null,
"message": null,
"url": null,
"payload": [],
"read": false,
"read_at": null,
"created_at": null
}
],
"links": {
"first": "/?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "/",
"per_page": "25",
"to": 2
}
}
Example response (200):
{
"data": [
{
"id": "9d8f1c2e-6a1b-4f0e-9c3d-2b7a5e4d1f88",
"type": "AppUpdateNotification",
"title": "Wonderful dashboard updated to version 2.1.0",
"message": "Click the button to view the latest features.",
"url": "https://wonderful.one/latest",
"payload": {
"title": "Wonderful dashboard updated to version 2.1.0",
"message": "Click the button to view the latest features.",
"url": "https://wonderful.one/latest"
},
"read": false,
"read_at": null,
"created_at": "2026-09-15T10:30:00.000000Z"
}
],
"links": {
"first": "https://api.wonderful.one/v2/notifications?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"path": "https://api.wonderful.one/v2/notifications",
"per_page": 25
}
}
Example response (400, Validation error):
{
"error": true,
"message": "Validation failed",
"invalid_fields": {
"status": [
"The selected status is invalid."
]
}
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
The notification UUID. Example: 9d8f1c2e-6a1b-4f0e-9c3d-2b7a5e4d1f88
type
string
The notification type (class basename). Example: AppUpdateNotification
title
string|null
The notification title. Example: Wonderful dashboard updated to version 2.1.0
message
string|null
The notification message. Example: Click the button to view the latest features.
payload
object
The raw notification payload.
read
boolean
Whether the notification has been read.
read_at
string|null
The time the notification was read, or null. Example: null
created_at
string
The time the notification was created. Example: 2026-09-15T10:30:00.000000Z
Unread Notification Count
requires authentication
Returns the number of unread notifications for the authenticated user.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/notifications/unread-count" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/notifications/unread-count"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/notifications/unread-count';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/notifications/unread-count'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200, Success):
{
"unread_count": 3
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Mark All Notifications As Read
requires authentication
Marks every unread notification for the authenticated user as read and returns the number of notifications affected.
Example request:
curl --request POST \
"https://api.wonderful.one/v2/notifications/read-all" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/notifications/read-all"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/notifications/read-all';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/notifications/read-all'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers)
response.json()Example response (200, Success):
{
"marked_read": 3
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Show Notification
requires authentication
Returns a single notification belonging to the authenticated user. Viewing a notification does not mark it as read.
Example request:
curl --request GET \
--get "https://api.wonderful.one/v2/notifications/consequatur" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/notifications/consequatur"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/notifications/consequatur';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/notifications/consequatur'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"data": {
"id": null,
"type": "",
"title": null,
"message": null,
"url": null,
"payload": [],
"read": false,
"read_at": null,
"created_at": null
}
}
Example response (200):
{
"data": {
"id": "9d8f1c2e-6a1b-4f0e-9c3d-2b7a5e4d1f88",
"type": "AppUpdateNotification",
"title": "Wonderful dashboard updated to version 2.1.0",
"message": "Click the button to view the latest features.",
"url": "https://wonderful.one/latest",
"payload": {
"title": "Wonderful dashboard updated to version 2.1.0",
"message": "Click the button to view the latest features.",
"url": "https://wonderful.one/latest"
},
"read": false,
"read_at": null,
"created_at": "2026-09-15T10:30:00.000000Z"
}
}
Example response (404, Notification not found):
{
"error": true,
"message": "Notification not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
The notification UUID. Example: 9d8f1c2e-6a1b-4f0e-9c3d-2b7a5e4d1f88
type
string
The notification type (class basename). Example: AppUpdateNotification
title
string|null
The notification title. Example: Wonderful dashboard updated to version 2.1.0
message
string|null
The notification message. Example: Click the button to view the latest features.
payload
object
The raw notification payload.
read
boolean
Whether the notification has been read.
read_at
string|null
The time the notification was read, or null. Example: null
created_at
string
The time the notification was created. Example: 2026-09-15T10:30:00.000000Z
Mark Notification As Read
requires authentication
Marks a single notification belonging to the authenticated user as read. The operation is idempotent.
Example request:
curl --request POST \
"https://api.wonderful.one/v2/notifications/2f6c8e1a-9b3d-4c7e-8a10-5d2f6b9c4e71/read" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/notifications/2f6c8e1a-9b3d-4c7e-8a10-5d2f6b9c4e71/read"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/notifications/2f6c8e1a-9b3d-4c7e-8a10-5d2f6b9c4e71/read';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/notifications/2f6c8e1a-9b3d-4c7e-8a10-5d2f6b9c4e71/read'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers)
response.json()Example response (200):
{
"data": {
"id": null,
"type": "",
"title": null,
"message": null,
"url": null,
"payload": [],
"read": false,
"read_at": null,
"created_at": null
}
}
Example response (200, Marked as read):
{
"data": {
"id": "9d8f1c2e-6a1b-4f0e-9c3d-2b7a5e4d1f88",
"type": "AppUpdateNotification",
"title": "Wonderful dashboard updated to version 2.1.0",
"message": "Click the button to view the latest features.",
"url": "https://wonderful.one/latest",
"payload": {
"title": "Wonderful dashboard updated to version 2.1.0",
"message": "Click the button to view the latest features.",
"url": "https://wonderful.one/latest"
},
"read": true,
"read_at": "2026-09-15T11:00:00.000000Z",
"created_at": "2026-09-15T10:30:00.000000Z"
}
}
Example response (404, Notification not found):
{
"error": true,
"message": "Notification not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
string
The notification UUID. Example: 9d8f1c2e-6a1b-4f0e-9c3d-2b7a5e4d1f88
type
string
The notification type (class basename). Example: AppUpdateNotification
title
string|null
The notification title. Example: Wonderful dashboard updated to version 2.1.0
message
string|null
The notification message. Example: Click the button to view the latest features.
payload
object
The raw notification payload.
read
boolean
Whether the notification has been read.
read_at
string|null
The time the notification was read, or null. Example: null
created_at
string
The time the notification was created. Example: 2026-09-15T10:30:00.000000Z
Delete Notification
requires authentication
Deletes a single notification belonging to the authenticated user. Returns HTTP 204 with an empty response body.
Example request:
curl --request DELETE \
"https://api.wonderful.one/v2/notifications/consequatur" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.wonderful.one/v2/notifications/consequatur"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/notifications/consequatur';
$response = $client->delete(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/notifications/consequatur'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('DELETE', url, headers=headers)
response.json()Example response (204, Notification deleted):
Empty response
Example response (404, Notification not found):
{
"error": true,
"message": "Notification not found"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST v2/woo/{id}/refund
requires authentication
Example request:
curl --request POST \
"https://api.wonderful.one/v2/woo/consequatur/refund" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"refund_amount\": 1234,
\"reference\": \"REFUND-1234\",
\"reason\": \"Item returned, too big.\"
}"
const url = new URL(
"https://api.wonderful.one/v2/woo/consequatur/refund"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"refund_amount": 1234,
"reference": "REFUND-1234",
"reason": "Item returned, too big."
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.wonderful.one/v2/woo/consequatur/refund';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'refund_amount' => 1234,
'reference' => 'REFUND-1234',
'reason' => 'Item returned, too big.',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/woo/consequatur/refund'
payload = {
"refund_amount": 1234,
"reference": "REFUND-1234",
"reason": "Item returned, too big."
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Supported Banks.
requires authentication
Some API endponts require a bank to be selected. Use this endpoint to get a list of all the currently active bank IDs, along with their display names and logos.
Example request:
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());$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 = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://api.wonderful.one/v2/supported-banks'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"data": [
{
"bank_id": "aib",
"bank_name": "Allied Irish Bank (GB)",
"bank_logo": "https://wonderful.co.uk/img/bank_logos/aib.png",
"status": "online"
},
{
"bank_id": "danske",
"bank_name": "Danske Bank",
"bank_logo": "https://wonderful.co.uk/img/bank_logos/danske.png",
"status": "online"
},
{
"bank_id": "barclays",
"bank_name": "Barclays",
"bank_logo": "https://wonderful.co.uk/img/bank_logos/barclays.png",
"status": "issues"
},
{
"bank_id": "monzo",
"bank_name": "Monzo",
"bank_logo": "https://wonderful.co.uk/img/bank_logos/monzo.png",
"status": "online"
},
{
"bank_id": "natwest",
"bank_name": "Natwest",
"bank_logo": "https://wonderful.co.uk/img/bank_logos/natwest.png",
"status": "online"
},
{
"bank_id": "revolut",
"bank_name": "Revolut",
"bank_logo": "https://wonderful.co.uk/img/bank_logos/revolut.png",
"status": "online"
},
{
"bank_id": "santander",
"bank_name": "Santander",
"bank_logo": "https://wonderful.co.uk/img/bank_logos/santander.png",
"status": "issues"
},
{
"bank_id": "starling",
"bank_name": "Starling",
"bank_logo": "https://wonderful.co.uk/img/bank_logos/starling.png",
"status": "online"
},
{
"bank_id": "tesco",
"bank_name": "Tesco",
"bank_logo": "https://wonderful.co.uk/img/bank_logos/tesco.png",
"status": "online"
},
{
"bank_id": "tide",
"bank_name": "Tide",
"bank_logo": "https://wonderful.co.uk/img/bank_logos/tide.png",
"status": "online"
},
{
"bank_id": "tsb",
"bank_name": "TSB",
"bank_logo": "https://wonderful.co.uk/img/bank_logos/tsb.png",
"status": "online"
}
]
}
Example response (401, Invalid auth token):
{
"error": true,
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
bank_id
string
Bank Identifier. Example: 'bos'
bank_name
string
Display name that can be shown to the customer. Example: 'Bank of Scotland'
bank_logo
string
URL of the logo that can be shown to the customer. Example: https://wonderful.co.uk/img/bank_logos/bos.png
card_logo
string|null
URL of the card logo for credit-card style display (nullable). Example: https://wonderful.co.uk/img/bank_logos/bos_card.png
status
string
Status of the bank. Possible values are: online, issues, offline. Example: 'online'
group
string|null
Group identifier for banks with multiple account types (nullable). Example: 'lloyds'
tile_background
string|null
CSS colour value for the bank card header background (nullable). Example: '#091276'