Payment Gateway API

Complete reference for integrating our payment system. Accept RUB payments via Bank Card and SBP with automatic USDT conversion.

https://admin.cashout.cx/api
🔐 All endpoints require authentication. Pass your API key in every request:
Authorization: Bearer mk_your_api_key_here

🔐 Authentication

Every API request must include your API key in the Authorization header:

Authorization: Bearer mk_your_api_key_here
⚠️ Security: Never expose your API Key in client-side code. All API calls must be made from your backend server.

Get Merchant Info

POST/api/auth/merchant/login

Authenticate and retrieve your merchant info. Use this to verify your API key is working.

Request Body

{ "apiKey": "mk_your_api_key_here" }

Response — Success

{
  "success": true,
  "data": {
    "companyName": "Your Company",
    "balance": 125.50,
    "frozenBalance": 10.00
  }
}

Response — Error

{ "success": false, "message": "Invalid API key" }

⚠️ Error Handling

All responses follow a consistent structure:

FieldTypeDescription
successbooleantrue on success, false on error
dataobjectResponse payload (on success)
messagestringHuman-readable description
errorstringTechnical error detail (on failure)

Common Errors

Scenariomessage
Missing / invalid API keyUnauthorized: valid API key required
No cascade configured for amount/methodNo cascade configured for this merchant.
Missing required fieldsMissing required fields: ...
Insufficient balanceInsufficient balance. Current: X USDT, Requested: Y USDT

💰 1. Get Available Currencies

GET/api/merchants/currenciesAuth Required

Request Headers

Authorization: Bearer mk_your_api_key_here

Response

{
  "success": true,
  "data": [
    { "code": "RUB", "name": "Russian Ruble", "symbol": "₽" }
  ]
}

💳 2. Get Payment Methods

Returns available payment methods for a given currency, based on your merchant's cascade configuration.

GET/api/merchants/payment-methods?currency=RUBAuth Required

Request Headers

Authorization: Bearer mk_your_api_key_here

Query Parameters

ParameterRequiredDescription
currency✅ YesCurrency code, e.g. RUB

Response

{
  "success": true,
  "data": [
    { "code": "CARD",            "name": "Bank Card (toCard)" },
    { "code": "SBP",             "name": "SBP (Fast Payment System)" },
    { "code": "TOACCOUNT",       "name": "Bank Account Transfer" },
    { "code": "TRANSGRAN",       "name": "Transgran (Card)" },
    { "code": "TRANSGRANSBP",    "name": "Transgran SBP" },
    { "code": "NSPK",            "name": "NSPK" },
    { "code": "MOBILE",          "name": "Mobile Payment" },
    { "code": "ECOM",            "name": "Online Banking Form" },
    { "code": "ALFA_ALFA",       "name": "Alfa-Bank → Alfa-Bank" },
    { "code": "SBER_SBER",       "name": "Sberbank → Sberbank" },
    { "code": "OZON_OZON",       "name": "Ozon Bank → Ozon Bank" },
    { "code": "TBANK_TBANK",     "name": "T-Bank → T-Bank" },
    { "code": "VTB_VTB",         "name": "VTB → VTB" },
    { "code": "GAZPROM_GAZPROM", "name": "Gazprombank → Gazprombank" },
    { "code": "PSB_PSB",         "name": "PSB → PSB" }
  ]
}

🚀 3. Create Transaction

Creates a new payment transaction. The system selects the PSP based on your cascade configuration for the given payment method and amount range.

POST/api/merchants/transactions/create-manualAuth Required

Request Headers

Authorization: Bearer mk_your_api_key_here
Content-Type: application/json

Request Body

FieldTypeRequiredDescription
amountnumber✅ YesPayment amount in fiat currency (e.g. 5000 for 5000 RUB). Must fall within a configured cascade range.
currencystring✅ YesCurrency code. Currently supported: RUB
paymentMethodstring✅ YesPayment method code. Available values: CARD, SBP, TOACCOUNT, TRANSGRAN, TRANSGRANSBP, NSPK, MOBILE, ECOM, ALFA_ALFA, SBER_SBER, OZON_OZON, TBANK_TBANK, VTB_VTB, GAZPROM_GAZPROM, PSB_PSB. Use GET /api/merchants/payment-methods?currency=RUB to get methods available for your cascade config.

Example Request

{
  "amount": 5000,
  "currency": "RUB",
  "paymentMethod": "CARD"
}

Response — Success

{
  "success": true,
  "message": "Transaction created successfully",
  "data": {
    "transactionId": "7a6509d1-c2e2-4f6f-806f-cad81a3c278d",
    "amount": "5000.00",
    "currency": "RUB",
    "usdtAmount": 62.45,
    "exchangeRate": 80.07,
    "status": "pending",
    "paymentDetails": {
      "paymentMethod": "card",
      "cardNumber": "4111-1111-1111-1111",
      "cardHolder": "IVAN IVANOV",
      "bankName": "Sberbank"
    },
    "createdAt": "2026-03-04T10:25:26.076Z",
    "expiresAt": "2026-03-04T10:55:26.076Z"
  }
}

Response Fields

FieldDescription
transactionIdUUID — use this to check status or open a dispute
amountOriginal amount in fiat currency
usdtAmountUSDT amount you will receive after commission
exchangeRateRUB/USDT rate used for conversion
statusCurrent transaction status (see table below)
paymentDetailsPayment requisites to show to the end customer
createdAtTransaction creation time (UTC ISO 8601)
expiresAtTransaction expiry time — 30 minutes after creation (UTC ISO 8601)

Transaction Statuses

StatusDescription
pendingCreated, awaiting payment confirmation
processingPayment is being processed
completed✅ Confirmed — USDT credited to your balance
failed❌ Payment failed
cancelled❌ Auto-cancelled after 30 min if still pending
dispute⚖️ Dispute opened
completed_after_dispute✅ Dispute resolved in your favour
failed_after_dispute❌ Dispute resolved against you
⏱ Auto-cancellation: Transactions in pending status are automatically cancelled 30 minutes after creation (expiresAt).

🔍 4. Get Transaction Status

GET/api/transactions/:transactionIdAuth Required

Request Headers

Authorization: Bearer mk_your_api_key_here

Path Parameters

ParameterDescription
transactionIdUUID from the create transaction response

Response

{
  "success": true,
  "data": {
    "id": "7a6509d1-c2e2-4f6f-806f-cad81a3c278d",
    "amount": "5000.00",
    "currency": "RUB",
    "usdtAmount": "62.45",
    "exchangeRate": "80.07",
    "status": "completed",
    "createdAt": "2026-03-04T10:25:26.076Z",
    "updatedAt": "2026-03-04T10:28:00.000Z"
  }
}

⚖️ 5. Create Dispute

Open a dispute for a transaction. Attach a supporting document if available.

POST/api/disputes/createAuth Required
📎 Content-Type: Use multipart/form-data (not JSON) — this endpoint accepts a file attachment.

Request Headers

Authorization: Bearer mk_your_api_key_here

Form Fields

FieldTypeRequiredDescription
transactionIdstring✅ YesUUID of the transaction being disputed
reasonstring✅ YesReason for the dispute
amountnumber✅ YesDisputed amount in original currency (RUB)
filefile❌ NoSupporting document — JPG/PNG/PDF, max 10 MB

Example (curl)

curl -X POST "https://admin.cashout.cx/api/disputes/create" \
  -H "Authorization: Bearer mk_your_api_key_here" \
  -F "transactionId=7a6509d1-c2e2-4f6f-806f-cad81a3c278d" \
  -F "reason=Payment confirmed but funds not received" \
  -F "amount=5000" \
  -F "file=@/path/to/screenshot.png"

Response — Success

{
  "success": true,
  "message": "Dispute created successfully",
  "data": {
    "id": "d1e2f3a4-b5c6-7890-abcd-ef1234567890",
    "transactionId": "7a6509d1-c2e2-4f6f-806f-cad81a3c278d",
    "reason": "Payment confirmed but funds not received",
    "amount": "5000.00",
    "status": "open",
    "createdAt": "2026-03-04T11:00:00.000Z"
  }
}

Dispute Statuses

StatusDescription
openSubmitted, under review
resolved_merchantResolved in your favour — USDT credited
resolved_pspResolved against you

🔔 Webhooks

Configure a webhook URL in your merchant settings to receive real-time status change notifications.

Webhook Payload

{
  "event": "transaction.status_changed",
  "transactionId": "7a6509d1-c2e2-4f6f-806f-cad81a3c278d",
  "status": "completed",
  "amount": "5000.00",
  "currency": "RUB",
  "usdtAmount": "62.45",
  "timestamp": "2026-03-04T10:28:00.000Z"
}

Signature Verification

// Node.js
const crypto = require('crypto');
function verifyWebhook(rawBody, signature, secret) {
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
🔁 Retry policy: Non-2xx responses are retried up to 3 times (30s, 5min, 30min).
Need help? Contact your account manager if you encounter integration issues.