Documentation Index
Fetch the complete documentation index at: https://developers-sandbox.uqpaytech.com/llms.txt
Use this file to discover all available pages before exploring further.
UQPAY Java SDK 以带类型的方式访问 UQPAY API,内置自动 OAuth2 鉴权、webhook 签名校验、基于 PGP 的授权决策以及沙盒模拟器。
GitHub
com.uqpay.sdk:uqpay-sdk-java
SDK 需要 Java 11 或更高版本,配合 Maven 3.6+ 或 Gradle 7+。
<dependency>
<groupId>com.uqpay.sdk</groupId>
<artifactId>uqpay-sdk-java</artifactId>
<version>1.0.0</version>
</dependency>
implementation 'com.uqpay.sdk:uqpay-sdk-java:1.0.0'
快速上手
import com.uqpay.sdk.v2.UqpayClient;
// 沙盒(测试用)
UqpayClient client = UqpayClient.sandbox("your-client-id", "your-api-key");
// 生产
UqpayClient client = UqpayClient.production("your-client-id", "your-api-key");
SDK 自动处理 OAuth2 鉴权。它会用 clientId 和 apiKey 换取 access token,缓存并在过期前自动刷新,你无需手动管理 token。
自定义 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);
| 常量 | 说明 |
|---|
Environment.SANDBOX | 沙盒环境,用于测试和开发 |
Environment.PRODUCTION | 生产环境,用于真实交易 |
所有 list 方法返回分页响应,提供 getData()、getTotalPages() 与 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()); // 总页数
System.out.println(page.getTotalItems()); // 总条数
Webhooks
校验 UQPAY 发来的 webhook 签名:
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()) {
// 处理卡交易的授权、清算等
} else if (Event.EVENT_NAME_CARDHOLDER_KYC.equals(event.getEventName())) {
// 处理 KYC 状态更新
}
} catch (UqpayWebhookException e) {
// 签名无效或时间戳超过阈值
response.setStatus(400);
}
校验器检查 HMAC-SHA512 签名,默认拒绝 timestamp 超过 300 秒的请求。
授权决策(PGP)
处理卡交易的实时授权决策。UQPAY 会向你的端点发送 PGP 加密的交易通知体,SDK 解密后调用你的处理器,并返回加密响应。
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;
// 启动时一次性配置 PGP 密钥
AuthDecisionConfig config = new AuthDecisionConfig(
"./keys/my-private.asc",
System.getenv("PGP_PASSPHRASE"),
"./keys/uqpay-public.asc"
);
AuthDecisionService authDecision = client.issuing().getAuthDecision();
authDecision.configure(config);
// 处理一次决策请求
AuthDecisionHandler handler = (AuthDecisionRequest tx) -> {
if (tx.getBillingAmount() > 10000) {
return AuthDecisionResponse.decline(tx.getTransactionId(), "51");
}
return AuthDecisionResponse.approve(tx.getTransactionId());
};
// 在 HTTP 处理器中传入原始加密请求体字符串:
String encryptedResponse = authDecision.processRequest(requestBodyString, handler);
response.getWriter().write(encryptedResponse);
错误处理
SDK 使用一组异常层级:
| 异常 | 说明 |
|---|
UqpayException | 所有 SDK 错误的基类 |
UqpayApiException | API 返回错误响应(包含 HTTP 状态、错误码、错误消息) |
UqpayAuthException | 鉴权失败(凭证无效、token 刷新失败) |
UqpayNetworkException | 网络层失败(超时、连接被拒) |
UqpayWebhookException | webhook 签名校验失败 |
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());
}