Developers

Integrate Kunog in an afternoon.

Clean primitives, predictable webhooks, and examples that match real apps.

Quickstart

Create a payment intent, send your customer to hosted checkout, then verify a webhook when the payment is confirmed.

1) Create intent
curl https://api.kunog.com/v1/payment_intents \
  -H "Authorization: Bearer kng_test_••••" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3b2d9a1a-9f1d-4c6f-bade-2bf0b3d0b12f" \
  -d '{
    "amount": 4900,
    "currency": "USD",
    "settlement": "USDC",
    "success_url": "https://kunog.com/success",
    "cancel_url": "https://kunog.com/cancel"
  }'
2) Redirect to checkout_url
// Node/Express example
app.post("/create-checkout", async (req, res) => {
  const r = await fetch("https://api.kunog.com/v1/payment_intents", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.KUNOG_KEY}`,
      "Content-Type": "application/json",
      "Idempotency-Key": crypto.randomUUID()
    },
    body: JSON.stringify({
      amount: 4900,
      currency: "USD",
      settlement: "USDC",
      metadata: { order_id: "KNG-2048" }
    })
  });

  const intent = await r.json();
  res.redirect(303, intent.checkout_url);
});

SDK pattern

Keep your app thin: wrap Kunog calls in a small client so you can swap environments and add retries.

Minimal client
export class KunogClient {
  constructor({ apiKey, baseUrl = "https://api.kunog.com" }) {
    this.apiKey = apiKey;
    this.baseUrl = baseUrl;
  }

  async createPaymentIntent(payload, { idempotencyKey }) {
    const r = await fetch(`${this.baseUrl}/v1/payment_intents`, {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${this.apiKey}`,
        "Content-Type": "application/json",
        "Idempotency-Key": idempotencyKey
      },
      body: JSON.stringify(payload)
    });
    if (!r.ok) throw new Error(`Kunog error: ${r.status}`);
    return r.json();
  }
}

Webhooks

Kunog sends signed webhooks for state changes. Always verify the signature and use idempotent handlers.

Events

  • payment_intent.created
  • payment_intent.pending
  • payment_intent.confirmed
  • payment_intent.expired
  • refund.created

Headers

  • Kunog-Signature (HMAC)
  • Kunog-Timestamp (ms)
  • Kunog-Event-Id
Verify signature (Node)
import crypto from "crypto";

function timingSafeEqual(a, b) {
  const aa = Buffer.from(a);
  const bb = Buffer.from(b);
  return aa.length === bb.length && crypto.timingSafeEqual(aa, bb);
}

export function verifyKunogWebhook({ rawBody, signature, timestamp, secret }) {
  const payload = `${timestamp}.${rawBody}`;
  const expected = crypto.createHmac("sha256", secret).update(payload).digest("hex");
  if (!timingSafeEqual(signature, expected)) throw new Error("Invalid signature");
  return true;
}

Idempotency

Retry safely by sending an Idempotency-Key header. Treat keys as unique per operation (e.g., intent creation).

Developer FAQ

Get test keys

This is a front-end-only template. Wire this form to your backend when you’re ready.