3.0 sdk的返回结果格式
{
"code": 0,
"msg": "success",
"count": 0,
"data": {}
}
返回的主要参数包括:
| 变量名 | 类型 | 描述 |
|---|---|---|
| code | int | 请求返回结果,0为成功,其他值为失败 |
| msg | string | 错误消息,success为成功,其他值为失败 |
| count | int | 当data为json数组的时候,count表示data里面的元素个数 |
| data | object | 具体返回的数据,data可以是单个json对象,也可以是json对象数组 |
3.1 查询支持链信息
查询支持的链信息
HashNut 支 持多链多币种, 商户创建订单前,可以先查询 HashNut 支持的链,然后通过链的代号查询该链支持的币种
curl --location --request POST 'https://testnet-web3.hashnut.io/api/v2.0.0/config/queryAllChainInfo'
返回信息如下:
{
"code": 0,
"msg": "success",
"ui": null,
"version": null,
"count": 0,
"data": [
{
"id": 1,
"chain": "ETH",
"chainDesc": "BlockChain Ethereum",
"enable": true,
"receiptAddress": "0x8126ac362f08ec6a58b43e537f3dbbb474c70595",
"txConfirmCount": "3",
"walletConnectEnable": true,
"bridgeServerAddress": "https://bridge.hashnut.io",
"decimals": 18,
"baseChainSymbol": "Ethereum",
"env": 1,
"chainId": "11155111",
"baseChainCoin": "ETH",
"createTime": 1710938845128,
"updateTime": 1710938845128,
"eip712ChainId": "0",
"eip1559Support": true
}
...
]
}
返回的主要参数包括:
| 变量名 | 类型 | 描述 |
|---|---|---|
| chain | string | hashnut支持的公链的名称的缩写,例如:ETH,BSC,TRON,POLYGON等 |
| chainDesc | string | 公链的描述 |
| enable | boolean | 公链是否可用 |
| receiptAddress | string | HashNut平台在该公链上的收款地址 |
| txConfirmCount | int | 在该公链上的交易需要被确认的次数,如果达到或者超过确认次数,则hashnut认为支付订单的交易有效 |
| walletConnectEnable | boolean | 该公链是否支持walletconnect协议拉起,如果不支持walletconnect协议拉起,则需要最终用户用钱包app扫码支付 |
| bridgeServerAddress | string | walletconnect的bridge server地址 |
| decimals | int | 例如:eth的精度是小数点后18位,tron的精度是6位 |
| baseChainSymbol | string | 基础链的名称 |
| env | int | 当前支付平台的环境 0-正式 1-测试 2-开发 |
| chainId | long | EVM 兼容链的ChainID,例如: POLYGON的正式环境为137,Mumbai环境为80001 |
| baseChainCoin | int | 基础链的币种缩写,例如:以太坊的缩写是ETH,POLYGON上面基础币种的缩写是MATIC |
| eip712ChainId | string | eip712当中,该链的链Id,该值仅对支持eip712的公链有效 |
| eip1559Support | int | 是否支持eip1559 |
3.2 查询支持的币种信息
查询支持的所有币种信息
获取到链代码之后,获取该链支持的币种,例如:查询支持的erc20币种
curl --location --request POST 'https://testnet-web3.hashnut.io/api/v2.0.0/config/queryAllCoinInfo'
返回信息如下:
{
"code": 0,
"msg": "success",
"ui": null,
"version": null,
"count": 0,
"data": [
{
"id": 1,
"chain": "ETH",
"chainCode": "erc20",
"coinCode": "usdt",
"isToken": true,
"enable": true,
"contractAddress": "0xe2d7250b2ec3cd208ac5b42886edd162411529c4",
"coinDesc": "tether usdt",
"gateWayEnable": true,
"decimals": "6",
"createTime": 1710938845130,
"updateTime": 1710938845130,
"nftmarket": "opensea"
}
...
]
}
主要返回参数如下:
| 变量名 | 类型 | 描述 |
|---|---|---|
| chain | string | 币种所在的链名称,例如:ETH |
| chainCode | string | hashnut支持的链的代码,目前hashnut支持erc20,trc20,bep20,polygon-erc20 |
| coinCode | string | 币种代号,目前erc20支持usdt,usdc,bep20支持busd,hashnut,trc20支持usdt |
| isToken | boolean | 该币种是否是token,如果是公链的基础代币,例如 eth,bsc,trx,则该值为false |
| enable | boolean | 该币种目前在hashnut是否可用,如果该币种不可用,则无法创建订单 |
| contractAddress | string | 当前币种在该公链上的智能合约地址 |
| coinDesc | string | 币种的描述信息 |
| gateWayEnable | boolean | 如果该字段为true,则用户可以通过币安APP,或者其他APP,走网关支付,目前hashnut仅支持币安网关 |
| decimals | int | 币种的精度,比如说,erc20的usdt币种精度为6,则支付1usdt,金额需要填写成1000000,又例如,busd的精度为18 |
3.3 通过币种类型来查询所支持的币种信息
通过币种类型来查询所支持的币种信息
curl --location 'https://testnet-web3.hashnut.io/api/v2.0.0/config/querySupportCoinsByChainCode' \
--header 'Content-Type: application/json' \
--data '{
"chainCode":"erc20"
}'
返回信息如下:
{
"code": 0,
"msg": "success",
"ui": null,
"version": null,
"count": 0,
"data": [
{
"id": 2,
"chain": "ETH",
"chainCode": "erc20",
"coinCode": "usdc",
"isToken": true,
"enable": true,
"contractAddress": "0x4ca772bb3e6326647b8dd02ddbc758773aa7c650",
"coinDesc": "usdc",
"gateWayEnable": true,
"decimals": "6",
"createTime": 1710938845132,
"updateTime": 1710938845132,
"nftmarket": "opensea"
},
...
]
}
请求的body当中携带的参数:
| 变量名 | 类型 | 描述 |
|---|---|---|
| chainCode | string | token类型,目前HashNut支持erc20,trc20,bep20,polygon-erc20 |
主要返回参数如下:
| 变量名 | 类型 | 描述 |
|---|---|---|
| chain | string | 币种所在的链名称,例如:ETH |
| chainCode | string | hashnut支持的链的代码,目前hashnut支持erc20,trc20,bep20,polygon-erc20 |
| coinCode | string | 币种代号,目前erc20支持usdt,usdc,bep20支持busd,hashnut,trc20支持usdt |
| isToken | boolean | 该币种是否是token,如果是公链的基础代币,例如 eth,bsc,trx,则该值为false |
| enable | boolean | 该币种目前在hashnut是否可用,如果该币种不可用,则无法创建订单 |
| contractAddress | string | 当前币种在该公链上的智能合约地址 |
| coinDesc | string | 币种的描述信息 |
| gateWayEnable | boolean | 如果该字段为true,则用户可以通过币安APP,或者其他APP,走网关支付,目前hashnut仅支持币安网关 |
| decimals | int | 币种的精度,比如说,erc20的usdt币种精度为6,则支付1usdt,金额需要填写成1000000,又例如,busd的精度为18 |
3.5 创建订单
web3 custody 模式
hashnut支持多币种支付,商户可以创建订单,并且选择订单的支付通道,订单根据资金的托管模式可以分为两种
请求:
curl --location 'https://testnet-web3.hashnut.io/api/v2.0.0/pay/createPayOrderWithApiKey' \
--header 'hashnut-request-uuid: xxxx' \
--header 'hashnut-request-timestamp: xxxx' \
--header 'hashnut-request-sign: xxxx' \
--header 'Content-Type: application/json' \
--data '{
"accessKeyId": "ACC_1156690317534035968",
"merchantOrderId": "100000",
"chainCode": "polygon-erc20",
"coinCode": "usdt",
"amount": 1.13,
"receiptAddress": "0x1a580cca96a3d1070cb23b63480b3afafe0bf025"
}'
请求的body当中携带的参数:
| 变量名 | 类型 | 描述 |
|---|---|---|
| accessKeyId | string | 商户API KEY ID |
| merchantOrderId | string | 商户订单号,商户订单号由商户生成的唯一订单id |
| chainCode | string | 链代号 |
| coinCode | string | 币种代号 |
| amount | Decimal(20) | 需要支付的金额,最多精确到小数点后2位 |
| receiptAddress | string | 商户部署的智能合约合约的地址 |
请求的header当中携带的参数:
| 变量名 | 类型 | 描述 |
|---|---|---|
| hashnut-request-uuid | string | 商户随机生成的uuid |
| hashnut-request-timestamp | string | 时间戳 |
| hashnut-request-sign | string | 使用api secret key对 (uuid+timestamp+body)的签名,body为请求内容json序列化后的字符串 |
hashnut-request-sign的生成代码如下:
String uuid=request.getHeader("hashnut-webhook-uuid");
String timeStamp=request.getHeader("hashnut-webhook-timestamp");
// body为请求内容json序列化后的字符串
String dataToSign=String.format("%s%s%s",uuid,timeStamp,body);
String sign= PayDigestUtil.HMACSHA256Base64(HashNutConfig.secretKey,dataToSign);
PayDigestUtil.HMACSHA256Base64代码如下:
public static String HMACSHA256Base64(String key,String data) throws Exception {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
sha256_HMAC.init(secret_key);
sha256_HMAC.update(data.getBytes());
byte[] array = sha256_HMAC.doFinal();
return Base64.getEncoder().encodeToString(array);
}
返回信息如下:
{
"code": 0,
"msg": "success",
"ui": null,
"version": null,
"count": 0,
"data": {
"mchAddress": "0x6a0b7b0b95ce640b3fe3fede6ebfed4de9293019",
"chain": "POLYGON",
"chainCode": "polygon-erc20",
"coinCode": "usdt",
"createChannel": 1,
"accessChannel": 0,
"merchantOrderId": "10000",
"payOrderId": "01HSKATBCK7CE20N88B25870M5",
"tokenAddress": "0x0de51eb069fd04f5ff6fb48f1dad6766ac558b33",
"receiptAddress": "0x78f43ee9985aacd8da1c6dd099213b402aa98672",
"amount": 1.160000,
"state": 4,
"accessSign": "24625267842A4074D6332A59A7BE49069C63B0392340171F1E2F1FF8C6AA9879",
"payTxId": "0xd77cd2e8488e3b8db02dc5e3f2bdac2da99795fbcf91408b6eae68da50d752fb",
"confirmCount": "3",
"walletConnectEnable": true,
"bridgeServerAddress": "https://bridge.hashnut.io",
"eip712ChainId": "0",
"chainId": "80001",
"createTime": "0",
"rate": 80,
"obtainAmount": 1.15072,
"platformFee": 0.00928
}
}
回复的参数包括
| 变量名 | 类型 | 描述 |
|---|---|---|
| chain | string | 支付订单的token所在 的链 |
| mchAddress | string | 下单的商户地址,也就是创建收款智能合约的商户地址 |
| chainCode | string | 链代码 |
| coinCode | string | 币种代码 |
| createChannel | int | 商户创建订单的渠道,0-商户系统 1-ApiKey,由于是通过api key创建订单,所以该值为1 |
| accessChannel | byte | 最终用户支付该订单的通道,由于是链上支付,所以该值为0 |
| merchantOrderId | string | 商户订单号,商户订单号由商户生成的唯一订单id |
| payOrderId | string | hashnut的平台订单号,由hashnut生成的唯一收款地址 |
| contractAddress | string | 币种的智能合约地址,用户发送交易时需要将to填写为币种的智能合约地址 |
| receiptAddress | string | 用于接收用户资金的智能合约地址 |
| inputData | string | 交易的inputdata数据,使用web3j编码的交易数据,包括: hashnut收款地址和订单金额amount |
| accessSign | string | 使用api key对(platformId+mchOrderId)的签名 |
商户拼接支付订单的URL
商户使用创建订单回复当中的accessSign,merchantOrderId,payOrderId拼接成支付的URL发送给最终用户,例如:
https://testnet-web3.hashnut.io/pay?accessSign=42889E72DAAE0C4275F804DDDFA4707823FE30EB4D4BB6064859CB65AA3E6305&merchantOrderId=10000&payOrderId=01HSKATBCK7CE20N88B25870M5
其中URL的参数:
| 变量名 | 类型 | 描述 |
|---|---|---|
| accessSign | string | 使用api key对(platformId+merchantOrderId)的签名 |
| merchantOrderId | string | 商户订单号 |
| payOrderId | string | HashNut的平台订单号,由HashNut生成的唯一订单ID |
pass through custody 模式
pass through custody 模式下,订单的收款地址回从splitter创建的多个钱包地址当中选择,通常来说会优先选择成功收款次数最多并且当前状态为空闲的地址.使用该模式创建订单的接口如下:
请求:
curl --location 'https://testnet-web3.hashnut.io/api/v2.0.0/pay/createPassThroughPayOrderWithApiKey' \
--header 'hashnut-request-uuid: xxxx' \
--header 'hashnut-request-timestamp: xxxx' \
--header 'hashnut-request-sign: xxxx' \
--header 'Content-Type: application/json' \
--data '{
"accessKeyId": "ACC_1156690317534035968",
"merchantOrderId": "100000",
"chainCode": "polygon-erc20",
"coinCode": "usdt",
"amount": 1.13,
"splitterAddress": "0x1a580cca96a3d1070cb23b63480b3afafe0bf025"
}'
请求的body当中携带的参数:
| 变量名 | 类型 | 描述 |
|---|---|---|
| accessKeyId | string | 商户API KEY ID |
| merchantOrderId | string | 商户订单号,商户订单号由商户生成的唯一订单id |
| chainCode | string | 链代号 |
| coinCode | string | 币种代号 |
| amount | Decimal(20) | 需要支付的金额,最多精确到小数点后2位 |
| splitterAddress | string | 商户部署的PassThrough分账合约地址 |
注意: splitterAddress在该模式下的作用为接收从各个合约钱包归集的资金,以及提现时进行分账。该功能的回复以及其他内容跟 web custody mode保持一致。
3.7 回调通知
回调通知
回调的URL可以在 创建ApiKey的接口里面配置,回调url包括后端回调url和前端回调url,无论是后端回调url还是前端回调url都包含如下几个参数:
| 变量名 | 类型 | 描述 |
|---|---|---|
| payOrderId | string | HashNut的平台订单号,由HashNut生成的唯一订单ID |
3.7 查询订单
查询订单信息
支付订单的用户收到URL之后,首先是需要使用accessSign查询订单信息,以确认订单是否被支付,防止重复支付订单
请求:
curl --location 'https://testnet-web3.hashnut.io/api/v2.0.0/pay/queryPayOrderWithAccessSign' \
--header 'Content-Type: application/json' \
--data '{
"merchantOrderId": "a89206d0-7883-48dd-9316-e494f2679e72",
"payOrderId": "01HSKATBCK7CE20N88B25870M5",
"accessSign": "24625267842A4074D6332A59A7BE49069C63B0392340171F1E2F1FF8C6AA9879"
}'
请求的参数包括:
| 变量名 | 类型 | 描述 |
|---|---|---|
| merchantOrderId | string | 商户订单号,商户订单号由商户生成的唯一订单id |
| payOrderId | string | hashnut的平台订单号 |
| accessSign | string | 使用api key对(platformId+mchOrderId)的签名 |
返回信息如下:
{
"code": 0,
"msg": "success",
"ui": null,
"version": null,
"count": 0,
"data": {
"mchAddress": "0x6a0b7b0b95ce640b3fe3fede6ebfed4de9293019",
"chain": "POLYGON",
"chainCode": "polygon-erc20",
"coinCode": "usdt",
"createChannel": 1,
"accessChannel": 0,
"merchantOrderId": "a89206d0-7883-48dd-9316-e494f2679e72",
"payOrderId": "01HSKATBCK7CE20N88B25870M5",
"tokenAddress": "0x0de51eb069fd04f5ff6fb48f1dad6766ac558b33",
"receiptAddress": "0x78f43ee9985aacd8da1c6dd099213b402aa98672",
"amount": 1.160000,
"state": 4,
"accessSign": "24625267842A4074D6332A59A7BE49069C63B0392340171F1E2F1FF8C6AA9879",
"payTxId": "0xd77cd2e8488e3b8db02dc5e3f2bdac2da99795fbcf91408b6eae68da50d752fb",
"confirmCount": "3",
"walletConnectEnable": true,
"bridgeServerAddress": "https://bridge.hashnut.io",
"eip712ChainId": "0",
"chainId": "80001",
"callBackUrl": "https://testnet-web3.hashnut.io/shop/payFinish?payOrderId=01HSKATBCK7CE20N88B25870M5&chain=POLYGON&amount=1160000&chainCode=polygon-erc20&sign=CAD9387C2D51389B2512C324932B1277F68B177E6C3933BC5EA686FB3A935C8C&merchantOrderId=a89206d0-7883-48dd-9316-e494f2679e72&accessSign=24625267842A4074D6332A59A7BE49069C63B0392340171F1E2F1FF8C6AA9879&obtainAmount=1150720&payTxId=0xd77cd2e8488e3b8db02dc5e3f2bdac2da99795fbcf91408b6eae68da50d752fb&receiptAddress=0x78f43ee9985aacd8da1c6dd099213b402aa98672&merchantAddress=0x6a0b7b0b95ce640b3fe3fede6ebfed4de9293019&confirmCount=3&state=4&coinCode=usdt&paySuccessTime=",
"createTime": "0",
"rate": 80,
"obtainAmount": 1.150720,
"platformFee": 0.009280
}
}
回复的参数包括:
| 变量名 | 类型 | 描述 |
|---|---|---|
| chain | string | 支付订单的token所在的链 |
| mchAddress | string | 下单的商户地址,也就是创建收款智能合约的商户地址 |
| chainCode | string | 链代码 |
| coinCode | string | 币种代码 |
| createChannel | int | 商户创建订单的渠道,0-商户系统 1-ApiKey,由于是通过api key创建订单,所以该值为1 |
| accessChannel | byte | 最终用户支付该订单的通道,由于是网关支付,所以该值为1 |
| mchOrderId | string | 商户订单号,商户订单号由商户生成的唯一订单id |
| platformId | string | hashnut的平台订单号,由hashnut生成的唯一订单号 |
| contractAddress | string | 币种的智能合约地址,用户发送交易时需要将to填写为币种的智能合约地址 |
| receiptAddress | string | 接收用户资金的智能合约地址 |
| inputData | string | 交易的inputdata数据,使用web3j编码的交易数据,包括: hashnut收款地址和订单金额amount |
| accessSign | string | 使用api key对(platformId+mchOrderId)的签名 |
| qrcodeLink | string | 网关支付二维码图片地址 |
| qrContent | string | 该值忽略 |
| walletConnectEnable | boolean | 该订单是否支持walletconnect拉起 |
| bridgeServerAddress | string | 如果walletConnectEnable为true,则该值表示walletconnect的bridge server地址 |
回复给用户时,用户需要关注订单的 state,如果state大于0,则表示已经被支付过,则拒绝再次支付
更加简洁且详细的使用方法可以参考 测试用例源码 当中ServiceTest.java