Skip to Content

Batch Close

Usage Flow

  1. Call the Batch Query API first to retrieve pending settlement batches. If no pending batches exist, no close operation is needed.
  2. A single terminal may connect to multiple Processors (each represented by a different channelCode). Call this API once for each channelCode returned in the Batch Query response.
  3. The channelCode value comes from the Batch Query response — always use it dynamically rather than using a fixed value.

Timeout Handling

If a Batch Close request times out due to a network issue, call the Batch Query API to verify the settlement result. The batch close was successful — and no retry is needed — if either of the following is true:

  • No pending settlement batch exists for that channelCode;
  • The batchNo of the pending batch returned by the query differs from the batchNo in your original close request (indicating the original batch has already been closed and a new batch has been opened).
ENDPOINT
POST
https://open.sunbay.us/v1/settlement/batch-close

The Batch Close API is used to close the current transaction batch and trigger the settlement process. After calling this API, the backend immediately initiates a batch close settlement request, and the API returns the batch close result. Once the batch is closed, it cannot be reversed, and transactions within the batch will enter the settlement process.

Parameters

Header parameters

NameTypeRequiredDescription
Authorization
stringY
Bearer Token authentication, format: Bearer {your_api_key}
Example: "Bearer sk_test_4eC39HqLyjWDarjtT1zdp7dc"
Content-Type
stringY
Request content type, fixed value: application/json
X-Client-Request-Id
string(64)Y
Request unique identifier, used to prevent duplicate requests and issue tracking. UUID format is recommended, each request must use a unique Request ID
Example: "550e8400-e29b-41d4-a716-446655440000"
X-Timestamp
stringY
Request timestamp, Unix timestamp (milliseconds), 13 digits. The deviation between the request timestamp and server time cannot exceed ±10 minutes
Pattern: ^[0-9]{13}$
Example: "1701234567890"

Body parameters

NameTypeRequiredDescription
appId
string(32)Y
Application ID
Example: "app_123456"
merchantId
string(32)Y
Merchant ID
Example: "mch_789012"
transactionRequestId
string(32)Y
Batch close request unique identifier. Used to identify the unique ID of this batch close, serves as an API idempotency control field, and can be used to query batch close results later. Can only contain letters, numbers, underscores and hyphens, maximum length 32 characters. Must not be repeated for each request
Pattern: ^[A-Za-z0-9_\-]+$
Example: "BATCH_CLOSE_20231119001"
terminalSn
string(32)Y
Payment terminal serial number. The payment terminal device serial number provided by SUNBAY, which is used for reading bank cards, processing PINs and other security operations
Example: "T1234567890"
channelCode
string(32)Y
Payment channel code. Obtain this value from the Batch Query API response — always use it dynamically rather than using a fixed value. A single terminal may connect to multiple Processors (each represented by a different channelCode); call this API once per channelCode returned by Batch Query.
Example: "TSYS"
description
string(128)N
Batch close description
Example: "End of business day, close batch"
attach
string(128)N
Additional data, returned as is, JSON format recommended
Example: "{\"closeTime\":\"2023-11-19T22:00:00+08:00\"}"

Request Example

{
  "appId": "app_123456",
  "merchantId": "mch_789012",
  "transactionRequestId": "BATCH_CLOSE_20231119001",
  "terminalSn": "T1234567890",
  "channelCode": "TSYS",
  "description": "End of business day, close batch"
}

Code Examples

cURLbash

Response parameters

NameTypeRequiredDescription
code
string(16)Y
Response code, 0 indicates success
Example: "0"
msg
string(128)N
Response description
Example: "Batch close successful"
traceId
string(64)Y
Trace ID, used for troubleshooting
Example: "TRACE123456789"
data
objectY

Full Settlement Flow Example (Java)

The following pseudocode demonstrates the complete flow: query pending batches → close each one → handle timeout.

// 1. Query pending settlement batches BatchQueryResponse queryResponse = client.batchQuery(new BatchQueryRequest(appId, merchantId, terminalSn)); List<BatchInfo> pendingBatches = queryResponse.getPendingBatches(); if (pendingBatches == null || pendingBatches.isEmpty()) { // No pending batches — nothing to close return; } // 2. Close each batch by channelCode for (BatchInfo batch : pendingBatches) { String channelCode = batch.getChannelCode(); String batchNo = batch.getBatchNo(); try { BatchCloseResponse closeResponse = client.batchClose(new BatchCloseRequest( appId, merchantId, generateRequestId(), terminalSn, channelCode )); log.info("Batch closed successfully: channelCode={}, batchNo={}", channelCode, closeResponse.getBatchNo()); } catch (TimeoutException e) { // 3. Timeout: verify the result via Batch Query handleTimeout(client, appId, merchantId, terminalSn, channelCode, batchNo); } } /** * After a timeout, query to confirm whether the batch close has taken effect. */ private void handleTimeout(NexusClient client, String appId, String merchantId, String terminalSn, String channelCode, String originalBatchNo) { BatchQueryResponse retryQuery = client.batchQuery(new BatchQueryRequest(appId, merchantId, terminalSn)); // Check if a pending batch still exists for this channelCode Optional<BatchInfo> pending = retryQuery.getPendingBatches().stream() .filter(b -> channelCode.equals(b.getChannelCode())) .findFirst(); if (pending.isEmpty()) { // No pending batch for this channelCode → close was successful log.info("Batch close confirmed (no pending batch): channelCode={}", channelCode); return; } if (!originalBatchNo.equals(pending.get().getBatchNo())) { // Pending batchNo has changed → original batch was closed, current is a new batch log.info("Batch close confirmed (batchNo changed): channelCode={}, old={}, new={}", channelCode, originalBatchNo, pending.get().getBatchNo()); return; } // Same batchNo still pending → close did not take effect, retry log.warn("Batch close not confirmed, retrying: channelCode={}, batchNo={}", channelCode, originalBatchNo); // Retry batchClose ... }
Last updated on