IBAN Add API

Description: Create a new IBAN account record. If iban is provided in the request, it will be validated for format and uniqueness first. If iban is omitted, one will be allocated automatically from the pre-generated IBAN pool and bound to the current api_account.

Production API URL: #/api/iban/add Sandbox API URL: https://ibantest.yabandpay.com/api/iban/add

Method: POST

Header:

Authorization: Bearer {api_account_token}
Content-Type: application/json

1. Request Format (Unified)

Field Type Description Required
uid string API account unique id (matches iban_api_account.uid) Required
timestamp integer Request Unix timestamp in seconds. Server validates clock skew and rejects stale requests. Required
nonce string 10-character random string, unique per request for replay prevention Required
sign string Signature, see signature algorithm below Required
data object Business parameters, see table below Required

1.1 data Object (Business Parameters)

Parameter Type Description Required
request_id string Client request id (recommended globally unique for idempotency and tracing; echoed back in response) Optional
customer_id string Unique customer id in the caller's business system Required
customer_type string Customer type: legal_entity for company / individual for person. Defaults to legal_entity. Optional
holder_name string IBAN holder name. If omitted, it is auto-generated as {customer_type}_{customer_id}. Optional
alternative_name string Alias or additional name Optional
creditor_identifier string Creditor identifier. Defaults to holder_name when omitted. Optional
iban string Explicit NL IBAN. If provided, its format and uniqueness are validated; otherwise the API allocates one from the pool automatically. Optional
access integer Access permission: 0=none, 1=full, 2=inbound, 3=outbound. Defaults to 1. Optional
status integer Status: 0=inactive, 1=active. Defaults to 1. Optional
remark string Remarks Optional

1.2 Signature Algorithm (HMAC-SHA256)

Client-side calculation steps (strict order):

  1. Remove the sign field from the raw request body. If a role field exists, it must also be excluded.
  2. Flatten every field inside data to the top level, together with uid / timestamp / nonce.
  3. Sort the flattened fields by key in ascending dictionary order (ksort()).
  4. Concatenate them as a query string in the form k1=v1&k2=v2&k3=v3.
  5. Compute HMAC-SHA256 with the account secret_key, and lowercase the hex digest as the value of sign.
Signature formula:
sign = hash_hmac('sha256', implode('&', ksort(merge(data, {uid,timestamp,nonce})) ), secret_key)

Signature example (PHP):

$secretKey = 'your_account_secret_key';
$body = [
    'uid'       => '900001',
    'timestamp' => 1731926400,
    'nonce'     => 'Qe3CkH2xP8',
    'data'      => [
        'request_id'    => 'req_202411180049',
        'customer_id'   => 'CUST20260001',
        'timezone'      => 'Asia/Shanghai',
        'customer_type' => 'legal_entity',
        'holder_name'   => 'Yabandpay B.V.',
    ],
];
$sign = getSignByYabandPayV3($body, $secretKey);
$body['sign'] = $sign;

2. Request Example

{
    "uid": "900001",
    "timestamp": 1731926400,
    "nonce": "Qe3CkH2xP8",
    "sign": "A1AC665F9B40F7C51212BCE080F5B987",
    "data": {
        "request_id": "req_202411180049",
        "customer_id": "CUST20260001",
        "customer_type": "legal_entity",
        "holder_name": "Yabandpay B.V.",
        "alternative_name": "YB HQ",
        "creditor_identifier": "YABAND001",
        "access": 1,
        "status": 1,
        "remark": "Dutch HQ corporate account"
    }
}

3. Response Example

Success (200)

{
    "status": true,
    "code": "200",
    "data": {
        "id": 1001,
        "customer_type": "legal_entity",
        "customer_id": "CUST20260001",
        "holder_name": "Yabandpay B.V.",
        "alternative_name": "YB HQ",
        "creditor_identifier": "YABAND001",
        "bic": "YABNNL22",
        "iban": "NL08YABN0187654321",
        "currency": "EUR",
        "balance": "0.00",
        "access": 1,
        "access_label": "full",
        "status": 1,
        "status_label": "active",
        "remark": "Dutch HQ corporate account",
        "api_account_id": 1,
        "created_at": 1784851200,
        "updated_at": 1784851200,
        "request_id": "req_202411180049",
        "response_id": "TRADE20260819XXXXXX"
    },
    "message": ""
}

Common Failure Codes

code Description
401 Missing headers, invalid token format, missing required fields like uid/sign/timestamp/nonce/data, etc.
-1001 Signature error
-1010 API account does not exist or has been disabled (middleware / account disabled)
-2001 Account cache is empty or uid is not present in the account registry
-3001 Database write failed / record not found
-3002 Invalid business parameters (e.g. customer_id/timezone missing)
-3004 NL IBAN Mod97 validation failed
-3035 IBAN already exists
-3036 Source IP is not in the whitelist
-3100 Token and uid mismatch
-1000 IBAN pool is empty and no explicit iban was provided

Invalid parameters example:

{
    "status": false,
    "code": "-3002",
    "message": "The given data was invalid.",
    "data": {}
}

Invalid IBAN format example:

{
    "status": false,
    "code": "-3004",
    "message": "invalid NL IBAN",
    "data": {}
}

4. Special Notes

  1. About the verify.api.sign middleware:

    • Validates that the header Authorization: Bearer {token} matches uid;
    • Checks the IP whitelist;
    • Re-computes the signature and compares it;
    • Once passed, flattens all business fields inside data onto the request top level and injects iban_api_user_info (account details array).
  2. About automatic IBAN allocation:

    • If data.iban is not provided, the API fetches one row from the iban_generated pool in a concurrency-safe manner (FOR UPDATE SKIP LOCKED + transaction + conditional UPDATE to ensure different accounts never share the same IBAN);
    • Once allocated, both iban.api_account_id and iban_generated.api_account_id are immediately set to the current API account;
    • The pool lock TTL defaults to 1800 seconds (30 minutes). Stale locks are released by a scheduled job.
  3. About NL IBAN format validation (when explicitly provided):

    • The rule is: must start with NL, and the overall Mod97-10 remainder must be 1;
    • Current default pattern requires YABN followed by 01 + 8 digits (the account part totals 10 digits).
  4. Callers can use request_id for idempotency: we echo it in responses for bilateral correlation.

results matching ""

    No results matching ""