对接支付宝APP支付后端实现最详细教程
作者:互联网
前言
本人是java后端开发,这次是做一个支付宝APP支付的功能,所以在这里注重讲解后端的代码实现以及业务结构流程。
业务结构流程图
接入前准备
去支付宝获取以下信息https://open.alipay.com/platform/manageHome.htm
appid、应用私钥、支付宝公钥、支付宝网关路径
代码实现
1.首先是配置类AppPayConfig,以下有些信息来自支付宝账户,这个在上面已经提到如何去获取。
public class AppPayConfig {
/**
* 1.商户appid
*/
public String APPID = "";
/**
* 私钥 pkcs8格式的
*/
public static String RSA_PRIVATE_KEY ="";
/**
* 3.支付宝公钥
*/
public static String ALIPAY_PUBLIC_KEY = "";
/*
* 4.服务器异步通知页面路径
*/
//支付完成后,支付宝会通过这个url请求到你的服务端..
//这个url一定是要公网可以访问才行。如果是本地测试,就需要做内网穿透。
//也就是说这个路径是你自定义的,你所写的回调接口的路径。
public static String notify_url = "";
/**
* 5.页面跳转同步通知页面路径,这个暂时没有用到,有兴趣的小伙伴可以研究一下。
*/
//这里同上..不做详细说明了..
public static String return_url = "";
/**
* 正式环境支付宝网关,如果是沙箱环境需更改成https://openapi.alipaydev.com/gateway.do
*/
public static String URL = "https://openapi.alipay.com/gateway.do";
/**
* 7.编码格式
*/
public static String CHARSET = "UTF-8";
/**
* 私钥 pkcs8格式的
*/
// 8.返回格式
public static String FORMAT = "json";
/**
* //签名方式 加密类型
*/
public static String SIGNTYPE = "RSA2";
}
2.前端选择支付宝支付后需要调用的下订单接口。
@Value("${ali.config.app.id}")
private String appId;
@Value("${ali.config.gateway.url}")
private String gatewayUrl;
@Value("${ali.config.return.url}")
private String returnUrl;
@Value("${ali.config.notice.url}")
private String notifyUrl;
@Value("${ali.config.private.key}")
private String privateKey;
@Value("${ali.config.public.key}")
private String publicKey;
public String order(AlipayBean alipayBean) {
String orderString = "";//这个字符串是用来返回给前端的
//这行代码是生成一个商户的订单号..根据你们自己的业务需求去生成就可以了..
log.info("==================支付宝下单,商户订单号为:" + alipayBean.getOut_trade_no());
Long price = otherTooler.fetchPrice(alipayBean.getOut_trade_no(), alipayBean.getSession_id());
try {
//实例化客户端(参数:网关地址、商户appid、商户私钥、格式、编码、支付宝公钥、加密类型),为了取得预付订单信息
AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, appId,
privateKey, "json", "utf-8",
publicKey, "RSA2");
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
//业务参数传入,可以传很多,参考API
//model.setPassbackParams(URLEncoder.encode(request.getBody().toString())); //公用参数(附加数据)
//对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。
model.setBody(alipayBean.getBody());
//商品名称
model.setSubject(alipayBean.getSubject());
//商户订单号
model.setOutTradeNo(alipayBean.getOut_trade_no());
//交易超时时间 这里的30m就是30分钟
model.setTimeoutExpress("30m");
//支付金额 后面保留2位小数点..不能超过2位
// model.setTotalAmount(String.valueOf(BigDecimal.valueOf(price).divide(BigDecimal.valueOf(100),2,BigDecimal.ROUND_DOWN)));
model.setTotalAmount("0.01");
//销售产品码(固定值) //这个不做多解释..看文档api接口参数解释
model.setProductCode(alipayBean.getProduct_code());
alipayBean.setSession_id(alipayBean.getSession_id());
alipayBean.setUserId(alipayBean.getUserId());
alipayBean.setShopId(alipayBean.getShopId());
model.setPassbackParams(JSON.toJSONString(alipayBean));
ali_request.setBizModel(model);
//异步回调地址
ali_request.setNotifyUrl(notifyUrl);
log.info("====================异步通知的地址为:" + ali_request.getNotifyUrl());
//同步回调地址(APP)同上
ali_request.setReturnUrl(returnUrl);
log.info("====================同步通知的地址为:" + ali_request.getReturnUrl());
// 这里和普通的接口调用不同,使用的是sdkExecute
//返回支付宝订单信息(预处理)
AlipayTradeAppPayResponse alipayTradeAppPayResponse = alipayClient.sdkExecute(ali_request);
//就是orderString 可以直接给APP请求,无需再做处理。
orderString = alipayTradeAppPayResponse.getBody();
System.out.println(orderString);
} catch (AlipayApiException e) {
e.printStackTrace();
log.info("与支付宝交互出错,未能生成订单,请检查代码!");
}
return orderString;
}
3.在第2步将支付宝返回的信息原样返回给前端后,支付宝那边会处理并调用你传递过去的异步回调通知地址。然后这个接口去获取传递过来的数据,并做验签,然后可根据自己的业务来做后续的事情。
注意:我用支付宝提供的request . getParameterMap ()方法获取不到传递过来的参数,上网查了半天,发现用流的方法就可以获取到信息。在用流的方式时,一定要注意,不要少截取了信息,传递过来的信息全部都要截取出来。
public String alipayNotify(HttpServletRequest request) throws Exception {
//获取支付宝POST过来反馈信息
BufferedReader bufr =
new BufferedReader(
new InputStreamReader(request.getInputStream(), "UTF-8"));
StringBuilder sBuilder = new StringBuilder("");
String temp = "";
while ((temp = bufr.readLine()) != null) {
sBuilder.append(temp);
}
bufr.close();
System.out.println(sBuilder);
HashMap<String, String> hashMap = new HashMap<>();
String[] split = sBuilder.toString().split("&");
for (String str : split) {
String[] strings = str.split("=");
if (strings != null && strings.length == 2) {
hashMap.put(strings[0], URLDecoder.decode(strings[1], "UTF-8"));
}
}
log.info("支付宝支付结果通知:" + hashMap.toString());
log.info("支付宝返回交易参数: " + "out_trade_no : " + hashMap.get("out_trade_no"));
log.info("支付宝返回交易参数: " + "trade_no : " + hashMap.get("trade_no"));
log.info("支付宝返回交易参数: " + "trade_status : " + hashMap.get("trade_status"));
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
//计算得出通知验证结果
boolean verify_result = AlipaySignature.rsaCheckV1(hashMap, publicKey, "utf-8", "RSA2");
if (!verify_result) {
AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, appId, privateKey, "json", "utf-8", publicKey, "RSA2"); //获得初始化的AlipayClient
AlipayTradeCancelRequest requests = new AlipayTradeCancelRequest();//创建API对应的request类
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setOutTradeNo(hashMap.get("out_trade_no"));
requests.setBizModel(model);
AlipayTradeCancelResponse response = alipayClient.execute(requests);//通过alipayClient调用API,获得对应的response类
System.out.print(response.getBody());
//验证失败
return "fail";
} else {
//根据自己的业务所需去处理
}
}
return "success";
}
}
标签:支付宝,教程,String,ali,APP,model,public,alipayBean 来源: https://blog.csdn.net/ShanLanF/article/details/115068396