Integration Guide

Integrate Flux into your website

A copy-paste friendly guide for adding Paytring-powered checkout to any site or app. Written so an AI coding assistant can implement it end-to-end.

1. How it works

Flux gives your backend a single REST endpoint that returns a hosted checkout URL. You redirect the buyer to that URL, they pay, and Paytring sends them back to your success page. You don't handle card data — Paytring acts as your payment collection agent and you remain the seller of record for your product.

  1. Your server calls POST /api/public/v1/orders/create
  2. Flux creates a Paytring order and returns a checkout_url + a short short_url
  3. You redirect (or link) the buyer to either URL
  4. Buyer completes payment on Paytring's hosted page
  5. Paytring redirects them back to your callback_url

2. Before you start

  • You need a Flux merchant account — sign up.
  • Submit KYC and sign the Merchant Services Agreement. Your account must be approved before live orders work.
  • You'll need a server (Node, Python, PHP, anything that can do HTTPS). Never call this API from the browser — your secret key would leak.

3. Generate API keys

  1. Open the dashboard → Settings → API Keys.
  2. Click Generate new key and give it a label (e.g. "production server").
  3. Copy the secret key (sk_live_…) now. You won't be able to see it again — only the prefix is stored.
  4. Store it in your server's secret manager / environment variables (e.g. FLUX_API_KEY).
Keep secret keys secret. Treat sk_live_… like a password. If it ever leaks, revoke it immediately from the API Keys page.

4. The endpoint

Base URL:

https://flux.paytr.ing

Endpoint:

POST /api/public/v1/orders/create
Authorization: Bearer sk_live_xxx
Content-Type: application/json

Request body

json
{
  "amount": 49.99,
  "currency": "USD",
  "customer": {
    "name": "Jane Doe",
    "email": "jane@example.com",
    "phone": "9999999999"
  },
  "receipt_id": "order_2026_001",
  "callback_url": "https://yoursite.com/payment/return",
  "notes": { "order_id": "2026_001", "plan": "pro" }
}
FieldTypeDescription
amountnumberRequired. Amount in major units (e.g. 49.99 = $49.99).
currencystringISO 4217 code. Defaults to USD.
customer.namestringBuyer's full name.
customer.emailstringBuyer's email — receipt is sent here.
customer.phonestringBuyer's phone, 7–20 chars.
receipt_idstringOptional. Your internal order ID.
callback_urlstringOptional. Where Paytring sends the buyer after payment.
notesobjectOptional. Map of <string,string> stored with the order.

Response

json
{
  "order_id": "ord_abc123",
  "checkout_url": "https://checkout.paytring.com/...",
  "short_url": "https://flux.paytr.ing/l/k7m4nq2",
  "payment_link_id": "f2c1...-uuid"
}

Use short_url when sharing on SMS/WhatsApp/email — it's compact and forwards the buyer to the same Paytring checkout.

5. Your integration snippets

Loading your integration details…

6. Copy-paste examples

cURL

curl -X POST https://flux.paytr.ing/api/public/v1/orders/create \
  -H "Authorization: Bearer $FLUX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 49.99,
    "currency": "USD",
    "customer": {
      "name": "Jane Doe",
      "email": "jane@example.com",
      "phone": "9999999999"
    },
    "callback_url": "https://yoursite.com/payment/return"
  }'

Node.js (server-side)

js
// pages/api/checkout.js  (Next.js example)
export default async function handler(req, res) {
  const r = await fetch(
    "https://flux.paytr.ing/api/public/v1/orders/create",
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.FLUX_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        amount: req.body.amount,
        currency: "USD",
        customer: req.body.customer,
        callback_url: `${process.env.SITE_URL}/payment/return`,
      }),
    },
  );
  const data = await r.json();
  if (!r.ok) return res.status(r.status).json(data);
  // Redirect the buyer to the hosted checkout
  res.redirect(303, data.short_url);
}

Python (Flask)

py
import os, requests
from flask import Flask, request, redirect

app = Flask(__name__)

@app.post("/checkout")
def checkout():
    r = requests.post(
        "https://flux.paytr.ing/api/public/v1/orders/create",
        headers={
            "Authorization": f"Bearer {os.environ['FLUX_API_KEY']}",
            "Content-Type": "application/json",
        },
        json={
            "amount": float(request.form["amount"]),
            "currency": "USD",
            "customer": {
                "name": request.form["name"],
                "email": request.form["email"],
                "phone": request.form["phone"],
            },
            "callback_url": "https://yoursite.com/payment/return",
        },
        timeout=15,
    )
    r.raise_for_status()
    return redirect(r.json()["short_url"], code=303)

PHP

php
<?php
$ch = curl_init("https://flux.paytr.ing/api/public/v1/orders/create");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer " . getenv("FLUX_API_KEY"),
    "Content-Type: application/json",
  ],
  CURLOPT_POSTFIELDS => json_encode([
    "amount" => 49.99,
    "currency" => "USD",
    "customer" => [
      "name" => $_POST["name"],
      "email" => $_POST["email"],
      "phone" => $_POST["phone"],
    ],
    "callback_url" => "https://yoursite.com/payment/return",
  ]),
]);
$res = json_decode(curl_exec($ch), true);
header("Location: " . $res["short_url"]);

7. Handling the return

After payment, Paytring redirects the buyer to your callback_url. Show a "thanks" page and confirm the order in your system. The order_id and receipt_id you sent will be preserved so you can reconcile.

Do not mark orders paid based on the redirect alone. Always treat the callback as a UI hint and reconcile with the Flux webhook or the Status API.

8. Webhooks

Configure a webhook endpoint in Dashboard → Settings → Webhook endpoint. Flux sends Stripe-compatible payment.success events to your backend whenever a buyer completes a payment.

Webhook payload example:

json
{
  "id": "evt_…",
  "object": "event",
  "type": "payment.success",
  "created": 1735689600,
  "data": {
    "object": {
      "order_id": "ord_abc123",
      "payment_link_id": "f2c1…",
      "merchant_id": "…",
      "amount_usd": 49.99,
      "currency": "USD",
      "status": "paid",
      "receipt_id": "order_2026_001",
      "paid_at": "2026-01-01T12:00:00.000Z"
    }
  }
}

Each request includes a Stripe-Signature header. Verify it with the webhook secret you configured:

js
const crypto = require("crypto");

function verifySignature(secret, body, signatureHeader) {
  const parts = signatureHeader.split(",").map((p) => p.trim());
  const timestamp = parts.find((p) => p.startsWith("t="))?.slice(2);
  const signature = parts.find((p) => p.startsWith("v1="))?.slice(3);
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${body}`)
    .digest("hex");
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

9. Order status API

Poll the status of an order any time. Use the order_id returned by POST /api/public/v1/orders/create.

GET /api/public/v1/orders/{order_id}
Authorization: Bearer sk_live_xxx

Response:

json
{
  "order_id": "ord_abc123",
  "payment_link_id": "f2c1…",
  "status": "paid",
  "amount_usd": 49.99,
  "currency": "USD",
  "receipt_id": "order_2026_001",
  "paid_at": "2026-01-01T12:00:00.000Z",
  "transaction_id": "…"
}
StatusMeaning
pendingBuyer has not paid yet
paidPayment completed successfully
refundedFully or partially refunded
failedPayment failed
cancelledPayment was cancelled

10. Refund API

Request a refund for a successful transaction. Refunds are processed after admin review.

POST /api/public/v1/refunds
Authorization: Bearer sk_live_xxx
Content-Type: application/json
json
{
  "transaction_id": "…",
  "amount_usd": 49.99,
  "reason": "Customer requested cancellation"
}

You can also use order_id instead of transaction_id. The response includes a refund_request_id and a pending status. Track it in your dashboard under Transactions → Refund requests.

11. Subscriptions

Native recurring billing (plans, automatic renewals, dunning, upgrades and cancellations) is on the roadmap and is not available yet. Today Paytring supports one-off payment links and API-created orders.

If you need monthly billing now, you can drive the schedule from your side: keep the subscription state in your system, create a new order via POST /api/public/v1/orders/create on each renewal date, and use the webhook or Status API to confirm each charge. Cancellations and upgrades are then simply a change in your own billing logic.

12. Errors

StatusMeaning
401Missing / invalid / revoked API key
400Validation failed — check the response body for details
403Your KYC is not approved yet
502Paytring rejected the order — check amount/customer fields
500Internal error — please retry

All error responses are JSON like { "error": "..." }.

13. Testing your integration

  1. Make a small live order ($1) from your server using the cURL snippet above.
  2. Open the returned short_url in a browser — Paytring's checkout should appear.
  3. Complete the test transaction with a card supported by your Paytring account.
  4. Verify the order shows up in your Flux dashboard under Payment Links.

Need help?

Email support@paytring.com with your merchant ID and we'll help you get integrated.