v2

API v2 Reference

A versioned REST API for creating payments, tracking status in real time, choosing the healthiest provider and managing webhook delivery.

Getting started

Base URL

https://fastpayglobal.app

Authentication

x-public-key: pk_live_…

All responses are JSON. Successful reads return a data field; failures return { "error": "message" }. Send Idempotency-Key on payment creation so retries never double-charge. CORS is open, but never ship a secret key to a browser.

OpenAPI specification

The full API v2 surface is published as an OpenAPI 3.1 document. Import it into Postman, Insomnia, Swagger Editor or an SDK generator to get typed clients and a ready-made request collection.

In Postman choose Import → Link and paste https://fastpayglobal.app/api/public/openapi.json. The spec always reflects the host it is served from.

Endpoints

GET
/api/v2/health
public
Platform health

Live health score per payment provider. No authentication required.

Rate limit: 60 req / min / IP

Request
curl https://fastpayglobal.app/api/v2/health
Response 200
{
  "status": "ok",
  "providers": [
    { "provider": "bkash", "health_score": 98, "success_count_1h": 49,
      "failure_count_1h": 1, "avg_response_ms_1h": 820, "last_failure_at": null }
  ]
}
POST
/api/v2/payments
Create a payment

Creates a payment and returns a hosted checkout URL. Send an Idempotency-Key header to safely retry the same request.

Rate limit: 60 req / min / IP

FieldTypeDescription
amountnumberAmount in major units (e.g. 10.00).
currencystringISO code, e.g. BDT or USD. Defaults to the brand currency.
orderIdstringYour order reference. Must be unique per payment.
customerobjectOptional { name, email, phone }.
metadataobjectOptional key/value data echoed back in webhooks.
Request
curl -X POST https://fastpayglobal.app/api/v2/payments \
  -H "x-public-key: pk_live_xxx" \
  -H "Idempotency-Key: order-123" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 10.00,
    "currency": "BDT",
    "orderId": "ORDER-123",
    "customer": { "name": "Customer", "email": "a@b.com", "phone": "01700000000" }
  }'
Response 200
{
  "data": {
    "id": "uuid",
    "orderId": "ORDER-123",
    "amount": 10,
    "currency": "BDT",
    "status": "pending",
    "hostedUrl": "https://fastpayglobal.app/pay/<id>",
    "expiresAt": "2026-08-10T10:15:00Z"
  }
}
GET
/api/v2/payments/:id
Payment status

Returns the current state of a payment. Statuses progress pending → detected → confirming → paid, or expired / failed / refunded.

Rate limit: 120 req / min / IP

Request
curl https://fastpayglobal.app/api/v2/payments/<id> \
  -H "x-public-key: pk_live_xxx"
Response 200
{
  "data": {
    "id": "uuid",
    "orderId": "ORDER-123",
    "amount": 10,
    "currency": "BDT",
    "status": "paid",
    "method": "bkash",
    "trxId": "TRX-XYZ",
    "createdAt": "2026-08-10T10:00:00Z",
    "expiresAt": "2026-08-10T10:15:00Z",
    "paidAt": "2026-08-10T10:04:12Z"
  }
}
POST
/api/v2/payments/:id/cancel
Cancel a payment

Expires a payment that has not reached a terminal state yet.

Rate limit: 30 req / min / IP

Request
curl -X POST https://fastpayglobal.app/api/v2/payments/<id>/cancel \
  -H "x-public-key: pk_live_xxx"
Response 200
{ "ok": true, "status": "expired" }
POST
/api/v2/payments/:id/refund
Refund a payment

Full or partial refund of a paid payment. Omit amount to refund the full value.

Rate limit: 30 req / min / IP

FieldTypeDescription
amountnumberOptional partial amount in major units.
reasonstringOptional reason, max 500 chars.
Request
curl -X POST https://fastpayglobal.app/api/v2/payments/<id>/refund \
  -H "x-public-key: pk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 5.00, "reason": "Customer request" }'
Response 200
{ "ok": true, "refundId": "uuid", "amount": 5 }
GET
/api/v2/routing/providers
Smart routing

Your enabled payment methods ranked by health score and 1-hour success rate. Use recommended to pre-select a method and degraded to hide unreliable ones.

Rate limit: 60 req / min / IP

Request
curl https://fastpayglobal.app/api/v2/routing/providers \
  -H "x-public-key: pk_live_xxx"
Response 200
{
  "data": [
    { "provider": "bkash", "label": "bKash Personal", "healthScore": 98,
      "successRate1h": 98, "avgResponseMs1h": 820,
      "degraded": false, "recommended": true },
    { "provider": "nagad", "label": "Nagad", "healthScore": 62,
      "successRate1h": 60, "degraded": true, "recommended": false }
  ]
}
GET
/api/v2/webhooks/events
List webhook events

Recent webhook deliveries for your brand. Filter with ?status=pending|failed|delivered&limit=50.

Rate limit: 60 req / min / IP

Request
curl "https://fastpayglobal.app/api/v2/webhooks/events?status=failed&limit=20" \
  -H "x-public-key: pk_live_xxx"
Response 200
{
  "data": [
    { "id": "uuid", "eventType": "payment.succeeded", "status": "failed",
      "attempts": 3, "nextAttemptAt": "2026-08-10T10:30:00Z",
      "createdAt": "2026-08-10T10:00:00Z", "payload": { } }
  ]
}
POST
/api/v2/webhooks/retry
Retry a webhook

Re-queues a pending or failed webhook event for immediate delivery.

Rate limit: 30 req / min / IP

FieldTypeDescription
eventIduuidThe webhook event to retry.
Request
curl -X POST https://fastpayglobal.app/api/v2/webhooks/retry \
  -H "x-public-key: pk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "eventId": "uuid" }'
Response 200
{ "ok": true, "status": "pending" }

Errors

StatusMeaning
400Invalid JSON or body failed validation (details included).
401Missing or invalid x-public-key.
402Plan expired — renew to keep the API live.
403Brand disabled, or caller IP not whitelisted.
404Resource not found for this brand.
409State conflict (already delivered, not refundable, invalid transition).
429Rate limited — honour the Retry-After header.
500Unexpected server error.

Webhooks

FastPay Global POSTs signed JSON to your brand webhook URL for payment.succeeded, payment.failed, payment.expired, payment.refunded and invoice.paid. Failed deliveries retry with exponential backoff and can be replayed from the Developer Portal or the retry endpoint.

Delivery
POST <your webhook url>
x-signature: <hex hmac-sha256 of the raw body>

{
  "event": "payment.succeeded",
  "paymentId": "uuid",
  "orderId": "ORDER-123",
  "amount": 10,
  "currency": "BDT",
  "method": "bkash",
  "trxId": "TRX-XYZ",
  "paidAt": "2026-08-10T10:04:12Z",
  "metadata": {}
}
Node.js
import crypto from "crypto";

const raw = req.rawBody;                       // exact bytes, not re-serialized JSON
const expected = crypto.createHmac("sha256", process.env.WEBHOOK_SECRET)
  .update(raw).digest("hex");

const ok = crypto.timingSafeEqual(
  Buffer.from(expected),
  Buffer.from(req.headers["x-signature"]),
);
if (!ok) return res.status(401).end();
PHP
<?php
$raw = file_get_contents('php://input');
$expected = hash_hmac('sha256', $raw, getenv('WEBHOOK_SECRET'));
if (!hash_equals($expected, $_SERVER['HTTP_X_SIGNATURE'] ?? '')) {
    http_response_code(401); exit;
}
Python
import hmac, hashlib

raw = request.get_data()
expected = hmac.new(WEBHOOK_SECRET.encode(), raw, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, request.headers.get("X-Signature", "")):
    abort(401)

Interactive explorer

Rendered live from the OpenAPI document. Add your x-public-key to try requests against your own brand.