支付宝支付退单接口对接demo

该文章主要讲述支付宝账号、秘钥申请以后,接口对接部分,如要申请账号,请到官网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;
}

支付款回调部门同支付回调是同一个

猜你喜欢

转载自blog.csdn.net/u010810559/article/details/84989038