支付宝支付之App支付
Posted ning0628
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了支付宝支付之App支付相关的知识,希望对你有一定的参考价值。
与微信支付对比,支付宝支付就没有那么多坑了,毕竟支付宝开放平台的文档还是描述的很详细的。
支付宝开放平台地址:https://docs.open.alipay.com/204/105297/
支付宝支付的流程如下图所示:
项目中接入支付宝支付的步骤:
在这里分为了三个文件进行整理:
- 基础信息配置文件:AlipayConfig.java
- 调用API接口:AliPayUtil.java
- 对外接口:AlipayController.java
AlipayConfig.java
此文件中主要是配置了应用ID、支付宝公钥、应用密钥等基础信息,以及支付宝支付API提供的对外接口地址信息。
1 package com.xhgx.web.pay.aliPay; 2 3 import com.erenju.util.GlobleConfig; 4 5 /** 6 * 支付宝支付基础信息配置 7 * @author rxn 8 * @date 2018/04/25 9 */ 10 public class AlipayConfig { 11 12 /** 13 * 合作身份者ID,签约账号,16位纯数字 14 */ 15 public static String partner = "2088******"; 16 /** 17 * 收款支付宝账号,一般情况下收款账号是签约账号 18 */ 19 public static String seller_id = partner; 20 /** 21 * appid 22 */ 23 public static String app_id = "2018*****";//正式 24 // public static String app_id = "2016*****";//沙箱 25 /** 26 * MD5密钥,32位字符串 27 */ 28 public static String key = "******"; 29 /** 30 * 支付宝公钥 (使用工具生成) 31 */ 32 public static String public_key = "";//正式 33 /** 34 * 应用密钥 (特别长) 35 */ 36 public static String private_key = ""; 37 38 /** 39 * 服务器异步通知页面路径,需http://格式的完整路径,不能加自定义参数,必须外网可以正常访问 40 * 异步通知页面,就是接受支付宝支付结果返回信息的Contrller,可以处理自己的支付后的逻辑 41 */ 42 public static String notify_url = GlobleConfig.getProperty("PayNotifyUrl")+"/alipay/notify.json"; 43 /** 44 * 服务器同步通知页面路径,需http://格式的完整路径,不能加自定义参数,必须外网可以正常访问 45 * 同步通知页面,就是支付宝支付成功后页面跳转的url 46 */ 47 public static String return_url = GlobleConfig.getProperty("PayNotifyUrl")+"/alipay/return.json"; 48 /** 49 * 签名方式 ,(必须与生成密钥的签名方式一致) 50 */ 51 // public static String sign_type = "MD5"; 52 public static String sign_type = "RSA2"; 53 /** 54 * 日志文件 55 */ 56 public static String log_path = ""; 57 /** 58 * 字符编码格式 59 */ 60 public static String charset = "utf-8"; 61 /** 62 * 返回格式 63 */ 64 public static String format = "json"; 65 /** 66 * 支付类型 67 */ 68 public static String payment_type = "1"; 69 /** 70 * 支付宝网关(app支付接口) 71 */ 72 public static String AppPayUrl = "https://openapi.alipay.com/gateway.do";//线上 73 // public static String AppPayUrl = "https://openapi.alipaydev.com/gateway.do";//调试 74 }
AliPayUtil.java
此文件为工具类文件,实现了调用支付宝API的一些接口,下面的代码中主要粘了调用支付的接口。
1 package com.xhgx.web.pay.aliPay; 2 3 import java.net.URLEncoder; 4 import java.util.HashMap; 5 import java.util.LinkedHashMap; 6 import java.util.Map; 7 import org.activiti.engine.repository.Model; 8 import org.springframework.security.web.header.writers.frameoptions.StaticAllowFromStrategy; 9 import com.alipay.api.AlipayApiException; 10 import com.alipay.api.AlipayClient; 11 import com.alipay.api.DefaultAlipayClient; 12 import com.alipay.api.domain.AlipayTradeAppPayModel; 13 import com.alipay.api.request.AlipayTradeAppPayRequest; 14 import com.alipay.api.response.AlipayTradeAppPayResponse; 15 16 /** 17 * 支付宝支付调用API接口 18 * @author rxn 19 * @date 2018/04/28 20 * 21 */ 22 public class AliPayUtil { 23 24 /** 25 * 创建订单 26 * @param orderId 订单id 27 * @param total_amount 付款金额(单位:元) 28 * @return 29 * @throws AlipayApiException 30 */ 31 public static Map<String, Object> createOrder(String orderId,String total_amount) throws AlipayApiException{ 32 33 String orderStr = ""; 34 Map<String,Object> m = new HashMap<String, Object>(); 35 try { 36 //封装订单 37 Map<String, String> orderMap = new LinkedHashMap<String,String>(); 38 //公共参数 39 Map<String, String> bizModel = new LinkedHashMap<String,String>(); 40 41 //商品参数封装 42 orderMap.put("out_trade_no",orderId);//商户订单号,必填 43 orderMap.put("subject", "*****");//订单名称,必填 44 // orderMap.put("total_amount", total_amount);//付款金额,必填 45 orderMap.put("total_amount", 0.01+"");//付款金额,必填 46 orderMap.put("body", "");//商品描述,选填 47 orderMap.put("timeout_express", "30m");//超时时间,选填 48 orderMap.put("prodect_code", "QUICK_MSECURITY_PAY");//销售产品码 49 50 //公共参数封装 51 bizModel.put("app_id", AlipayConfig.app_id);//appId 52 bizModel.put("method", AlipayConfig.AppPayUrl);//请求网关地址 53 bizModel.put("format", AlipayConfig.format);//返回格式 54 bizModel.put("private_key", AlipayConfig.private_key);//密钥 55 56 //实例化客户端,只需要实例化一次即可 57 AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.AppPayUrl, AlipayConfig.app_id, AlipayConfig.private_key, "json", AlipayConfig.charset, AlipayConfig.public_key, AlipayConfig.sign_type); 58 //实例化具体API对应的request类,类名称和接口名称对应 59 AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest(); 60 61 //传入参数,sdk已经封装了公共参数,这里只需传入业务参数。 62 //以下方法是sdk的model入参方式(model和biz_content同时存在的情况下取biz_content) 63 AlipayTradeAppPayModel model = new AlipayTradeAppPayModel(); 64 // model.setPassbackParams(URLEncoder.encode(orderMap.get("body")));//公用回传参数,选填,UrlEncode之后才可以发送给支付宝。 65 model.setBody(orderMap.get("body"));//商品信息 66 model.setSubject(orderMap.get("subject"));//商品名称 67 model.setOutTradeNo(orderMap.get("out_trade_no"));//商品订单号 68 model.setTimeoutExpress(orderMap.get("timeout_express"));//交易超出时间 69 model.setTotalAmount(orderMap.get("total_amount"));//总金额 70 model.setProductCode(orderMap.get("prodect_code"));//销售产品码 71 model.setSellerId(AlipayConfig.seller_id);//支付宝用户id 72 ali_request.setBizModel(model); 73 ali_request.setNotifyUrl(AlipayConfig.notify_url);//回调地址 74 75 AlipayTradeAppPayResponse response = alipayClient.sdkExecute(ali_request); 76 orderStr = response.getBody(); 77 78 if(response.isSuccess()){ 79 m.put("result", orderStr); 80 m.put("code", 0); 81 m.put("msg", "订单生成成功"); 82 }else{ 83 m.put("code", 1); 84 m.put("msg", "订单生成失败"); 85 } 86 87 } catch (Exception e) { 88 // TODO: handle exception 89 m.put("code", 1); 90 e.printStackTrace(); 91 m.put("msg", "订单生成失败"); 92 } 93 94 return m; 95 } 96 }
AlipayController.java
此文件中主要是对外的异步通知接口,异步通知接口和同步通知接口性质是一样的,都是为了接收支付后平台返回的信息,下面的代码中只实现了异步通知接口。
1 package com.xhgx.web.pay.aliPay; 2 3 import java.util.Date; 4 import java.util.HashMap; 5 import java.util.Iterator; 6 import java.util.Map; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 import org.springframework.stereotype.Controller; 10 import org.springframework.web.bind.annotation.RequestMapping; 11 import org.springframework.web.bind.annotation.ResponseBody; 12 import com.alipay.api.AlipayApiException; 13 import com.alipay.api.internal.util.AlipaySignature; 14 import com.xhgx.service.PayNotifyTblService; 15 import com.xhgx.service.domain.PayNotifyTbl; 16 import com.xhgx.web.SpringContextUtil; 17 import common.Logger; 18 19 @Controller 20 public class AlipayController { 21 22 public static Logger log = Logger.getLogger(AlipayController.class); 23 24 /** 25 * 支付宝支付成功后,异步通知,回调该接口 26 * @param request 27 * @param response 28 * @return 29 */ 30 @ResponseBody 31 @RequestMapping("/alipay/notify.json") 32 public static String notifyUrl(HttpServletRequest request,HttpServletResponse response){ 33 log.info("支付宝支付:"+"异步通知"); 34 Map<String, String> params = new HashMap<String, String>(); 35 36 //1.从支付宝回调的request中取值 37 Map<String, String[]> requestParams = request.getParameterMap(); 38 39 for(Iterator<String> iter = requestParams.keySet().iterator();iter.hasNext();){ 40 String name = iter.next(); 41 String[] values = requestParams.get(name); 42 String valueStr = ""; 43 for(int i=0;i<values.length;i++){ 44 valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; 45 } 46 //乱码解决 47 // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk"); 48 params.put(name, valueStr); 49 } 50 51 //2.封装必须的参数 52 String out_trade_no = request.getParameter("out_trade_no"); 53 String orderType = request.getParameter("body"); 54 String tradeStatus = request.getParameter("trade_status"); 55 String app_id = request.getParameter("app_id"); 56 String trade_no = request.getParameter("trade_no");//支付宝交易号 57 String notify_time = request.getParameter("notify_time");//通知时间 58 String total_amount = request.getParameter("total_amount");//订单金额,单位元 59 60 //3.签名验证(对支付宝返回的数据验证,确定是支付宝返回的) 61 boolean signVerified = false; 62 //3.1调用SDK验证签名 63 try { 64 signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.public_key, AlipayConfig.charset,AlipayConfig.sign_type); 65 } catch (AlipayApiException e) { 66 // TODO Auto-generated catch block 67 e.printStackTrace(); 68 } 69 70 if(payNotifyTblService==null){ 71 payNotifyTblService= (PayNotifyTblService) SpringContextUtil.getBean(PayNotifyTblService.class); 72 } 73 74 //创建有一个对象,保存通知信息,根据业务需求来决定 75 PayNotifyTbl payNotifyTbl = new PayNotifyTbl(); 76 payNotifyTbl.setPay_type(2);//支付类型:2支付宝 77 payNotifyTbl.setCreate_dt(new Date()); 78 79 payNotifyTbl.setReturn_code(tradeStatus); 80 payNotifyTbl.setResult_code(tradeStatus); 81 82 //4.对验签进行处理 83 if(signVerified){ 84 if(tradeStatus.equals("TRADE_SUCCESS")){ 85 86 //支付成功,进行业务处理 87 88 payNotifyTbl.setAppid(app_id); 89 payNotifyTbl.setOrder_id(out_trade_no); 90 payNotifyTbl.setTotal_fee(Double.parseDouble(total_amount)); 91 payNotifyTbl.setTransaction_id(trade_no); 92 payNotifyTbl.setTime_end(notify_time); 93 payNotifyTbl.setPay_result("交易成功"); 94 95 payNotifyTbl = payNotifyTblService.save(payNotifyTbl); 96 97 return "success"; 98 }else{ 99 payNotifyTbl.setPay_result("参数有误"); 100 payNotifyTbl = payNotifyTblService.save(payNotifyTbl); 101 log.info("参数有误"); 102 return "fail"; 103 } 104 }else{ 105 payNotifyTbl.setPay_result("交易失败"); 106 payNotifyTbl = payNotifyTblService.save(payNotifyTbl); 107 log.info("交易失败"); 108 return "fail"; 109 } 110 }else{ 111 payNotifyTbl.setPay_result("验签失败"); 112 payNotifyTbl = payNotifyTblService.save(payNotifyTbl); 113 log.info("验签失败"); 114 return "fail"; 115 } 116 } 117 118 /** 119 * 支付宝支付成功后,同步通知 120 * @param request 121 * @param response 122 * @return 123 */ 124 @ResponseBody 125 @RequestMapping("/alipay/return.json") 126 public static String returnUrl(HttpServletRequest request,HttpServletResponse response){ 127 log.info("支付宝支付:"+"同步通知"); 128 129 130 131 return null; 132 } 133 }
以上是关于支付宝支付之App支付的主要内容,如果未能解决你的问题,请参考以下文章
wemall app商城源码Android之支付宝通知处理类
uniapp获取支付宝user_id - 支付宝提现 - 登录授权 - APP支付宝登陆 - H5支付宝授权