PS Wallet Help
RUEN
Open wallet

Invoices

Creating, retrieving, and deleting payment invoices in the PS Wallet Pay API: createInvoice, getInvoices, deleteInvoice.

On this page

An invoice is a payment request that a user opens via a link and pays in PS Wallet. The payment amount minus the fee is credited to the app balance, and an invoice_paid webhook is sent to your server.

An invoice can be issued in a coin (USDT, USDT-TRC20, TRX, etc.) or in fiat (USD, RUB), in which case the user chooses the coin to pay with. For coin codes and amount formatting rules, see Coins and amounts.

Invoice statuses

StatusMeaning
activeThe invoice is awaiting payment.
paidThe invoice is paid and the funds are credited to the app balance.
expiredThe validity period (expires_in) has ended; the invoice can no longer be paid.

An invoice deleted via deleteInvoice can't be paid and no longer appears in getInvoices.

createInvoice

Create a payment invoice. POST only. Returns Invoice.

ParameterTypeDescription
currency_typeStringOptional. crypto (default) or fiat.
assetStringRequired if currency_type=crypto. Invoice coin: USDT (any network), USDT-TRC20, USDT-BEP20, USDT-ERC20, USDT-TON, XAUT, TRX, BNB, ETH, GRAM.
fiatStringRequired if currency_type=fiat. Amount currency: USD or RUB.
accepted_assetsStringOptional, fiat only. Coins accepted for payment, comma-separated, for example USDT,TRX. In JSON you can also pass an array. Default: USDT,TRX,BNB,ETH,GRAM,RUB (of these, only the ones currently available).
amountStringRequired. Amount in the asset coin or in the fiat currency, for example 125.50.
descriptionStringOptional. Description shown to the user. Up to 1024 characters.
hidden_messageStringOptional. Message the user sees after payment. Up to 2048 characters.
paid_btn_nameStringOptional. Button on the screen after payment: viewItem, openChannel, openBot, or callback (see below).
paid_btn_urlStringRequired if paid_btn_name is specified. Button link, starts with https:// or http://, up to 512 characters.
payloadStringOptional. Any data of your own (for example, an order number), up to 4 KB. Returned in the invoice and in the webhook.
allow_commentsBooleanOptional. Allow the user to leave a comment with the payment. Default: true.
allow_anonymousBooleanOptional. Allow anonymous payment: the payer's name won't be visible in the app history. Default: true.
expires_inNumberOptional. Invoice lifetime in seconds, from 1 to 2678400 (31 days). By default, the invoice never expires.

Boolean parameters accept true/false as well as 1/0, which is convenient for application/x-www-form-urlencoded.

Request example

curl https://pay.pswallet.org/api/createInvoice \
  -H "PSWallet-Pay-API-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "asset": "USDT",
    "amount": "12.5",
    "description": "Подписка на месяц",
    "payload": "order-1042",
    "expires_in": 3600
  }'
// Node.js 18+ (built-in fetch)
const response = await fetch("https://pay.pswallet.org/api/createInvoice", {
  method: "POST",
  headers: {
    "PSWallet-Pay-API-Token": process.env.PSWALLET_PAY_TOKEN,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    asset: "USDT",
    amount: "12.5",
    description: "Подписка на месяц",
    payload: "order-1042",
    expires_in: 3600,
  }),
});
const data = await response.json();
if (!data.ok) throw new Error(data.error.name);

const invoice = data.result;
// store invoice.invoice_id alongside the order and send the link to the user
console.log(invoice.bot_invoice_url);
import os
import requests

response = requests.post(
    "https://pay.pswallet.org/api/createInvoice",
    headers={"PSWallet-Pay-API-Token": os.environ["PSWALLET_PAY_TOKEN"]},
    json={
        "asset": "USDT",
        "amount": "12.5",
        "description": "Подписка на месяц",
        "payload": "order-1042",
        "expires_in": 3600,
    },
    timeout=15,
)
data = response.json()
if not data["ok"]:
    raise RuntimeError(data["error"]["name"])

invoice = data["result"]
# store invoice["invoice_id"] alongside the order and send the link to the user
print(invoice["bot_invoice_url"])

Response:

json
{
  "ok": true,
  "result": {
    "invoice_id": 528,
    "hash": "IVq3Lm9TzR4wXkPa",
    "currency_type": "crypto",
    "asset": "USDT",
    "amount": "12.5",
    "bot_invoice_url": "https://t.me/pswallet?start=IVq3Lm9TzR4wXkPa",
    "mini_app_invoice_url": "https://t.me/pswallet?startapp=IVq3Lm9TzR4wXkPa",
    "web_app_invoice_url": "https://t.me/pswallet?startapp=IVq3Lm9TzR4wXkPa",
    "pay_url": "https://t.me/pswallet?start=IVq3Lm9TzR4wXkPa",
    "description": "Подписка на месяц",
    "status": "active",
    "created_at": "2026-10-28T15:51:21.000+00:00",
    "allow_comments": true,
    "allow_anonymous": true,
    "expiration_date": "2026-10-28T16:51:21.000+00:00",
    "payload": "order-1042",
    "paid_anonymously": false
  }
}

Send the user bot_invoice_url (the invoice opens in the bot chat with a payment button) or mini_app_invoice_url (opens the payment screen directly in the mini app).

✓

Pass the order number in payload: it will be returned in the invoice_paid webhook, so you can easily find the order without a separate mapping table.

Invoice in dollars or rubles

To issue an invoice in fiat, pass currency_type=fiat, the fiat currency, and, if needed, a list of coins in accepted_assets:

json
{
  "currency_type": "fiat",
  "fiat": "USD",
  "amount": "9.99",
  "accepted_assets": "USDT,TRX",
  "description": "Премиум на месяц"
}

The user chooses a coin from the allowed ones, and the amount is converted at the exchange rate at the time of payment. For details, see Coins and amounts.

i

If accepted_assets contains a coin that is currently unavailable, the PARAM_ACCEPTED_ASSETS_INVALID error is returned. Rubles (RUB) are currently not accepted for payment, and a list consisting only of RUB will also return this error.

Button after payment

After payment, the user sees a screen with the hidden_message message (if set) and a button that leads to paid_btn_url:

paid_btn_nameButton text
viewItem"Open item"
openChannel"Open channel"
openBot"Open bot"
callback"Return"

createInvoice errors

The response code is 400 unless stated otherwise.

  • PARAM_CURRENCY_TYPE_INVALID — currency_type is neither crypto nor fiat.
  • PARAM_ASSET_REQUIRED, PARAM_ASSET_INVALID — the asset coin is missing, unknown, or currently unavailable.
  • PARAM_FIAT_REQUIRED, PARAM_FIAT_INVALID — the fiat currency is missing or unknown.
  • PARAM_ACCEPTED_ASSETS_INVALID — invalid accepted_assets list.
  • PARAM_AMOUNT_REQUIRED, PARAM_AMOUNT_INVALID — the amount is missing, is not greater than zero, or has more decimal places than the coin allows.
  • PARAM_DESCRIPTION_INVALID, PARAM_HIDDEN_MESSAGE_INVALID, PARAM_PAYLOAD_INVALID — the text is longer than allowed.
  • PARAM_PAID_BTN_NAME_INVALID, PARAM_PAID_BTN_URL_REQUIRED, PARAM_PAID_BTN_URL_INVALID — invalid button after payment.
  • PARAM_ALLOW_COMMENTS_INVALID, PARAM_ALLOW_ANONYMOUS_INVALID — not a boolean value.
  • PARAM_EXPIRES_IN_INVALID — expires_in is not an integer from 1 to 2678400.
  • 403 APP_FROZEN — the app is frozen.

getInvoices

List of the app's invoices, newest first. Deleted invoices are not returned. Returns an object { "items": [Invoice, …] }.

ParameterTypeDescription
assetStringOptional. Only invoices in this coin (by the invoice's asset field, not by the payment coin).
fiatStringOptional. Only invoices in this fiat currency.
invoice_idsStringOptional. Invoice IDs, comma-separated (the first 1000 are used).
statusStringOptional. active, paid, or expired. Default: all.
offsetNumberOptional. How many invoices to skip. Default: 0.
countNumberOptional. How many to return, from 1 to 1000. Default: 100.
cURL
curl "https://pay.pswallet.org/api/getInvoices?status=paid&count=10" \
  -H "PSWallet-Pay-API-Token: $TOKEN"

Response:

json
{
  "ok": true,
  "result": {
    "items": [
      {
        "invoice_id": 528,
        "hash": "IVq3Lm9TzR4wXkPa",
        "currency_type": "crypto",
        "asset": "USDT",
        "amount": "12.5",
        "status": "paid",
        "paid_asset": "USDT-TRC20",
        "paid_amount": "12.5",
        "paid_usd_rate": "1",
        "fee_asset": "USDT-TRC20",
        "fee_amount": 0.375,
        "paid_at": "2026-10-28T15:51:22.000+00:00",
        "paid_anonymously": false,
        "payload": "order-1042"
      }
    ]
  }
}

The example shows only some of the fields. For the full list, see the Invoice type description.

Errors (code 400): PARAM_ASSET_INVALID, PARAM_FIAT_INVALID, PARAM_INVOICE_IDS_INVALID, PARAM_STATUS_INVALID, PARAM_OFFSET_INVALID, PARAM_COUNT_INVALID.

deleteInvoice

Delete an invoice. POST only. After deletion it can't be paid and no longer appears in getInvoices. A paid invoice can't be deleted.

ParameterTypeDescription
invoice_idNumberRequired. Invoice ID.

Returns true.

cURL
curl https://pay.pswallet.org/api/deleteInvoice \
  -H "PSWallet-Pay-API-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"invoice_id": 528}'

Errors (code 400 unless stated otherwise):

  • PARAM_INVOICE_ID_REQUIRED, PARAM_INVOICE_ID_INVALID — invoice_id is missing or invalid.
  • 404 INVOICE_NOT_FOUND — the invoice was not found or has already been deleted.
  • INVOICE_PAID — the invoice has already been paid.
Updated November 9, 2026Translated automatically from Russian.