Skip to content

Async Bank Verify

Submit a bank slip for asynchronous verification. Instead of blocking until the result is ready, the API immediately returns a jobId; the slip is verified in the background and the result is delivered to your webhook and/or fetched by polling the job.

Use async verification for high-volume / bulk workloads where you don't need the result inline. For a single inline result, use the synchronous POST /verify/bank instead.

Bank only

Async verification is available for bank slips only, and accepts a QR payload string only (no image / base64 / url). TrueWallet has no payload and stays on the synchronous /verify/truewallet route.

Endpoint

http
POST /verify/bank/async

Full URL: https://api-partners.easyslip.com/v2/verify/bank/async

Authentication

Required. Uses HMAC-SHA256 with your branch UUID as X-API-Key. See Authentication Guide.

http
X-API-Key: YOUR_BRANCH_UUID
X-Timestamp: 1700000000
X-Nonce: 550e8400-e29b-41d4-a716-446655440000
X-Signature: HMAC_SHA256_SIGNATURE
Content-Type: application/json

Request

Parameters

ParameterTypeRequiredDescription
payloadstringYesQR code payload (1-128 characters)
callbackUrlstringConditionalHTTPS URL the result is POSTed to. Required unless a default webhook URL is configured for the branch. Max 255 chars.
remarkstringNoCustom remark (1-255 characters)
matchAccountbooleanNoMatch receiver with registered accounts
matchAmountnumberNoExpected amount to validate
checkDuplicatebooleanNoCheck for duplicate slip (default: false)

callbackUrl requirements

callbackUrl must use HTTPS and must resolve to a public address — URLs pointing at private/internal IP ranges are rejected. If you omit callbackUrl, the branch's configured webhook URL is used; if neither is set the request is rejected with VALIDATION_ERROR.

Request Body

json
{
  "payload": "00000000000000000000000000000000000000000000000",
  "callbackUrl": "https://example.com/webhooks/easyslip",
  "remark": "Order #12345",
  "checkDuplicate": true
}

Type Definitions

typescript
// Request
interface AsyncVerifyBankRequest {
  payload: string;          // 1-128 chars
  callbackUrl?: string;     // https URL, max 255 chars (required if no branch webhook)
  remark?: string;          // 1-255 chars
  matchAccount?: boolean;
  matchAmount?: number;
  checkDuplicate?: boolean;
}

// Response
interface AsyncVerifyResponse {
  success: true;
  data: {
    jobId: string;          // UUID — use it to poll GET /verify/bank/jobs/:jobId
  };
  message: string;
}

Examples

bash
curl -X POST https://api-partners.easyslip.com/v2/verify/bank/async \
  -H "X-API-Key: YOUR_BRANCH_UUID" \
  -H "X-Timestamp: ${TIMESTAMP}" \
  -H "X-Nonce: ${NONCE}" \
  -H "X-Signature: ${SIGNATURE}" \
  -H "Content-Type: application/json" \
  -d '{
    "payload": "00000000000000000000000000000000000000000000000",
    "callbackUrl": "https://example.com/webhooks/easyslip",
    "checkDuplicate": true
  }'
javascript
const verifyBankAsync = async (payload, callbackUrl, options = {}) => {
  const body = JSON.stringify({ payload, callbackUrl, ...options });
  const response = await fetch('https://api-partners.easyslip.com/v2/verify/bank/async', {
    method: 'POST',
    headers: {
      ...signRequest({ method: 'POST', path: '/verify/bank/async', body, apiKey: 'YOUR_BRANCH_UUID', secretKey: 'YOUR_SECRET_KEY' }),
      'Content-Type': 'application/json'
    },
    body
  });

  const result = await response.json();
  if (!result.success) throw new Error(result.error.message);

  return result.data.jobId;
};

// Usage
const jobId = await verifyBankAsync(
  '00000000000000000000000000000000000000000000000',
  'https://example.com/webhooks/easyslip',
  { checkDuplicate: true }
);
console.log('Queued job:', jobId);
typescript
interface AsyncOptions {
  remark?: string;
  matchAccount?: boolean;
  matchAmount?: number;
  checkDuplicate?: boolean;
}

async function verifyBankAsync(payload: string, callbackUrl: string, options: AsyncOptions = {}): Promise<string> {
  const body = JSON.stringify({ payload, callbackUrl, ...options });
  const response = await fetch('https://api-partners.easyslip.com/v2/verify/bank/async', {
    method: 'POST',
    headers: {
      ...signRequest({ method: 'POST', path: '/verify/bank/async', body, apiKey: process.env.EASYSLIP_API_KEY!, secretKey: process.env.EASYSLIP_SECRET_KEY! }),
      'Content-Type': 'application/json'
    },
    body
  });

  const result = await response.json();
  if (!result.success) throw new Error(result.error?.message || 'Async verify failed');

  return result.data.jobId;
}
php
function verifyBankAsync(string $payload, string $callbackUrl, array $options = []): string
{
    $data = array_merge(['payload' => $payload, 'callbackUrl' => $callbackUrl], $options);

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => 'https://api-partners.easyslip.com/v2/verify/bank/async',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            // Use signRequest() helper - see Authentication Guide
            'Content-Type: application/json'
        ],
        CURLOPT_POSTFIELDS => json_encode($data)
    ]);

    $response = curl_exec($ch);
    curl_close($ch);

    $result = json_decode($response, true);
    if (!$result['success']) {
        throw new Exception($result['error']['message']);
    }

    return $result['data']['jobId'];
}
python
import requests
import os

def verify_bank_async(payload: str, callback_url: str, **options) -> str:
    data = {'payload': payload, 'callbackUrl': callback_url, **options}
    response = requests.post(
        'https://api-partners.easyslip.com/v2/verify/bank/async',
        headers={
            **sign_request('POST', '/verify/bank/async', data, os.environ['EASYSLIP_API_KEY'], os.environ['EASYSLIP_SECRET_KEY']),
            'Content-Type': 'application/json'
        },
        json=data
    )

    result = response.json()
    if not result['success']:
        raise Exception(result['error']['message'])

    return result['data']['jobId']

Response

Accepted (202)

json
{
  "success": true,
  "data": {
    "jobId": "550e8400-e29b-41d4-a716-446655440000"
  },
  "message": "Verification job queued"
}

A 202 Accepted means the job was queued — not that the slip was verified. Wait for the webhook, or poll the job with the returned jobId.

Error Responses

Missing Payload / callbackUrl (400)

json
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Payload is required and cannot be empty"
  }
}

Invalid callbackUrl (400)

json
{
  "success": false,
  "error": {
    "code": "INVALID_CALLBACK_URL",
    "message": "callbackUrl must use the https protocol"
  }
}

Rate Limit Exceeded (429)

json
{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded"
  }
}

See Rate Limits for the X-RateLimit-* and Retry-After headers.

Notes

  • The response jobId is a UUID; store it to correlate the webhook and to poll job status.
  • Results are delivered to your webhook (see Webhooks); polling is a fallback.
  • To submit many slips in one request, use POST /verify/bank/batch (up to 100 slips).
  • Async is payload-only — for image / URL verification use the synchronous POST /verify/bank.

Bank Slip Verification API for Thai Banking