悠悠楠杉
Java实现银联支付接口对接全流程开发指南
一、银联支付对接核心流程
银联支付接口对接主要包含以下关键环节:
- 商户入驻:在银联商务平台完成商户注册
- 参数配置:获取商户号、终端号、加密证书等核心参数
- 开发对接:实现交易接口和通知处理
- 联调测试:通过银联测试环境验证
- 生产上线:切换正式环境参数
二、开发环境准备
java
// Maven依赖配置示例
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
需要准备:
- 银联提供的商户开发包(SDK)
- 商户证书文件(.pfx格式)
- 银联公钥证书
- 测试商户号
三、核心接口实现代码
1. 支付请求封装
java
public class UnionPayRequest {
private String merId; // 商户号
private String orderId; // 订单号
private BigDecimal amount; // 金额(分)
private String frontUrl; // 前台通知地址
private String backUrl; // 后台通知地址
// 生成签名方法
public String generateSign() throws Exception {
Map<String,String> params = new TreeMap<>();
params.put("merId", this.merId);
params.put("orderId", this.orderId);
params.put("txnAmt", String.valueOf(amount.multiply(new BigDecimal(100))));
// 使用SHA256withRSA进行签名
PrivateKey privateKey = CertUtil.getPrivateKey();
return RSA.sign(params.toString(), privateKey);
}
}
2. 支付结果通知处理
java
@PostMapping("/unionpay/notify")
public String paymentNotify(HttpServletRequest request) {
try {
// 1. 获取所有参数
Map<String,String> params = getAllRequestParam(request);
// 2. 验证签名
boolean signValid = verifySign(params);
if(!signValid) {
return "FAIL";
}
// 3. 处理业务逻辑
String orderId = params.get("orderId");
String txnTime = params.get("txnTime");
String respCode = params.get("respCode");
if("00".equals(respCode)) {
orderService.updateOrderStatus(orderId, OrderStatus.PAID);
return "SUCCESS";
}
} catch (Exception e) {
logger.error("银联通知处理异常", e);
}
return "FAIL";
}
四、关键安全措施
证书管理:
- 证书文件应当存储在安全目录
- 生产环境建议使用硬件加密机
通信安全:java
// 启用HTTPS示例
SSLContext sslContext = SSLContextBuilder
.create()
.loadTrustMaterial(new File("unionpay.cer"), "123456".toCharArray())
.build();HttpClient httpClient = HttpClients.custom()
.setSSLContext(sslContext)
.build();防重复支付:
- 订单号必须唯一
- 建议增加支付状态校验
五、常见问题解决
验签失败:
- 检查证书是否过期
- 确认参数排序规则(银联要求按字母序排序)
交易状态不同步:
- 建议实现定时查询补单机制
java @Scheduled(cron = "0 0/5 * * * ?") public void queryTimeoutOrders() { List<Order> orders = orderService.getUnconfirmedOrders(); orders.forEach(order -> { unionPayService.queryOrder(order.getOrderId()); }); }
- 建议实现定时查询补单机制
编码问题:
- 所有请求必须使用UTF-8编码
- 金额单位必须转换为分
六、生产环境 checklist
- [ ] 切换正式环境域名
- [ ] 更新正式商户证书
- [ ] 配置防火墙白名单
- [ ] 启用交易监控告警
- [ ] 压力测试报告验收
总结:银联支付对接需要特别注意安全规范和异常处理。建议在开发阶段充分利用银联提供的仿真测试系统,完成至少200笔以上全流程测试后再上线生产。实际开发中还需考虑分布式环境下的幂等控制、对账文件处理等扩展需求。