跳转到正文
buybitcoinsmart

术语表 /开发者参考

PaymentDetails

PaymentDetails 是什么?
PaymentDetails 是 BIP70 的内层消息,实际描述一笔付款:向哪些输出付款、付多少、请求何时过期,以及将已签名交易发送到何处。

规定于 BIP-70。

PaymentDetails 是商家实际签名的部分,外层信封只携带证明其真实性的证书。它包含七个字段:默认为 main 的网络名称、输出列表、必填的时间戳、可选的过期时间、备注、回调 URL,以及不透明的 merchant_data 数据块。如今,BIP21 URI 加一个结账页面即可完成同样的工作,既不需要签名,也不需要服务器。

运作方式

状态:历史遗留。Bitcoin Core 于2020年6月3日在版本0.20.0中移除了 BIP70,PaymentDetails 已没有任何在用的实现。本站仍加以记录,是因为这些字段名称依然出现在旧的集成指南和 bitcoin.org 的开发者参考文档中。

其结构由 Protocol Buffers 而非 JSON 承载。这一选择有一个值得说明的原因:商家把 PaymentDetails 序列化为字节串,并将这些原样字节作为不透明字段放入外层 PaymentRequest,而不是作为嵌套消息。签名覆盖的是这段字节串,因此任何库即使以不同顺序重新编码相同的字段,也不会使有效签名失效。

这七个字段分为指令和记录两类。

  • network,字符串,默认值为 "main",唯一另一个已定义的值是 "test"。
  • outputs,重复列表,每个条目将一个以聪为单位的金额与一个脚本配对。允许有多个输出,商家借此把客户的一笔付款分配到热钱包和冷存储,而无需客户付款两次。
  • time,必填的 Unix 时间戳,记录请求的创建时间。
  • expires,可选的 Unix 时间戳,钱包应在此时间之后拒绝该请求。正是这个字段让 BIP70 用起来像刷卡终端,因为商家可以报出法币价格,并在固定时间窗口内保证该价格。
  • memo,向付款人显示的 UTF-8备注。
  • payment_url,钱包在广播交易后发送其 Payment 消息的地址。
  • merchant_data,原样回传的不透明字节,使商家能够将付款与购物车对应起来。

只有 time 和输出脚本是必填项。其余字段商家都可以省略,而大多数商家确实省略了。

在哪里会遇到它

PaymentDetails 背后的理念比这条消息本身存续得更久,这一点值得留意。

如今,价格过期由交易所而非您的钱包处理。通过即时购买界面购买时,会看到一个附有倒计时的报价;倒计时结束后,报价会按新价格重新生成。这就是在网页应用中重新实现的 expires,它以完全相同的方式保护卖方免受价格波动影响。交易所订单簿上的订单撮合以另一种方式完成同样的工作,即根本不报固定价格。

整条消息在商家一侧的对应物,是结账软件中的发票记录。BTCPay Server 及类似工具会生成 BIP21 URI,按设定的分钟数保持其有效,并将收到的交易与内部订单标识符对账,这正是 merchant_data 的用途。

PaymentDetails vs 收据

PaymentDetails 是请求;BIP70 中的收据是商家随后返回的 PaymentACK。前者描述应当发生什么,后者确认商家已看到它发生。两者都不是区块链上的事实,这正是人们低估的局限:商家的签名确认只能证明商家的服务器说过某些话,并不能证明某笔交易已确认。结算一笔比特币付款的是确认数,而不是收据。

请勿混淆

常见问题

BIP70 为什么将 PaymentDetails 存储为原始字节,而不是嵌套消息?

这样签名覆盖的就是一段确切的字节串。Protocol Buffers 允许以不同的有效方式重新编码相同的字段,而对序列化后的数据块签名,意味着任何库都不会因重新序列化而意外破坏有效签名。

相关术语

开发者参考中的更多术语

阅读本页英文版