跳到主要内容

3.0 sdk的返回结果格式

{
"code": 0,
"msg": "success",
"count": 0,
"data": {}
}

返回的主要参数包括:

变量名类型描述
codeint请求返回结果,0为成功,其他值为失败
msgstring错误消息,success为成功,其他值为失败
countint当data为json数组的时候,count表示data里面的元素个数
dataobject具体返回的数据,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
}
...
]
}

返回的主要参数包括:

变量名类型描述
chainstringhashnut支持的公链的名称的缩写,例如:ETH,BSC,TRON,POLYGON等
chainDescstring公链的描述
enableboolean公链是否可用
receiptAddressstringHashNut平台在该公链上的收款地址
txConfirmCountint在该公链上的交易需要被确认的次数,如果达到或者超过确认次数,则hashnut认为支付订单的交易有效
walletConnectEnableboolean该公链是否支持walletconnect协议拉起,如果不支持walletconnect协议拉起,则需要最终用户用钱包app扫码支付
bridgeServerAddressstringwalletconnect的bridge server地址
decimalsint例如:eth的精度是小数点后18位,tron的精度是6位
baseChainSymbolstring基础链的名称
envint当前支付平台的环境 0-正式 1-测试 2-开发
chainIdlongEVM兼容链的ChainID,例如: POLYGON的正式环境为137,Mumbai环境为80001
baseChainCoinint基础链的币种缩写,例如:以太坊的缩写是ETH,POLYGON上面基础币种的缩写是MATIC
eip712ChainIdstringeip712当中,该链的链Id,该值仅对支持eip712的公链有效
eip1559Supportint是否支持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"
}
...
]
}

主要返回参数如下:

变量名类型描述
chainstring币种所在的链名称,例如:ETH
chainCodestringhashnut支持的链的代码,目前hashnut支持erc20,trc20,bep20,polygon-erc20
coinCodestring币种代号,目前erc20支持usdt,usdc,bep20支持busd,hashnut,trc20支持usdt
isTokenboolean该币种是否是token,如果是公链的基础代币,例如 eth,bsc,trx,则该值为false
enableboolean该币种目前在hashnut是否可用,如果该币种不可用,则无法创建订单
contractAddressstring当前币种在该公链上的智能合约地址
coinDescstring币种的描述信息
gateWayEnableboolean如果该字段为true,则用户可以通过币安APP,或者其他APP,走网关支付,目前hashnut仅支持币安网关
decimalsint币种的精度,比如说,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当中携带的参数:

变量名类型描述
chainCodestringtoken类型,目前HashNut支持erc20,trc20,bep20,polygon-erc20

主要返回参数如下:

变量名类型描述
chainstring币种所在的链名称,例如:ETH
chainCodestringhashnut支持的链的代码,目前hashnut支持erc20,trc20,bep20,polygon-erc20
coinCodestring币种代号,目前erc20支持usdt,usdc,bep20支持busd,hashnut,trc20支持usdt
isTokenboolean该币种是否是token,如果是公链的基础代币,例如 eth,bsc,trx,则该值为false
enableboolean该币种目前在hashnut是否可用,如果该币种不可用,则无法创建订单
contractAddressstring当前币种在该公链上的智能合约地址
coinDescstring币种的描述信息
gateWayEnableboolean如果该字段为true,则用户可以通过币安APP,或者其他APP,走网关支付,目前hashnut仅支持币安网关
decimalsint币种的精度,比如说,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当中携带的参数:

变量名类型描述
accessKeyIdstring商户API KEY ID
merchantOrderIdstring商户订单号,商户订单号由商户生成的唯一订单id
chainCodestring链代号
coinCodestring币种代号
amountDecimal(20)需要支付的金额,最多精确到小数点后2位
receiptAddressstring商户部署的智能合约合约的地址

请求的header当中携带的参数:

变量名类型描述
hashnut-request-uuidstring商户随机生成的uuid
hashnut-request-timestampstring时间戳
hashnut-request-signstring使用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
}
}

回复的参数包括

变量名类型描述
chainstring支付订单的token所在的链
mchAddressstring下单的商户地址,也就是创建收款智能合约的商户地址
chainCodestring链代码
coinCodestring币种代码
createChannelint商户创建订单的渠道,0-商户系统 1-ApiKey,由于是通过api key创建订单,所以该值为1
accessChannelbyte最终用户支付该订单的通道,由于是链上支付,所以该值为0
merchantOrderIdstring商户订单号,商户订单号由商户生成的唯一订单id
payOrderIdstringhashnut的平台订单号,由hashnut生成的唯一收款地址
contractAddressstring币种的智能合约地址,用户发送交易时需要将to填写为币种的智能合约地址
receiptAddressstring用于接收用户资金的智能合约地址
inputDatastring交易的inputdata数据,使用web3j编码的交易数据,包括: hashnut收款地址和订单金额amount
accessSignstring使用api key对(platformId+mchOrderId)的签名

商户拼接支付订单的URL

商户使用创建订单回复当中的accessSign,merchantOrderId,payOrderId拼接成支付的URL发送给最终用户,例如:

https://testnet-web3.hashnut.io/pay?accessSign=42889E72DAAE0C4275F804DDDFA4707823FE30EB4D4BB6064859CB65AA3E6305&merchantOrderId=10000&payOrderId=01HSKATBCK7CE20N88B25870M5

其中URL的参数:

变量名类型描述
accessSignstring使用api key对(platformId+merchantOrderId)的签名
merchantOrderIdstring商户订单号
payOrderIdstringHashNut的平台订单号,由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当中携带的参数:

变量名类型描述
accessKeyIdstring商户API KEY ID
merchantOrderIdstring商户订单号,商户订单号由商户生成的唯一订单id
chainCodestring链代号
coinCodestring币种代号
amountDecimal(20)需要支付的金额,最多精确到小数点后2位
splitterAddressstring商户部署的PassThrough分账合约地址

注意: splitterAddress在该模式下的作用为接收从各个合约钱包归集的资金,以及提现时进行分账。该功能的回复以及其他内容跟 web custody mode保持一致。

3.7 回调通知

回调通知

回调的URL可以在 创建ApiKey的接口里面配置,回调url包括后端回调url和前端回调url,无论是后端回调url还是前端回调url都包含如下几个参数:

变量名类型描述
payOrderIdstringHashNut的平台订单号,由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"
}'

请求的参数包括:

变量名类型描述
merchantOrderIdstring商户订单号,商户订单号由商户生成的唯一订单id
payOrderIdstringhashnut的平台订单号
accessSignstring使用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
}
}

回复的参数包括:

变量名类型描述
chainstring支付订单的token所在的链
mchAddressstring下单的商户地址,也就是创建收款智能合约的商户地址
chainCodestring链代码
coinCodestring币种代码
createChannelint商户创建订单的渠道,0-商户系统 1-ApiKey,由于是通过api key创建订单,所以该值为1
accessChannelbyte最终用户支付该订单的通道,由于是网关支付,所以该值为1
mchOrderIdstring商户订单号,商户订单号由商户生成的唯一订单id
platformIdstringhashnut的平台订单号,由hashnut生成的唯一订单号
contractAddressstring币种的智能合约地址,用户发送交易时需要将to填写为币种的智能合约地址
receiptAddressstring接收用户资金的智能合约地址
inputDatastring交易的inputdata数据,使用web3j编码的交易数据,包括: hashnut收款地址和订单金额amount
accessSignstring使用api key对(platformId+mchOrderId)的签名
qrcodeLinkstring网关支付二维码图片地址
qrContentstring该值忽略
walletConnectEnableboolean该订单是否支持walletconnect拉起
bridgeServerAddressstring如果walletConnectEnable为true,则该值表示walletconnect的bridge server地址

回复给用户时,用户需要关注订单的 state,如果state大于0,则表示已经被支付过,则拒绝再次支付

更加简洁且详细的使用方法可以参考 测试用例源码 当中ServiceTest.java