# API hóa đơn điện tử monahddt — bản tài liệu raw

> **Trạng thái: đang hoàn thiện — API mở theo lộ trình.** Tài liệu cập nhật ngày 03/09/2026. monahddt chưa công bố endpoint, khóa truy cập, sandbox, SLA hoặc hợp đồng tương thích sản xuất. Mọi URL, đường dẫn, tên trường và trạng thái bên dưới đều là cấu trúc minh họa để thảo luận tích hợp.

- Trang tài liệu: <https://monahddt.vn/api>
- Liên hệ tích hợp: <https://monahddt.vn/lien-he?nhu-cau=api>
- Hotline: 1900 636 648

## 1. Luồng bất đồng bộ dự kiến

```text
create → check → issue → check → PDF/XML + mã tra cứu → gửi khách
```

1. `create`: client gửi mã tham chiếu, người bán, người mua, hàng hóa, thuế và tổng tiền.
2. `check`: monahddt kiểm tra quyền, trường bắt buộc, định dạng, tổng tiền và khóa chống lặp.
3. `issue`: yêu cầu hợp lệ vào hàng đợi ký và chuyển theo luồng cơ quan thuế phù hợp.
4. `check`: client nhận webhook hoặc kiểm tra lại bằng mã tác vụ.
5. `files`: sau khi phát hành thành công mới có tham chiếu XML gốc, PDF và mã tra cứu.
6. `send`: thông tin hóa đơn được gửi qua kênh đã xác minh và cấu hình.

Phát hành là tác vụ bất đồng bộ. Client phải lưu `client_reference`, dùng idempotency key và xử lý riêng các trạng thái đang chờ, thành công, bị từ chối hoặc cần sửa dữ liệu.

## 2. Cấu hình placeholder

Các giá trị sau chưa tồn tại công khai. MONA chỉ cấp chúng khi môi trường tương ứng được mở:

```dotenv
MONAHDDT_API_BASE_URL=<URL_DO_MONAHDDT_CAP>
MONAHDDT_CREATE_PATH=<DUONG_DAN_DA_CONG_BO>
MONAHDDT_API_KEY=<KHOA_SANDBOX_HOAC_PRODUCTION>
```

Không tự suy đoán domain, đường dẫn hoặc mã trạng thái từ tài liệu preview này.

## 3. Mẫu PHP — đặt trước cho dự án WordPress/PHP

```php
<?php
$baseUrl = getenv('MONAHDDT_API_BASE_URL');
$createPath = getenv('MONAHDDT_CREATE_PATH');
$apiKey = getenv('MONAHDDT_API_KEY');

// Các biến trên chỉ được cấp khi API mở; chưa có endpoint công khai.
$payload = [
    'client_reference' => 'ORDER-0246',
    'seller_tax_id' => '<MST_NGUOI_BAN>',
    'buyer' => [
        'name' => 'Công ty mẫu',
        'tax_id' => '<MST_NGUOI_MUA>'
    ],
    'items' => [[
        'name' => 'Dịch vụ tháng 09/2026',
        'quantity' => 1,
        'unit_price' => 1000000,
        'tax_rate' => '<THUE_SUAT_DA_DOI_CHIEU>'
    ]]
];

$request = curl_init(rtrim($baseUrl, '/') . '/' . ltrim($createPath, '/'));
curl_setopt_array($request, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
        'Idempotency-Key: order-0246-invoice-v1'
    ],
    CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE)
]);

$response = curl_exec($request);
$httpCode = curl_getinfo($request, CURLINFO_HTTP_CODE);
curl_close($request);
```

Khi API mở, ví dụ chính thức sẽ bổ sung timeout, retry, log an toàn và cách phân loại lỗi HTTP.

## 4. Mẫu cURL

```bash
# Chỉ chạy sau khi MONA cấp URL, đường dẫn và khóa sandbox thật.
curl --request POST \
  "${MONAHDDT_API_BASE_URL}/${MONAHDDT_CREATE_PATH}" \
  --header "Authorization: Bearer ${MONAHDDT_API_KEY}" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: order-0246-invoice-v1" \
  --data @invoice-request.json
```

## 5. Mẫu Node.js

```js
const baseUrl = process.env.MONAHDDT_API_BASE_URL;
const createPath = process.env.MONAHDDT_CREATE_PATH;
const apiKey = process.env.MONAHDDT_API_KEY;

// URL và đường dẫn chỉ có giá trị sau khi API được công bố.
const response = await fetch(
  baseUrl.replace(/\/$/, '') + '/' + createPath.replace(/^\//, ''),
  {
    method: 'POST',
    headers: {
      Authorization: 'Bearer ' + apiKey,
      'Content-Type': 'application/json',
      'Idempotency-Key': 'order-0246-invoice-v1'
    },
    body: JSON.stringify({
      client_reference: 'ORDER-0246',
      seller_tax_id: '<MST_NGUOI_BAN>',
      buyer: {
        name: 'Công ty mẫu',
        tax_id: '<MST_NGUOI_MUA>'
      },
      items: [{
        name: 'Dịch vụ tháng 09/2026',
        quantity: 1,
        unit_price: 1000000,
        tax_rate: '<THUE_SUAT_DA_DOI_CHIEU>'
      }]
    })
  }
);
```

## 6. Request minh họa

```json
{
  "client_reference": "ORDER-0246",
  "seller_tax_id": "<MST_NGUOI_BAN>",
  "buyer": {
    "name": "Công ty mẫu",
    "tax_id": "<MST_NGUOI_MUA>"
  },
  "items": [
    {
      "name": "Dịch vụ tháng 09/2026",
      "quantity": 1,
      "unit_price": 1000000,
      "tax_rate": "<THUE_SUAT_DA_DOI_CHIEU>"
    }
  ]
}
```

Tên trường, kiểu dữ liệu, quy tắc làm tròn và cách biểu diễn thuế suất chưa phải hợp đồng API. Bản công bố sau này phải khớp OpenAPI và changelog theo version.

## 7. Response minh họa

```json
{
  "documentation_status": "example_only",
  "job_reference": "<DO_MONAHDDT_TRA_KHI_API_MO>",
  "client_reference": "ORDER-0246",
  "status": "<TRANG_THAI_TRONG_HOP_DONG_API_TUONG_LAI>",
  "next_action": "<CHO_KIEM_TRA_HOAC_CHO_PHAT_HANH>",
  "files": null,
  "lookup_code": null
}
```

`files` và `lookup_code` giữ giá trị rỗng cho đến khi phát hành thành công. Client không tự dựng URL PDF, XML hoặc mã tra cứu.

## 8. Webhook dự kiến

Tên event, header chữ ký, thuật toán ký và lịch retry chưa được công bố. Hợp đồng webhook khi mở cần có:

- timestamp để giới hạn thời gian chấp nhận;
- event ID riêng để chống xử lý lặp;
- chữ ký tính trên raw request body;
- mã tác vụ và mã tham chiếu của client;
- trạng thái trước và trạng thái mới;
- lý do từ chối có cấu trúc;
- quy tắc retry và thời gian chờ;
- hướng dẫn xoay secret mà không ngắt tích hợp.

Client nên ghi nhận event ID trước khi chạy nghiệp vụ, đưa phần xử lý nặng vào hàng đợi và trả HTTP trong thời gian ngắn. Chi tiết mã phản hồi sẽ nằm trong bản chính thức.

## 9. Sandbox

Sandbox chưa mở đăng ký. Lộ trình dự kiến gồm:

- đặc tả OpenAPI theo version;
- dữ liệu test không chứa thông tin người mua thật;
- khóa riêng theo môi trường;
- webhook inspector;
- bảng mã lỗi và ví dụ xử lý;
- giới hạn tần suất;
- changelog và lịch ngừng version cũ.

Ngày mở, SLA, quota, SDK, MCP và chính sách versioning đang là TODO. Đăng ký nhận tin tại <https://monahddt.vn/lien-he?nhu-cau=api>.

## 10. Checklist trước khi tích hợp thật

- Đối chiếu XSD hiện hành do Cục Thuế công bố.
- Chốt NCC/T-VAN và môi trường truyền nhận.
- Xác định loại hóa đơn, luồng có mã hoặc không mã và phương thức ký.
- Không đưa dữ liệu sản xuất vào sandbox.
- Không log khóa API, thông tin người mua hoặc XML hóa đơn nguyên vẹn.
- Dùng idempotency key ổn định theo một nghiệp vụ phát hành.
- Kiểm tra webhook trên raw body trước khi parse JSON.
- Thử mất mạng, timeout, webhook lặp và phản hồi đến sai thứ tự.
- Chỉ hiển thị PDF, XML và mã tra cứu do API trả sau khi phát hành thành công.

## 11. Căn cứ nghiệp vụ

Thiết kế nghiệp vụ bám Luật Quản lý thuế 108/2025/QH15, Nghị định 254/2026/NĐ-CP và Thông tư 91/2026/TT-BTC. Nghị định 70/2025/NĐ-CP đã được thay từ 01/7/2026, nên chỉ dùng để giải thích mốc lịch sử. Trước khi mở production, MONA phải đối chiếu văn bản gốc và bộ XSD hiện hành.
