Paytrail API

Take payments from your own website, app or Discord bot. Base URL https://paytrail.cc/api/public/v1

How it works

You don't need Komerza or SellAuth. From your own server: 1) create a checkout session with the amount, 2) send the buyer to the url you get back, 3) the buyer pays by card, Apple Pay or Google Pay, 4) they're sent to your success_url and you confirm the payment by fetching the session (status paid). Sessions expire after 2 hours.

Your server ──POST /checkout-sessions──▶ Paytrail
Your server ◀── { id, url } ─────────── Paytrail
Buyer ──────── opens url, pays ───────▶ Paytrail
Buyer ◀──── redirected to success_url ── Paytrail
Your server ──GET /checkout-sessions/{id}──▶ status: "paid"

Authentication

Create a secret key in Dashboard → Developers. Send it as a Bearer token on every request. Keys start with pf_live_, are shown once, and can be revoked any time. Only call the API from your server — never from a browser or a public bot repo.

Authorization: Bearer pf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Base URL: https://paytrail.cc/api/public/v1

Create a checkout session

POST /checkout-sessions. amount is an integer in minor units (1000 = $10.00), min 50. Required: amount, description. Optional: currency (default USD), customer_email, success_url, cancel_url, reference (your own order id), metadata (string → string). The 2% checkout fee is added on the payment page — don't add it yourself.

curl -X POST https://paytrail.cc/api/public/v1/checkout-sessions \
  -H "Authorization: Bearer $PAYTRAIL_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 1000,
    "currency": "USD",
    "description": "VIP rank — 30 days",
    "customer_email": "buyer@example.com",
    "reference": "order_123",
    "success_url": "https://yourshop.com/thanks?order=order_123",
    "cancel_url": "https://yourshop.com/cart"
  }'

# 201 Created
{
  "id": "6f1c…",
  "object": "checkout_session",
  "status": "open",
  "amount": 1000,
  "currency": "USD",
  "url": "https://paytrail.cc/pay/session/6f1c…",
  "expires_at": "2026-10-28T23:00:00.000Z",
  ...
}

Check a session

GET /checkout-sessions/{id}. status is open, paid or expired. Always confirm paid from your server before delivering — never trust the redirect alone.

curl https://paytrail.cc/api/public/v1/checkout-sessions/6f1c… -H "Authorization: Bearer $PAYTRAIL_KEY"

{ "id": "6f1c…", "status": "paid", "paid_at": "2026-10-28T21:14:03Z", "reference": "order_123", ... }

Example: Node.js / Discord bot

A full flow in a few lines. Works in Express, Next.js API routes, discord.js bots, etc.

const API = "https://paytrail.cc/api/public/v1";
const headers = { Authorization: `Bearer ${process.env.PAYTRAIL_KEY}`, "Content-Type": "application/json" };

// 1. Create a payment link
const session = await fetch(`${API}/checkout-sessions`, {
  method: "POST", headers,
  body: JSON.stringify({ amount: 499, description: "Premium role", reference: interaction.user.id }),
}).then((r) => r.json());
await interaction.reply(`Pay here: ${session.url}`);

// 2. Later (e.g. poll every 10s, or when the buyer returns to success_url)
const s = await fetch(`${API}/checkout-sessions/${session.id}`, { headers }).then((r) => r.json());
if (s.status === "paid") giveRole(s.reference);

Example: Python

import os, requests
API = "https://paytrail.cc/api/public/v1"
H = {"Authorization": f"Bearer {os.environ['PAYTRAIL_KEY']}"}

s = requests.post(f"{API}/checkout-sessions", headers=H,
                  json={"amount": 2500, "description": "Pro license"}).json()
print("Send buyer to:", s["url"])

status = requests.get(f"{API}/checkout-sessions/{s['id']}", headers=H).json()["status"]

Errors

Errors return JSON { "error": { "message": "…" } } with status 400 (bad input), 401 (missing, revoked or unapproved key), or 404 (no such session for your account).

Fees

The buyer pays the amount + 2% checkout fee (shown as its own line). From the amount, Paytrail keeps 9.5%; you receive the rest in your balance. Rounded half-up to the nearest cent.

{ "amount": 1000, "checkout_fee": 20, "customer_pays": 1020, "processing_fee": 95, "you_receive": 905 }

Discord sale notifications

Paste a Discord channel webhook in Dashboard → Developers. Every successful payment — API, Komerza or SellAuth — posts a message with the amount paid, what you receive, customer email, country and the invoice / session id.

Payouts

Balances are paid out in USDC on Solana. A payout is marked completed only after the transaction is confirmed on-chain.