llms.txt API v1 · 2026-11-02
Get started快速开始

Signing SDKs签名工具包

Ready-made signing and verification code for eight languages.八种语言的签名与验签代码,可直接集成。

Ready-made code for the signing rules in Signing: one self-contained file per language, standard library only, no package to install. Copy it into your project. Every file has the same functions and a built-in self-test against the published test vector.

把 签名 的签名规则写好的现成代码:每种语言一个独立文件,只用标准库,不需要装任何包,拷进项目即可。每个文件的函数一致,并自带一个按公开测试向量做的自检。

Downloads下载

Language语言File文件Requires要求Self-test自检
Pythonmerchant_sign.py3.8+python3 merchant_sign.py
Node.jsmerchant-sign.js18+node merchant-sign.js
Gomerchantsign.go · merchantsign_test.go1.21+go test ./merchantsign
JavaMerchantSign.java11+java MerchantSign.java
PHPMerchantSign.php7.4+php MerchantSign.php
C# / .NETMerchantSign.cs.NET 6+MerchantSign.SelfTest()
Rubymerchant_sign.rb2.6+ruby merchant_sign.rb
bash + opensslmerchant-sign.shbash, openssl, curlbash merchant-sign.sh

A passing self-test prints self-test passed e5273ee9…6589: it reproduces the test vector, accepts a correctly signed request, and refuses a tampered body, another merchant code and a timestamp outside the window.

自检通过会打印 self-test passed e5273ee9…6589:能算出测试向量,接受签对的请求,拒绝改过的正文、别的商户编码和超窗的时间戳。

Functions函数

Names follow each language's style (signed_headers in Python and Ruby, signedHeaders in Node.js, Java and PHP, SignRequest / SignedHeaders in Go and C#).

函数名按各语言习惯(Python、Ruby 是 signed_headers,Node.js、Java、PHP 是 signedHeaders,Go、C# 是 SignRequest / SignedHeaders)。

Function函数Use it to用途
signedHeaders(merchantCode, secretKey, method, path, rawBody)Call the Platform API: the five headers (Content-Type, X-Merchant-Code, a new X-Request-Id, X-Timestamp, X-Signature). Send exactly rawBody.调平台接口:生成五个请求头(Content-Type、X-Merchant-Code、新的 X-Request-Id、X-Timestamp、X-Signature)。正文必须原样发 rawBody。
verify(secretKey, merchantCode, headers, method, path, rawBody)Serve the Wallet API: checks the headers are present, X-Merchant-Code is yours, the timestamp is within ±300 s and the signature matches (constant-time). Returns OK, INVALID_SIGNATURE or TIMESTAMP_EXPIRED — answer the last two as the envelope code.实现钱包接口:检查请求头齐全、X-Merchant-Code 是自己的、时间戳在 ±300 秒内、签名一致(常量时间比较)。返回 OK、INVALID_SIGNATURE 或 TIMESTAMP_EXPIRED,后两个直接作为信封的 code 回给平台。
sign(secretKey, method, path, merchantCode, timestamp, requestId, rawBody)The raw algorithm, for debugging against the test vector.算法本身,排查时对照测试向量用。
stringToSign(…) · bodySha256(rawBody)The two intermediate values: log them when a signature does not match.两个中间值:签名对不上时把它们打出来比对。
newRequestId()32 random hex characters; a new one for every request, retries included.32 位随机十六进制;每个请求(含重试)都换新的。
envelope(code, message, data)The JSON response body for your Wallet API (not in Java and C#: use your JSON library).钱包接口的响应正文(Java、C# 没有,用自己的 JSON 库)。

When a signature does not match签名对不上时

  • Sign the exact bytes you send. Re-serialising JSON (key order, spaces, escaped / or Unicode) changes the hash.
  • PATH is the path only: no host, no query string, same case. For the Wallet API it includes the path part of your callbackUrl.
  • X-Merchant-Code, X-Timestamp and X-Request-Id go into the string to sign byte-for-byte as sent.
  • Compare your bodySha256 and stringToSign with the test vector; then check that the secret key has no trailing space or newline.
  • 签的必须是实际发出的那份字节。重新序列化 JSON(键顺序、空格、转义的 / 或 Unicode)会让哈希变。
  • PATH 只是路径:不含域名和查询串,大小写一致。钱包接口要带上 callbackUrl 自己的路径部分。
  • X-Merchant-Code、X-Timestamp、X-Request-Id 按发出去的原样进待签字符串。
  • 先把自己的 bodySha256 与 stringToSign 和测试向量对一遍,再看密钥两端有没有多出的空格或换行。