Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.request.network/llms.txt

Use this file to discover all available pages before exploring further.

What you’ll build

A backend that creates a Secure Payment link in response to your app’s events — a customer hitting checkout, an invoice being approved, a subscription renewing. The customer opens the link, pays from any chain/token in any supported wallet, and your webhook fires when the payment confirms. Audience: developers integrating Request Network into an e-commerce app, marketplace, SaaS, or accounting product. Apps used:
  • Auth API — Client IDs, webhooks
  • Request APIPOST /v2/secure-payments and POST /v2/secure-payments/payouts
  • Secure Payment — what your customer sees when they open the link

Prerequisites

Complete steps 1–4 of the Quickstart:
  1. Sign in to the Dashboard with your wallet
  2. Create a payment destination
  3. Create a Client ID (with allowed domains for browser apps, empty for backend-only)
  4. Register a webhook URL pointing at your handler
You’ll need:
  • clientId — passed as x-client-id on every API call
  • destinationId — composite ID combining humanReadableInteropAddress + tokenAddress
  • Webhook signing secret — for verifying webhook payloads
Use POST /v2/secure-payments to mint a link the customer pays into.
const response = await fetch("https://api.request.network/v2/secure-payments", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-client-id": process.env.RN_CLIENT_ID!,
  },
  body: JSON.stringify({
    requests: [
      {
        destinationId:
          "0x6923831ACf5c327260D7ac7C9DfF5b1c3cB3C7D7@eip155:8453#ABCD1234:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
        amount: "100",
      },
    ],
    reference: order.id,
    payerIdentifier: customer.email,
  }),
});

const { securePaymentUrl, requestIds, token } = await response.json();
// Send securePaymentUrl to the customer (redirect, email, etc.)
The response includes securePaymentUrl — share it with the customer. They open it on pay.request.network, connect a wallet, and pay.

Send the customer back to your site after payment

Pass redirectUrl (and optionally redirectLabel) when creating the payment link. After a successful payment, the success screen renders a button that opens your URL — the payer clicks it to return to your site. There is no auto-redirect; the button is an explicit user action.
const response = await fetch("https://api.request.network/v2/secure-payments", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-client-id": process.env.RN_CLIENT_ID!,
  },
  body: JSON.stringify({
    requests: [{ destinationId: process.env.MERCHANT_DESTINATION!, amount: "100" }],
    reference: order.id,
    redirectUrl: `https://yourshop.com/orders/${order.id}/thank-you`,
    redirectLabel: "Back to your order",
  }),
});

const { securePaymentUrl } = await response.json();
// Send securePaymentUrl to the customer (redirect, email, etc.)
Validation rules:
  • redirectUrl must be http(s). Other schemes (javascript:, data:, etc.) and HTML/script payload characters are rejected with 400 redirectUrl must be a safe http(s) URL with no script/HTML payload.
  • redirectLabel is 1–255 chars and rejects HTML control characters (<, >, &, ", ', `).
  • redirectLabel cannot be set without redirectUrl — the API rejects with 400 redirectLabel cannot be provided without redirectUrl.
  • If you don’t pass redirectLabel, the button reads “Go Back and Close”.
The same fields are accepted on POST /v2/secure-payments/payouts for hosted payout links.

EVM and Tron destinations side-by-side

Tron is a drop-in replacement for any EVM destination as long as you submit a single recipient per call. The shape is identical; only the destinationId and addresses change format.
{
  "requests": [
    {
      "destinationId": "0x6923831ACf5c327260D7ac7C9DfF5b1c3cB3C7D7@eip155:8453#ABCD1234:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "amount": "100"
    }
  ]
}
Submitting multiple requests[] items where any destination is on Tron returns a 400 with Batch payments are not supported for TRON networks. Please submit individual payment requests. See Batch payouts for the EVM-only batch flow.
To pay someone (a contractor, vendor, refund recipient) via a hosted link they open and sign, use POST /v2/secure-payments/payouts. Same shape, single recipient, EVM or Tron.
const response = await fetch(
  "https://api.request.network/v2/secure-payments/payouts",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-client-id": process.env.RN_CLIENT_ID!,
    },
    body: JSON.stringify({
      recipient: "0x6923831ACf5c327260D7ac7C9DfF5b1c3cB3C7D7",
      creatorWalletAddress: process.env.PAYOUT_WALLET!,
      network: "base",
      currency: "USDC-base",
      amount: "250",
      reference: "INVOICE-2026-042",
    }),
  },
);

const { securePaymentUrl } = await response.json();
The hosted URL the response returns is opened by you (or whoever signs payouts). The signer’s wallet must match creatorWalletAddress.

Receive payment notifications

Your webhook endpoint receives signed POSTs as the payment lifecycle progresses. Verify the HMAC-SHA256 signature against your webhook secret before parsing the body.
import { createHmac, timingSafeEqual } from "node:crypto";
import express from "express";

const app = express();

// Capture raw body for signature verification
app.use(
  "/webhook",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const signature = req.headers["x-request-network-signature"] as string;
    const expected = createHmac("sha256", process.env.WEBHOOK_SECRET!)
      .update(req.body)
      .digest("hex");

    const sigBuf = Buffer.from(signature, "hex");
    const expBuf = Buffer.from(expected, "hex");
    const ok =
      sigBuf.length === expBuf.length &&
      timingSafeEqual(sigBuf, expBuf);

    if (!ok) return res.status(401).send("invalid signature");

    const event = JSON.parse(req.body.toString("utf8"));

    if (event.event === "payment.confirmed") {
      // Mark the order paid in your DB, fire fulfillment, etc.
    }

    res.status(200).send("ok");
  },
);
For the full webhook spec — all 12 events, retry policy, headers — see Webhook reconciliation and the Webhooks reference.

Next steps

Multi-chain checkout

What the customer sees when they pay across chains.

Batch payouts

Pay many EVM recipients in one signed transaction.

Webhook reconciliation

The reliable, signature-verified way to detect payments.

Secure Payments reference

Full request/response schemas for every endpoint.