Tạo / Cập nhật cấu hình ngân hàng
API này cho phép tạo mới hoặc cập nhật cấu hình kết nối ngân hàng cho tài khoản Merchant. Khi gửi cùng bankBin, hệ thống sẽ tự động tạo mới hoặc ghi đè cấu hình hiện tại.
POST
URLhttps://open-api.tingee.vn/v1/merchant/create-or-update-config
Tạo mới hoặc cập nhật cấu hình tích hợp ngân hàng cho Merchant.
Header Request
| Header | Bắt buộc | Mô tả |
|---|---|---|
Content-Type | ✓ | application/json |
x-client-id | ✓ | Mã định danh của đối tác do TINGEE cung cấp. |
x-signature | ✓ | Chữ ký xác thực HMAC SHA512. Xem thêm tại Cách sinh chữ ký. |
x-request-timestamp | ✓ | Thời gian gửi request (format: yyyyMMddHHmmssSSS, múi giờ UTC+7) |
Body Parameter
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
merchantId | number | ✕ | ID của Merchant (Bắt buộc nếu kết nối bằng tài khoản Master Merchant). |
bankBin | string | ✕ | Mã BIN ngân hàng. Ưu tiên hơn bankName nếu truyền cả hai. |
bankName | string | ✕ | Tên ngân hàng (ví dụ: ACB, BIDV, CTG). Bắt buộc nếu không truyền bankBin. |
accountType | string | ✓ | Loại tài khoản: business-account (Doanh nghiệp) hoặc business-household-account (Hộ kinh doanh). |
id | number | ✕ | ID của cấu hình hiện tại (truyền để cập nhật, bỏ trống để tạo mới). |
otpNumber | string | ✕ | Mã OTP xác nhận (yêu cầu bởi một số ngân hàng). |
confirmId | string | ✕ | Mã xác nhận nhận được sau bước đăng ký cấu hình ACB. |
bidvConfigDto | object | ~ | Cấu hình cho ngân hàng BIDV. Truyền khi bankBin là BIDV. |
bidvConfigDto.accountNumber | string | ✓ | Số tài khoản ngân hàng BIDV. |
bidvConfigDto.accountName | string | ✓ | Tên chủ tài khoản BIDV. |
bidvConfigDto.vaPrefix | string | ✓ | Tiền tố Virtual Account của BIDV. |
bidvConfigDto.bankPartnerId | string | ✓ | Mã đối tác ngân hàng BIDV cấp. |
ctgConfigDto | object | ~ | Cấu hình cho ngân hàng VietinBank (CTG). Truyền khi bankBin là VietinBank. |
ctgConfigDto.accountNumber | string | ✓ | Số tài khoản ngân hàng VietinBank. |
ctgConfigDto.accountName | string | ✓ | Tên chủ tài khoản VietinBank. |
ctgConfigDto.vaPrefix | string | ✓ | Tiền tố Virtual Account của VietinBank. |
acbConfigDto | object | ~ | Cấu hình cho ngân hàng ACB. Truyền khi bankBin là ACB. |
acbConfigDto.accountNumber | string | ✓ | Số tài khoản ngân hàng ACB. |
acbConfigDto.accountName | string | ✓ | Tên chủ tài khoản ACB. |
acbConfigDto.vaPrefix | string | ✓ | Tiền tố Virtual Account. |
acbConfigDto.mobile | string | ✓ | Số điện thoại đăng ký nhận OTP. |
acbConfigDto.acbUserId | string | ✓ | User ID đăng nhập ACB Online / Biz. |
msbConfigDto | object | ~ | Cấu hình cho ngân hàng MSB. Truyền khi bankBin là MSB. |
msbConfigDto.accountNumber | string | ✓ | Số tài khoản ngân hàng MSB. |
msbConfigDto.vaPrefix | string | ✓ | Tiền tố Virtual Account. |
msbConfigDto.mobile | string | ✓ | Số điện thoại đăng ký. |
msbConfigDto.merchantId | string | ✓ | Mã Merchant do MSB cấp. |
msbConfigDto.terminalId | string | ✓ | Mã terminal do MSB cấp. |
msbConfigDto.accessCode | string | ✓ | Access code do MSB cấp. |
msbConfigDto.referralCode | string | ✓ | Mã giới thiệu do MSB cấp. |
baokimConfigDto | object | ~ | Cấu hình cho ví điện tử BaoKim. Truyền khi bankBin là BAOKIM. |
baokimConfigDto.walletId | string | ✕ | ID ví BaoKim. |
baokimConfigDto.accountName | string | ✕ | Tên chủ ví BaoKim. |
baokimConfigDto.mid | string | ✕ | Mã Merchant (MID) do BaoKim cấp. |
baokimConfigDto.privateKey | string | ✕ | Khóa bí mật do BaoKim cấp. |
Ví dụ mã nguồn
- cURL
- NestJS
- C#
- Java
- PHP
curl --location --request POST 'https://open-api.tingee.vn/v1/merchant/create-or-update-config' \
--header 'accept: application/json' \
--header 'x-client-id: YOUR_CLIENT_ID' \
--header 'x-request-timestamp: 20240509154004003' \
--header 'x-signature: YOUR_SIGNATURE' \
--header 'Content-Type: application/json' \
--data '{
"bankBin": "970418",
"accountType": "business-account",
"bidvConfigDto": {
"accountNumber": "1234567890",
"accountName": "CONG TY TNHH ABC",
"vaPrefix": "TINGEE",
"bankPartnerId": "PARTNER_001"
}
}'
import axios from "axios";
import { createHmac } from "crypto";
const CLIENT_ID = "YOUR_CLIENT_ID";
const SECRET_KEY = "YOUR_SECRET_KEY";
// Timestamp theo múi giờ UTC+7, định dạng yyyyMMddHHmmssSSS
function getTimestamp() {
return new Date(Date.now() + 7 * 60 * 60 * 1000)
.toISOString()
.replace(/[-:TZ.]/g, "")
.slice(0, 17);
}
async function merchantCreateOrUpdateConfig() {
const body = {
bankBin: "970418",
accountType: "business-account",
bidvConfigDto: {
accountNumber: "1234567890",
accountName: "CONG TY TNHH ABC",
vaPrefix: "TINGEE",
bankPartnerId: "PARTNER_001",
},
};
const bodyJson = JSON.stringify(body);
const timestamp = getTimestamp();
const signature = createHmac("sha512", SECRET_KEY)
.update(`${timestamp}:${bodyJson}`)
.digest("hex");
const res = await axios.request({
method: "POST",
url: "https://open-api.tingee.vn/v1/merchant/create-or-update-config",
data: bodyJson,
headers: {
accept: "application/json",
"Content-Type": "application/json",
"x-client-id": CLIENT_ID,
"x-request-timestamp": timestamp,
"x-signature": signature,
},
});
console.log(res.data);
}
merchantCreateOrUpdateConfig();
using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;
public class Program
{
private const string ClientId = "YOUR_CLIENT_ID";
private const string SecretKey = "YOUR_SECRET_KEY";
private static readonly HttpClient Client = new HttpClient();
public static async Task Main()
{
var body = new
{
bankBin = "970418",
accountType = "business-account",
bidvConfigDto = new
{
accountNumber = "1234567890",
accountName = "CONG TY TNHH ABC",
vaPrefix = "TINGEE",
bankPartnerId = "PARTNER_001"
}
};
// Không escape tiếng Việt / ký tự đặc biệt để khớp với JSON.stringify phía TINGEE
var jsonOptions = new JsonSerializerOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping };
var bodyJson = JsonSerializer.Serialize(body, jsonOptions);
// Timestamp theo múi giờ UTC+7, định dạng yyyyMMddHHmmssSSS
var timestamp = DateTime.UtcNow.AddHours(7).ToString("yyyyMMddHHmmssfff");
var signature = HmacSha512(SecretKey, $"{timestamp}:{bodyJson}");
var request = new HttpRequestMessage(HttpMethod.Post, "https://open-api.tingee.vn/v1/merchant/create-or-update-config");
request.Headers.Add("accept", "application/json");
request.Headers.Add("x-client-id", ClientId);
request.Headers.Add("x-request-timestamp", timestamp);
request.Headers.Add("x-signature", signature);
request.Content = new StringContent(bodyJson, Encoding.UTF8, "application/json");
var response = await Client.SendAsync(request);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
private static string HmacSha512(string key, string message)
{
using var hmac = new HMACSHA512(Encoding.UTF8.GetBytes(key));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
return Convert.ToHexString(hash).ToLower();
}
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class Main {
private static final String CLIENT_ID = "YOUR_CLIENT_ID";
private static final String SECRET_KEY = "YOUR_SECRET_KEY";
public static void main(String[] args) throws Exception {
// JSON minified, giống kết quả JSON.stringify()
String bodyJson = "{\"bankBin\":\"970418\",\"accountType\":\"business-account\",\"bidvConfigDto\":{\"accountNumber\":\"1234567890\",\"accountName\":\"CONG TY TNHH ABC\",\"vaPrefix\":\"TINGEE\",\"bankPartnerId\":\"PARTNER_001\"}}";
// Timestamp theo múi giờ UTC+7, định dạng yyyyMMddHHmmssSSS
String timestamp = ZonedDateTime.now(ZoneId.of("Asia/Ho_Chi_Minh"))
.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
String signature = hmacSha512(SECRET_KEY, timestamp + ":" + bodyJson);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://open-api.tingee.vn/v1/merchant/create-or-update-config"))
.header("accept", "application/json")
.header("Content-Type", "application/json")
.header("x-client-id", CLIENT_ID)
.header("x-request-timestamp", timestamp)
.header("x-signature", signature)
.method("POST", HttpRequest.BodyPublishers.ofString(bodyJson, StandardCharsets.UTF_8))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
private static String hmacSha512(String key, String data) throws Exception {
Mac mac = Mac.getInstance("HmacSHA512");
mac.init(new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA512"));
byte[] hash = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
StringBuilder hex = new StringBuilder();
for (byte b : hash) hex.append(String.format("%02x", b));
return hex.toString();
}
}
<?php
$clientId = "YOUR_CLIENT_ID";
$secretKey = "YOUR_SECRET_KEY";
$body = [
"bankBin" => "970418",
"accountType" => "business-account",
"bidvConfigDto" => [
"accountNumber" => "1234567890",
"accountName" => "CONG TY TNHH ABC",
"vaPrefix" => "TINGEE",
"bankPartnerId" => "PARTNER_001",
],
];
// Không escape "/" và tiếng Việt để khớp với JSON.stringify phía TINGEE
$bodyJson = json_encode($body, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
// Timestamp theo múi giờ UTC+7, định dạng yyyyMMddHHmmssSSS
$now = new DateTime("now", new DateTimeZone("Asia/Ho_Chi_Minh"));
$timestamp = $now->format("YmdHisv");
$signature = hash_hmac("sha512", $timestamp . ":" . $bodyJson, $secretKey);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => "https://open-api.tingee.vn/v1/merchant/create-or-update-config",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $bodyJson,
CURLOPT_HTTPHEADER => [
"Accept: application/json",
"Content-Type: application/json",
"x-client-id: " . $clientId,
"x-request-timestamp: " . $timestamp,
"x-signature: " . $signature,
],
]);
$response = curl_exec($ch);
if ($response === false) {
echo "cURL Error: " . curl_error($ch);
} else {
echo $response;
}
curl_close($ch);
Response mẫu
{
"code": "00",
"message": "Success",
"data": 125
}
| Trường | Kiểu | Mô tả |
|---|---|---|
code | string | Mã kết quả (00 = Thành công). |
message | string | Thông điệp phản hồi. |
data | number | ID của cấu hình vừa được tạo hoặc cập nhật. |
Mã lỗi thường gặp
| Code | Mô tả | Hướng xử lý |
|---|---|---|
1065 | OTP đã hết thời gian chờ | confirmId chỉ có hiệu lực khoảng 4 phút; gọi lại Đăng ký cấu hình tài khoản DN để lấy confirmId mới và xác nhận ngay. |
1080 | ConfirmId không chính xác | Dùng đúng confirmId trả về cho cùng Merchant. |
1013 | Cấu hình không tồn tại | Khi cập nhật, kiểm tra id cấu hình (lấy từ Danh sách cấu hình); bỏ id nếu muốn tạo mới. |
1095, 1096 | Lỗi merchantId của Master Merchant | Truyền merchantId của Merchant con thuộc Master Merchant đang gọi API. |
90, 91, 92, 97 | Lỗi xác thực request (timestamp, client-id, chữ ký) | Xem Mã lỗi hệ thống. |
Others | Lỗi khác | Xem Danh sách mã lỗi. |