POST /bank-accounts
Create a bank account. The account is auto-linked to the calling branch, so it is visible to your branch immediately.
Endpoint
POST /bank-accountsFull URL: https://api.easyslip.com/v2/bank-accounts
Authentication
Required. See Authentication Guide.
Authorization: Bearer YOUR_API_KEY
Content-Type: application/jsonRequest
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
bankCode | string | Yes | A valid code from GET /banks |
bankNumber | string | Yes | The account number |
nameTh | string | Yes | Account holder name in Thai (≤255 chars) |
nameEn | string | Yes | Account holder name in English (≤255 chars) |
type | string | Yes | Account type — NATURAL or JURISTIC |
extraVerify | string | No | Verify option for the bank — must be one of the bank's supported option values (see GET /banks) |
matchMode | string | No | PromptPay matching mode — NAME, NUMBER, or NAME_NUMBER. PromptPay accounts only; omission has effective mode NUMBER |
Request Body
{
"bankCode": "004",
"bankNumber": "123-4-56789-0",
"nameTh": "บริษัท ตัวอย่าง จำกัด",
"nameEn": "EXAMPLE CO., LTD.",
"type": "JURISTIC"
}serviceId is automatic
serviceId is set server-side from your API key — you cannot set it in the request.
Type Definitions
// Request
interface CreateBankAccountRequest {
bankCode: string; // must be a valid code from GET /banks
bankNumber: string;
nameTh: string; // ≤255 chars
nameEn: string; // ≤255 chars
type: 'NATURAL' | 'JURISTIC';
extraVerify?: string; // must be one of the bank's extraVerify option values (see GET /banks)
matchMode?: 'NAME' | 'NUMBER' | 'NAME_NUMBER'; // PromptPay only; omitted means effective NUMBER
}
// Response
interface BankAccountResponse {
success: true;
data: BankAccount;
}
interface BankAccount {
id: number;
bankCode: string;
bankNumber: string;
nameTh: string;
nameEn: string;
type: 'NATURAL' | 'JURISTIC';
extraVerify: string | null;
matchMode: 'NAME' | 'NUMBER' | 'NAME_NUMBER' | null;
createdAt: string; // ISO 8601
updatedAt: string; // ISO 8601
}
// Error Response
interface ErrorResponse {
success: false;
error: {
code: string;
message: string;
};
}Examples
curl -X POST https://api.easyslip.com/v2/bank-accounts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"bankCode": "004",
"bankNumber": "123-4-56789-0",
"nameTh": "บริษัท ตัวอย่าง จำกัด",
"nameEn": "EXAMPLE CO., LTD.",
"type": "JURISTIC"
}'const createBankAccount = async (account) => {
const response = await fetch('https://api.easyslip.com/v2/bank-accounts', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify(account)
});
const result = await response.json();
if (!result.success) {
throw new Error(result.error.message);
}
return result.data;
};
// Usage
const account = await createBankAccount({
bankCode: '004',
bankNumber: '123-4-56789-0',
nameTh: 'บริษัท ตัวอย่าง จำกัด',
nameEn: 'EXAMPLE CO., LTD.',
type: 'JURISTIC'
});
console.log('Created account:', account.id);function createBankAccount(array $account): array
{
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.easyslip.com/v2/bank-accounts',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json'
],
CURLOPT_POSTFIELDS => json_encode($account)
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
if (!$result['success']) {
throw new Exception($result['error']['message']);
}
return $result['data'];
}
// Usage
$account = createBankAccount([
'bankCode' => '004',
'bankNumber' => '123-4-56789-0',
'nameTh' => 'บริษัท ตัวอย่าง จำกัด',
'nameEn' => 'EXAMPLE CO., LTD.',
'type' => 'JURISTIC'
]);
echo "Created account: " . $account['id'];import requests
def create_bank_account(account: dict) -> dict:
response = requests.post(
'https://api.easyslip.com/v2/bank-accounts',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
json=account
)
result = response.json()
if not result['success']:
raise Exception(result['error']['message'])
return result['data']
# Usage
account = create_bank_account({
'bankCode': '004',
'bankNumber': '123-4-56789-0',
'nameTh': 'บริษัท ตัวอย่าง จำกัด',
'nameEn': 'EXAMPLE CO., LTD.',
'type': 'JURISTIC'
})
print('Created account:', account['id'])Response
Success Response (201)
{
"success": true,
"data": {
"id": 12345,
"bankCode": "004",
"bankNumber": "123-4-56789-0",
"nameTh": "บริษัท ตัวอย่าง จำกัด",
"nameEn": "EXAMPLE CO., LTD.",
"type": "JURISTIC",
"extraVerify": null,
"matchMode": null,
"createdAt": "2024-01-15T14:30:00+07:00",
"updatedAt": "2024-01-15T14:30:00+07:00"
}
}Error Responses
Validation Error (400)
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "bankNumber: Too small: expected string to have >=1 characters"
}
}Invalid Bank Code (400)
{
"success": false,
"error": {
"code": "INVALID_BANK_CODE",
"message": "The provided bankCode is not supported"
}
}Invalid Extra Verify (400)
{
"success": false,
"error": {
"code": "INVALID_EXTRA_VERIFY",
"message": "The provided extraVerify is not a valid option for this bank"
}
}Invalid Match Mode (400)
{
"success": false,
"error": {
"code": "INVALID_MATCH_MODE",
"message": "matchMode is supported only for PromptPay accounts"
}
}Duplicate Account (409)
{
"success": false,
"error": {
"code": "BANK_ACCOUNT_DUPLICATE",
"message": "An active account with the same bank code and number already exists"
}
}PromptPay match modes
matchMode controls which account fields must match a PromptPay slip:
| Value | Matching requirement |
|---|---|
NAME | The slip receiver name matches nameTh or nameEn |
NUMBER | The slip proxy account number matches bankNumber |
NAME_NUMBER | Both the receiver name and proxy account number match |
{
"bankCode": "PROMPTPAY",
"bankNumber": "0812345678",
"nameTh": "นาย ทดสอบ",
"nameEn": "TEST USER",
"type": "NATURAL",
"extraVerify": "MSISDN",
"matchMode": "NAME_NUMBER"
}extraVerify remains required for matching
matchMode does not replace extraVerify. For every mode, the slip's PromptPay proxy type must still match the account's extraVerify value (MSISDN, NATID, EWALLETID, or BILLERID) before name/number matching is evaluated.
For backward compatibility, omitting matchMode is accepted. The stored legacy value may be null, but API responses and matching behavior expose/use the effective mode NUMBER.
Notes
- The new account is automatically linked to the calling branch — no separate link step is needed to use it from this branch.
bankCodemust be a valid code fromGET /banks.extraVerifyis optional. If provided, it must be one of the target bank's supported optionvalues — otherwise400 INVALID_EXTRA_VERIFY. The valid set is per-bank; callGET /banksand read that bank'sextraVerifyoptions.matchModecan only be sent whenbankCodeisPROMPTPAY; sending it for another bank returns400 INVALID_MATCH_MODE.- A duplicate is defined as an active account with the same
bankCode+bankNumberwithin your service.