Java SDK
GitHub Repository: sunbay-nexus-sdk-java
Official SUNBAY Nexus Java SDK, providing complete payment integration capabilities for Java 8+ applications.
Features
- ✅ Clean and intuitive API design
- ✅ Builder pattern for request construction
- ✅ Support for Java 8+
- ✅ Automatic authentication
- ✅ Automatic retry for GET requests
- ✅ Comprehensive exception handling
- ✅ Minimal dependencies
Installation
Maven
<dependency>
<groupId>com.sunmi</groupId>
<artifactId>sunbay-nexus-sdk-java</artifactId>
<version>LATEST</version> <!-- Always use the latest version, check https://central.sonatype.com/ -->
</dependency>Quick Start
1. Initialize Client
NexusClient is thread-safe and uses an internal HTTP connection pool to manage connections. Create it once at application startup and reuse it globally — do not create a new instance for every request. Repeated creation prevents connection pool reuse and wastes system resources.
// Create once, reuse globally
NexusClient client = new NexusClient.Builder()
.apiKey("{YOUR_API_KEY}") // Required: API key
.baseUrl("https://open.sunbay.us") // Required: API base URL
.connectTimeout(10000) // Optional: connect timeout, default 10000ms
.readTimeout(30000) // Optional: read timeout, default 30000ms
.maxRetries(3) // Optional: GET request retries, default 3
.maxTotal(200) // Optional: max connections in pool, default 200
.maxPerRoute(200) // Optional: max connections per route, default 200
.build();
// Reuse client throughout the application
// Call client.close() on application shutdown to release connection pool resourcesWe recommend tuning connectTimeout, readTimeout, maxRetries, maxTotal, and maxPerRoute based on your concurrency level and business requirements. For high-concurrency scenarios, consider increasing maxTotal and maxPerRoute.
2. Create Payment Transaction
import com.sunmi.sunbay.nexus.NexusClient;
import com.sunmi.sunbay.nexus.exception.SUNBAYBusinessException;
import com.sunmi.sunbay.nexus.exception.SUNBAYNetworkException;
import com.sunmi.sunbay.nexus.model.common.SaleAmount;
import com.sunmi.sunbay.nexus.model.request.SaleRequest;
import com.sunmi.sunbay.nexus.model.response.SaleResponse;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
// Assume client is already initialized (singleton or try-with-resources)
// NexusClient client = ... (from step 1)
// Set expiration time (optional)
ZonedDateTime expireTime = ZonedDateTime.now().plusMinutes(10);
String timeExpire = expireTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX"));
// Build amount using Builder pattern
// Note: All amount fields use Integer type, in smallest currency unit (cents)
// Example: 100.00 USD = 10000 cents
SaleAmount amount = SaleAmount.builder()
.orderAmount(10000) // 100.00 USD, in cents
.priceCurrency("USD")
.build();
// Build payment request using Builder pattern
SaleRequest request = SaleRequest.builder()
.appId("app_123456")
.merchantId("mch_789012")
.referenceOrderId("ORDER20231119001")
.transactionRequestId("PAY_REQ_" + System.currentTimeMillis())
.amount(amount)
.description("Product purchase")
.terminalSn("T1234567890")
.timeExpire(timeExpire)
.build();
// Execute transaction
try {
SaleResponse response = client.sale(request);
// If no exception is thrown, transaction is successful
System.out.println("Transaction ID: " + response.getTransactionId());
} catch (SUNBAYNetworkException e) {
System.err.println("Network Error: " + e.getMessage());
} catch (SUNBAYBusinessException e) {
System.err.println("API Error: " + e.getCode() + " - " + e.getMessage());
}API Methods
All request classes support the Builder pattern for convenient object construction.
In-Person Payment APIs
sale(SaleRequest)- Payment transactionauth(AuthRequest)- Pre-authorizationforcedAuth(ForcedAuthRequest)- Forced authorizationincrementalAuth(IncrementalAuthRequest)- Incremental authorizationpostAuth(PostAuthRequest)- Post-authorization completionrefund(RefundRequest)- RefundvoidTransaction(VoidRequest)- Void transactionabort(AbortRequest)- Abort transactiontipAdjust(TipAdjustRequest)- Tip adjustmentbatchQuery(BatchQueryRequest)- Query open (unsettled) batchesbatchClose(BatchCloseRequest)- Batch settlementbatchCloseList(BatchCloseListRequest)- Query closed (settled) batches
Example: Pre-authorization
AuthRequest request = AuthRequest.builder()
.appId("app_123456")
.merchantId("mch_789012")
.referenceOrderId("AUTH" + System.currentTimeMillis())
.transactionRequestId("PAY_REQ_" + System.currentTimeMillis())
.amount(AuthAmount.builder()
.orderAmount(20000) // 200.00 USD, in cents
.priceCurrency("USD")
.build())
.description("Hotel reservation")
.terminalSn("T1234567890")
.build();
AuthResponse response = client.auth(request);Example: Batch Settlement
BatchCloseRequest request = BatchCloseRequest.builder()
.appId("app_123456")
.merchantId("mch_789012")
.transactionRequestId("BATCH_CLOSE_" + System.currentTimeMillis())
.terminalSn("T1234567890")
.description("End of day settlement")
.build();
BatchCloseResponse response = client.batchClose(request);Online Payment APIs
createCheckoutSession(CreateCheckoutSessionRequest)- Create hosted checkout sessionexpireCheckoutSession(ExpireCheckoutSessionRequest)- Expire a checkout sessioncheckoutDirectPayment(CheckoutDirectPaymentRequest)- Direct payment (server-to-server)onlineRefund(OnlineRefundRequest)- Online refund
Transaction Query APIs
query(QueryRequest)- Query transaction
Example: Query Transaction
QueryRequest request = QueryRequest.builder()
.appId("app_123456")
.merchantId("mch_789012")
.transactionId("TXN20231119001")
.build();
QueryResponse response = client.query(request);Merchant APIs
merchantQuery(MerchantQueryRequest)- Retrieve merchant informationmerchantTerminalsQuery(MerchantTerminalsQueryRequest)- List terminals bound to a merchant
Exception Handling
The SDK throws two types of exceptions:
SUNBAYNetworkException: Network-related errors (connection timeout, network errors, etc.)SUNBAYBusinessException: Business logic errors (parameter validation, API business errors, etc.)
Always catch SUNBAYNetworkException first, then SUNBAYBusinessException
// Build request using Builder pattern
SaleRequest request = SaleRequest.builder()
.appId("app_123456")
.merchantId("mch_789012")
.referenceOrderId("ORDER20231119001")
.transactionRequestId("PAY_REQ_" + System.currentTimeMillis())
.amount(SaleAmount.builder()
.orderAmount(10000) // 100.00 USD, in cents
.priceCurrency("USD")
.build())
.description("Product purchase")
.terminalSn("T1234567890")
.build();
try {
SaleResponse response = client.sale(request);
// If no exception is thrown, transaction is successful
// Use response object here
} catch (SUNBAYNetworkException e) {
// Network exception (e.g., connection timeout, network error)
System.err.println("Network Error: " + e.getMessage());
if (e.isRetryable()) {
// Can retry
}
} catch (SUNBAYBusinessException e) {
// Business exception (e.g., insufficient funds, parameter error)
System.err.println("API Error: " + e.getCode() + " - " + e.getMessage());
if (e.getTraceId() != null) {
System.err.println("Trace ID: " + e.getTraceId());
}
}Configuration Options
NexusClient client = new NexusClient.Builder()
.apiKey("sk_test_xxx")
.baseUrl("https://open.sunbay.us") // Default: https://open.sunbay.us
.connectTimeout(10000) // Default: 10000ms (10 seconds)
.readTimeout(30000) // Default: 30000ms (30 seconds)
.maxRetries(3) // Default: 3 times (GET request retry)
.maxTotal(200) // Default: 200 (max connections in pool)
.maxPerRoute(200) // Default: 200 (max connections per route)
.build();Connection Pool Configuration
The SDK uses Apache HttpClient’s connection pool to efficiently manage HTTP connections. You can configure:
-
maxTotal: Maximum total connections across all routes in the pool (default: 200)
- This is the total number of connections that can be open simultaneously across all hosts/routes
- Example: If you have 10 different API endpoints, the total connections across all endpoints cannot exceed this value
-
maxPerRoute: Maximum connections per route/host (default: 200)
- This is the maximum number of connections that can be open for a single host/route
- A route is typically defined by protocol (http/https), host, and port
- Example: For
https://open.sunbay.us, you can have at most 200 concurrent connections
Example:
- If
maxTotal = 200andmaxPerRoute = 200 - You can have at most 200 connections to
https://open.sunbay.us(limited by maxPerRoute) - But if connecting to multiple hosts, the total connections across all hosts cannot exceed 200 (limited by maxTotal)
These settings help optimize performance in high-concurrency scenarios.
System Requirements
- Java 8 or higher
- Apache HttpClient 4.5.14
- Jackson 2.18.2
Related Links
License
MIT License