進階
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: "..."
}) 安全考量
元數據應該加密,防止路由節點讀取敏感資訊。
大小限制
元數據增加發票大小,建議保持簡潔。
相關資源
- • Custom Records
- • TLV 編碼
- • 發票編碼
已複製連結