Java SDK
The official HashNut Java SDK provides a convenient wrapper around the HashNut Payment API.
- GitHub: nuttybounty/hashnut-sdk
- Distribution: JitPack
Installation
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.1</version>
</dependency>Gradle
groovy
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.nuttybounty:hashnut-sdk:v4.0.1'
}Initialize the Client
java
import io.hashnut.client.HashNutClientImpl;
import io.hashnut.service.HashNutServiceImpl;
// Always pass false as the second argument — that selects the production environment
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);Methods
createOrder
Create a new payment order.
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("Monthly Subscription")
.withExpireDuration(1800L)
.withCallbackUrl("https://yoursite.com/payment-result")
.build());
System.out.println("Pay Order ID: " + resp.getData().getPayOrderId());
System.out.println("Receipt Address: " + resp.getData().getReceiptAddress());
System.out.println("Access Sign: " + resp.getData().getAccessSign());queryOrder
Query the current state of an order.
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("the-access-sign-from-create-order")
.build());
System.out.println("State: " + resp.getData().getState());
System.out.println("Tx Hash: " + resp.getData().getPayTxId());confirmPaid
Manually confirm payment with a transaction hash.
java
import io.hashnut.model.request.ConfirmPaidRequest;
import io.hashnut.model.response.SingleResponse;
SingleResponse resp = service.confirmPaid(new ConfirmPaidRequest.Builder()
.withPayOrderId("01J5X9NDEKTSV4RRFFQ69G5FAV")
.withMerchantOrderId("ORDER-001")
.withAccessSign("the-access-sign-from-create-order")
.withPayTxId("0x9876543210fedcba...")
.build());cancelOrder
Cancel an unpaid order.
java
import io.hashnut.model.request.CancelOrderRequest;
SingleResponse resp = service.cancelOrder(new CancelOrderRequest.Builder()
.withPayOrderId("01J5X9NDEKTSV4RRFFQ69G5FAV")
.build());queryAllChainInfo
Query all supported blockchain networks.
java
import io.hashnut.model.request.QueryChainsRequest;
import io.hashnut.model.response.QueryChainsResponse;
QueryChainsResponse resp = service.queryAllChainInfo(new QueryChainsRequest.Builder().build());
for (var chain : resp.getData()) {
System.out.printf("%s (chainId=%s)%n", chain.getBlockChain(), chain.getChainId());
}queryAllCoinInfo
Query all supported tokens.
java
import io.hashnut.model.request.QueryCoinsRequest;
import io.hashnut.model.response.QueryCoinsResponse;
QueryCoinsResponse resp = service.queryAllCoinInfo(new QueryCoinsRequest.Builder().build());
for (var coin : resp.getData()) {
System.out.printf("%s/%s - %d decimals%n", coin.getBlockChain(), coin.getTokenSymbol(), coin.getDecimals());
}Error Handling
All methods throw HashNutException for API errors:
java
import io.hashnut.exception.HashNutException;
try {
var resp = service.createOrder(new CreateOrderRequest.Builder()
/* ... */
.build());
} catch (HashNutException e) {
System.err.println("API Error: " + e.getMessage());
}Order States
Use the OrderState class for state constants:
java
import io.hashnut.model.OrderState;
int state = resp.getData().getState();
switch (state) {
case OrderState.INIT: // 0 - Order created
case OrderState.PAID: // 1 - Payment detected
case OrderState.CONFIRMING: // 2 - Awaiting confirmations
System.out.println("Payment in progress...");
break;
case OrderState.SUCCESS: // 3 - Payment confirmed
case OrderState.FINISH: // 4 - Order completed
System.out.println("Payment successful!");
break;
case OrderState.FAILED: // -1
case OrderState.EXPIRE: // -2
case OrderState.CANCELED: // -3
System.out.println("Payment failed/expired/canceled");
break;
}Complete Example
java
import io.hashnut.client.HashNutClientImpl;
import io.hashnut.exception.HashNutException;
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. Create order
CreateOrderResponse 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("Test Order")
.withExpireDuration(600L)
.build());
var order = createResp.getData();
System.out.printf("Order created: %s%n", order.getPayOrderId());
System.out.printf("Send %s USDT to: %s%n", order.getAmount(), order.getReceiptAddress());
// 2. Poll for payment (in production, use webhooks instead)
for (int i = 0; i < 60; i++) {
Thread.sleep(10_000);
QueryOrderResponse queryResp = service.queryOrder(new QueryOrderRequest.Builder()
.withPayOrderId(order.getPayOrderId())
.withMerchantOrderId(order.getMerchantOrderId())
.withAccessSign(order.getAccessSign())
.build());
int state = queryResp.getData().getState();
System.out.printf("State: %s%n", OrderState.toString(state));
if (state == OrderState.SUCCESS || state == OrderState.FINISH) {
System.out.println("Payment successful!");
return;
}
}
}
}TIP
In production, prefer webhook notifications over polling. Polling is shown here for simplicity.