Create a draft invoice
This API lets you create a draft invoice (draft/preview) and returns the Base64 PDF file of the created invoice.
POST
URLhttps://open-api.tingee.vn/v1/e-invoice/create
Create a draft invoice (draft/preview) and return the Base64 PDF file.
Header Request
| Header | Required | Description |
|---|---|---|
Content-Type | ✓ | application/json |
x-client-id | ✓ | Partner identifier issued by TINGEE. |
x-signature | ✓ | HMAC SHA512 authentication signature. See How to generate the signature. |
x-request-timestamp | ✓ | Time the request is sent (format: yyyyMMddHHmmssSSS, UTC+7) |
Body Parameter
| Field | Type | Required | Description |
|---|---|---|---|
merchantId | number | ✕ | Merchant ID. (Required if you connect with a Master Merchant account). |
accountId | number | ✕ | Account configuration ID (if empty, the default account is used). |
invoicePattern | string | ✓ | Invoice template number (mẫu số). See Get invoice templates. |
invoiceSeries | string | ✓ | Invoice symbol (ký hiệu). See Get invoice templates. |
invoiceCode | string | ✓ | Invoice code generated by the partner (unique key), used later to download the invoice / send email. |
invoiceDate | date | ✓ | Invoice date (format: YYYY-MM-DD, e.g. 2025-12-09). |
invoiceType | string | ✕ | Invoice type (provider-specific). |
buyerTaxCode | string | ✕ | Buyer's tax code. |
buyerIdentity | string | ✕ | Buyer's identity document number (citizen ID card (CCCD) / passport / business registration certificate (GPKD) number). The BKAV provider does not use this field yet. |
buyerIdType | string | ✕ | Document type of buyerIdentity: 1=citizen ID card (CCCD), 2=passport, 3=business registration certificate (GPKD). Other values are rejected. Currently only sent to SInvoice; if you pass buyerIdentity without buyerIdType, it defaults to 1. |
buyerName | string | ✕ | Buyer name. TINGEE does not require this field, but the provider (e.g. SInvoice) may reject the invoice if both buyerName and buyerLegalName are missing. |
buyerLegalName | string | ✕ | Buyer's company name. |
buyerAddress | string | ✕ | Buyer address. |
buyerPhone | string | ✕ | Buyer phone number. |
buyerEmail | string | ✕ | Buyer email. |
buyerBankAccount | string | ✕ | Buyer's bank account number. |
buyerBankName | string | ✕ | Buyer's bank name. |
paymentMethod | number | ✕ | Payment method: 1=cash (TM), 2=bank transfer (CK), 3=cash/bank transfer (TM/CK) (Default: 3). |
paymentMethodName | string | ✕ | Payment method name (generated by the system from paymentMethod if not passed). |
currency | string | ✕ | Currency code (Default: VND). |
exchangeRate | string | ✕ | Foreign currency exchange rate (Default: 1). |
amountInWords | string | ✕ | Amount in words (generated automatically if not passed). |
note | string | ✕ | Invoice note. |
items | array | ✓ | List of goods/services (see the items[] table below). |
totalDiscount | string | ✕ | Total discount amount (calculated by the system if not passed). |
totalBeforeTax | string | ✕ | Total amount before tax (calculated by the system if not passed). |
totalTax | string | ✕ | Total tax amount (calculated by the system if not passed). |
totalAfterTax | string | ✕ | Total amount after tax (calculated by the system if not passed). |
taxRateSummaries | array | ✕ | Tax rate summary (calculated by the system if not passed, see the table below). |
items[] — Goods / service details
| Field | Type | Required | Description |
|---|---|---|---|
itemCode | string | ✕ | Item code. |
itemName | string | ✓ | Goods / service name. |
unitName | string | ✕ | Unit of measure. |
quantity | string | ✓ | Quantity. |
unitPrice | string | ✓ | Unit price. |
discount | string | ✕ | Discount percentage (e.g. 10 = 10%). |
discountAmount | string | ✕ | Discount amount (if not passed, the system calculates it from quantity × unitPrice × discount). |
totalBeforeTax | string | ✕ | Total amount before tax (calculated by the system if not passed). |
taxRateCode | string | ✓ | Tax rate code: 0, 5, 8, 10, -1 (not subject to VAT, KCT), -2 (not required to declare and pay tax, KKKNT). |
taxAmount | string | ✕ | Tax amount (calculated by the system if not passed). |
totalAfterTax | string | ✕ | Total amount after tax (calculated by the system if not passed). |
itemType | number | ✕ | Line type (Default: 1): 1=goods, 2=promotion, 3=discount, 4=note, 5=service, 6=statement (bảng kê), 7=other fees. Provider limitations: XCyber does not support 2, 6, 7; HiLo and MISA do not support 6, 7; BKAV does not support 6 (returns error 2038). |
adjustmentType | number | ✕ | Increase/decrease adjustment (for adjustment invoices). |
taxRateSummaries[] — Tax rate summary
| Field | Type | Required | Description |
|---|---|---|---|
taxRateCode | string | ✓ | Tax rate code. |
totalTaxableAmount | string | ✕ | Total taxable amount. |
taxAmount | string | ✕ | Total tax amount. |
Code samples
- cURL
- NestJS
- C#
- Java
- PHP
curl --location --request POST 'https://open-api.tingee.vn/v1/e-invoice/create' \
--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 '{
"invoicePattern": "1",
"invoiceSeries": "C25TAB",
"invoiceCode": "INV-20251209-001",
"invoiceDate": "2025-12-09",
"buyerName": "Nguyen Van A",
"buyerLegalName": "CONG TY TNHH ABC",
"buyerTaxCode": "0109876543",
"buyerAddress": "123 Nguyen Hue, Quan 1, TP.HCM",
"paymentMethod": 2,
"paymentMethodName": "Chuyển khoản",
"items": [
{
"itemName": "Dịch vụ thanh toán",
"unitName": "Gói",
"quantity": "1",
"unitPrice": "1000000",
"taxRateCode": "10"
}
]
}'
import axios from "axios";
import { createHmac } from "crypto";
const CLIENT_ID = "YOUR_CLIENT_ID";
const SECRET_KEY = "YOUR_SECRET_KEY";
// Timestamp in UTC+7, format yyyyMMddHHmmssSSS
function getTimestamp() {
return new Date(Date.now() + 7 * 60 * 60 * 1000)
.toISOString()
.replace(/[-:TZ.]/g, "")
.slice(0, 17);
}
async function eInvoiceCreate() {
const body = {
invoicePattern: "1",
invoiceSeries: "C25TAB",
invoiceCode: "INV-20251209-001",
invoiceDate: "2025-12-09",
buyerName: "Nguyen Van A",
buyerLegalName: "CONG TY TNHH ABC",
buyerTaxCode: "0109876543",
buyerAddress: "123 Nguyen Hue, Quan 1, TP.HCM",
paymentMethod: 2,
paymentMethodName: "Chuyển khoản",
items: [
{
itemName: "Dịch vụ thanh toán",
unitName: "Gói",
quantity: "1",
unitPrice: "1000000",
taxRateCode: "10",
},
],
};
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/e-invoice/create",
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);
}
eInvoiceCreate();
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
{
invoicePattern = "1",
invoiceSeries = "C25TAB",
invoiceCode = "INV-20251209-001",
invoiceDate = "2025-12-09",
buyerName = "Nguyen Van A",
buyerLegalName = "CONG TY TNHH ABC",
buyerTaxCode = "0109876543",
buyerAddress = "123 Nguyen Hue, Quan 1, TP.HCM",
paymentMethod = 2,
paymentMethodName = "Chuyển khoản",
items = new object[]
{
new
{
itemName = "Dịch vụ thanh toán",
unitName = "Gói",
quantity = "1",
unitPrice = "1000000",
taxRateCode = "10"
}
}
};
// Do not escape non-ASCII / special characters so the JSON matches TINGEE's JSON.stringify
var jsonOptions = new JsonSerializerOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping };
var bodyJson = JsonSerializer.Serialize(body, jsonOptions);
// Timestamp in UTC+7, format 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/e-invoice/create");
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 {
// Minified JSON, same as JSON.stringify()
String bodyJson = "{\"invoicePattern\":\"1\",\"invoiceSeries\":\"C25TAB\",\"invoiceCode\":\"INV-20251209-001\",\"invoiceDate\":\"2025-12-09\",\"buyerName\":\"Nguyen Van A\",\"buyerLegalName\":\"CONG TY TNHH ABC\",\"buyerTaxCode\":\"0109876543\",\"buyerAddress\":\"123 Nguyen Hue, Quan 1, TP.HCM\",\"paymentMethod\":2,\"paymentMethodName\":\"Chuyển khoản\",\"items\":[{\"itemName\":\"Dịch vụ thanh toán\",\"unitName\":\"Gói\",\"quantity\":\"1\",\"unitPrice\":\"1000000\",\"taxRateCode\":\"10\"}]}";
// Timestamp in UTC+7, format 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/e-invoice/create"))
.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 = [
"invoicePattern" => "1",
"invoiceSeries" => "C25TAB",
"invoiceCode" => "INV-20251209-001",
"invoiceDate" => "2025-12-09",
"buyerName" => "Nguyen Van A",
"buyerLegalName" => "CONG TY TNHH ABC",
"buyerTaxCode" => "0109876543",
"buyerAddress" => "123 Nguyen Hue, Quan 1, TP.HCM",
"paymentMethod" => 2,
"paymentMethodName" => "Chuyển khoản",
"items" => [
[
"itemName" => "Dịch vụ thanh toán",
"unitName" => "Gói",
"quantity" => "1",
"unitPrice" => "1000000",
"taxRateCode" => "10",
],
],
];
// Do not escape "/" or non-ASCII characters so the JSON matches TINGEE's JSON.stringify
$bodyJson = json_encode($body, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
// Timestamp in UTC+7, format 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/e-invoice/create",
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);
Sample Response
{
"code": "00",
"message": "Success",
"data": {
"invoiceCode": "INV-20251209-001",
"pdfBase64": "JVBERi0xLjQKMSAwIG9iago8PA..."
}
}
| Field | Type | Description |
|---|---|---|
code | string | Status code. |
message | string | Result message. |
data.invoiceCode | string | Invoice code. |
data.pdfBase64 | string | PDF file content in Base64. |
Common error codes
| Code | Description | How to handle |
|---|---|---|
2032 | No default provider account is configured | Create an account with isDefault = true via Create/Update account, or pass accountId. |
1057 | No account found for accountId | Check accountId with List accounts. |
2038 | The provider does not support the item type (itemType) | XCyber does not support itemType 2/6/7; HiLo and MISA do not support 6/7; BKAV does not support 6. |
1095, 1096 | Master Merchant merchantId error | Pass the merchantId of a sub-Merchant belonging to the Master Merchant calling the API. |
90, 91, 92, 97 | Request authentication error (timestamp, client-id, signature) | See System error codes. |
Others | Other errors | See Error codes. |