该文章主要讲述支付宝账号、秘钥申请以后,接口对接部分,如要申请账号,请到官网https://www.alipay.com/
下面通过两部分来跟支付宝对接,第一部分是申请调用支付宝,前端页面发起请求,后台接口进行处理,生成一个form表单给页面,页面直接调用支付宝;第二部分是支付宝异步通知结果,后台接口直接接收。
请求接口:
public String aliPayRequest(OrderPay orderPay, HttpServletResponse response) { //调用支付宝请求 AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE); AlipayTradeWapPayRequest alipay_request=new AlipayTradeWapPayRequest(); // 封装请求支付信息 alipay_request.setBizContent("{" + " \"out_trade_no\":\""+orderPay.getOrder_id()+"\"," + " \"total_amount\":\""+orderPay.getActual_amount()+"\"," + " \"subject\":\"门票\"," + " \"product_code\":\"QUICK_WAP_WAY\"" + " }");//填充业务参数 // 设置异步通知地址 alipay_request.setNotifyUrl(AlipayConfig.notify_url); // 设置同步地址 这个没有 alipay_request.setReturnUrl(AlipayConfig.return_url); log.info("调用支付宝请求:"+ JSON.toJSONString(alipay_request)); // form表单生产 String form = ""; try { // 调用SDK生成表单 form = client.pageExecute(alipay_request).getBody(); response.setContentType("text/html;charset=" + AlipayConfig.CHARSET); response.getWriter().write(form);//直接将完整的表单html输出到页面 response.getWriter().flush(); response.getWriter().close(); }catch(Exception e) { log.error(e.getMessage()); throw new CustomException(e.getMessage()); } return ""; }
异步回调接口:
@ResponseBody @RequestMapping(value = "/spotOrder/receiveFromAlipay") public void receiveFromAlipay(HttpServletRequest request, HttpServletResponse response) throws IOException { log.info("##################进入SpotOrderController的receiveFromAlipay方法####################"); String result = "fail"; BaseResult<OrderPay> baseResult = new BaseResult<OrderPay>(); try { 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不相等也可以使用这段代码转化 // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk"); params.put(name, valueStr); } log.info("params:" + params.toString()); // if (params.get("trade_status")==null) { // log.info("fail"); // return "fail"; // } // 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)// // 商户订单号 String out_trade_no = new // String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8"); // 支付宝交易号 String trade_no = new // String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8"); result = alipayService.receiveFromAlipay(params); }catch(Exception e) { log.error(e.getMessage()); } response.setCharacterEncoding("utf-8"); PrintWriter writer = null; try { writer = response.getWriter(); writer.write(result); } catch (Exception e) { e.printStackTrace(); } finally { writer.flush(); writer.close(); writer = null; } }
public String receiveFromAlipay(Map<String, String> params) { log.info("##################进入支付回调##################"); log.info("支付宝回调参数:"+JSON.toJSONString(params)); try { boolean signVerified; signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, params.get("charset"), params.get("sign_type"));// 验证成功 if (signVerified) { log.info("验签成功!"); OrderPay orderPay = new OrderPay(); orderPay.setOrder_id(params.get("out_trade_no")); log.info("orderPay!"+JSON.toJSONString(orderPay)); OrderPay orderPayResult = orderPayMapper.selectInfoByParams(orderPay); log.info("orderPayResult:"+JSON.toJSONString(orderPayResult)); // 商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号 if(orderPayResult == null) { log.info("商户订单号不正确,支付失败!订单号为"+orderPay.getOrder_id()); throw new CustomException("商户订单号不正确,支付失败!订单号为"+orderPay.getOrder_id()); } String trade_status = params.get("trade_status"); //插入流水表 OrderPay insert_orderPayList = new OrderPay(); insert_orderPayList.setActual_amount(Double.parseDouble(params.get("total_amount"))); insert_orderPayList.setOrder_id(orderPay.getOrder_id()); insert_orderPayList.setPay_method("301"); insert_orderPayList.setTimestamp(DateUntils.getCurrentDateString("yyyy-MM-dd HH:mm:ss")); insert_orderPayList.setTotal_amount(Double.parseDouble(params.get("total_amount"))); insert_orderPayList.setTrade_no(params.get("trade_no")); OrderPay orderPayRefund = new OrderPay(); orderPayRefund.setOrder_id(orderPay.getOrder_id()); orderPayRefund.setTimestamp(DateUntils.getCurrentDateString("yyyy-MM-ss HH:mm:ss")); orderPayRefund.setTrade_no(params.get("trade_no")); String refund_fee = params.get("refund_fee"); //refund_fee为空时,代表支付,不为空时代表退单 if(refund_fee==null||"".equals(refund_fee)){ log.info("进入支付返回。。。"); //trade_finished支付成功,不支持退款。trade_success支付成功,支持退款,trade_close支付超时,交易关闭 if(trade_status.equals("TRADE_FINISHED")||trade_status.equals("TRADE_SUCCESS")){ insert_orderPayList.setPay_status(PayStatus.PAYSUCCESS+""); //修改退单表状态 orderPayRefund.setPay_status(PayStatus.PAYSUCCESS.getCode()+""); spotOrderService.payCallBack("SUCCESS",orderPay.getOrder_id(),"301"); //支付成功,支付状态修改以及支付回调 } }else{ log.info("return true:"+trade_status); if (trade_status.equals("TRADE_CLOSED") || trade_status.equals("TRADE_SUCCESS")) { insert_orderPayList.setPay_status(PayStatus.REFUNDSUCCESS.getCode() + ""); //修改退单表状态 orderPayRefund.setPay_status(PayStatus.REFUNDSUCCESS.getCode() + ""); spotOrderService.refundBack(orderPay.getOrder_id()); } } int updateByOrderId = orderPayMapper.updateByOrderId(orderPayRefund); if(updateByOrderId<0) { log.error("修改支付表失败"); throw new CustomException("修改支付表失败"); } int insert_orderPayListResult = orderPayListMapper.insert_orderPayList(insert_orderPayList); if(insert_orderPayListResult<0) { log.info("添加流水信息失败"); } // 返回支付宝已经接收成功!当为success时 // response.getWriter().write("failure"); // ——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— return "success"; } else { // 验证失败 return "fail"; } }catch(Exception e) { e.printStackTrace(); log.info(e.getMessage()); return "fail"; } }
支付宝退款部分请求:
public BaseBean refund(RefundOrderVO refundOrderVO) { log.info("#######################进入通用退款#######################"); log.info("通用退款入参为:" + JSON.toJSONString(refundOrderVO)); BaseBean baseBean = new BaseBean(); String WIDout_trade_no = refundOrderVO.getOrder_id(); //商户订单号 String WIDtrade_no = "";//支付宝交易号 String WIDrefund_amount = refundOrderVO.getTotal_price()+"";//退款金额 String WIDrefund_reason = "";//退款的原因说明 String WIDout_request_no = ""; if(WIDout_trade_no!=null || WIDtrade_no != null){ OrderPay orderPay = new OrderPay(); //修改支付表 orderPay.setOrder_id(refundOrderVO.getOrder_id()); orderPay.setPay_status(PayStatus.INREFUND.getCode()+""); orderPay.setTimestamp(DateUntils.getCurrentDateString("yyyy-MM-dd HH:mm:ss")); log.info("插入支付表的数据为"+JSON.toJSONString(orderPay)); try { //商户订单号和支付宝交易号不能同时为空。 trade_no、 out_trade_no如果同时存在优先取trade_no //商户订单号,和支付宝交易号二选一 String out_trade_no = new String(WIDout_trade_no.getBytes("ISO-8859-1"),"UTF-8"); //支付宝交易号,和商户订单号二选一 String trade_no = new String(WIDtrade_no.getBytes("ISO-8859-1"),"UTF-8"); //退款金额,不能大于订单总金额 String refund_amount=new String(WIDrefund_amount.getBytes("ISO-8859-1"),"UTF-8"); //退款的原因说明 String refund_reason=new String(WIDrefund_reason.getBytes("ISO-8859-1"),"UTF-8"); //标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传。 String out_request_no=new String(WIDout_request_no.getBytes("ISO-8859-1"),"UTF-8"); /**********************/ // SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签 AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE); AlipayTradeRefundRequest alipay_request = new AlipayTradeRefundRequest(); alipay_request.setBizContent("{" + "\"out_trade_no\":\"" +out_trade_no+"\","+ "\"refund_amount\":\"" +refund_amount+"\"}"); log.info("发送请求之前============"); AlipayTradeRefundResponse alipay_response =client.execute(alipay_request); log.info("支付宝退款申请 返回:body--\r\n" + alipay_response.getBody()); log.info("支付宝退款申请 返回:alipay_response--\r\n" + alipay_response); AlipayTradeRefund alipayTradeRefundResponse = JSONObject.parseObject(alipay_response.getBody(), AlipayTradeRefund.class); String alipay_trade_refund_response = alipayTradeRefundResponse.getAlipay_trade_refund_response(); Map innerMap = JSONObject.parseObject(alipay_trade_refund_response,Map.class); if(innerMap.get("code").equals("10000")) { baseBean.setStatus(1); }else{ baseBean.setStatus(0); } //查询退单状态是否为已退单 OrderPay orderPayResultInfo = orderPayMapper.selectInfoByParams(orderPay); log.info("进入退单返回。。。"+orderPayResultInfo.getPay_status()+"--------------"+PayStatus.INREFUND.getCode()); if(!orderPayResultInfo.getPay_status().equals(PayStatus.REFUNDSUCCESS.getCode()+"")){ int updateOrderPay = orderPayMapper.updateByOrderId(orderPay); if(updateOrderPay < 0) { log.error("数据库修改失败,orderpay:"+JSON.toJSONString(orderPay)); throw new CustomException("数据库修改失败,orderpay:"+JSON.toJSONString(orderPay)); } //插入支付流水表 int insert_orderPayList = orderPayListMapper.insert_orderPayList(orderPay); if(insert_orderPayList<0) { log.error("数据库插入失败,orderpayList:"+JSON.toJSONString(orderPay)); throw new CustomException("数据库插入失败,orderpayList:"+JSON.toJSONString(orderPay)); } } }catch (Exception e) { log.error(e.getMessage()); log.error("#############调用支付宝退款申请失败###############"); } } else { log.error("#############退款申请参数有误 无:" + WIDtrade_no + "为空###############"); throw new CustomException("退款申请参数有误"); } log.info("######################退出通用退款#######################"); return baseBean; }
支付款回调部门同支付回调是同一个