How it worksHardwarePayment methods IndustriesPricingDevelopers Log in Get started
Developers

Build payments into your product in an afternoon

A clean REST interface, signed requests and signed webhooks — the same for sandbox and production. Card, wallet, iDEAL and Sentoo, settled locally in USD, ANG and EUR.

The interface below shows how you integrate — contact us for ku_test_ sandbox keys to start building today.
Ways to integrate

Pick the integration that fits

From a two-line payment link to a full API integration — card data never touches your servers.

Hosted checkout

Create a session and redirect. We handle the payment page, 3-D Secure and PCI scope.

POST cp-api?action=payments.create-link

Payment links & QR

Generate a shareable link or QR with an amount, expiry and usage cap — send via WhatsApp or e-mail.

Portal → Payment links, or payments.create-link

SoftPOS & terminals

Tap-to-Pay on iPhone/Android and PAX/Ingenico terminals through one session endpoint.

Tap to Pay app (coming)

Saved cards & mandates

Tokenize cards with setup intents and charge later for subscriptions and no-shows.

Coming: saved cards via the gateway wallet

E-commerce plugins

Drop-in modules for WooCommerce, Shopify, Magento, PrestaShop, Wix and BigCommerce.

Booking & PMS

Connect your PMS or booking platform for pre-auths, deposit holds and check-in links.

Quickstart

One call to a payment page

Create a payment link server-side with your API key, then send the customer to the returned URL. Base URL: https://unwowmvqapfqyowzqbzn.supabase.co/functions/v1/cp-api

request · Node.js
// create a payment link (server-side; never expose your key in a browser)
const res = await fetch("https://unwowmvqapfqyowzqbzn.supabase.co/functions/v1/cp-api?action=payments.create-link", {
  method: "POST",
  headers: { "Authorization": "Bearer ku_live_…", "Content-Type": "application/json" },
  body: JSON.stringify({
    amount_minor: 12500,          // $125.00, in cents
    currency: "USD",
    description: "Dinner for two — table 8",
    customer_email: "guest@demo.kuentoo.com",
    expires_days: 30
  })
});
const link = await res.json();

// send the customer to the payment page
redirect(link.url);
response · JSON
{
  "ok": true,
  "id": "6f1c…-…",
  "reference": "CP-MFZK3Q9A1B2C3D",
  "url": "https://kuentoo.com/pay.html?k=…",
  "expires_at": "2026-10-24T18:00:00Z"
}

// other actions (GET unless noted):
//   payments.get?id=…     payments.list?status=&from=&to=&q=
//   refunds.create (POST) { payment_id, amount_minor, reason }
//   payments.create-link also accepts send_email: true (mails the link to customer_email)
//   Idempotency-Key: <your unique id>  on POSTs — same key within 24 h returns the same result (header Idempotent-Replayed: true)
//   payouts.list          statements.list          (scope payouts:read)
//   disputes.list         disputes.get?id=…        (scope payments:read)
Security

Signed requests, replay-safe

Authenticate with a scoped API key over TLS. Card data never reaches your servers: the customer pays on a PCI DSS Level 1 hosted page, so you stay out of PCI scope.

  • Header: Authorization: Bearer ku_live_… (or ku_test_… in the sandbox)
  • Keys are scoped: payments:read, payments:write, refunds:write, payouts:read
  • A key is shown once, at creation; only a SHA-256 hash is stored
  • Revoke and rotate keys in the Merchant Portal → Developers, any time
  • Every call is logged in your activity log as api:ku_live_…
requests · curl
# fetch one payment
curl "https://unwowmvqapfqyowzqbzn.supabase.co/functions/v1/cp-api?action=payments.get&id=6f1c…" \
  -H "Authorization: Bearer ku_live_…"

# refund $50.00 of it
curl -X POST "https://unwowmvqapfqyowzqbzn.supabase.co/functions/v1/cp-api?action=refunds.create" \
  -H "Authorization: Bearer ku_live_…" \
  -H "Content-Type: application/json" \
  -d '{"payment_id":"6f1c…","amount_minor":5000,"reason":"Two guests did not show"}'
Webhooks

Know the moment money moves

Signed, retried event deliveries keep your systems in sync. Verify X-Kuentoo-Signature before you trust a payload: t=<unix>,v1=HMAC-SHA256(secret, t + "." + body).

EventFires when
payment.succeededA payment is confirmed by the gateway
payment.failedA payment is declined or errors
refund.succeededA refund is processed
payout.paidA payout to your bank account is sent
dispute.openedA customer disputed a payment (chargeback)
dispute.closedA chargeback was won, lost or accepted
statement.readyYour monthly statement is available
test.pingYou press “Send test” in the portal
  • Signed deliveries; reject a timestamp older than 5 minutes (replay)
  • Retries after 1 min, 5 min, 30 min, 2 h, 12 h and 24 h on non-2xx
  • Handle idempotently on data.reference — the same event may arrive twice
  • Respond 2xx within 8 seconds; do heavy work asynchronously
// Node.js — verify X-Kuentoo-Signature
const crypto = require('crypto');
function verify(secret, header, rawBody) {
  const [t, v1] = header.split(',').map(p => p.split('=')[1]);
  if (Math.abs(Date.now()/1000 - Number(t)) > 300) return false;   // replay window 5 min
  const expected = crypto.createHmac('sha256', secret).update(t + '.' + rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}

// PHP
[$t, $v1] = array_map(fn($p) => explode('=', $p, 2)[1], explode(',', $_SERVER['HTTP_X_KUENTOO_SIGNATURE']));
$ok = abs(time() - (int)$t) <= 300 && hash_equals(hash_hmac('sha256', $t . '.' . file_get_contents('php://input'), $secret), $v1);
Sandbox

Sandbox

Use a ku_test_… key. In the sandbox the amount decides the outcome; use Visa 4929 4212 3460 0821 with any CVC. No real money moves.

AmountExpiry monthResult
1.00 – 24.99anyApproved
25.00 – 49.99anyApproved, settlement rejected
50.00 – 74.99anyReferral
100.00 – 149.99anyDeclined
any013-D Secure: authenticated
any123-D Secure: challenge
any063-D Secure: rejected
Sandbox payments and webhooks behave exactly like live ones, including refunds and the payment.failed event. Switch to a ku_live_… key when you go live — nothing else changes.
Get started

Request sandbox access

Tell us what you’re building and we’ll issue test keys and the signing helpers. Same-day testing is typical.

Request test keys