赞
踩
前几天写了微信支付,附上链接 https://blog.csdn.net/qq_43494610/article/details/90411391 ,今天抽了个时间把支付宝支付补上。
二、支付宝
首先附上支付宝支付的api地址 https://docs.open.alipay.com/api_1/alipay.trade.fastpay.refund.query
在这里我们使用的事沙箱环境,具体的沙箱环境使用方法官方文档里面都有说明, 这里就不一一解释了。附上官方文档链接 https://docs.open.alipay.com/200/105310/
先说下支付宝支付的自我总结:在看支付宝支付文档可以看到有一个<统一收单线下交易预创建>接口,在调用此接口的时候回生成一个支付二维码路径,用户打开自己的支付宝扫一扫支付,如果是用这个接口的话就跟微信支付流程差不多,需要前端定时去查询订单状态,自我感觉此接口对我们服务端的压力不小。在这里我并没有使用这个接口,用的是<统一收单下单并支付页面接口>,此接口在用户发起支付请求后会给前端返回一段html代码,前端把这段代码展示在页面,这是支付宝自己定义的一个页面,中间有一个二维码,此二维码就是用户支付的二维码,用户可以选择扫码支付也可以登录支付宝账户支付,支付成功后会跳转一个我们在后台设置的页面,也就是支付成功需要返回的我们自己的页面。如下图:
在使用沙箱环境测试支付时,必须下载专门的沙箱app,不然扫码会提示二维码已失效。沙箱app用着会有一些难受,不过看着自己的余额是真的舒服。在测试支付时,由于用的是沙箱环境,会有一些bug,比如支付成功没有返回商户页面,这些在换成正式环境会解决。
下面是具体的实现代码:
1.Controller层
@ApiOperation("支付宝统一收单下单并支付页面接口")
@PostMapping(value="/alipay")
public Result alipay(HttpServletResponse response,WeChatParams ps) throws AlipayApiException, IOException {
return tbPaymentRecordService.alipay(response,ps);
}
2.Service层
/**
* 支付宝预下单接口
* @param ps
* @return
* @throws AlipayApiException
*/
Result alipay(HttpServletResponse response,WeChatParams ps) throws AlipayApiException, IOException;
3.Impl
@Override public Result alipay(HttpServletResponse response,WeChatParams ps) throws AlipayApiException, IOException { AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "JSON", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type); //获得初始化的AlipayClient AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request alipayRequest.setReturnUrl(AlipayConfig.return_url); alipayRequest.setNotifyUrl(AlipayConfig.notify_url);//在公共参数中设置回跳和通知地址 //获取需要的参数 String numberCode = getNumberCode(); String orderId = getNumberCode(); Long doctorId = Login.userId(); TbPaymentAmount tbPaymentAmount = new TbPaymentAmount().selectById(ps.getAmountId()); //参数封装,具体参数看官方文档 alipayRequest.setBizContent("{" + " \"out_trade_no\":\"" + numberCode + "\"," + " \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," + " \"total_amount\":" + tbPaymentAmount.getAmount() + "," + " \"subject\":\"服务充值\"," + " \"body\":\"服务充值\"," + " \"passback_params\":\"merchantBizType%3d3C%26merchantBizNo%3d2016010101111\"," + " \"timeout_express\":\"1m\"," + " \"extend_params\":{" + //" \"sys_service_provider_id\":\"2088511833207846\"" + " }"+ " }");//填充业务参数 //在这里执行自己的业务逻辑,生成订单信息,此时订单是未支付状态 String form=""; try { form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单 } catch (AlipayApiException e) { e.printStackTrace(); } //这一段代码是把结果放到response里面返回给前端,这里因为我们前端的问题所以把这里注掉了,用的是return返回,这个看个人选择,response和return二选一 /*response.setContentType("text/html;charset=" + AlipayConfig.charset); response.getWriter().write(form);//直接将完整的表单html输出到页面 response.getWriter().flush(); response.getWriter().close();*/ return Result.success(form); }
/** * 生成订单号 当前时间+8位随机码 * * @return */ public static String getNumberCode() { DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); Calendar calendar = Calendar.getInstance(); String date = df.format(calendar.getTime()); Random random = new Random(); String str = random.nextInt(100000) + ""; while (str.length() < 8) { str = "1" + str; } return date + str; }
下面是用到的工具类
/* * *类名:AlipayConfig *功能:基础配置类 *详细:设置帐户有关信息及返回路径 *修改日期:2017-04-05 *说明: *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。 *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。 */ public class AlipayConfig { // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号 public static String app_id = ""; // 商户私钥,您的PKCS8格式RSA2私钥 public static String merchant_private_key = ""; // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。 public static String alipay_public_key = ""; // 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 public static String notify_url = ""; // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 public static String return_url = ""; // 签名方式 public static String sign_type = "RSA2"; // 字符编码格式 public static String charset = "utf-8"; // 支付宝网关 public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do"; // 支付宝网关 public static String log_path = "C:\\"; }
里面的app_id 是你在创建好沙箱应用生成的
merchant_private_key 是你的商户私钥,详见 https://docs.open.alipay.com/291/105971
alipay_public_key是在你把私钥输进去后,点击这即可看见
notify_url 是你的回调地址,必须是公网可以访问,如果没有服务器的话可以下载一个内网穿透,具体使用方法就不多说了
return_url 是用户在支付成功后要返回的页面
下面是支付回调相关代码
1.Controller层
/**
* 支付宝支付成功回调
*/
@ApiOperation("支付宝支付回调")
@PostMapping("/aliPayCallBack.do")
public void aliPayCallBack(HttpServletResponse response, HttpServletRequest request) throws AlipayApiException {
tbPaymentRecordService.aliPayCallBack(response, request);
}
2.Service层
/**
* 支付宝支付回调
* @param response
* @param request
*/
void aliPayCallBack(HttpServletResponse response, HttpServletRequest request);
3.Impl层
@Override public void aliPayCallBack(HttpServletResponse response, HttpServletRequest request) { try { //获取支付宝POST过来反馈信息 Map<String,String> params = new HashMap<String,String>(); Map requestParams = request.getParameterMap(); for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) { String name = (String) iter.next(); String[] values = (String[]) requestParams.get(name); String valueStr = ""; for (int i = 0; i < values.length; i++) { valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; } //乱码解决,这段代码在出现乱码时使用。 //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); params.put(name, valueStr); } boolean flag = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset,"RSA2"); // 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)// String order_no = request.getParameter("out_trade_no"); // 获取订单号 String trade_no = request.getParameter("trade_no"); // 支付宝交易凭证号 String pay_amount = request.getParameter("buyer_pay_amount"); String trade_status = request.getParameter("trade_status"); // 交易状态 // 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)// if (flag==true) {// 验证成功 TbOrder tb = tbOrderDao.selectTbOrderByOrderNo(order_no); try{ if (trade_status.equals("TRADE_SUCCESS")) { //这里执行支付成功的业务逻辑 System.out.println("支付宝订单支付成功!"); } if (trade_status.equals("WAIT_BUYER_PAY")) { System.out.println("订单创建成功!"); } response.getWriter().write("success"); }catch (Exception e) { //这里执行支付失败的业务逻辑 System.out.println("支付宝支付异常"); e.printStackTrace(); } response.getWriter().write("failure"); } } catch (Exception e) { e.printStackTrace(); } }
上面就是支付宝扫码支付全部的代码了,有什么遗漏的地方可以在下面评论,我会在第一时间补充。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。