Skip to main content
This guide is written for first-time integrators. By the end, you will:
  1. Create a payment intent on your backend.
  2. Return client_secret to your frontend.
  3. Open KryptoPay checkout with the SDK.
  4. Handle success and backend fulfillment.

Before you start

  • API base URL: https://api.kryptopay.xyz
  • Keep API keys server-side only
  • Frontend should only receive client_secret

Step 1: Create intent on your backend

Use your API key from server code. Do not call this endpoint directly from browser code.

cURL

curl -X POST "https://api.kryptopay.xyz/v1/payment_intents" \
  -H "Authorization: Bearer kp_test_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "amount_units": 2500000,
    "chain": "base",
    "token": "USDC",
    "expires_in_minutes": 15,
    "lane": "sdk",
    "metadata": { "order_id": "ord_1001" }
  }'

Node.js (Express)

import express from "express";

const app = express();
app.use(express.json());

app.post("/api/create-intent", async (req, res) => {
  const { amountUnits, orderId } = req.body;

  const kpRes = await fetch("https://api.kryptopay.xyz/v1/payment_intents", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.KRYPTOPAY_API_KEY}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      amount_units: amountUnits,
      chain: "base",
      token: "USDC",
      expires_in_minutes: 15,
      lane: "sdk",
      metadata: { order_id: orderId }
    })
  });

  const data = await kpRes.json();
  if (!kpRes.ok) return res.status(kpRes.status).json(data);

  // Return only what frontend needs
  return res.json({ clientSecret: data.client_secret, intentId: data.id });
});

Next.js route handler

// app/api/create-intent/route.ts
import { NextResponse } from "next/server";

export async function POST(req: Request) {
  const body = await req.json();

  const kpRes = await fetch("https://api.kryptopay.xyz/v1/payment_intents", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.KRYPTOPAY_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      amount_units: body.amountUnits,
      chain: "base",
      token: "USDC",
      expires_in_minutes: 15,
      lane: "sdk",
      metadata: { order_id: body.orderId },
    }),
  });

  const data = await kpRes.json();
  return NextResponse.json(data, { status: kpRes.status });
}

Python (coming soon)

Python examples and server SDK helpers are planned. The HTTP flow is the same: call POST /v1/payment_intents server-side, then return client_secret to the client.

Step 2: Open checkout in frontend

import { openKryptoPayModal } from "@kryptopay/sdk";

openKryptoPayModal({
  clientSecret,
  baseUrl: "https://api.kryptopay.xyz",
  merchantName: "Acme Store",
  onSuccess: (event) => {
    console.log("paid", event.payment_intent_id, event.tx_hash);
  },
  onError: (error) => {
    console.error(error.code, error.message);
  },
});

Step 3: Fulfillment model

Treat frontend callbacks as user UX signals. For fulfillment and accounting, use backend systems and your event pipeline so duplicate callbacks or page refreshes do not create duplicate business actions.

Common mistakes

  • Calling POST /v1/payment_intents from frontend code
  • Exposing API key in JavaScript bundles
  • Treating frontend success callback as final source of truth
  • Forgetting to persist order_id or internal reference in metadata

Example apps

Reference integrations are available at: