Northvault API
Create a checkout, send your shopper to it, get paid. Base URL for everything below:
https://northvault.co.uk/api/v1
Getting started
- Create an account — free, and it starts in test mode.
- Grab your keys from Integration & keys.
- Build and test the whole flow with your
nv_test_key. Nothing is charged. - Pay the one-time setup fee to activate your
nv_live_key.
Nothing about your integration changes between test and live — you swap the key, that's all.
API keys
Every account has four keys. The key you send decides both the mode and what you're allowed to do.
| Key | Where it belongs | Can do |
|---|---|---|
nv_live_… | Your server only | Everything, real money |
nv_test_… | Your server only | Everything, simulated |
nv_pub_live_… | Safe in page source | Create checkouts only |
nv_pub_test_… | Safe in page source | Create checkouts only |
Never put a secret key in browser JavaScript, a mobile app, or a public repo. Publishable keys exist for that. A secret key sent from a browser is readable by every visitor.
Create a checkout
POST /api/v1/checkouts
Server-to-server, with a secret key. Redirect the shopper to checkout_url.
curl -X POST https://northvault.co.uk/api/v1/checkouts \
-H "Authorization: Bearer nv_test_…" \
-H "Content-Type: application/json" \
-d '{
"amount_minor": 4900,
"currency": "EUR",
"description": "Order #1042",
"reference": "1042",
"customer": { "name": "Ada Lovelace", "email": "ada@example.com" },
"return_url": "https://your-site.example/thanks"
}'
{
"ok": true,
"checkout": {
"id": "nv_9f2c…",
"status": "pending",
"amount_minor": 4900,
"currency": "EUR",
"checkout_url": "https://northvault.co.uk/pay/…"
}
}
| Field | Required | Notes |
|---|---|---|
amount_minor | yes | Smallest unit. €10.50 is 1050, not 10.50. |
currency | no | ISO code, defaults to EUR |
description | no | Shown to the shopper |
reference | no | Your own order id — echoed back in webhooks |
customer | no | name, email |
return_url | no | https only. Shopper returns here after paying. |
Sending a decimal amount is rejected rather than guessed — silently charging 10 cents instead of €10 is worse than an error.
Check a payment
GET /api/v1/checkouts/{id}
Status is verified against the payment processor, not just our own record.
curl https://northvault.co.uk/api/v1/checkouts/nv_9f2c… \
-H "Authorization: Bearer nv_test_…"
Statuses: pending → redirected → paid or failed.
Treat only paid as money received — never a return-URL hit.
GET /api/v1/checkouts lists your 50 most recent.
Browser checkouts
POST /api/v1/public/checkouts
For when the checkout must be created client-side. Uses a publishable key, sent in the body as key. CORS is open. It can only create — it cannot read anything back.
fetch('https://northvault.co.uk/api/v1/public/checkouts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
key: 'nv_pub_test_…',
amount_minor: 4900,
currency: 'EUR',
return_url: 'https://your-site.example/thanks'
})
}).then(r => r.json()).then(d => { location.href = d.checkout_url; });
Rate limited per key and per IP. A burst of ordinary shop traffic will never hit it.
Webhooks
Set an endpoint in Integration & keys and we POST there when a payment settles, so you don't have to poll.
POST your-endpoint
X-Northvault-Event: checkout.paid
X-Northvault-Timestamp: 1753920000
X-Northvault-Signature: v1=9a3f…
{ "event": "checkout.paid",
"data": { "id": "nv_9f2c…", "status": "paid", "amount_minor": 4900,
"fee_minor": 226, "currency": "EUR", "reference": "1042" } }
Verify every request before acting on it:
$ts = $_SERVER['HTTP_X_NORTHVAULT_TIMESTAMP'];
$sig = $_SERVER['HTTP_X_NORTHVAULT_SIGNATURE'];
$body = file_get_contents('php://input');
$mine = 'v1=' . hash_hmac('sha256', $ts . '.' . $body, $YOUR_WEBHOOK_SECRET);
if (!hash_equals($mine, $sig) || abs(time() - (int)$ts) > 300) {
http_response_code(400); exit; // reject: forged or replayed
}
The timestamp is part of the signed string deliberately — signing the body alone would let a captured request be replayed forever. Reply 2xx; anything else is retried with backoff, up to 8 attempts.
Shopify
One script tag in layout/theme.liquid, just before </body>:
<script src="https://northvault.co.uk/nv.js"
data-nv-key="nv_pub_live_…"
data-nv-return="https://your-store.com/pages/thank-you"
defer></script>
It intercepts the Checkout button, reads the live cart, and opens a Northvault checkout. If we're ever unreachable it falls through to your normal Shopify checkout, so a sale is never lost.
Shopify only permits replacing checkout on Plus, so this hooks the cart step. Turn off "Buy it now" / dynamic checkout buttons in your theme, or those routes bypass it.
WooCommerce
Download the plugin from Install — your key is already inside it. Upload it under Plugins → Add New → Upload, activate, then enable Northvault Secure Checkout under WooCommerce → Settings → Payments.
Orders stay pending until we confirm the money arrived, then move to processing. The plugin re-checks server-side on return, so a hand-crafted return URL can't mark an order paid.
Testing
Use an nv_test_ key. Test checkouts run the identical lifecycle against a simulated gateway and never reach a real processor, so you can drive both success and decline on demand.
There's also a demo store wired to your own test key if you want to watch the flow before writing any code.
Pricing
A one-time setup fee activates live payments. After that, commission is deducted from each settled payment before it reaches your balance — your exact rate is shown in Integration & keys.
Test mode is free and unlimited.
Chargebacks
You do not handle disputes. Northvault is merchant of record, so chargebacks are raised against us — we monitor, answer and defend every case, and eligible disputes on covered transactions are absorbed by us rather than deducted from you.
- Ethoca and Verifi pre-dispute alerts resolve most complaints before they become chargebacks.
- Representment is filed by our disputes team — you never compile evidence packets.
- Ratios are monitored live against Visa VAMP and Mastercard ECP thresholds.
Cover applies to transactions processed through Northvault that pass 3DS2 and our risk checks. Exact terms are in your merchant agreement.
Errors
| Code | Error | Meaning |
|---|---|---|
| 400 | bad_amount | Not a positive integer in minor units |
| 400 | use_amount_minor | You sent a decimal amount |
| 401 | invalid_api_key | Key wrong or revoked |
| 402 | setup_fee_required | Live not activated yet — test keys still work |
| 403 | publishable_key_not_allowed | Publishable key used on a secret-key endpoint |
| 404 | not_found | No such checkout on this account |
| 429 | rate_limited | Slow down; see Retry-After |
Every error carries a human-readable message explaining what to change.
Need a hand?
Open a ticket or use live chat from your dashboard — a real person answers.
Create your account