支付宝对接代码
支付宝支付相关步骤
首先需要注册商户号,其次开通相关支付业务,这个官网上有相关的步骤。
前期相关准备
对接之前之前我们需要完成系统内部的创建订单功能,这里我们使用的是JPA主键一般都是自增的,这里需要注意不建议使用自增,支付宝没有相关校验,但是为了业务方便我们需要注意。
@ApiModel(description = “订单实体”)
@Entity
@Setter
@Getter
@Table(name = “tab_order”)
public class OrderEntity extends IdEntity implements Serializable {
private static final Logger logger = LoggerFactory.getLogger(OrderEntity.class);
private static final long serialVersionUID = 6555998898311764041L;
@Id
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name = "st_id", length = 32, insertable = false, updatable = false)
@JSONField(serializeUsing = ToStringSerializer.class)
private String id;
我这里使用的是 UUID 在新增订单的时候使用 UUID 插入。这里有个小问题需要注意(常规 UUID 生成的字符串是36位,我们需要去掉横杠将位数控制在32位,一般取消横杠后就是32位)
生成密钥
如果需要对接支付,支付宝会要求我们生成密钥与公钥文件,有了这些文件后我们就可以开始对接支付宝了。
对接支付
引入支付宝支付SDK
<!-- 支付宝sdk -->
<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.15.0.ALL</version>
</dependency>
以前准备就绪就可以对接支付了,这里我对接的是支付宝最新的密钥证书支付,功能是扫码支付。
这是相关配置
public class ApiURLConsts {
/**
* 支付宝APPID
*/
public static final String ALIPAY_APPID = "你的APPID";
/**
* 支付宝请求网关地址
*/
public static final String ALIPAY_URL = "https://openapi.alipay.com/gateway.do";
/**
* 回调地址
*/
public static String ALIPAY_NOTIFYURL = "http://www.XXX.com/XXXX/xxxx/pay/alipay/notify.json";
/**
* 私钥
*/
public static String RSA_PRIVATE_KEY = "你的私钥";
/**
* 支付宝返回格式
*/
public static final String ALIPAY_FORMAT = "json";
/**
* 支付宝编码
*/
public static final String ALIPAY_CHARSET = "UTF-8";
/**
* RSA2
*/
public static final String SIGNTYPE = "RSA2";
}
配置构建完毕后,这是支付对应请求的代码。
public JSONObject getAlipayOrderNo(OrderEntity entity) {
String orderStr = "";
try{
if (null != entity && PsopConstant.OrderStatus.INIT.equals(entity.getStatus())) {
//构造client
CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
//设置网关地址
certAlipayRequest.setServerUrl(ApiURLConsts.ALIPAY_URL);
//设置应用Id
certAlipayRequest.setAppId(ApiURLConsts.ALIPAY_APPID);
//设置应用私钥
certAlipayRequest.setPrivateKey(ApiURLConsts.RSA_PRIVATE_KEY);
//设置请求格式,固定值json
certAlipayRequest.setFormat(ApiURLConsts.ALIPAY_FORMAT);
//设置字符集
certAlipayRequest.setCharset(ApiURLConsts.ALIPAY_CHARSET);
//设置签名类型
certAlipayRequest.setSignType(ApiURLConsts.SIGNTYPE);
String path = Thread.currentThread().getContextClassLoader().getResource("").getPath();
//设置应用公钥证书路径
certAlipayRequest.setCertPath(path + "certpublickey/appCertPublicKey_2021002149618207.crt");
//设置支付宝公钥证书路径
certAlipayRequest.setAlipayPublicCertPath(path + "certpublickey/alipayCertPublicKey_RSA2.crt");
//设置支付宝根证书路径
certAlipayRequest.setRootCertPath(path + "certpublickey/alipayRootCert.crt");
//构造client
AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.precreate
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setOutTradeNo(entity.getId());
model.setTotalAmount(entity.getPrice());
//model.setSubject(entity.getGoodName());
//充值内容
model.setSubject("XXXXXXXXXXXXX");
request.setBizModel(model);
request.setNotifyUrl(ApiURLConsts.ALIPAY_NOTIFYURL);
AlipayTradePrecreateResponse response = alipayClient.certificateExecute(request);
//(1)服务端请求返回,RSA2密钥和公钥证书请求方式不同,如当面付
// RSA2密钥请求
// response = alipayClient.execute(request);
// 公钥证书请求请求
// response = alipayClient.certificateExecute(request);
// (2)网站类适用接口请求,RSA2密钥和公钥证书请求方式相同,如手机网站支付、电脑网站支付
// response = alipayClient.pageExecute(request);
// (3)客户端类适用接口请求请求,RSA2密钥和公钥证书请求方式相同,如app支付
// response = alipayClient.sdkExecute(request);
if(response.isSuccess()){
System.out.println("调用成功");
} else {
System.out.println("调用失败");
}
orderStr = response.getBody();
}
}catch (Exception ex){
ex.printStackTrace();
}
return JSONHelper.success(orderStr);
}
请求完毕后,还需要一个回调,这里需要注意上文配置类中的 ALIPAY_NOTIFYURL 该属性。这里是支付后的回调地址。来继续你后续的业务
@RequestMapping(value = "alipay/notify.json")
public void alipayNotify(HttpServletRequest request) {
System.out.println("收到支付宝回调");
// 获取支付宝POST过来反馈信息
try {
Map<String, String[]> parameterMap = request.getParameterMap();
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + Arrays.toString(entry.getValue()));
}
String[] trade_statuses = parameterMap.get("trade_status");
if (null != trade_statuses && trade_statuses.length > 0){
String tradestatuses = trade_statuses[0];
if (StringUtil.isNotBlank(tradestatuses)){
if (tradestatuses.equals("TRADE_SUCCESS")){
//交易支付成功。
String[] out_trade_nos = parameterMap.get("out_trade_no");
if (null != out_trade_nos && out_trade_nos.length > 0){
OrderEntity byId = orderService.findById(out_trade_nos[0]);
byId.setStatus(PsopConstant.OrderStatus.PAYED);
}
}else if (tradestatuses.equals("WAIT_BUYER_PAY")){
//交易创建,等待买家付款。
return;
}else if (tradestatuses.equals("TRADE_CLOSED")){
//未付款交易超时关闭,或支付完成后全额退款。
return;
}else if (tradestatuses.equals("TRADE_FINISHED")){
//交易结束,不可退款。
String[] out_trade_nos = parameterMap.get("out_trade_no");
if (null != out_trade_nos && out_trade_nos.length > 0){
OrderEntity byId = orderService.findById(out_trade_nos[0]);
byId.setStatus(PsopConstant.OrderStatus.PAYED);
}
return;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
我这里写的比较简单,只是处理了对应的交易状态。
最后只需要写好接口给前端调用就可以了。
整个支付宝交易对接到这里就结束了。