GOVPAY Developers
API Documentation
Integrate Cayman Islands government payments with Hosted Checkout, eGov applications, and POS capture. Base URL https://govpayv2.netcluesdemo.com/api
Introduction
GOVPAY is the payments platform for Cayman Islands government services — licences, fees, utilities, and counter collections across web and POS.
Use the GOVPAY APIs to create payable applications, redirect citizens to Hosted Checkout, capture payments, and record counter (POS) collections. Responses are JSON. Amounts for eGov applications are in Cayman Islands Dollars (KYD / CI$).
| Environment | Base URL | Use |
|---|---|---|
| Production | https://govpayv2.netcluesdemo.com/api | Live government payments |
| Sandbox | https://sandbox.govpayv2.netcluesdemo.com/api | Integration testing |
| Local | http://localhost:3057/api | Prototype development |
Who this documentation is for
Agency developers integrating Hosted Checkout or POS capture, partners building citizen experiences, and teams validating payment status against the ledger.
Collection channels
| Channel | Description |
|---|---|
| Web | Hosted Checkout and citizen dashboard payments |
| POS | Countertop terminal collections at government service desks |
Authentication
Protect customer and capture endpoints with a session. Partner server integrations use API keys (Key Id + Key Secret).
Citizen session (cookie)
Citizen portal and Hosted Checkout capture use an HTTP-only session cookie (`govpay_session`) issued after login or registration. Send it automatically from the browser; do not expose it to client-side JavaScript.
API keys (server-to-server)
For agency backends creating applications or recording POS payments, authenticate with Basic Auth using your Key Id and Key Secret. Credentials are issued for your integration and used only over the API — there is no Console settings UI for API keys.
curl https://govpayv2.netcluesdemo.com/api/egov/applications \
-u KEY_ID:KEY_SECRET \
-H "Content-Type: application/json" \
-d '{ ... }'Never ship secrets in the browser
Key Secret must only live on your server. Browser flows should use Hosted Checkout or a citizen session — never embed Key Secret in frontend code.
Roles
| Role | Typical use |
|---|---|
| Agency / partner | Create applications, initiate Hosted Checkout |
| Citizen | Pay via Hosted Checkout, manage saved cards |
| POS operator | Record counter payments on authenticated terminals |
| Admin | Reports and ledger — not for public integrations |
Quick start
Collect a Driving Licence Renewal fee in three steps: create an application, open Hosted Checkout, confirm payment.
- 1
Create an application
POST /api/egov/applications with applicant and licence fields. GOVPAY calculates the KYD fee and returns an application id plus hostedPayUrl.
- 2
Redirect to Hosted Checkout
Send the citizen to /pay/hosted/{applicationId}. They sign in, choose a card (or other method), and confirm.
- 3
Confirm status
GET /api/egov/applications/{id} until status is paid, or listen for the application.paid webhook.
# 1) Create application
curl -X POST https://govpayv2.netcluesdemo.com/api/egov/applications \
-H "Content-Type: application/json" \
-d '{
"fullName": "Jordan Ebanks",
"dateOfBirth": "1990-04-12",
"nationality": "Caymanian",
"citizenship": "caymanian",
"email": "jordan@email.ky",
"phone": "+1-345-555-0100",
"addressLine1": "12 Harbour Dr",
"district": "George Town",
"licenceNumber": "DL-884201",
"licenceClass": "B",
"licenceGroup": "0-3",
"termYears": 5,
"expiryDate": "2026-08-01",
"signedName": "Jordan Ebanks"
}'
# Response includes hostedPayUrl → open in browser
# 2) Citizen completes Hosted Checkout
# 3) Poll GET /api/egov/applications/{id}Payment flow
Understand how applications move from draft to settled on the payment ledger.
| Status | Meaning |
|---|---|
| draft | Application started but not ready for payment |
| pending_payment | Payable — Hosted Checkout can collect |
| paid | Successfully settled; ledger entry created |
| cancelled | Voided before capture |
Successful captures write to the admin payment ledger with channel web or pos and type cash, card, or bank transfer. Citizen dashboards show matching receipts under Payments.
- Use a unique payment reference per capture for reconciliation.
- Treat paid as terminal for that application id.
- Refunds are processed via support policy — not a public refund API yet.
Payment methods
Supported instruments across web and POS channels.
| Method | Channel | Notes |
|---|---|---|
| card | Web, POS | Visa, Mastercard, Amex via saved cards or terminal |
| banktransfer | Web, POS | Bank transfer confirmation flows |
| cash | POS only | Counter cash with shift / till reconciliation |
Currency
eGov Driving Licence fees are priced in KYD (CI$). Admin ledgers may display USD formatting for consolidated reporting — always trust amountCid on the application object for Cayman fees.
Create application
Create a payable Driving Licence Renewal application and receive a Hosted Checkout URL.
/api/egov/applicationsCreates a DVDL renewal application, calculates the fee, and returns hostedPayUrl.
fullNameApplicant legal name
dateOfBirthISO date YYYY-MM-DD
nationalityNationality as displayed on the licence
citizenship`caymanian` or `non_caymanian`
emailCitizen email for receipts and login
phoneContact phone
addressLine1Street address
districte.g. George Town, West Bay
licenceNumberExisting licence number
licenceClassLicence class (e.g. B)
licenceGroup`0-3` or `4`
termYears`3`, `5`, or `10`
expiryDateCurrent expiry YYYY-MM-DD
signedNameDigital signature name
curl -X POST https://govpayv2.netcluesdemo.com/api/egov/applications \
-H "Content-Type: application/json" \
-d '{
"fullName": "Jordan Ebanks",
"dateOfBirth": "1990-04-12",
"nationality": "Caymanian",
"citizenship": "caymanian",
"email": "jordan@email.ky",
"phone": "+1-345-555-0100",
"addressLine1": "12 Harbour Dr",
"district": "George Town",
"licenceNumber": "DL-884201",
"licenceClass": "B",
"licenceGroup": "0-3",
"termYears": 5,
"expiryDate": "2026-08-01",
"signedName": "Jordan Ebanks"
}'Response (201)
{
"application": {
"id": "app_01J8…",
"service": "driving_licence_renewal",
"status": "pending_payment",
"fullName": "Jordan Ebanks",
"amountCid": 75,
"currency": "KYD",
"createdAt": "2026-07-30T12:00:00.000Z"
},
"hostedPayUrl": "/pay/hosted/app_01J8…"
}Fetch application
Retrieve an application and its payment status by id.
/api/egov/applications/{id}Returns the application object for status checks and receipts.
idApplication id from create response
curl https://govpayv2.netcluesdemo.com/api/egov/applications/app_01J8…404 Not found
Unknown ids return `{ "error": "Not found" }` with HTTP 404.
Capture payment
Settle a pending application after the citizen authenticates (Hosted Checkout).
/api/egov/applications/{id}Requires a citizen session. Captures payment and marks the application paid.
methodDefaults to `card`. Use `bank` for bank transfer.
paymentMethodIdSaved card id when method is `card` (required for card).
curl -X POST https://govpayv2.netcluesdemo.com/api/egov/applications/app_01J8… \
-H "Content-Type: application/json" \
-H "Cookie: govpay_session=…" \
-d '{
"method": "card",
"paymentMethodId": "pm_visa_4242"
}'Session required
Unauthenticated capture returns 401. Prefer Hosted Checkout so GOVPAY handles login, card selection, and this call for you.
Hosted Checkout
GOVPAY-hosted payment page — redirect citizens to a full checkout URL, or embed the same modal with checkout.js.
After creating an application, redirect the citizen to the returned hostedPayUrl, or open the same UI in-place with Standard Checkout (checkout.js). Hosted Checkout handles authentication, saved cards, confirmation, and receipt messaging. You only need to create the application and verify final status.
| Item | Value |
|---|---|
| URL pattern | /pay/hosted/{applicationId} |
| Embed URL | /pay/hosted/{applicationId}?embed=1 |
| Example | https://govpayv2.netcluesdemo.com/pay/hosted/app_01J8… |
| Auth | Citizen login / OTP inside checkout |
| PCI scope | Card data stays on GOVPAY — reduce your SAQ burden |
- 1
Create
Your server calls POST /api/egov/applications.
- 2
Open
Redirect to hostedPayUrl, or open via checkout.js (see Standard Checkout).
- 3
Citizen pays
Login → select method → confirm. Capture runs server-side.
- 4
Reconcile
Poll GET application or consume application.paid webhook.
Best practice
Always create applications from your backend, never from untrusted clients with fee-manipulating fields. Fee calculation is server-side from licenceGroup, termYears, and citizenship.
Standard Checkout (JS)
Drop-in checkout.js script and Pay with GOVPAY button for HTML or React partner apps.
Include checkout.js on any page. Mount a branded Pay with GOVPAY button, or call GovPay.Checkout to open the same hosted modal in an iframe overlay. Your backend still creates the application; the browser only receives the application id.
| Item | Value |
|---|---|
| Script | https://govpayv2.netcluesdemo.com/checkout.js |
| Demo | https://govpayv2.netcluesdemo.com/checkout-demo |
| Button helper | GovPay.mountPayButton(target, options) |
| Imperative API | new GovPay.Checkout(options).open() |
<script src="https://govpayv2.netcluesdemo.com/checkout.js"></script>
<div id="govpay"></div>
<script>
GovPay.mountPayButton("#govpay", {
createApplication: async function () {
var res = await fetch("/api/your-create-session", { method: "POST" });
var data = await res.json();
return { applicationId: data.applicationId };
},
handler: function (response) {
console.log("Payment success", response);
},
onDismiss: function () {
console.log("Citizen closed checkout");
}
});
</script>- 1
Load script
Add <script src="https://govpayv2.netcluesdemo.com/checkout.js"></script> (or Next.js <Script src="/checkout.js" />).
- 2
Create application
Server-side POST /api/egov/applications — never put secrets in the browser.
- 3
Open modal
Pass applicationId into GovPay.Checkout or mountPayButton. The script iframes /pay/hosted/{id}?embed=1.
- 4
Handle result
handler() receives paid events via postMessage; always re-verify status on your server.
Live demo
Open https://govpayv2.netcluesdemo.com/checkout-demo to try the Pay with GOVPAY button against this environment.
POS overview
Countertop terminals at government service desks collect cash, card, and bank transfer payments into the same ledger.
POS payments create admin ledger rows with channel `pos` and a payment type of `cash`, `card`, or `banktransfer`. Operators work in shifts with opening and closing cash counts.
- Use a unique `reference` per payment (idempotent upsert by reference).
- Include terminalId and operatorName for audit trails.
- Cash remains POS-only — do not send cash on web captures.
Record POS payment
Persist a counter payment to the GOVPAY ledger.
/api/pos/paymentsRecords a successful POS collection for reconciliation and receipts.
referenceUnique payment reference (e.g. GP-2026-88448)
amountPositive amount in major units
method`cash` | `card` | `banktransfer`
citizenNamePayer name
citizenEmailFor citizen receipt / dashboard history
serviceService label (defaults to Counter Payment)
terminalIdPOS terminal identifier
operatorNameLogged-in operator display name
curl -X POST https://govpayv2.netcluesdemo.com/api/pos/payments \
-H "Content-Type: application/json" \
-d '{
"reference": "GP-2026-88490",
"amount": 320,
"method": "cash",
"citizenName": "David McField",
"citizenEmail": "david@email.ky",
"service": "Planning Permit Fee",
"terminalId": "POS-GT-01",
"operatorName": "Grace Whittaker"
}'Saved cards
Citizen vault for cards used in Hosted Checkout and dashboard payments.
/api/payment-methodsList saved cards for the authenticated citizen.
/api/payment-methodsAdd a card (Luhn-validated). Requires customer session.
/api/payment-methods?id={cardId}Remove a saved card by id.
cardNumberPAN (demo accepts valid Luhn 16-digit test cards)
expiryMonthMM
expiryYearYYYY or YY
cvvCard security code
cardholderNameName on card
setDefaultMake this the default payment method
PCI note
Prefer Hosted Checkout so your integration never handles raw PANs. Direct card APIs are for the GOVPAY citizen portal only.
Transactions
Citizen payment history and overview stats.
/api/payments/transactionsReturns `{ transactions, stats }` for the authenticated user’s email.
{
"transactions": [
{
"id": "GPY-DVDL-…",
"service": "Driving Licence Renewal",
"amount": "CI$75.00",
"status": "success",
"channel": "Web"
}
],
"stats": { "totalPaid": 3, "totalAmount": "…" }
}Subscriptions
Recurring citizen services managed in the dashboard.
/api/subscriptionsList subscriptions for the signed-in citizen.
/api/subscriptions/cancelCancel a subscription by id in the request body.
Subscription products are configured per agency (utilities, renewals). Cancellation is immediate for the citizen portal; settle any outstanding invoices per agency policy.
Webhooks
Receive asynchronous notifications when payments settle or fail — without polling.
Register an HTTPS callback URL via the API. GOVPAY POSTs signed JSON events when ledger state changes. Respond with HTTP 2xx within 5 seconds; failures retry with exponential backoff.
- 1
Register URL
Call the webhooks API with your integration credentials to register your HTTPS endpoint.
- 2
Verify signature
Validate X-GovPay-Signature using your webhook secret.
- 3
Idempotent handling
Events may retry — key off event.id when updating your systems.
Webhook events
Event types emitted by GOVPAY.
| Event | When |
|---|---|
| payment.captured | Hosted or POS payment settled successfully |
| payment.failed | Capture attempt failed |
| application.paid | eGov application moved to paid |
| application.created | New payable application created |
| pos.payment.recorded | Counter payment written to ledger |
| refund.processed | Refund completed in support flow |
{
"id": "evt_01J8…",
"event": "application.paid",
"createdAt": "2026-07-30T14:22:01.000Z",
"data": {
"applicationId": "app_01J8…",
"reference": "GPY-DVDL-1722…",
"amountCid": 75,
"currency": "KYD",
"channel": "web",
"method": "card"
}
}Webhook security
Verify that events originate from GOVPAY.
- Validate the HMAC signature in X-GovPay-Signature (hex digest of raw body with your webhook secret).
- Optionally restrict inbound traffic to known GOVPAY webhook IP ranges.
- Use HTTPS only — plain HTTP endpoints are rejected.
- Rotate webhook secrets via the API if an endpoint is compromised.
import crypto from "crypto";
function verifyGovPaySignature(rawBody, signatureHeader, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signatureHeader)
);
}Errors
Consistent JSON error envelope across GOVPAY APIs.
{ "error": "Missing field: email" }| HTTP | Meaning |
|---|---|
| 400 | Validation / bad request |
| 401 | Missing or invalid session / credentials |
| 403 | Authenticated but not permitted |
| 404 | Resource not found |
| 500 | Unexpected server error — retry with backoff |
Idempotency
Safely retry payment writes without double charging.
POS payments upsert by `reference`. Re-posting the same reference updates the same ledger row instead of creating duplicates. For eGov captures, once an application is `paid`, subsequent capture calls return the paid application without charging again.
- Generate references on your server before calling POS APIs.
- Store application ids before redirecting to Hosted Checkout.
- Webhook handlers must be idempotent on event.id.
Changelog
Notable API and documentation updates.
| Date | Change |
|---|---|
| 2026-07-30 | Public developer documentation launched — Hosted Checkout, eGov applications, POS payments, webhooks guide |
| 2026-07 | Ledger channels reduced to web & pos; payment types cash, card, bank transfer |
| 2026-06 | Driving Licence Renewal Hosted Checkout and POS counter settlement |