Skip to main content

Forebit Payments — Guide for AI Agents

This page contains everything an AI agent (Claude, Cursor, Codex, or any LLM-based coding tool) needs to integrate Forebit Payments into a website. Copy-paste this entire page into your AI agent’s context. You are integrating Forebit Payments, a cryptocurrency payment processing API. Forebit provides a hosted checkout page — you create a payment via the API, redirect the customer to the checkout URL, and listen for webhook events to confirm payment.

Architecture Overview

The integration flow is:
  1. Your server creates a payment via the REST API
  2. The API returns a url to a Forebit-hosted checkout page
  3. You redirect the customer to that URL
  4. The customer selects a cryptocurrency and pays
  5. Forebit sends a webhook to your server when the payment status changes
  6. Your server verifies the webhook signature and updates the order
  7. Optionally, the customer is redirected back to your site via redirectUrl
There is no client-side SDK. All API calls happen server-side. The checkout UI is fully hosted by Forebit.

Credentials

Obtain these from the Forebit dashboard:
CredentialWhere to find itPurpose
Business IDPayments → Settings → DeveloperIdentifies your business in API URLs
API KeyPayments → Settings → DeveloperBearer token for API authentication
Webhook SecretDeveloper → Webhookswhsec_... prefix, used with Svix to verify webhook signatures

Environment variables

FOREBIT_BUSINESS_ID=your_business_id
FOREBIT_API_KEY=your_payments_api_key
FOREBIT_WEBHOOK_SECRET=whsec_...

API Basics

Base URL

https://prod-payments-api.forebit.io
All requests must use HTTPS.

Authentication

Every request requires a Bearer token:
Authorization: Bearer YOUR_API_KEY

Response format

Success:
{
  "data": { ... },
  "message": null,
  "errors": null
}
Error (RFC 7807 ProblemDetails):
{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "Bad Request",
  "status": 400,
  "detail": "Validation failed"
}

HTTP status codes

StatusMeaning
200Success
400Invalid parameters or validation error
401Invalid or missing API key
403Insufficient permissions for this business
404Payment or business not found

Endpoints

All endpoints are scoped to a business:
MethodEndpointDescription
POST/v1/businesses/{businessId}/paymentsCreate a new payment
GET/v1/businesses/{businessId}/payments/{paymentId}Get a single payment
GET/v1/businesses/{businessId}/paymentsList payments (paginated)
PUT/v1/businesses/{businessId}/payments/{paymentId}/noteUpdate internal note

Creating a Payment

POST /v1/businesses/{businessId}/payments

Request body

FieldTypeRequiredDescription
currencystringYesISO 4217 currency code (e.g. USD, EUR)
amountnumberYesPayment amount (minimum 0.5)
namestringNoDisplay name shown to customer on checkout page
descriptionstringNoInternal description, not visible to customers
customerEmailstring (email)NoCustomer email for receipts and status updates
customerIpstringNoCustomer IP address. Auto-detected from checkout page visit if omitted
customerUserAgentstringNoCustomer user-agent. Auto-detected from checkout page visit if omitted
redirectUrlstring (URI)NoURL to redirect the customer after payment completes
notifyUrlstring (URI)NoWebhook URL for this specific payment (overrides default)
metadataobjectNoArbitrary key-value string pairs stored with the payment. Use this to attach your internal order ID
paymentMethodsobjectNoRestrict which payment methods are available to the customer
feeTransfersarrayNoFee transfer configuration

Example request

curl -X POST https://prod-payments-api.forebit.io/v1/businesses/{businessId}/payments \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "currency": "USD",
    "amount": 25.00,
    "name": "Order #1234",
    "description": "Premium plan subscription",
    "customerEmail": "customer@example.com",
    "redirectUrl": "https://yoursite.com/thank-you",
    "notifyUrl": "https://yoursite.com/webhooks/forebit",
    "metadata": {
      "orderId": "1234",
      "plan": "premium"
    }
  }'

Example response

{
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "url": "https://pay.forebit.io/payment/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  },
  "message": null,
  "errors": null
}
  • id — UUID of the payment, use this to query the payment later
  • url — hosted checkout page URL, redirect the customer here

Restricting payment methods

Pass the paymentMethods object to control which cryptocurrencies are available. If omitted, all methods configured for your business are enabled.
{
  "paymentMethods": {
    "FOREBIT_CRYPTO": ["BITCOIN", "ETHEREUM", "SOLANA"],
    "CONTRACT_CRYPTO": ["CONTRACT_ERC20_USDT", "CONTRACT_ERC20_USDC"]
  }
}
Charge types:
TypeDescription
FOREBIT_CRYPTONative coins and tokens via Forebit wallets
CONTRACT_CRYPTOERC-20 tokens via smart contract
CONTRACT_TRXTRC-20 tokens via smart contract
NONENo crypto payment method
Available coins per charge type:
  • FOREBIT_CRYPTO: BITCOIN, ETHEREUM, LITECOIN, BITCOIN_CASH, ETH_USD_COIN, ETH_TETHER, MONERO, BNB, ETH_BUSD, ETH_MATIC, ETH_SHIBA_INU, ETH_APE_COIN, ETH_CRONOS, ETH_DAI, ETH_UNISWAP, TRON, TRX_TETHER, TRX_USD_C, SOLANA, SOL_TETHER, SOL_USD_COIN, TON
  • CONTRACT_CRYPTO: CONTRACT_ERC20_ETH, CONTRACT_ERC20_USDT, CONTRACT_ERC20_USDC
  • CONTRACT_TRX: CONTRACT_TRC20_TRX, CONTRACT_TRC20_USDT, CONTRACT_TRC20_USDC

Retrieving a Payment

GET /v1/businesses/{businessId}/payments/{paymentId}
curl https://prod-payments-api.forebit.io/v1/businesses/{businessId}/payments/{paymentId} \
  -H "Authorization: Bearer YOUR_API_KEY"

Response fields

FieldTypeDescription
idstring (UUID)Payment identifier
namestringDisplay name
descriptionstringInternal description
endAmountnumberFinal payment amount
prePaymentAmountnumberAmount before payment processing
currencystringISO 4217 currency code
statusPaymentStatusCurrent payment status
createdAtdate-timeWhen the payment was created
expiresAtdate-timeWhen the payment expires
timelinearrayStatus change history
customerobjectCustomer details including email and IP info
metadataobjectCustom key-value pairs you attached
selectedPaymentMethodPaymentMethodMethod chosen by the customer
forebitCryptoChargeobjectForebit crypto charge details (if applicable)
contractChargeobjectContract charge details (if applicable)
forebitFeenumberFee amount
notestringInternal note
netAmountUsdnumberNet amount in USD

Listing Payments

GET /v1/businesses/{businessId}/payments

Query parameters

ParameterTypeDescription
PageNumberintegerPage number
PageSizeintegerResults per page
fromTimedate-timeStart of date range
toTimedate-timeEnd of date range
statusesarrayFilter by status (repeat parameter for multiple)
cryptoCoinsarrayFilter by cryptocurrency
fromAmountnumberMinimum amount
toAmountnumberMaximum amount
searchStringstringFree-text search across description, name, note, or customer email
Example:
curl "https://prod-payments-api.forebit.io/v1/businesses/{businessId}/payments?PageSize=20&statuses=COMPLETED&statuses=PENDING" \
  -H "Authorization: Bearer YOUR_API_KEY"

Payment Statuses

StatusDescription
AWAITING_PAYMENTPayment created, waiting for customer to pay
PENDINGPayment detected on-chain, awaiting confirmation
PROCESSINGPayment is being processed
UNDERPAIDCustomer sent less than the required amount
COMPLETEDPayment confirmed and completed — fulfill the order
FAILEDPayment failed
CANCELLEDPayment was cancelled
EXPIREDPayment expired before completion

Webhooks

Forebit uses Svix for webhook delivery. Svix provides automatic retries, signature validation, and delivery logs.

Webhook events

EventDescription
PAYMENT_CREATEDPayment was created
PAYMENT_METHOD_SELECTEDCustomer selected a payment method
PAYMENT_PENDINGPayment detected, awaiting confirmation
PAYMENT_UNDERPAIDCustomer sent less than required
PAYMENT_COMPLETEDPayment confirmed — this is the event to fulfill orders on
PAYMENT_EXPIREDPayment expired
PAYMENT_CANCELLEDPayment was cancelled

Webhook payload structure

{
  "EventType": "PAYMENT_COMPLETED",
  "ForPaymentEvents": {
    "Id": "78d1cc6a-2e46-421b-b03b-3c307bfbd1bc",
    "BusinessId": 1001,
    "Name": "Order #1234",
    "Description": "",
    "EndAmount": 25.00,
    "PrePaymentAmount": 25.00,
    "Currency": "USD",
    "Status": "COMPLETED",
    "CreatedAt": "2025-08-14T09:18:56.295788Z",
    "ExpiresAt": "2025-08-14T09:48:56.295788Z",
    "Timeline": [
      { "Time": "2025-08-14T09:18:56Z", "PaymentStatus": "AWAITING_PAYMENT" },
      { "Time": "2025-08-14T09:20:40Z", "PaymentStatus": "PENDING" },
      { "Time": "2025-08-14T09:20:40Z", "PaymentStatus": "COMPLETED" }
    ],
    "Customer": {
      "Id": 68,
      "Email": "customer@example.com",
      "IpAddresses": [
        {
          "City": "New York",
          "Ip": "203.0.113.50",
          "Country": "United States",
          "RiskScore": 0,
          "ConnectionType": "RESIDENTIAL",
          "ISP": "Example ISP",
          "DateCreated": "2025-07-21T09:13:11Z"
        }
      ]
    },
    "SelectedPaymentMethod": "FOREBIT_CRYPTO",
    "ForebitCryptoCharge": {
      "Amount": 0.00025,
      "CoinName": "BITCOIN",
      "ExchangeRate": 100000.00,
      "IsUnderpaid": false,
      "Address": "bc1q...",
      "Transaction": {
        "Amount": 0.00025,
        "ToAddress": "bc1q...",
        "Id": "txhash...",
        "Confirmations": 3,
        "Network": "BTC",
        "FromAddress": "bc1qsender...",
        "TokenName": "BITCOIN"
      },
      "WalletName": "main"
    },
    "ForebitFee": 0.50,
    "RedirectUrl": "https://yoursite.com/thank-you"
  }
}
Important: Webhook field names use PascalCase (e.g. EventType, ForPaymentEvents, EndAmount), while the REST API responses use camelCase (e.g. endAmount, currency).

Webhook payload TypeScript types

interface BaseWebhookResponse {
  EventType: string;
  ForPaymentEvents?: PaymentForWebhookResponse | null;
}

interface PaymentForWebhookResponse {
  Id: string;
  BusinessId: number;
  Name?: string;
  Description?: string;
  EndAmount: number;
  PrePaymentAmount: number;
  Currency: string;
  Status: PaymentStatus;
  CreatedAt: string;
  ExpiresAt: string;
  Timeline: { Time: string; PaymentStatus: PaymentStatus }[];
  Customer?: {
    Id: number;
    Email: string;
    IpAddresses: {
      City?: string;
      Ip: string;
      Country?: string;
      RiskScore?: number;
      ConnectionType: string;
      ISP?: string;
      DateCreated: string;
    }[];
  } | null;
  Metadata?: Record<string, string> | null;
  SelectedPaymentMethod?: PaymentMethod | null;
  ForebitCryptoCharge?: {
    Amount: number;
    CoinName: string;
    ExchangeRate: number;
    IsUnderpaid: boolean;
    Address: string;
    Transaction?: {
      Amount: number;
      ToAddress: string;
      Id: string;
      Confirmations: number;
      BlockNumber?: string;
      Network?: string;
      FromAddress?: string;
      TokenName?: string;
    } | null;
    WalletName: string;
  } | null;
  ContractCharge?: {
    Amount: number;
    ExchangeRate: number;
    IsUnderpaid: boolean;
    Address: string;
    Transaction: {
      Amount: number;
      ToAddress: string;
      Id: string;
      Confirmations: number;
      BlockNumber?: string;
      Network?: string;
      FromAddress?: string;
      TokenName?: string;
    };
    WalletName: string;
    CoinName: string;
  } | null;
  ForebitFee?: number;
  RedirectUrl?: string;
}

type PaymentStatus =
  | 'AWAITING_PAYMENT' | 'PENDING' | 'PROCESSING'
  | 'UNDERPAID' | 'COMPLETED' | 'FAILED'
  | 'CANCELLED' | 'EXPIRED';

type PaymentMethod = 'FOREBIT_CRYPTO' | 'CONTRACT_CRYPTO' | 'CONTRACT_TRX' | 'NONE';

Verifying webhook signatures

Use the Svix library to verify webhook signatures. This is critical for security — never process a webhook without verifying the signature first. Required headers from the webhook request: svix-id, svix-timestamp, svix-signature. Node.js:
import { Webhook } from "svix";

const wh = new Webhook(process.env.FOREBIT_WEBHOOK_SECRET);

// Inside your webhook handler:
// payload = raw request body as a string
// headers = object with svix-id, svix-timestamp, svix-signature
const event = wh.verify(payload, headers);
Python:
from svix.webhooks import Webhook

wh = Webhook(os.environ["FOREBIT_WEBHOOK_SECRET"])

# payload = raw request body as bytes
# headers = dict with svix-id, svix-timestamp, svix-signature
event = wh.verify(payload, headers)
Install: npm install svix (Node.js) or pip install svix (Python).

Full Integration Examples

Node.js (Express)

import express from "express";
import { Webhook } from "svix";

const app = express();

const FOREBIT_API_KEY = process.env.FOREBIT_API_KEY;
const FOREBIT_BUSINESS_ID = process.env.FOREBIT_BUSINESS_ID;
const FOREBIT_WEBHOOK_SECRET = process.env.FOREBIT_WEBHOOK_SECRET;
const BASE_URL = "https://prod-payments-api.forebit.io";

// 1. Create a payment and redirect to checkout
app.post("/checkout", async (req, res) => {
  const { orderId, amount, email } = req.body;

  const response = await fetch(
    `${BASE_URL}/v1/businesses/${FOREBIT_BUSINESS_ID}/payments`,
    {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${FOREBIT_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        currency: "USD",
        amount,
        name: `Order #${orderId}`,
        customerEmail: email,
        redirectUrl: "https://yoursite.com/thank-you",
        notifyUrl: "https://yoursite.com/webhooks/forebit",
        metadata: { orderId },
      }),
    }
  );

  const result = await response.json();

  if (!response.ok) {
    return res.status(400).json({ error: result });
  }

  // Save result.data.id to your database linked to the order
  // Then redirect the customer to checkout
  res.json({ checkoutUrl: result.data.url });
});

// 2. Handle webhooks — use raw body for signature verification
app.post(
  "/webhooks/forebit",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const wh = new Webhook(FOREBIT_WEBHOOK_SECRET);

    let event;
    try {
      event = wh.verify(req.body.toString(), {
        "svix-id": req.headers["svix-id"],
        "svix-timestamp": req.headers["svix-timestamp"],
        "svix-signature": req.headers["svix-signature"],
      });
    } catch (err) {
      console.error("Webhook verification failed:", err.message);
      return res.status(400).send("Invalid signature");
    }

    const { EventType, ForPaymentEvents: payment } = event;

    switch (EventType) {
      case "PAYMENT_COMPLETED":
        // Fulfill the order using payment.Metadata.orderId
        console.log(`Payment ${payment.Id} completed for ${payment.EndAmount} ${payment.Currency}`);
        // Update your database: mark order as paid
        break;

      case "PAYMENT_EXPIRED":
        // Handle expired payment
        console.log(`Payment ${payment.Id} expired`);
        break;

      case "PAYMENT_UNDERPAID":
        // Handle underpaid payment
        console.log(`Payment ${payment.Id} underpaid`);
        break;
    }

    res.status(200).send("OK");
  }
);

// Use json parsing for all other routes
app.use(express.json());

app.listen(3000);

Python (Flask)

import os
import requests
from flask import Flask, request, jsonify
from svix.webhooks import Webhook

app = Flask(__name__)

FOREBIT_API_KEY = os.environ["FOREBIT_API_KEY"]
FOREBIT_BUSINESS_ID = os.environ["FOREBIT_BUSINESS_ID"]
FOREBIT_WEBHOOK_SECRET = os.environ["FOREBIT_WEBHOOK_SECRET"]
BASE_URL = "https://prod-payments-api.forebit.io"


@app.route("/checkout", methods=["POST"])
def checkout():
    data = request.json
    order_id = data["orderId"]
    amount = data["amount"]
    email = data.get("email")

    resp = requests.post(
        f"{BASE_URL}/v1/businesses/{FOREBIT_BUSINESS_ID}/payments",
        headers={
            "Authorization": f"Bearer {FOREBIT_API_KEY}",
            "Content-Type": "application/json",
        },
        json={
            "currency": "USD",
            "amount": amount,
            "name": f"Order #{order_id}",
            "customerEmail": email,
            "redirectUrl": "https://yoursite.com/thank-you",
            "notifyUrl": "https://yoursite.com/webhooks/forebit",
            "metadata": {"orderId": order_id},
        },
    )

    result = resp.json()

    if resp.status_code != 200:
        return jsonify({"error": result}), 400

    # Save result["data"]["id"] to your database
    return jsonify({"checkoutUrl": result["data"]["url"]})


@app.route("/webhooks/forebit", methods=["POST"])
def webhook():
    wh = Webhook(FOREBIT_WEBHOOK_SECRET)

    try:
        event = wh.verify(
            request.get_data(as_text=True),
            {
                "svix-id": request.headers.get("svix-id"),
                "svix-timestamp": request.headers.get("svix-timestamp"),
                "svix-signature": request.headers.get("svix-signature"),
            },
        )
    except Exception as e:
        print(f"Webhook verification failed: {e}")
        return "Invalid signature", 400

    event_type = event["EventType"]
    payment = event["ForPaymentEvents"]

    if event_type == "PAYMENT_COMPLETED":
        order_id = payment.get("Metadata", {}).get("orderId")
        print(f"Payment {payment['Id']} completed — fulfill order {order_id}")
        # Update your database: mark order as paid

    elif event_type == "PAYMENT_EXPIRED":
        print(f"Payment {payment['Id']} expired")

    return "OK", 200

Next.js (App Router)

// app/api/checkout/route.ts
import { NextResponse } from "next/server";

const FOREBIT_API_KEY = process.env.FOREBIT_API_KEY!;
const FOREBIT_BUSINESS_ID = process.env.FOREBIT_BUSINESS_ID!;

export async function POST(req: Request) {
  const { orderId, amount, email } = await req.json();

  const response = await fetch(
    `https://prod-payments-api.forebit.io/v1/businesses/${FOREBIT_BUSINESS_ID}/payments`,
    {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${FOREBIT_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        currency: "USD",
        amount,
        name: `Order #${orderId}`,
        customerEmail: email,
        redirectUrl: "https://yoursite.com/thank-you",
        notifyUrl: "https://yoursite.com/api/webhooks/forebit",
        metadata: { orderId },
      }),
    }
  );

  const result = await response.json();

  if (!response.ok) {
    return NextResponse.json({ error: result }, { status: 400 });
  }

  return NextResponse.json({ checkoutUrl: result.data.url });
}
// app/api/webhooks/forebit/route.ts
import { Webhook } from "svix";

const FOREBIT_WEBHOOK_SECRET = process.env.FOREBIT_WEBHOOK_SECRET!;

export async function POST(req: Request) {
  const body = await req.text();
  const headers = {
    "svix-id": req.headers.get("svix-id") ?? "",
    "svix-timestamp": req.headers.get("svix-timestamp") ?? "",
    "svix-signature": req.headers.get("svix-signature") ?? "",
  };

  const wh = new Webhook(FOREBIT_WEBHOOK_SECRET);

  let event: any;
  try {
    event = wh.verify(body, headers);
  } catch {
    return new Response("Invalid signature", { status: 400 });
  }

  const { EventType, ForPaymentEvents: payment } = event;

  if (EventType === "PAYMENT_COMPLETED") {
    const orderId = payment.Metadata?.orderId;
    // Fulfill the order in your database
  }

  return new Response("OK", { status: 200 });
}

Best Practices

Security

  • Always verify webhook signatures using Svix before processing any webhook event. Never trust the payload without verification.
  • Keep your API key server-side only. Never expose it in client-side code, browser JavaScript, or mobile apps.
  • Use HTTPS for all webhook endpoints. Forebit will not deliver webhooks to HTTP URLs in production.
  • Store the webhook secret securely in environment variables, never hardcoded.

Payment creation

  • Always store the payment id from the create response in your database, linked to your internal order. You need it to reconcile webhooks and query payment status.
  • Use metadata to attach your internal order ID, user ID, or any reference data. This data is returned in webhooks and GET requests, making reconciliation easy.
  • Set redirectUrl so the customer returns to your site after payment. Without it, they stay on the Forebit checkout page.
  • Set notifyUrl per-payment if you have multiple webhook endpoints, or rely on the default configured in the dashboard.
  • Set customerEmail so the customer receives email receipts and status updates.
  • Minimum amount is 0.5 in your chosen currency.

Webhook handling

  • Respond with 200 quickly. Process the webhook asynchronously if your fulfillment logic is slow. Svix will retry on non-2xx responses.
  • Make your webhook handler idempotent. You may receive the same event more than once due to retries. Use the payment Id to deduplicate.
  • Only fulfill orders on PAYMENT_COMPLETED. Do not fulfill on PENDING or PROCESSING — these are intermediate states.
  • Handle PAYMENT_EXPIRED and PAYMENT_CANCELLED to clean up pending orders in your system.
  • Use the raw request body for signature verification. Parsing the JSON first and re-serializing it will break the signature.

Error handling

  • Check for non-200 responses from the API and handle them gracefully.
  • API errors use RFC 7807 ProblemDetails format with type, title, status, and detail fields.
  • If a payment creation fails, show the user an error and let them retry. Do not create duplicate payments — check your database first.

Testing

  • Use small amounts (minimum 0.5) for test payments.
  • Use the Svix CLI or dashboard to replay webhooks to your endpoint during development.
  • Use a tool like ngrok to expose your local webhook endpoint during development.

Supported Cryptocurrencies (Full List)

CoinIdentifierNetwork
BitcoinBITCOINBTC
EthereumETHEREUMETHEREUM
LitecoinLITECOINLTC
Bitcoin CashBITCOIN_CASHBTC
USDC (ERC-20)ETH_USD_COINETHEREUM
USDT (ERC-20)ETH_TETHERETHEREUM
MoneroMONERO
BNBBNBETHEREUM
DAI (ERC-20)ETH_DAIETHEREUM
Uniswap (ERC-20)ETH_UNISWAPETHEREUM
MATIC (ERC-20)ETH_MATICETHEREUM
SHIB (ERC-20)ETH_SHIBA_INUETHEREUM
APE (ERC-20)ETH_APE_COINETHEREUM
CRO (ERC-20)ETH_CRONOSETHEREUM
BUSD (ERC-20)ETH_BUSDETHEREUM
TronTRONTRON
USDT (TRC-20)TRX_TETHERTRON
USDC (TRC-20)TRX_USD_CTRON
SolanaSOLANASOLANA
USDT (Solana)SOL_TETHERSOLANA
USDC (Solana)SOL_USD_COINSOLANA
TONTON
Contract ETHCONTRACT_ERC20_ETHETHEREUM
Contract USDT (ERC-20)CONTRACT_ERC20_USDTETHEREUM
Contract USDC (ERC-20)CONTRACT_ERC20_USDCETHEREUM
Contract TRXCONTRACT_TRC20_TRXTRON
Contract USDT (TRC-20)CONTRACT_TRC20_USDTTRON
Contract USDC (TRC-20)CONTRACT_TRC20_USDCTRON
Networks: ETHEREUM, TRON, BTC, LTC, SOLANA

Quick Reference

Base URL:       https://prod-payments-api.forebit.io
Auth header:    Authorization: Bearer YOUR_API_KEY
Create payment: POST /v1/businesses/{businessId}/payments
Get payment:    GET  /v1/businesses/{businessId}/payments/{paymentId}
List payments:  GET  /v1/businesses/{businessId}/payments
Update note:    PUT  /v1/businesses/{businessId}/payments/{paymentId}/note

Webhook lib:    svix (npm install svix / pip install svix)
Fulfill on:     PAYMENT_COMPLETED event only
Min amount:     0.5 (in chosen currency)