Betron API Documentation

Welcome to the Betron API documentation. This guide explains how to integrate Betron’s payment services into your application using simple, REST-style endpoints.

Production
Base URL https://betron.org/api/v1

Quickstart

Before you begin: contact the Betron team to obtain your API Key and API Secret, configure your callback URLs, and whitelist your server IP addresses.

1. Get your credentials
- API Key and API Secret from Betron
- Callback URLs for transactions and withdrawals
2. Fetch available banks
Use the /bank endpoints to list supported banks and their limits before creating transactions.
3. Create a transaction
Create a deposit using POST /transaction, redirect your customer to the provided checkout_url, and wait for callbacks.
4. Handle callbacks
Use signed webhook callbacks to track transaction and withdrawal status changes in real time.

Authentication

All requests to the Betron API must be made over HTTPS and include a bearer token in the Authorization header.

Bearer token

Example headers:

Headers
GET /api/v1/bank HTTP/1.1
Host: betron.org
Authorization: Bearer YOUR_API_TOKEN
Accept: application/json

The token value is provided by the Betron team and must match the configured API token on the server. If the header is missing, empty, or invalid, the API returns a 401 Unauthorized response.

Optional HMAC Signature

For additional security, requests and callbacks can be signed using an HMAC built from your API Secret and the payload.

Headers (example)
Authorization: Bearer YOUR_API_TOKEN
X-Signature: HMAC_SIGNATURE_HERE

The exact signing algorithm and string-to-sign format will be provided during integration.

Available Banks

Use these endpoints to retrieve the list of banks that are currently available for processing deposit and withdrawal transactions.

List banks for deposit

GET /api/v1/bank
GET /api/v1/bank/transaction

Both endpoints return the same response and are suitable for deposit flows.

Response · 200 OK
{
  "success": true,
  "message": "Banks retrieved successfully",
  "code": 200,
  "total": 1,
  "data": [
    {
      "id": 1,
      "name": "Bank A",
      "image": "https://example.com/bank-a.png",
      "transaction_status": 1,
      "withdrawal_status": 1,
      "status": 1
    }
  ]
}

List banks for withdrawal

GET /api/v1/bank/withdrawal
Response · 200 OK
{
  "success": true,
  "message": "Banks retrieved successfully",
  "code": 200,
  "total": 1,
  "data": [
    {
      "id": 5,
      "name": "Bank W",
      "image": "https://example.com/bank-w.png",
      "transaction_status": 1,
      "withdrawal_status": 1,
      "status": 1
    }
  ]
}

Transactions (Deposit)

Deposit transactions allow you to accept payments from your customers.

Create transaction

POST /api/v1/transaction
Field Type Required Description
first_name string yes Customer first name.
last_name string yes Customer last name.
phone string yes Customer phone number.
amount number yes Payment amount.
bank_id integer yes Bank identifier obtained from the banks endpoint.
client_ip string yes Client IP address of the user initiating the payment.
order_id integer yes Your internal order reference.
user_id integer yes Your internal user identifier.
site_id, site_name, transaction_fee mixed set by Betron These values are injected by Betron based on your API token; you do not need to send them.
Request body · JSON
{
  "first_name": "John",
  "last_name": "Doe",
  "phone": "+905551112233",
  "amount": 250.0,
  "bank_id": 1,
  "client_ip": "203.0.113.10",
  "order_id": 12345,
  "user_id": 42
}
Response · 201 Created
{
  "success": true,
  "code": 200,
  "message": "Transaction created",
  "data": {
    "transaction_uuid": "d3a6b9f0-1234-5678-9abc-def012345678",
    "receiver_iban": "TR000000000000000000000000",
    "receiver_name": "Betron Payment Account"
  }
}

Redirect the customer to checkout_url to complete the payment.

Update transaction

PUT /api/v1/transaction/{uuid}

Use this endpoint to update an existing transaction, for example to cancel it.

Request body · JSON
{
  "status": "canceled",
  "reason": "Customer canceled the payment"
}

Get transaction status

GET /api/v1/transaction/{uuid}/status
Response · 200 OK
{
  "success": true,
  "code": 201,
  "message": "Transaction details",
  "data": {
    "id": 1,
    "uuid": "d3a6b9f0-1234-5678-9abc-def012345678",
    "user_id": 42,
    "first_name": "John",
    "last_name": "Doe",
    "sender": "John Doe",
    "phone": "+905551112233",
    "amount": 250.0,
    "currency": "TRY",
    "order_id": 12345,
    "receiver_iban": "TR000000000000000000000000",
    "receiver_name": "Betron Payment Account",
    "receiver": "Betron Payment Account",
    "bank_id": 1,
    "bank_name": "Bank A",
    "status": "success",
    "paid_status": true,
    "client_ip": "203.0.113.10",
    "created_at": "2026-02-24T12:34:56Z",
    "updated_at": "2026-02-24T12:35:56Z"
  }
}

Withdrawals

Withdrawal endpoints are used to send funds to a customer or payout account.

Create withdrawal

POST /api/v1/withdrawal
Request body · JSON
{
  "user_id": 42,
  "first_name": "John",
  "last_name": "Doe",
  "iban": "TR000000000000000000000000",
  "bank_id": 5,
  "amount": 1000.0,
  "order_id": "WITHDRAW-98765"
}
Response · 201 Created
{
  "success": true,
  "code": 201,
  "message": "Withdrawal created successfully",
  "data": {
    "id": 10,
    "uuid": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
    "first_name": "John",
    "last_name": "Doe",
    "receiver": "John Doe",
    "iban": "TR000000000000000000000000",
    "bank_id": 5,
    "bank_name": "Bank W",
    "amount": 1000.0,
    "order_id": "WITHDRAW-98765",
    "site_id": 1,
    "site_name": "Betron",
    "sender_name": null,
    "sender_iban": null,
    "status": 0,
    "paid_status": false,
    "created_at": "2026-02-24T13:40:00Z",
    "updated_at": "2026-02-24T13:40:00Z"
  }
}

Get withdrawal status

GET /api/v1/withdrawal/{uuid}/status
Response · 200 OK
{
  "success": true,
  "code": 201,
  "message": "Withdrawal created successfully",
  "data": {
    "id": 10,
    "uuid": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
    "first_name": "John",
    "last_name": "Doe",
    "receiver": "John Doe",
    "iban": "TR000000000000000000000000",
    "bank_id": 5,
    "bank_name": "Bank W",
    "amount": 1000.0,
    "order_id": "WITHDRAW-98765",
    "site_id": 1,
    "site_name": "Betron",
    "sender_name": "Betron",
    "sender_iban": "TR000000000000000000000000",
    "status": 1,
    "paid_status": true,
    "created_at": "2026-02-24T13:40:00Z",
    "updated_at": "2026-02-24T13:45:00Z"
  }
}

Wallets

Wallet endpoints allow you to view your Betron balances.

Get wallet

GET /api/v1/wallet
Response · 200 OK
{
  "success": true,
  "message": "Account retrieved successfully",
  "code": 200,
  "data": {
    "id": 1,
    "name": "Main Wallet",
    "iban": "TR000000000000000000000000"
  }
}

Callbacks

Betron sends webhook callbacks when a transaction’s paid_status becomes true. Callbacks are sent to one or more URLs configured on your side.

Configuring webhook URLs & secret

In your Betron environment, the following variables control webhook delivery:

  • TRANSACTION_WEBHOOK_URL – single callback URL (backwards compatible)
  • TRANSACTION_WEBHOOK_URLS – comma‑separated list of URLs (e.g. https://a.com/hook,https://b.com/hook)
  • TRANSACTION_WEBHOOK_SECRET_KEY – shared HMAC secret used to sign payloads
  • TRANSACTION_WEBHOOK_ENABLED – enable / disable callbacks (default: true)

HTTP request

For each successful transaction update, Betron will perform an HTTP POST request to every configured URL.

Headers
POST /your/webhook/endpoint HTTP/1.1
Host: merchant.example.com
Content-Type: application/json
X-Signature: <HMAC_SHA256_SIGNATURE>
X-Timestamp: 1737654321

Transaction webhook payload

Body · JSON
{
  "transaction_id": 1,
  "uuid": "d3a6b9f0-1234-5678-9abc-def012345678",
  "user_id": 42,
  "amount": 250.0,
  "currency": "TRY",
  "status": "success",
  "paid_status": true,
  "first_name": "John",
  "last_name": "Doe",
  "phone": "+905551112233",
  "receiver_iban": "TR000000000000000000000000",
  "receiver_name": "Betron Payment Account",
  "bank_id": 1,
  "bank_name": "Bank A",
  "wallet_id": 10,
  "site_id": 1,
  "site_name": "Betron",
  "order_id": 12345,
  "payment_method": "manual",
  "created_at": "2026-02-24T12:34:56Z",
  "updated_at": "2026-02-24T12:35:10Z",
  "accepted_at": "2026-02-24T12:35:00Z",
  "timestamp": 1737654321
}

How the HMAC signature is generated

Betron signs each callback using HMAC‑SHA256 with your secret key.

  1. Sort the JSON payload by keys (ascending).
  2. Build the signature string: signature_string = timestamp + json_encode(sorted_payload) + secret_key
  3. Compute the signature: signature = HMAC_SHA256(signature_string, secret_key).
  4. Send this value in the X-Signature header and the Unix timestamp in X-Timestamp.
Example (pseudo-code)
// payload is the JSON body as an object/array
sortedPayload = sortKeysAscending(payload)
jsonPayload   = jsonEncode(sortedPayload, withoutEscapingSlashes)
signatureStr  = payload["timestamp"] + jsonPayload + SECRET_KEY

signature = HMAC_SHA256(signatureStr, SECRET_KEY)

Verifying the webhook on your server

On your side you should recompute the signature and compare it to the X-Signature header.

PHP verification example
$secret   = 'YOUR_TRANSACTION_WEBHOOK_SECRET_KEY';
$body     = file_get_contents('php://input');        // raw JSON
$payload  = json_decode($body, true);               // associative array
$timestamp = $_SERVER['HTTP_X_TIMESTAMP'] ?? null;
$received  = $_SERVER['HTTP_X_SIGNATURE'] ?? null;

ksort($payload);
$jsonPayload  = json_encode($payload, JSON_UNESCAPED_SLASHES);
$signatureStr = $timestamp . $jsonPayload . $secret;
$expected     = hash_hmac('sha256', $signatureStr, $secret);

if (!hash_equals($expected, $received)) {
    http_response_code(401);
    exit('Invalid signature');
}

// Signature is valid – process the webhook safely.

Errors

Betron uses standard HTTP status codes and a consistent JSON structure for error responses.

Status Meaning
200, 201 Successful request / resource created.
400 Bad request (invalid parameters).
401 Unauthorized (missing or invalid bearer token).
403 Forbidden (e.g. blacklisted).
404 Resource not found.
422 Validation error.
500 Internal server error.

Error response format

Body · JSON (domain / business errors)
{
  "success": false,
  "code": 400,
  "message": "Minimum amount is 2000",
  "data": []
}