最近太忙了,天天加班,没有空打理博客,今天分享一下springboot做支付宝支付
首先用maven加载官方的包,公司这里有自己的maven仓库,使用Nexus搭建的,之后在分享Nexus搭建
公司有maven仓库的做法
<dependency> <groupId>com.alipay.api</groupId> <artifactId>alipay-sdk-java</artifactId> <version>20170324180803</version> </dependency>
如你没有maven仓库,那就直接加载jar包
<dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-sdk-java</artifactId> <version>1.0.0</version> <scope>system</scope> <type>jar</type> <systemPath>${pom.basedir}/libs/alipay-sdk-java20161213173952.jar</systemPath> </dependency>
pom.xml同目录下新建一个libs文件夹,把支付宝的sdk放到这个文件夹里
我这里的支付宝支付是使用接口的方式,思路:
请求接口的时候,需要一个订单号参数和return_url地址(支付成之后跳转的链接),接口返回支付宝的支付的url地址
还需要一个接口执行接受支付宝的异步回调通知
支付宝配置文件
@ConfigurationProperties(prefix = "alipay") @Data @Component public class AliPayConfig { /** * 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号 */ private String appID; /** * 商户私钥,您的PKCS8格式RSA2私钥 */ private String merchantPrivateKey; /** * 支付宝公钥 */ private String alipayPublicKey; /** * 签名方式 */ private String signType="RSA2"; /** * 网关 */ private String gatewayUrl="https://openapi.alipay.com/gateway.do"; /** * 编码 */ private String charset= "utf-8"; /** * 异步通知地址 */ private String notifyUrl=""; /** * 类型 */ private String format="json"; /** * 商户号 */ private String sysServiceProviderId="1234"; }
添加配置项目application.yml
alipay: appID: 2016091200494055 merchantPrivateKey: 商户私钥 alipayPublicKey: 支付宝公钥 gatewayUrl: https://openapi.alipaydev.com/gateway.do sysServiceProviderId: 1234 notifyUrl: http://XXXX.com
生成支付链接
@RequestMapping("/pay") public class AliPayController { @Autowired AliPayConfig aliPayConfig; @PostMapping("/alipayUrl") public ResponseEntity doPost(@Valid @RequestBody AliPayFormVo aliPayFormVo) throws ServletException, IOException { AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getGatewayUrl(), aliPayConfig.getAppID(), aliPayConfig.getMerchantPrivateKey(), aliPayConfig.getFormat(), aliPayConfig.getCharset(), aliPayConfig.getAlipayPublicKey(), aliPayConfig.getSignType()); //获得初始化的AlipayClient AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request alipayRequest.setReturnUrl(aliPayFormVo.getReturnUrl()); alipayRequest.setNotifyUrl(aliPayConfig.getNotifyUrl());//在公共参数中设置回跳和通知地址 String subject=productDTO.getPname(); alipayRequest.setBizContent("{" + " \"out_trade_no\":\""+【商户订单号】+"\"," + " \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," + " \"total_amount\":"+【支付金额】+"," + " \"subject\":\""+【商品名称】+"\"," + " \"body\":\""+【商品介绍】+"\"," + " \"extend_params\":{" + " \"sys_service_provider_id\":\""+aliPayConfig.getSysServiceProviderId()+"\"" + " }"+ " }");//填充业务参数 String payUrl = ""; try { #这里使用GET的方式,这样就能生成支付链接 payUrl = alipayClient.pageExecute(alipayRequest, "GET").getBody(); //调用SDK生成表单 } catch (AlipayApiException e) { e.printStackTrace(); } Map<String,String> map=new HashMap<>(); map.put("payUrl",payUrl); return ResultUtil.success(map); } }
支付异步回调
/** * 支付宝支付异步回调 * * @param request * @return */ @RequestMapping("/alipayNotify") public void alipayNotify(HttpServletRequest request, HttpServletResponse response) { System.err.println("支付宝进入异步通知"); String resultFail = "fail"; String resultSuccess = "success"; 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] + ","; } //乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化 /*try { valueStr = new String(valueStr.getBytes("ISO-8859-1"), "GBK"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); }*/ params.put(name, valueStr); } log.info("params={}", params); boolean signVerified = false; //调用SDK验证签名 try { signVerified = AlipaySignature.rsaCheckV1(params, aliPayConfig.getAlipayPublicKey(), aliPayConfig.getCharset(), aliPayConfig.getSignType()); } catch (AlipayApiException e) { log.error("【支付宝异步通知】支付宝回调通知失败 e={} params={}", e, params); responseBody(response, resultFail); return; //e.printStackTrace(); } if (!signVerified) { log.error("【支付宝异步通知】验证签名错误 params={} ", params); responseBody(response, resultFail); return; } BigDecimal trade_price = new BigDecimal(request.getParameter("total_amount")); //商户订单号 String out_trade_no = params.get("out_trade_no"); //支付宝交易号 String trade_no = params.get("trade_no"); //交易状态 String trade_status = params.get("trade_status"); // 支付成功修改订单状态 if (trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")) { //业务处理,主要是更新订单状态 } log.error("【支付宝异步通知】支付宝状态错误 params={} ", params); responseBody(response, resultFail); return; } private void responseBody(HttpServletResponse response, String contentBody) { try { response.setContentType("type=text/html;charset=UTF-8"); String s = contentBody; response.getWriter().write(s); } catch (Exception e) { e.printStackTrace(); } return; }
做这个功能遇到的坑,就是异步回调的时候编码有问题,支付宝demo里有解决编码的问题,加上去不能接口问题,后来不知道怎么就好了