Java SDK
HashNut 官方 Java SDK,提供对 HashNut 支付 API 的便捷封装。
- GitHub: nuttybounty/hashnut-sdk
- 发布: JitPack
安装
Maven
xml
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.nuttybounty</groupId>
<artifactId>hashnut-sdk</artifactId>
<version>v4.0.2</version>
</dependency>Gradle
groovy
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.nuttybounty:hashnut-sdk:v4.0.2'
}初始化客户端
java
import io.hashnut.client.HashNutClientImpl;
import io.hashnut.service.HashNutServiceImpl;
// 第二个参数固定传 false,即使用生产环境
var client = new HashNutClientImpl("your-secret-key", false);
var service = new HashNutServiceImpl(client);java
var client = new HashNutClientImpl("your-secret-key", "https://custom.endpoint.com/api/v4.0.0");
var service = new HashNutServiceImpl(client);方法
createOrder
创建支付订单。
java
import io.hashnut.model.request.CreateOrderRequest;
import io.hashnut.model.response.CreateOrderResponse;
CreateOrderResponse resp = service.createOrder(new CreateOrderRequest.Builder()
.withAccessKeyId("your-access-key-id")
.withMerchantOrderId("ORDER-001")
.withBlockChain("ETH")
.withTokenSymbol("usdt")
.withAmount("25.00")
.withSplitterAddress("0xYourSplitterAddress")
.withSubject("月度订阅")
.withExpireDuration(1800L)
.withCallbackUrl("https://yoursite.com/payment-result")
.build());
System.out.println("订单ID: " + resp.getData().getPayOrderId());
System.out.println("收款地址: " + resp.getData().getReceiptAddress());queryOrder
查询订单状态。
java
import io.hashnut.model.request.QueryOrderRequest;
import io.hashnut.model.response.QueryOrderResponse;
QueryOrderResponse resp = service.queryOrder(new QueryOrderRequest.Builder()
.withPayOrderId("01J5X9NDEKTSV4RRFFQ69G5FAV")
.withMerchantOrderId("ORDER-001")
.withAccessSign("创建订单时返回的accessSign")
.build());
System.out.println("状态: " + resp.getData().getState());
System.out.println("交易哈希: " + resp.getData().getPayTxId());confirmPaid
手动确认支付交易。
java
import io.hashnut.model.request.ConfirmPaidRequest;
service.confirmPaid(new ConfirmPaidRequest.Builder()
.withPayOrderId("01J5X9NDEKTSV4RRFFQ69G5FAV")
.withMerchantOrderId("ORDER-001")
.withAccessSign("创建订单时返回的accessSign")
.withPayTxId("0x9876543210fedcba...")
.build());cancelOrder
取消未支付的订单。
java
import io.hashnut.model.request.CancelOrderRequest;
service.cancelOrder(new CancelOrderRequest.Builder()
.withPayOrderId("01J5X9NDEKTSV4RRFFQ69G5FAV")
.build());queryAllChainInfo / queryAllCoinInfo
查询支持的链和币种。
java
// 查询所有链
var chainsResp = service.queryAllChainInfo(new QueryChainsRequest.Builder().build());
for (var chain : chainsResp.getData()) {
System.out.printf("%s (chainId=%s)%n", chain.getBlockChain(), chain.getChainId());
}
// 查询所有币种
var coinsResp = service.queryAllCoinInfo(new QueryCoinsRequest.Builder().build());
for (var coin : coinsResp.getData()) {
System.out.printf("%s/%s - %d 位小数%n", coin.getBlockChain(), coin.getTokenSymbol(), coin.getDecimals());
}错误处理
所有方法在 API 错误时抛出 HashNutException:
java
import io.hashnut.exception.HashNutException;
try {
var resp = service.createOrder(new CreateOrderRequest.Builder()
/* ... */
.build());
} catch (HashNutException e) {
System.err.println("API 错误: " + e.getMessage());
}订单状态
使用 OrderState 类的常量:
java
import io.hashnut.model.OrderState;
int state = resp.getData().getState();
switch (state) {
case OrderState.INIT: // 0 - 订单已创建
case OrderState.PAID: // 1 - 检测到支付
case OrderState.CONFIRMING: // 2 - 等待确认
System.out.println("支付中...");
break;
case OrderState.SUCCESS: // 3 - 支付成功
case OrderState.FINISH: // 4 - 订单完成
System.out.println("支付成功!");
break;
case OrderState.FAILED: // -1 - 失败
case OrderState.EXPIRE: // -2 - 过期
case OrderState.CANCELED: // -3 - 已取消
System.out.println("支付失败/过期/已取消");
break;
}完整示例
java
import io.hashnut.client.HashNutClientImpl;
import io.hashnut.model.OrderState;
import io.hashnut.model.request.*;
import io.hashnut.model.response.*;
import io.hashnut.service.HashNutServiceImpl;
public class PaymentExample {
public static void main(String[] args) throws Exception {
var client = new HashNutClientImpl("your-secret-key", false);
var service = new HashNutServiceImpl(client);
// 1. 创建订单
var createResp = service.createOrder(new CreateOrderRequest.Builder()
.withAccessKeyId("your-access-key-id")
.withMerchantOrderId("ORDER-" + System.currentTimeMillis())
.withBlockChain("ETH")
.withTokenSymbol("usdt")
.withAmount("1.00")
.withSplitterAddress("0xYourSplitterAddress")
.withSubject("测试订单")
.withExpireDuration(600L)
.build());
var order = createResp.getData();
System.out.printf("订单已创建: %s%n", order.getPayOrderId());
System.out.printf("请转账 %s USDT 到: %s%n", order.getAmount(), order.getReceiptAddress());
// 2. 轮询订单状态(生产环境请使用 webhook)
for (int i = 0; i < 60; i++) {
Thread.sleep(10_000);
var queryResp = service.queryOrder(new QueryOrderRequest.Builder()
.withPayOrderId(order.getPayOrderId())
.withMerchantOrderId(order.getMerchantOrderId())
.withAccessSign(order.getAccessSign())
.build());
int state = queryResp.getData().getState();
System.out.printf("状态: %s%n", OrderState.toString(state));
if (state == OrderState.SUCCESS || state == OrderState.FINISH) {
System.out.println("支付成功!");
return;
}
}
}
}TIP
生产环境请优先使用 Webhook 通知,轮询仅用于演示。