Skip to content

2.5 验证 api key ​

前面几步验证的是分账合约和资金链路,走的都是 HashNut 控制台。这一步换成你自己的服务器来下单, 验证一键开户生成的 api key 能否正常创建订单、查询订单,以及能否收到 HashNut 的支付通知。

最省事的做法是跑一遍示范商城——它就是一个最小可用的接入样例,代码可以直接拿去改。

NOTE

示范商城有 Go 和 Java 两个版本,功能完全一致,选一个跑即可。 两者共用同一个 React 前端、同一份 migrate.sql,后端都监听 1800 端口,数据库都用 demo_shop。

2.5.1 环境要求 ​

依赖版本说明
Docker任意较新版本用来跑 PostgreSQL,省去本机装数据库
Node.js18+前端
Go1.21+只有选 Go 版后端时需要
Java + MavenJava 11+ / Maven 3.6+只有选 Java 版后端时需要
内网穿透工具——仅本地开发需要,让 HashNut 能把支付通知发到你本机。
ngrok / frp / Cloudflare Tunnel 均可,见 附录

2.5.2 克隆代码 ​

Go 版:

bash
git clone https://github.com/nuttybounty/hashnut-demo-go.git
cd hashnut-demo-go

Java 版:

bash
git clone https://github.com/nuttybounty/hashnut-demo.git
cd hashnut-demo

NOTE

Java 版的 HashNut SDK 通过 JitPack 自动拉取,不用手动安装。

2.5.3 用 Docker 起一个 PostgreSQL ​

bash
docker run -d \
  --name hashnut-demo-pg \
  -e POSTGRES_PASSWORD=postgres \
  -e POSTGRES_DB=demo_shop \
  -p 5432:5432 \
  postgres:16

这几个参数对应的就是后端配置里的默认值,改了这里就要同步改后端配置:

参数值对应后端配置
用户名postgres(镜像默认)user / username
POSTGRES_PASSWORDpostgrespassword
POSTGRES_DBdemo_shopdbname / url 里的库名
-p 5432:5432映射到本机 5432host / port

确认容器起来了:

bash
docker exec hashnut-demo-pg pg_isready -U postgres

输出 accepting connections 即可。

NOTE

POSTGRES_DB=demo_shop 会在容器首次启动时自动建库,所以不需要再手动 CREATE DATABASE。 如果你复用的是一个已存在的容器,这个环境变量不会生效,需要手动建库: docker exec -i hashnut-demo-pg psql -U postgres -c "CREATE DATABASE demo_shop;"

2.5.4 把开户信息填进 migrate.sql ​

打开仓库根目录的 migrate.sql,找到 t_hashnut_api_key 那段,把占位符换成 1.4 保存开户信息 里导出的值。

导出的 txt 末尾已经附了可以直接粘贴的 SQL,形如:

sql
INSERT INTO t_hashnut_api_key (block_chain, splitter, access_key_id, secret_key) VALUES
    ('ETH', '0xbd09...fca', '01...YW', 'H1...Tt')
ON CONFLICT (block_chain) DO UPDATE SET
    splitter = EXCLUDED.splitter,
    access_key_id = EXCLUDED.access_key_id,
    secret_key = EXCLUDED.secret_key;

WARNING

migrate.sql 里自带那两行是占位示例(${split address} / secret-key),直接执行会导致下单验签失败。 一次一键开户只覆盖一条链,如果你要同时接 ETH 和 TRON,需要在客户端切换钱包各跑一次,把两段 SQL 都贴进来。

同时检查 t_coin_info 那段,确认里面的链和币种是你实际要用的——它决定了前端支付页面能选哪些链。

改完执行:

bash
docker exec -i hashnut-demo-pg psql -U postgres -d demo_shop < migrate.sql

验证数据进去了:

bash
docker exec -i hashnut-demo-pg psql -U postgres -d demo_shop -c "select block_chain, splitter, access_key_id from t_hashnut_api_key;"

2.5.5 配置并启动后端 ​

Go 版:编辑 etc/application.yaml

yaml
server:
  port: 1800

database:
  host: "localhost"
  port: 5432
  user: "postgres"
  password: "postgres"
  dbname: "demo_shop"
  sslmode: "disable"

hashnut:
  testMode: false    # 固定 false,即正式环境
  baseURL: ""        # 留空使用默认地址
bash
go run main.go

Java 版:编辑 src/main/resources/application.yml

yaml
server:
  port: 1800

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/demo_shop
    username: postgres
    password: postgres

hashnut:
  test-mode: false   # 固定 false,即正式环境
  base-url: ""       # 留空使用默认地址
bash
mvn spring-boot:run

两者都启动在 http://localhost:1800。确认后端连上数据库了:

bash
curl http://localhost:1800/api/chains

应该返回你在 t_coin_info 里配的链和币种。

WARNING

testMode / test-mode 必须保持 false。设成 true 会让 SDK 指向另一个后端地址, 那里查不到你的 api key,下单会直接失败。

2.5.6 确认 notifyUrl 可达 ​

notifyUrl 是 HashNut 主动来请求你的地址,必须公网可达。有公网服务器就直接用; 本地开发用内网穿透顶上,做法见 附录:本地调试让 notifyUrl 公网可达。

这里只要确认那个地址现在是通的:

bash
curl https://你的公网地址/api/chains

能返回链和币种即通。用 ngrok 免费版的话注意重启后地址会变,变了要回商户系统把 api key 的 notifyUrl 同步改掉,否则支付通知会发到失效地址上——表现就是"支付成功但订单状态一直不变"。

2.5.7 启动前端 ​

前端是独立仓库,Go 版和 Java 版共用:

bash
git clone https://github.com/nuttybounty/hashnut-demo-web.git
cd hashnut-demo-web
npm install
npm run dev

启动在 http://localhost:5173,Vite 会自动把 /api 代理到 localhost:1800,不用额外配置跨域。

2.5.8 跑一遍完整支付 ​

浏览器打开 http://localhost:5173,然后:

  1. 随便选一个商品,点 Pay with Crypto
  2. 选链和币种(就是 t_coin_info 里配的那些)
  3. 页面跳到 HashNut 支付页,用钱包完成支付
  4. 支付完成后自动跳回 http://localhost:5173/payment-result,显示支付成功

整条链路是这样走的:

浏览器 (localhost:5173)
  → POST /api/orders            (Vite 代理到 localhost:1800,后端用 api key 调 HashNut 创建订单)
  → 跳转 HashNut 支付页
  → 用户链上支付
  → HashNut 服务器 → 内网穿透 → localhost:1800/api/notify     (notifyUrl:后端收通知)
  → HashNut 支付页 → localhost:5173/payment-result?state=4    (callbackUrl:前端跳转)

走通说明 api key 的下单、查询、回调通知都正常,这一节的目的就达到了。

出问题时先看哪里 ​

现象大概率原因
创建订单就失败,提示验签相关错误migrate.sql 里还是占位符,或 accessKey / secretKey 复制时漏了字符
提示 api key 不存在testMode / test-mode 没有设成 false
前端支付页选不到链t_coin_info 没配那条链,或后端没连上数据库
支付成功但订单状态一直不变notifyUrl 不通:穿透工具没开、地址变了没同步、或把 notifyUrl 和 callbackUrl 填反了
下单被拒绝,提示 IP 相关api key 的 bindIp 不是 *,也不是你的出口 IP

2.5.9 接下来 ​

示范商城的完整接口清单、数据库表结构和部署说明见两个仓库的 README:

要把这套东西改成自己的业务,重点看后端三个地方:创建订单、查询订单、/api/notify 的验签与处理。 接口细节见 创建订单、查询订单、支付通知。