PS Wallet Help
RUEN
Open wallet

Requests and responses

PS Wallet Pay API address, token authorization, HTTP methods, parameter and response formats, and the request rate limit.

On this page

All PS Wallet Pay API methods are called at a single address, authorized with the app token in a header, and respond with a JSON object containing the ok field.

API address

https://pay.pswallet.org/api/{method}

Replace {method} with the method name, for example https://pay.pswallet.org/api/createInvoice.

  • HTTPS only, UTF-8 encoding.
  • The method name is case-insensitive: getMe and getme are the same method.

Authorization

Pass the app token in the PSWallet-Pay-API-Token header:

PSWallet-Pay-API-Token: 1234:AbCdEf...

The token looks like <app ID>:<secret>. You can view and reissue it in the app dashboard under "API token" — see the Security section for details.

A request without a token, with an invalid or reissued token, or to a deleted app will receive a 401 UNAUTHORIZED error.

HTTP methods and parameters

  • GET and POST are supported.
  • Parameters are passed in the query string or in the POST body as application/json or application/x-www-form-urlencoded.
  • Methods that create or delete data accept only POST. For GET they respond with a 405 POST_REQUIRED error.

POST-only methods:

  • createInvoice
  • deleteInvoice
  • transfer
  • createCheck
  • deleteCheck
✓

The easiest approach is to always call methods via POST with a JSON body: this works for all methods, and amounts and lists are passed without escaping.

Response format

The response is always a JSON object with the ok field.

A successful response has ok: true, and the result is in the result field:

json
{
  "ok": true,
  "result": {
    "app_id": 1234,
    "name": "My Shop",
    "payment_processing_bot_username": "pswallet"
  }
}

An error has ok: false, and the description is in the error field:

json
{
  "ok": false,
  "error": { "code": 400, "name": "PARAM_AMOUNT_INVALID" }
}

code matches the HTTP status of the response, and name is the machine-readable error name. All codes are listed in the Errors section.

Request example

Let's create an invoice for 12.5 USDT. The payApi functions in the Node.js and Python examples can be used to call any method.

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": "Подписка на месяц"}'
// Node.js 18+ (built-in fetch)
const TOKEN = process.env.PSWALLET_PAY_TOKEN;

async function payApi(method, params = {}) {
  const response = await fetch(`https://pay.pswallet.org/api/${method}`, {
    method: "POST",
    headers: {
      "PSWallet-Pay-API-Token": TOKEN,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(params),
  });
  const data = await response.json();
  if (!data.ok) {
    throw new Error(`PS Wallet Pay: ${data.error.code} ${data.error.name}`);
  }
  return data.result;
}

const invoice = await payApi("createInvoice", {
  asset: "USDT",
  amount: "12.5",
  description: "Подписка на месяц",
});
console.log(invoice.bot_invoice_url);
import os
import requests

TOKEN = os.environ["PSWALLET_PAY_TOKEN"]


def pay_api(method: str, params: dict | None = None):
    response = requests.post(
        f"https://pay.pswallet.org/api/{method}",
        headers={"PSWallet-Pay-API-Token": TOKEN},
        json=params or dict(),
        timeout=15,
    )
    data = response.json()
    if not data["ok"]:
        error = data["error"]
        raise RuntimeError(f"PS Wallet Pay: {error['code']} {error['name']}")
    return data["result"]


invoice = pay_api("createInvoice", {
    "asset": "USDT",
    "amount": "12.5",
    "description": "Подписка на месяц",
})
print(invoice["bot_invoice_url"])

Rate limit

Each app is limited to 30 requests per second. If you exceed the limit, the API responds with a 429 TOO_MANY_REQUESTS error: wait a moment and retry the request.

If you need to find out about invoice payments frequently, don't poll getInvoices in a loop — set up webhooks instead.

What is checked before a method is called

Before executing a method, the API checks the request step by step and returns an error at the first problem:

CheckError
The method exists405 METHOD_NOT_FOUND
A method that creates or deletes data is called via POST405 POST_REQUIRED
The token is provided and valid401 UNAUTHORIZED
PS Wallet Pay is currently running503 TEMPORARILY_UNAVAILABLE
The rate limit is not exceeded429 TOO_MANY_REQUESTS
The request address is on the IP allowlist (if a list is set)403 IP_NOT_ALLOWED
The app is not frozen403 APP_FROZEN

After that, the method's own parameters are checked — see the sections describing the methods.

Retrying requests

Read methods (getMe, getInvoices, getBalance, and others) can be safely retried.

  • transfer is protected from duplicate submission by the spend_id parameter. If a request was interrupted and you don't know whether the transfer went through, check it with getTransfers using the same spend_id — see the Transfers section for details.
  • createInvoice and createCheck have no retry key: a repeated request will create another invoice or check. An extra unpaid invoice can be deleted with deleteInvoice, and an unactivated check with deleteCheck.
Updated November 9, 2026Translated automatically from Russian.