跳至主要內容
進階

Payment Metadata 支付元數據

了解閃電網路支付中的元數據欄位,如何在支付中攜帶額外資訊。

8 分鐘

什麼是 Payment Metadata?

Payment Metadata 允許發票接收者在發票中嵌入任意數據,發送者在支付時將其回傳。 這實現了無狀態發票處理。

功能位: option_payment_metadata(bit 48/49)允許在發票和支付中包含元數據。

無狀態發票

傳統發票問題:

有狀態處理:
1. 商家創建發票
   • 生成 preimage 和 payment_hash
   • 存儲到數據庫:{hash → preimage, order_id, amount}

2. 等待支付
   • 需要保持數據庫中的記錄
   • 可能有大量未支付的發票

3. 收到支付
   • 查詢數據庫獲取 preimage
   • 需要數據庫可用

問題:擴展性差,數據庫是瓶頸

無狀態處理(使用 payment_metadata):
1. 商家創建發票
   • preimage = HMAC(secret, order_id || amount || nonce)
   • payment_hash = SHA256(preimage)
   • metadata = encrypt(order_id || amount || nonce)
   • 不需要存儲任何東西!

2. 收到支付
   • 從 TLV 中提取 payment_metadata
   • 解密獲取 order_id, amount, nonce
   • 重新計算 preimage
   • 驗證並完成支付

協議細節

BOLT 11 中的 metadata:

Tagged Field 'm':
• 格式:m + 數據長度 + 任意字節
• 最大長度:取決於發票總長度限制

發票範例(偽碼):
lnbc100n1p...
  m=<encrypted_order_data>
  h=<payment_hash>

洋蔥 TLV 中的傳輸:
最終跳的 TLV 載荷:
{
  type: 16 (payment_metadata)
  length: <length>
  value: <metadata_bytes>
}

發送者必須將發票中的 metadata 原封不動地傳給接收者

應用場景

常見用途:

1. 訂單關聯:
metadata = encrypt({
  order_id: "ORD-12345",
  items: ["item1", "item2"],
  timestamp: 1700000000
})

2. 用戶識別:
metadata = encrypt({
  user_id: "user_abc",
  subscription: "premium",
  period: "monthly"
})

3. 回調資訊:
metadata = encrypt({
  callback_url: "https://...",
  webhook_secret: "..."
})

安全考量

元數據應該加密,防止路由節點讀取敏感資訊。

大小限制

元數據增加發票大小,建議保持簡潔。

相關資源

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