志不强者智不达,言不信者行不果。这篇文章主要讲述支付宝支付之App支付相关的知识,希望能为你提供帮助。
与微信支付对比,支付宝支付就没有那么多坑了,毕竟支付宝开放平台的文档还是描述的很详细的。
支付宝开放平台地址:https://docs.open.alipay.com/204/105297/
支付宝支付的流程如下图所示:
文章图片
文章图片
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*/ 15public static String partner = "2088******"; 16/** 17* 收款支付宝账号,一般情况下收款账号是签约账号 18*/ 19public static String seller_id = partner; 20/** 21* appid 22*/ 23public static String app_id = "2018*****"; //正式 24 //public static String app_id = "2016*****"; //沙箱 25/** 26* MD5密钥,32位字符串 27*/ 28public static String key = "******"; 29/** 30* 支付宝公钥 (使用工具生成) 31*/ 32public static String public_key = ""; //正式 33/** 34* 应用密钥 (特别长) 35*/ 36public static String private_key = ""; 37 38/** 39* 服务器异步通知页面路径,需http://格式的完整路径,不能加自定义参数,必须外网可以正常访问 40* 异步通知页面,就是接受支付宝支付结果返回信息的Contrller,可以处理自己的支付后的逻辑 41*/ 42public static String notify_url = GlobleConfig.getProperty("PayNotifyUrl")+"/alipay/notify.json"; 43/** 44* 服务器同步通知页面路径,需http://格式的完整路径,不能加自定义参数,必须外网可以正常访问 45* 同步通知页面,就是支付宝支付成功后页面跳转的url 46*/ 47public static String return_url = GlobleConfig.getProperty("PayNotifyUrl")+"/alipay/return.json"; 48/** 49* 签名方式 ,(必须与生成密钥的签名方式一致) 50*/ 51 //public static String sign_type = "MD5"; 52public static String sign_type = "RSA2"; 53/** 54* 日志文件 55*/ 56public static String log_path = ""; 57/** 58* 字符编码格式 59*/ 60public static String charset = "utf-8"; 61/** 62* 返回格式 63*/ 64public static String format = "json"; 65/** 66* 支付类型 67*/ 68public static String payment_type = "1"; 69/** 70* 支付宝网关(app支付接口) 71*/ 72public static String AppPayUrl = "https://openapi.alipay.com/gateway.do"; //线上 73 //public static String AppPayUrl = "https://openapi.alipaydev.com/gateway.do"; //调试 74 }
View Code【支付宝支付之App支付】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*/ 31public static Map< String, Object> createOrder(String orderId,String total_amount) throws AlipayApiException{ 32 33String orderStr = ""; 34Map< String,Object> m = new HashMap< String, Object> (); 35try { 36//封装订单 37Map< String, String> orderMap = new LinkedHashMap< String,String> (); 38//公共参数 39Map< String, String> bizModel = new LinkedHashMap< String,String> (); 40 41//商品参数封装 42orderMap.put("out_trade_no",orderId); //商户订单号,必填 43orderMap.put("subject", "*****"); //订单名称,必填 44 //orderMap.put("total_amount", total_amount); //付款金额,必填 45orderMap.put("total_amount", 0.01+""); //付款金额,必填 46orderMap.put("body", ""); //商品描述,选填 47orderMap.put("timeout_express", "30m"); //超时时间,选填 48orderMap.put("prodect_code", "QUICK_MSECURITY_PAY"); //销售产品码 49 50//公共参数封装 51bizModel.put("app_id", AlipayConfig.app_id); //appId 52bizModel.put("method", AlipayConfig.AppPayUrl); //请求网关地址 53bizModel.put("format", AlipayConfig.format); //返回格式 54bizModel.put("private_key", AlipayConfig.private_key); //密钥 55 56//实例化客户端,只需要实例化一次即可 57AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.AppPayUrl, AlipayConfig.app_id, AlipayConfig.private_key, "json", AlipayConfig.charset, AlipayConfig.public_key, AlipayConfig.sign_type); 58//实例化具体API对应的request类,类名称和接口名称对应 59AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest(); 60 61//传入参数,sdk已经封装了公共参数,这里只需传入业务参数。 62//以下方法是sdk的model入参方式(model和biz_content同时存在的情况下取biz_content) 63AlipayTradeAppPayModel model = new AlipayTradeAppPayModel(); 64 //model.setPassbackParams(URLEncoder.encode(orderMap.get("body"))); //公用回传参数,选填,UrlEncode之后才可以发送给支付宝。 65model.setBody(orderMap.get("body")); //商品信息 66model.setSubject(orderMap.get("subject")); //商品名称 67model.setOutTradeNo(orderMap.get("out_trade_no")); //商品订单号 68model.setTimeoutExpress(orderMap.get("timeout_express")); //交易超出时间 69model.setTotalAmount(orderMap.get("total_amount")); //总金额 70model.setProductCode(orderMap.get("prodect_code")); //销售产品码 71model.setSellerId(AlipayConfig.seller_id); //支付宝用户id 72ali_request.setBizModel(model); 73ali_request.setNotifyUrl(AlipayConfig.notify_url); //回调地址 74 75AlipayTradeAppPayResponse response = alipayClient.sdkExecute(ali_request); 76orderStr = response.getBody(); 77 78if(response.isSuccess()){ 79m.put("result", orderStr); 80m.put("code", 0); 81m.put("msg", "订单生成成功"); 82}else{ 83m.put("code", 1); 84m.put("msg", "订单生成失败"); 85} 86 87} catch (Exception e) { 88// TODO: handle exception 89m.put("code", 1); 90e.printStackTrace(); 91m.put("msg", "订单生成失败"); 92} 93 94return m; 95} 96 }
View CodeAlipayController.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 22public 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") 32public static String notifyUrl(HttpServletRequest request,HttpServletResponse response){ 33log.info("支付宝支付:"+"异步通知"); 34Map< String, String> params = new HashMap< String, String> (); 35 36//1.从支付宝回调的request中取值 37Map< String, String[]> requestParams = request.getParameterMap(); 38 39for(Iterator< String> iter = requestParams.keySet().iterator(); iter.hasNext(); ){ 40String name = iter.next(); 41String[] values = requestParams.get(name); 42String valueStr = ""; 43for(int i=0; i< values.length; i++){ 44valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; 45} 46//乱码解决 47 //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk"); 48params.put(name, valueStr); 49} 50 51//2.封装必须的参数 52String out_trade_no = request.getParameter("out_trade_no"); 53String orderType = request.getParameter("body"); 54String tradeStatus = request.getParameter("trade_status"); 55String app_id = request.getParameter("app_id"); 56String trade_no = request.getParameter("trade_no"); //支付宝交易号 57String notify_time = request.getParameter("notify_time"); //通知时间 58String total_amount = request.getParameter("total_amount"); //订单金额,单位元 59 60//3.签名验证(对支付宝返回的数据验证,确定是支付宝返回的) 61boolean signVerified = false; 62//3.1调用SDK验证签名 63try { 64signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.public_key, AlipayConfig.charset,AlipayConfig.sign_type); 65} catch (AlipayApiException e) { 66// TODO Auto-generated catch block 67e.printStackTrace(); 68} 69 70if(payNotifyTblService==null){ 71payNotifyTblService= (PayNotifyTblService) SpringContextUtil.getBean(PayNotifyTblService.class); 72} 73 74//创建有一个对象,保存通知信息,根据业务需求来决定 75PayNotifyTbl payNotifyTbl = new PayNotifyTbl(); 76payNotifyTbl.setPay_type(2); //支付类型:2支付宝 77payNotifyTbl.setCreate_dt(new Date()); 78 79payNotifyTbl.setReturn_code(tradeStatus); 80payNotifyTbl.setResult_code(tradeStatus); 81 82//4.对验签进行处理 83if(signVerified){ 84if(tradeStatus.equals("TRADE_SUCCESS")){ 85 86//支付成功,进行业务处理 87 88payNotifyTbl.setAppid(app_id); 89payNotifyTbl.setOrder_id(out_trade_no); 90payNotifyTbl.setTotal_fee(Double.parseDouble(total_amount)); 91payNotifyTbl.setTransaction_id(trade_no); 92payNotifyTbl.setTime_end(notify_time); 93payNotifyTbl.setPay_result("交易成功"); 94 95payNotifyTbl = payNotifyTblService.save(payNotifyTbl); 96 97return "success"; 98}else{ 99payNotifyTbl.setPay_result("参数有误"); 100payNotifyTbl = payNotifyTblService.save(payNotifyTbl); 101log.info("参数有误"); 102return "fail"; 103} 104}else{ 105payNotifyTbl.setPay_result("交易失败"); 106payNotifyTbl = payNotifyTblService.save(payNotifyTbl); 107log.info("交易失败"); 108return "fail"; 109} 110}else{ 111payNotifyTbl.setPay_result("验签失败"); 112payNotifyTbl = payNotifyTblService.save(payNotifyTbl); 113log.info("验签失败"); 114return "fail"; 115} 116} 117 118/** 119* 支付宝支付成功后,同步通知 120* @param request 121* @param response 122* @return 123*/ 124@ResponseBody 125@RequestMapping("/alipay/return.json") 126public static String returnUrl(HttpServletRequest request,HttpServletResponse response){ 127log.info("支付宝支付:"+"同步通知"); 128 129 130 131return null; 132} 133 }
View Code
推荐阅读
- Kotlin之let,apply,with,run函数区别(转)
- xcrun: error: unable to find utility "PackageApplication", not a developer tool or in PATH
- Android开发中常见的设计模式——单例模式
- ARC-100C - Linear Approximation
- spring基础----事件(Applicaition Event)
- Appium-实现手势密码登陆
- 012_call和apply区别
- ApplicationListener接口的生命周期
- CS:APP CH01.A Tour of Computer Systems