跳至主要內容
高級

Invoice Request 發票請求

了解 BOLT 12 的發票請求機制,如何從 Offer 獲取動態生成的發票。

10 分鐘

發票請求概述

Invoice Request 是 BOLT 12 協議的核心部分,允許買家向賣家請求發票。 這是從靜態 Offer 到動態 Invoice 的橋樑。

互動式協議: 不同於 BOLT 11 的一次性發票,BOLT 12 允許買賣雙方通過 洋蔥訊息互動,實現更靈活的支付流程。

完整流程

BOLT 12 Payment Flow:

  Seller                                    Buyer
    |                                         |
    | [1. Publish Offer]                      |
    |---------------------------------------->|
    |     (website, QR code, NFC, etc.)       |
    |                                         |
    |                     [2. Parse Offer]    |
    |                     [3. Create Request] |
    |                                         |
    | <-------- invoice_request --------------|
    |           (via onion message)           |
    |                                         |
    | [4. Validate Request]                   |
    | [5. Generate Invoice]                   |
    |                                         |
    |----------- invoice -------------------->|
    |           (via onion message)           |
    |                                         |
    |                     [6. Validate Invoice]
    |                     [7. Send Payment]   |
    |                                         |
    | <=========== HTLC =====================|
    |                                         |
    | [8. Confirm Receipt]                    |
    |                                         |

Invoice Request 結構

invoice_request TLV Fields:

Required Fields:
• offer_id (4): 32 bytes
  - Offer 的 ID(Offer 的 merkle root)

• payer_key (38): 33 bytes
  - 買家的公鑰(用於簽名和回覆路由)

• payer_signature (240): 64 bytes
  - 買家的 Schnorr 簽名

Optional Fields:
• chain (3): 32 bytes
  - 區塊鏈識別(如果 Offer 支援多條鏈)

• amount (8): TU64
  - 請求金額(如果 Offer 沒有固定金額)

• quantity (32): TU64
  - 數量(如果 Offer 支援數量)

• payer_info (50): variable
  - 買家附加資訊(賣家會在 Invoice 中回傳)

• payer_note (34): UTF-8 string
  - 買家備註

驗證規則

賣家驗證 invoice_request:

必要檢查:

1. offer_id 匹配
   - 確認請求對應到有效的 Offer

2. 簽名驗證
   - payer_signature 與 payer_key 匹配
   - 簽名覆蓋所有請求欄位

3. 金額檢查
   - 如果 Offer 有固定金額:不應有 amount 欄位
   - 如果 Offer 無固定金額:必須有 amount 欄位
   - 金額在 Offer 的 min/max 範圍內

4. 數量檢查(如果適用)
   - 數量在 Offer 允許範圍內
   - 總金額 = 單價 * 數量

5. 鏈檢查
   - chain 在 Offer 支援的鏈列表中

失敗處理:

如果驗證失敗,賣家可以:
• 靜默忽略(推薦,避免資訊洩漏)
• 發送 invoice_error 訊息(告知原因)

invoice_error 包含:
• erroneous_field: 有問題的欄位
• error: 錯誤描述

Invoice 回應

賣家生成 invoice:

Invoice 繼承 Offer 欄位:

從 Offer 複製(不變):
• description
• features
• chains
• offer_id 參考

從 invoice_request 複製:
• payer_key
• payer_info(如果提供)
• quantity(如果適用)

Invoice 新增欄位:

• payment_hash: 32 bytes
  - 為此支付新生成

• amount: TU64
  - 最終確定的金額

• created_at: TU64
  - 發票創建時間

• relative_expiry: TU32
  - 從 created_at 算起的過期秒數

• paths: blinded_path[]
  - 支付路徑(可以是盲化路徑)

• signature: 64 bytes
  - 賣家的 Schnorr 簽名

洋蔥訊息傳輸

通過洋蔥訊息傳輸:

發送 invoice_request:

買家:
1. 從 Offer 獲取 paths(盲化路徑到賣家)
2. 構建洋蔥訊息:
   • 目的地:Offer 的 paths 之一
   • 回覆路徑:買家的盲化路徑
   • 內容:invoice_request TLV
3. 通過閃電網路發送

接收和回覆:

賣家:
1. 解密洋蔥訊息
2. 提取 invoice_request
3. 驗證請求
4. 生成 invoice
5. 使用回覆路徑發送 invoice

買家:
1. 接收洋蔥訊息
2. 提取 invoice
3. 驗證 invoice
4. 發送 HTLC 支付

回覆路徑重要性:
• 買家創建自己的盲化路徑
• 賣家不知道買家真實身份
• 雙向隱私保護
• 需要買家在線接收回覆

非互動式 Offer

如果 Offer 包含 invoice,則可以直接支付, 無需 invoice_request 步驟。

重試機制

如果沒有收到 invoice,買家可以重新發送請求。 賣家應該能處理重複請求。

在線需求: invoice_request 流程需要賣家在線以生成發票。 對於離線收款,可以考慮預生成的 BOLT 11 發票或其他方案。

相關資源

下一步: 了解 Onion Messages 如何傳輸這些請求和回覆。

已複製連結
已複製到剪貼簿