AGDor Pay

Documentation

There are two different scenarios. One for projects that work via API and webhooks. The second for operators who create invoices manually from the panel and send the ready payment page or builder view to the client.

API Flow Automatic Integration For websites, SaaS, Telegram bots and client projects where invoice is created programmatically and status is received via webhook. project_code, api_key, wallet_code, invoice.confirmed Dashboard Flow Manual Invoices from Panel For operators, managers and administrators who create invoices themselves, configure templates and send a link or ready text to the client. Project, wallet, templates, payment page, builder view

Automatic Integration

The API flow starts in the panel, but then works without manual actions. You create a project, attach wallets to it, save `api_key` and then your service creates invoices itself.

1

Create a project

Open Dashboard → Projects. After saving, the project gets `project_code`, `api_key` and `webhook_secret`. `api_key` is shown only once.

2

Add a wallet and link it to the project

In Dashboard → Wallets create the desired payment method, and then enable it in the project through the list of allowed wallets.

3

Get payment methods

Your project calls `r=payment_methods`, gets active `wallet_code` and shows the client a list of available networks or Binance ID.

4

Create an invoice

After the client selects a payment method, your server calls `r=create_invoice`, gets `invoice_id`, exact amount and destination address, and then shows this data to the user.

5

Wait for confirmation

When Payment Service finds a payment, it changes the invoice status and sends `invoice.confirmed` to the `Webhook URL` of your project.

If `api_key` is lost, it cannot be read again. For a production project, you need to generate a new key in the project settings and update it on the client side.

Authorization

Each API request must pass `project_code` and `api_key`. Preferred method: HTTP headers.

Field Where to pass Description
X-Project-Code Header Internal project code.
X-API-Key Header Project secret for API requests.
project_code POST / GET Fallback option if the client cannot send headers.
api_key POST Fallback option for server-to-server requests.
curl -X POST "https://agdorpay.com/api?r=payment_methods" \
  -H "X-Project-Code: project_demo_123" \
  -H "X-API-Key: ********"

API Methods

r=ping

Service availability check.

GET https://agdorpay.com/api?r=ping

r=payment_methods

Returns active `wallet_code`, currency, network and display name of the payment method for the selected project.

GET/POST https://agdorpay.com/api?r=payment_methods

r=create_invoice

Creates an invoice and returns the exact amount with micro-offset that the client must pay.

POST https://agdorpay.com/api?r=create_invoice

r=get_invoice

Returns the current invoice state by `invoice_id` or `external_id`.

GET/POST https://agdorpay.com/api?r=get_invoice

r=cancel_invoice

Cancels the invoice while it is in `pending` status.

POST https://agdorpay.com/api?r=cancel_invoice

r=confirm_invoice

Manual invoice confirmation from the project side. Used only for special scenarios.

POST https://agdorpay.com/api?r=confirm_invoice

`payment_methods` example

{
  "status": "success",
  "data": {
    "project_code": "project_demo_123",
    "wallets": [
      {
        "wallet_code": "usdt_trc20_main",
        "label": "USDT TRC20",
        "payment_type": "crypto_wallet",
        "currency": "USDT",
        "network": "TRC20",
        "address": "T..."
      }
    ]
  }
}

`create_invoice` example

curl -X POST "https://agdorpay.com/api?r=create_invoice" \
  -H "X-Project-Code: project_demo_123" \
  -H "X-API-Key: ********" \
  -d "amount=25.00" \
  -d "wallet_code=usdt_trc20_main" \
  -d "external_id=order_10452" \
  -d "customer_id=user_42"
{
  "status": "success",
  "data": {
    "invoice_id": "inv_87a3bfd",
    "project_code": "project_demo_123",
    "external_id": "order_10452",
    "customer_id": "user_42",
    "status": "pending",
    "amount_requested": "25.00",
    "amount": "25.0427",
    "currency": "USDT",
    "payment_type": "crypto_wallet",
    "network": "TRC20",
    "address": "T...",
    "wallet_code": "usdt_trc20_main",
    "wallet_label": "USDT TRC20",
    "expires_at": "2026-06-13 18:30:00",
    "confirmed_at": null,
    "txid": null,
    "metadata": {}
  }
}
The amount field in the response may be greater than the requested amount. You need to pay exactly this, otherwise automatic payment matching will not work.

Webhooks

After invoice confirmation, the service sends a POST request to the `Webhook URL` specified in the project. Resubmission is possible, so the client handler must be idempotent.

Header Description
X-Payment-Event-Id Unique webhook event identifier.
X-Payment-Timestamp Unix timestamp that participates in the signature.
X-Payment-Signature HMAC-SHA256 signature by the formula `timestamp.payload`.
signature = HMAC_SHA256(
  timestamp + "." + raw_json_payload,
  webhook_secret
)
{
  "event_id": "evt_...",
  "event_type": "invoice.confirmed",
  "invoice_id": "inv_87a3bfd",
  "project_code": "project_demo_123",
  "external_id": "order_10452",
  "customer_id": "user_42",
  "status": "confirmed",
  "amount_requested": "25.00",
  "amount": "25.0427",
  "currency": "USDT",
  "payment_type": "crypto_wallet",
  "network": "TRC20",
  "address": "T...",
  "wallet_code": "usdt_trc20_main",
  "wallet_label": "USDT TRC20",
  "txid": "transaction_hash",
  "confirmed_at": "2026-06-13 18:41:20",
  "metadata": {}
}
<?php
$rawBody = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_PAYMENT_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_PAYMENT_SIGNATURE'] ?? '';
$expected = hash_hmac('sha256', $timestamp . '.' . $rawBody, $webhookSecret);

if (!hash_equals($expected, $signature)) {
    http_response_code(403);
    exit('bad signature');
}

Polling as a fallback

If you do not want to rely only on webhooks, you can periodically call `r=get_invoice` and check the status. This is especially useful for internal dashboards or long client sessions.

When to use

  • internal dashboard without external webhook endpoint
  • fallback channel alongside webhook
  • status check in browser session of the user

Best practices

  • poll once every 5-10 seconds
  • stop polling on `confirmed`, `manual_confirmed`, `cancelled`, `expired`
  • do not spam the service with parallel requests for one invoice

Examples

Minimal PHP client

<?php
$ch = curl_init("https://agdorpay.com/api?r=create_invoice");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERAGENT => 'Mozilla/5.0 AGDor Pay Client',
    CURLOPT_HTTPHEADER => [
        'X-Project-Code: project_demo_123',
        'X-API-Key: ********',
    ],
    CURLOPT_POSTFIELDS => http_build_query([
        'amount' => '25.00',
        'wallet_code' => 'usdt_trc20_main',
        'external_id' => 'order_10452',
    ]),
]);
$response = curl_exec($ch);

Minimal cURL status check

curl "https://agdorpay.com/api?r=get_invoice" \
  -H "X-Project-Code: project_demo_123" \
  -H "X-API-Key: ********" \
  -d "invoice_id=inv_87a3bfd"

Invoice statuses

Status Meaning
pendingInvoice created and waiting for payment.
confirmedPayment found automatically.
manual_confirmedInvoice confirmed manually.
cancelledInvoice cancelled by operator or project.
expiredInvoice deadline expired before confirmation.