> For the complete documentation index, see [llms.txt](https://docs.skypaybd.top/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.skypaybd.top/integration-and-api/verify-payment.md).

# Verify Payment

The **Verify Payment** API validates that a customer's transaction has been successfully executed, settled on the corresponding rail, and credited to your merchant account.

SkyPay provides two verification pathways:

1. **Hosted Verification (`/api/payment/verify`)**: Server-to-server query to inspect transaction status using a settled Transaction ID.
2. **Headless Verification (`/api/v2/payment/verify`)**: Multi-rail verification engine supporting real-time MFS SMS reconciliation, Bangla QR push matching, BEP20 EVM blockchain node queries, and Binance Pay API verification.

***

## 1. Version 1 — Hosted Transaction Query (`/api/payment/verify`)

Use this endpoint from your backend server to double-check transaction states received from client redirection query parameters or webhooks.

### Endpoint Details

* **URL**: `https://core.skypaybd.top/api/payment/verify`
* **Method**: `POST` (or `GET`)
* **Headers**:
  * `BRAND-KEY`: `<your_active_brand_key>` (Required)
  * `Content-Type`: `application/json`

### Request Parameters

| Parameter        | Type   | Required | Aliases                                                          | Description                          |
| ---------------- | ------ | -------- | ---------------------------------------------------------------- | ------------------------------------ |
| `transaction_id` | String | **Yes**  | `transactionId`, `transactionid`, `trx_id`, `trx`, `transaction` | Unique transaction reference string. |

### Request Example (cURL)

```bash
curl -X POST "https://core.skypaybd.top/api/payment/verify" \
  -H "BRAND-KEY: your_active_brand_key" \
  -H "Content-Type: application/json" \
  -d '{
    "transaction_id": "BLM37A9B1X"
  }'
```

### Success Response (HTTP 200 OK)

```json
{
  "status": true,
  "data": {
    "cus_name": "Rahim Ahmed",
    "cus_email": "rahim@example.com",
    "amount": "1500.00",
    "transaction_id": "BLM37A9B1X",
    "meta_data": {
      "order_id": "ORD-99120"
    },
    "payment_method": "bkash",
    "status": "COMPLETED"
  }
}
```

### Status Definitions:

* **`COMPLETED`**: Transaction settled and verified on hardware relay or banking node. Merchant may safely fulfill the order.
* **`PENDING`**: Payment initiated or under manual review (e.g., bank transfer slip).
* **`FAILED`**: Transaction aborted, duplicate, expired, or invalid.

***

## 2. Version 2 — Headless Multi-Rail Verification (`/api/v2/payment/verify`)

The Headless verification endpoint validates client-submitted transaction proofs across four distinct payment architectures.

### Endpoint Details

* **URL**: `https://core.skypaybd.top/api/v2/payment/verify`
* **Method**: `POST`
* **Headers**:
  * `BRAND-KEY`: `<your_active_brand_key>` (Required)
  * `Content-Type`: `application/json`

### General Request Schema

| Field            | Type   | Required | Aliases                                                                                                                 | Description                                                                                   |
| ---------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `id`             | String | **Yes**  | —                                                                                                                       | Temporary session token returned by `/api/v2/payment/create`.                                 |
| `method`         | String | **Yes**  | —                                                                                                                       | Selected payment channel: `bkash`, `nagad`, `rocket`, `upay`, `banglaqr`, `binance`, `bep20`. |
| `transaction_id` | String | **Yes**  | `order_id`, `order`, `trx_id`, `transactionId`, `tx_hash`, `txhash`, `hash`, `number`, `mobile`, `trx`, `mobile_number` | Channel-specific transaction proof (SMS TrxID, sender phone, TxHash, or Binance Order ID).    |

***

## 3. Channel-by-Channel Verification Deep Dive

### Rail A: Mobile Financial Services (bKash, Nagad, Rocket, Upay)

Customer sends money via MFS app/USSD to your active number and inputs the provider's Transaction ID.

#### Verification Mechanics

* SkyPay queries the encrypted local database synchronized from your connected Android hardware relay phone.
* The system matches the SMS sender address (e.g., `bKash`, `16216`, `16167`), the recipient phone number, the parsed transaction amount, and the transaction ID.
* If a match is found and has not been credited previously, the transaction is marked `COMPLETED`.

{% hint style="warning" %}
**Cellular SMS Latency Handling**: Telecommunication networks experience delivery latencies of **5 to 20 seconds**. If the customer submits their TrxID immediately, the SMS may still be in transit. Implement a client polling loop (every 5 seconds, up to 3 attempts) before displaying an error.
{% endhint %}

#### Request

```json
{
  "id": "ids_98fbc102e4aa",
  "method": "bkash",
  "transaction_id": "CKL48A9D01"
}
```

#### Success Response (HTTP 200)

```json
{
  "status": true,
  "message": "Payment verified successfully.",
  "data": {
    "cus_name": "Tanvir Hasan",
    "cus_email": "headless@skypaybd.top",
    "amount": 2400,
    "transaction_id": "CKL48A9D01",
    "meta_data": {
      "invoice_no": "INV-7731"
    },
    "payment_method": "bkash",
    "status": "COMPLETED"
  }
}
```

***

### Rail B: Bangla QR

Customer scans your Bangla QR code via their banking application (Citytouch, MTBL, bKash, etc.) and completes payment.

#### Verification Mechanics

* Customer provides their **paying mobile number** (or the last 4 digits).
* SkyPay reconciles the payment against incoming real-time push data from the bank or acquirer gateway (TallyPay, MTB, etc.).
* Exact payment amount and sender MSISDN are matched.

#### Request

```json
{
  "id": "ids_98fbc102e4aa",
  "method": "banglaqr",
  "transaction_id": "01712345678"
}
```

#### Success Response (HTTP 200)

```json
{
  "status": true,
  "message": "Payment verified successfully.",
  "data": {
    "cus_name": "Tanvir Hasan",
    "cus_email": "headless@skypaybd.top",
    "amount": 2400,
    "transaction_id": "BQR20491823",
    "meta_data": {
      "invoice_no": "INV-7731"
    },
    "payment_method": "banglaqr",
    "status": "COMPLETED"
  }
}
```

***

### Rail C: BEP20 (USDT on BNB Smart Chain)

Customer transfers USDT directly to your brand's designated EVM wallet on BNB Smart Chain.

#### Verification Mechanics

* The customer supplies the 66-character EVM Transaction Hash (`0x...`).
* SkyPay Core issues an authenticated JSON-RPC call (`eth_getTransactionReceipt`) to high-speed BSC nodes.
* The system verifies:
  1. Transaction execution status is `0x1` (Success).
  2. The contract called is the official BSC USDT Contract: `0x55d398326f99059ff775485246999027b3197955`.
  3. The topic hash is ERC20 `Transfer(address,address,uint256)`: `0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef`.
  4. The transfer destination address matches your merchant wallet address.
  5. The transferred amount equals or exceeds the converted `amount_usdt`.

#### Request

```json
{
  "id": "ids_98fbc102e4aa",
  "method": "bep20",
  "transaction_id": "0x58cfa9d6bf303f8376997f7fa2032df362ab82cfb8ef10ad93144d67396a8498"
}
```

#### Success Response (HTTP 200)

```json
{
  "status": true,
  "message": "Payment verified successfully.",
  "data": {
    "cus_name": "Tanvir Hasan",
    "cus_email": "headless@skypaybd.top",
    "amount": 2400,
    "amount_usdt": 19.2,
    "transaction_id": "0x58cfa9d6bf303f8376997f7fa2032df362ab82cfb8ef10ad93144d67396a8498",
    "receiver": "0x51c7263b8be9238318e8df3c921312389102488a",
    "meta_data": {
      "invoice_no": "INV-7731"
    },
    "payment_method": "bep20",
    "status": "COMPLETED"
  }
}
```

***

### Rail D: Binance Pay

Customer sends USDT via Binance Pay to your Merchant Binance UID.

#### Verification Mechanics

* Customer inputs their Binance Pay Order ID or Transaction ID.
* SkyPay Core executes an authenticated server-to-server query against the Binance Pay Open API.
* The system verifies transaction settlement, recipient UID, currency (USDT), and paid volume.

#### Request

```json
{
  "id": "ids_98fbc102e4aa",
  "method": "binance",
  "transaction_id": "2918471029384758"
}
```

#### Success Response (HTTP 200)

```json
{
  "status": true,
  "message": "Payment verified successfully.",
  "data": {
    "cus_name": "Tanvir Hasan",
    "cus_email": "headless@skypaybd.top",
    "amount": 2400,
    "transaction_id": "2918471029384758",
    "meta_data": {
      "invoice_no": "INV-7731"
    },
    "payment_method": "binance",
    "status": "COMPLETED"
  }
}
```

***

## 4. Failure & Error Responses

### 1. Duplicate Transaction ID (HTTP 400 Bad Request)

Returned when a TrxID has already been claimed and credited for another order:

```json
{
  "status": false,
  "message": "This transaction ID has already been verified and credited."
}
```

### 2. Transaction Not Found (HTTP 404 Not Found)

Returned when the TrxID cannot be found in the device SMS logs or blockchain index:

```json
{
  "status": false,
  "message": "Transaction ID not found. Ensure customer has completed transfer."
}
```

### 3. Upstream BSC RPC Timeout (HTTP 502 Bad Gateway)

Returned if the decentralized node fails to respond within timeout limits:

```json
{
  "status": false,
  "message": "Upstream blockchain node timeout. Retry verification in 10 seconds."
}
```

***

## 5. Multi-Language Implementation Examples

### Node.js (Axios)

```javascript
const axios = require('axios');

async function verifyPayment(sessionId, method, transactionId) {
  const url = 'https://core.skypaybd.top/api/v2/payment/verify';
  const response = await axios.post(url, {
    id: sessionId,
    method: method,
    transaction_id: transactionId
  }, {
    headers: {
      'BRAND-KEY': process.env.SKYPAY_BRAND_KEY,
      'Content-Type': 'application/json'
    }
  });

  return response.data;
}
```

### Python (Requests)

```python
import os
import requests

def verify_headless_trx(session_id: str, method: str, trx_id: str):
    url = "https://core.skypaybd.top/api/v2/payment/verify"
    headers = {
        "BRAND-KEY": os.getenv("SKYPAY_BRAND_KEY"),
        "Content-Type": "application/json"
    }
    payload = {
        "id": session_id,
        "method": method,
        "transaction_id": trx_id
    }
    
    response = requests.post(url, json=payload, headers=headers, timeout=15)
    return response.json()
```

### Go (Golang)

```go
package main

import (
	"bytes"
	"encoding/json"
	"io"
	"net/http"
	"time"
)

type VerifyPayload struct {
	ID            string `json:"id"`
	Method        string `json:"method"`
	TransactionID string `json:"transaction_id"`
}

func VerifyTransaction(sessionID, method, trxID, brandKey string) ([]byte, error) {
	payload, _ := json.Marshal(VerifyPayload{
		ID:            sessionID,
		Method:        method,
		TransactionID: trxID,
	})

	req, _ := http.NewRequest("POST", "https://core.skypaybd.top/api/v2/payment/verify", bytes.NewBuffer(payload))
	req.Header.Set("BRAND-KEY", brandKey)
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 15 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	return io.ReadAll(resp.Body)
}
```

***

## 6. Next Steps

To automate payment handling without polling, set up real-time webhooks:

* [← Previous: Create Payment](/integration-and-api/create-payment.md)
* [Next: Webhooks (IPN) →](/integration-and-api/webhooks.md)
