Skip to main content
The UQPAY Java SDK provides typed access to the UQPAY API, including automatic OAuth2 authentication, webhook verification, PGP-based authorization decision, and a sandbox simulator.

GitHub

com.uqpay.sdk:uqpay-sdk-java
The SDK requires Java 11 or higher, with Maven 3.6+ or Gradle 7+.

Installation

<dependency>
    <groupId>com.uqpay.sdk</groupId>
    <artifactId>uqpay-sdk-java</artifactId>
    <version>1.0.0</version>
</dependency>

Quick start

import com.uqpay.sdk.v2.UqpayClient;

// Sandbox (for testing)
UqpayClient client = UqpayClient.sandbox("your-client-id", "your-api-key");

// Production
UqpayClient client = UqpayClient.production("your-client-id", "your-api-key");

Authentication

The SDK handles OAuth2 authentication automatically. It fetches an access token using your clientId and apiKey, caches it, and refreshes it before expiry. You do not need to manage tokens manually.

Configuration

Custom HTTP client

import okhttp3.OkHttpClient;
import com.uqpay.sdk.v2.config.Configuration;
import com.uqpay.sdk.v2.config.Environment;

OkHttpClient httpClient = new OkHttpClient.Builder()
        .connectTimeout(Duration.ofSeconds(60))
        .readTimeout(Duration.ofSeconds(60))
        .build();

Configuration config = Configuration.builder()
        .clientId("your-client-id")
        .apiKey("your-api-key")
        .environment(Environment.PRODUCTION)
        .httpClient(httpClient)
        .build();

UqpayClient client = new UqpayClient(config);

Environments

ConstantDescription
Environment.SANDBOXSandbox environment for testing and development
Environment.PRODUCTIONProduction environment for live transactions

Pagination

All list methods return a paginated response with getData(), getTotalPages(), and getTotalItems():
ListCardsRequest req = new ListCardsRequest();
req.setPageNumber(1);
req.setPageSize(50);
ListCardsResponse page = client.issuing().getCards().list(req);

System.out.println(page.getData());       // List<Card>
System.out.println(page.getTotalPages()); // total number of pages
System.out.println(page.getTotalItems()); // total number of items

Webhooks

Verify incoming webhook signatures from UQPAY:
import com.uqpay.sdk.v2.webhook.WebhookVerifier;
import com.uqpay.sdk.v2.webhook.Event;
import com.uqpay.sdk.v2.common.UqpayWebhookException;

WebhookVerifier verifier = new WebhookVerifier("your-webhook-secret");

try {
    Event event = verifier.verifyAndParse(
        requestBodyString,
        request.getHeader("x-signature"),
        request.getHeader("x-timestamp")
    );

    if (event.isCardTransactionEvent()) {
        // handle card transaction authorization, clearing, etc.
    } else if (Event.EVENT_NAME_CARDHOLDER_KYC.equals(event.getEventName())) {
        // handle KYC status update
    }
} catch (UqpayWebhookException e) {
    // signature invalid or timestamp expired
    response.setStatus(400);
}
The verifier checks the HMAC-SHA512 signature and rejects requests with a timestamp older than 300 seconds by default.

Authorization decision (PGP)

Handle real-time card transaction authorization decisions. UQPAY sends PGP-encrypted transactions to your endpoint; the SDK decrypts them, calls your handler, and returns an encrypted response.
import com.uqpay.sdk.v2.issuing.AuthDecisionService;
import com.uqpay.sdk.v2.issuing.model.AuthDecisionConfig;
import com.uqpay.sdk.v2.issuing.model.AuthDecisionRequest;
import com.uqpay.sdk.v2.issuing.model.AuthDecisionResponse;

// Configure PGP keys (once at startup)
AuthDecisionConfig config = new AuthDecisionConfig(
    "./keys/my-private.asc",
    System.getenv("PGP_PASSPHRASE"),
    "./keys/uqpay-public.asc"
);

AuthDecisionService authDecision = client.issuing().getAuthDecision();
authDecision.configure(config);

// Handle a decision request
AuthDecisionHandler handler = (AuthDecisionRequest tx) -> {
    if (tx.getBillingAmount() > 10000) {
        return AuthDecisionResponse.decline(tx.getTransactionId(), "51");
    }
    return AuthDecisionResponse.approve(tx.getTransactionId());
};

// In your HTTP handler, pass the raw encrypted body string:
String encryptedResponse = authDecision.processRequest(requestBodyString, handler);
response.getWriter().write(encryptedResponse);

Error handling

The SDK uses a hierarchy of exceptions:
ExceptionDescription
UqpayExceptionBase exception for all SDK errors
UqpayApiExceptionAPI returned an error response (includes HTTP status, error code, message)
UqpayAuthExceptionAuthentication failed (invalid credentials, token refresh failure)
UqpayNetworkExceptionNetwork-level failure (timeout, connection refused)
UqpayWebhookExceptionWebhook signature verification failed
try {
    Balance balance = client.banking().getBalances().get("SGD");
} catch (UqpayApiException e) {
    System.err.printf("API error: status=%d, code=%s, message=%s%n",
            e.getStatusCode(), e.getCode(), e.getMessage());
} catch (UqpayAuthException e) {
    System.err.println("Authentication failed: " + e.getMessage());
} catch (UqpayNetworkException e) {
    System.err.println("Network error: " + e.getMessage());
} catch (UqpayException e) {
    System.err.println("SDK error: " + e.getMessage());
}