List bank QR institutions
curl --request GET \
--url https://www.ntanduy.com/api/v1/tools/bank-qr/banks \
--header 'Authorization: Bearer <token>'import requests
url = "https://www.ntanduy.com/api/v1/tools/bank-qr/banks"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://www.ntanduy.com/api/v1/tools/bank-qr/banks', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.ntanduy.com/api/v1/tools/bank-qr/banks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://www.ntanduy.com/api/v1/tools/bank-qr/banks"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://www.ntanduy.com/api/v1/tools/bank-qr/banks")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.ntanduy.com/api/v1/tools/bank-qr/banks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"banks": [
{
"bin": "970422",
"code": "MB",
"shortName": "MBBank",
"name": "Ngân hàng TMCP Quân đội",
"transferSupported": true
},
{
"bin": "970436",
"code": "VCB",
"shortName": "Vietcombank",
"name": "Ngân hàng TMCP Ngoại Thương Việt Nam",
"transferSupported": true
}
],
"count": 2,
"updatedAt": "2026-08-21T00:00:00.000Z"
}
}Payment utilities
List bank QR institutions
Load the validated Vietnamese bank metadata accepted by the Bank QR generator.
GET
/
api
/
v1
/
tools
/
bank-qr
/
banks
List bank QR institutions
curl --request GET \
--url https://www.ntanduy.com/api/v1/tools/bank-qr/banks \
--header 'Authorization: Bearer <token>'import requests
url = "https://www.ntanduy.com/api/v1/tools/bank-qr/banks"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://www.ntanduy.com/api/v1/tools/bank-qr/banks', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.ntanduy.com/api/v1/tools/bank-qr/banks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://www.ntanduy.com/api/v1/tools/bank-qr/banks"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://www.ntanduy.com/api/v1/tools/bank-qr/banks")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.ntanduy.com/api/v1/tools/bank-qr/banks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"banks": [
{
"bin": "970422",
"code": "MB",
"shortName": "MBBank",
"name": "Ngân hàng TMCP Quân đội",
"transferSupported": true
},
{
"bin": "970436",
"code": "VCB",
"shortName": "Vietcombank",
"name": "Ngân hàng TMCP Ngoại Thương Việt Nam",
"transferSupported": true
}
],
"count": 2,
"updatedAt": "2026-08-21T00:00:00.000Z"
}
}Authenticate with OAuth or a Pirehub API key with the
Administrator-issued API keys use the key’s per-minute and monthly request limits. See the
Bank transfer QR guide for the complete
integration flow, caching guidance, validation rules, and security limitations.
bank-qr:banks scope.
Use this endpoint to populate a bank selector before calling the Bank QR
generation endpoint.
The response includes each bank’s six-digit bin, code, shortName, display
name, transfer-support metadata, and an optional public logo URL. Retain one of
the first three identifiers as the bank field sent to
POST /api/v1/tools/bank-qr.
The directory is refreshed from an upstream bank-directory service and falls back to a versioned local
snapshot when the upstream directory is unavailable. updatedAt identifies the
source snapshot. Cache the response according to Cache-Control; do not poll the
endpoint on every form interaction.
A missing or unreachable
logo must not prevent bank selection. Provide a
local fallback. The transferSupported flag describes compatibility metadata;
it is not proof that an account exists or can receive a transfer.Subscription-backed API keys
Paid self-service keys use shared owner credits and the plan’s per-second and concurrent-job limits. Successful results, including cache hits, consume the configured action cost; errors release the reservation. Video jobs settle at completion. InspectX-ApiKey-Credit-* and X-ApiKey-RateLimit-*.
An optional Idempotency-Key prevents repeated synchronous execution/debits;
repeated operations return 409 rather than replaying a response. Job starts use
requestId instead. See API plans and idempotency
for costs, billing periods, headers, error codes and retry rules.Authorizations
pirehubOAuthpirehubApiKeybearerApiKey
OAuth 2.0 Authorization Code with PKCE, issued by Pirehub's Clerk authorization server. Request only the scopes required by the operation.
Headers
Self-service keys only. Owner-scoped operation identifier; reuse after admission returns 409 without another debit or execution. USAGE_CONCURRENCY_EXCEEDED retains no new reservation: wait and retry with the same identifier and payload. No response replay. Video jobs use requestId instead.
Required string length:
1 - 80Pattern:
^[a-zA-Z0-9_-]+$