Skip to Content
SDKsNexus SDK (Cloud Integration)Java

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

<dependency> <groupId>com.sunmi</groupId> <artifactId>sunbay-nexus-sdk-java</artifactId> <version>1.0.8</version> </dependency>

Quick Start

1. Initialize Client

NexusClient is thread-safe and can be reused in multi-threaded environments. There are two usage patterns:

Pattern 1: Singleton Pattern (Recommended for Production)

// Create once, reuse globally NexusClient client = new NexusClient.Builder() .apiKey("{YOUR_API_KEY}") .baseUrl("https://open.sunbay.us") .build(); // Use client throughout the application // Remember to call client.close() when shutting down

Pattern 2: try-with-resources (For Temporary Use)

// Client implements AutoCloseable, can use try-with-resources try (NexusClient client = new NexusClient.Builder() .apiKey("{YOUR_API_KEY}") .baseUrl("https://open.sunbay.us") .build()) { // Use client SaleResponse response = client.sale(request); // Client automatically closes when exiting try block }

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.

Transaction APIs

  • sale(SaleRequest) - Payment transaction
  • auth(AuthRequest) - Pre-authorization
  • forcedAuth(ForcedAuthRequest) - Forced authorization
  • incrementalAuth(IncrementalAuthRequest) - Incremental authorization
  • postAuth(PostAuthRequest) - Post-authorization completion
  • refund(RefundRequest) - Refund
  • voidTransaction(VoidRequest) - Void transaction
  • abort(AbortRequest) - Abort transaction
  • tipAdjust(TipAdjustRequest) - Tip adjustment

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);

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);

Settlement APIs

  • batchClose(BatchCloseRequest) - Batch settlement

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);

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(30000) // Default: 30000ms (30 seconds) .readTimeout(60000) // Default: 60000ms (60 seconds) .maxRetries(3) // Default: 3 times (GET request retry) .maxTotal(200) // Default: 200 (max connections in pool) .maxPerRoute(20) // Default: 20 (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: 20)

    • 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 20 concurrent connections

Example:

  • If maxTotal = 200 and maxPerRoute = 20
  • You can have at most 20 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

License

MIT License

Last updated on