支付宝沙箱支付、退款

本文包括支付宝沙箱支付及退款功能

前期查看相关网页:
https://blog.csdn.net/weixin_44520739/article/details/89214609
http://www.3qphp.com/java/framework/3306.html
https://blog.csdn.net/qq_21179737/article/details/80407294

支付宝文档:https://docs.open.alipay.com/291/106103/

支付宝文档中心:https://docs.open.alipay.com/catalog

开发者中心:https://developers.alipay.com/platform/appDaily.htm?tab=info


设置密钥

不用非得选他推荐的那种方式

设置后就有应用公钥和支付宝公钥了


这两部分需要放到代码中




一、引入maven依赖

com.alipay.sdk

alipay-sdk-java

3.3.49.ALL

二、代码,建议不要在网页上观看,拉到IDE上看效果更好。

@Controller

public class ClientPayController {

@Autowired

    private OrderServiceorderService;

    @Autowired

    private OrderItemServiceorderItemService;

    //应用的APPID,收款账号即是APPID对应支付宝账号

    private final StringAPP_ID ="";

    //生成的应用私钥

    private final StringAPP_PRIVATE_KEY ="";

    private final StringCHARSET ="UTF-8";

    //支付宝公钥

    private final StringALIPAY_PUBLIC_KEY ="";

    //这是沙箱接口路径,正式路径为https://openapi.alipay.com/gateway.do

    private final StringGATEWAY_URL ="https://openapi.alipaydev.com/gateway.do";

    private final StringFORMAT ="JSON";

    //签名方式

    private final StringSIGN_TYPE ="RSA2";

    //支付宝异步通知路径,付款完毕后会异步调用本项目的方法,必须为公网地址

//    private final String NOTIFY_URL = "http://192.168.0.101:8080/notifyUrl";

//支付宝同步通知路径,也就是当付款完毕后跳转本项目的页面,可以不是公网地址

    private final StringRETURN_URL ="http://127.0.0.1:8080/returnUrl";

    @CrossOrigin(allowCredentials="true")//用来保存session,第一次登陆时不管用,第二次就可以了,我也不知道为啥

@RequestMapping("alipay")

public void alipay(HttpServletResponse httpResponse,int oid,float total)throws IOException {

Random r =new Random();

        //实例化客户端,填入所需参数

        AlipayClient alipayClient =new DefaultAlipayClient(GATEWAY_URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);

        AlipayTradePagePayRequest request =new AlipayTradePagePayRequest();

        //在公共参数中设置回跳和通知地址

        request.setReturnUrl(RETURN_URL);

//        request.setNotifyUrl(NOTIFY_URL);

        Order order =orderService.get(oid);

        OrderItem orderItem =orderItemService.getOrderItem(order);

        //商户订单号,商户网站订单系统中唯一订单号,必填

//订单id

        String out_trade_no = order.getOrderCode();

        //付款金额,必填

        String total_amount = Float.toString(total);

        //订单名称,必填

        String subject = orderItem.getProduct().getName();

        //商品描述,可空

        String body = orderItem.getProduct().getSubTitle();

        request.setBizContent("{\"out_trade_no\":\"" + out_trade_no +"\","

                +"\"total_amount\":\"" + total_amount +"\","

                +"\"subject\":\"" + subject +"\","

                +"\"body\":\"" + body +"\","

                +"\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        String form ="";

        try {

form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单

        }catch (AlipayApiException e) {

e.printStackTrace();

        }

httpResponse.setContentType("text/html;charset=" +CHARSET);

        httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面

        httpResponse.getWriter().flush();

        httpResponse.getWriter().close();

    }

@CrossOrigin(allowCredentials="true")

@RequestMapping(value ="/returnUrl", method = RequestMethod.GET)

public StringreturnUrl(HttpServletRequest request, HttpServletResponse response)

throws IOException, AlipayApiException {

System.out.println("=================================同步回调=====================================");

        // 获取支付宝GET过来反馈信息

        Map params =new HashMap();

        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("utf-8"), "utf-8");

            params.put(name, valueStr);

        }

System.out.println(params);//查看参数都有哪些

        boolean signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE); // 调用SDK验证签名

//验证签名通过

        if (signVerified) {

// 商户订单号

            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");

            // 付款金额

            String total_amount =new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");

            System.out.println("商户订单号=" + out_trade_no);

            System.out.println("支付宝交易号=" + trade_no);

            System.out.println("付款金额=" + total_amount);

            //支付成功,修复支付状态

//payService.updateById(Integer.valueOf(out_trade_no));

            Order order =orderService.getByOrderCode(out_trade_no).get(0);

            order.setStatus("waitDelivery");

            order.setAliCode(trade_no);

            orderService.add(order);

            return "fore/payed";//跳转付款成功页面

        }else {

return "支付失败";//跳转付款失败页面

        }

}

@CrossOrigin(allowCredentials="true")

@RequestMapping(value ="/notifyUrl", method = RequestMethod.POST)

public void notifyUrl(HttpServletRequest request, HttpServletResponse response)

throws AlipayApiException, IOException {

System.out.println("#################################异步回调######################################");

        // 获取支付宝POST过来反馈信息

        Map params =new HashMap();

        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);

        }

System.out.println(params);

        boolean signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE); // 调用SDK验证签名

// ——请在这里编写您的程序(以下代码仅作参考)——

/*

* 实际验证过程建议商户务必添加以下校验: 1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,

* 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额), 3、校验通知中的seller_id(或者seller_email)

* 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)

* 4、验证app_id是否为该商户本身。

*/

        if (signVerified) {// 验证成功

// 商户订单号

            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");

            // 交易状态

            String trade_status =new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");

            System.out.println("商户订单号="+out_trade_no);

            System.out.println("支付宝交易号="+trade_no);

            System.out.println("交易状态="+trade_status);

            if (trade_status.equals("TRADE_FINISHED")) {

// 判断该笔订单是否在商户网站中已经做过处理

// 如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序

// 如果有做过处理,不执行商户的业务程序

// 注意:

// 退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知

            }else if (trade_status.equals("TRADE_SUCCESS")) {

// 判断该笔订单是否在商户网站中已经做过处理

// 如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序

// 如果有做过处理,不执行商户的业务程序

// 注意:

// 付款完成后,支付宝系统发送该交易状态通知

            }

System.out.println("异步回调验证成功");

            response.getWriter().write("success");

        }else {// 验证失败

            System.out.println("异步回调验证失败");

            response.getWriter().write("fail");

            // 调试用,写文本函数记录程序运行情况是否正常

// String sWord = AlipaySignature.getSignCheckContentV1(params);

// AlipayConfig.logResult(sWord);

        }

response.getWriter().flush();

        response.getWriter().close();

    }

//退款

    @CrossOrigin(allowCredentials="true")

@RequestMapping(value ="/refund", method = RequestMethod.GET)

public Stringrefund(HttpServletResponse httpResponse,HttpServletResponse response,HttpSession session,String oid)throws IOException, AlipayApiException {

response.setContentType("text/html;charset=utf-8");

        PrintWriter out = response.getWriter();

        //获得初始化的AlipayClient

        AlipayClient alipayClient =new DefaultAlipayClient(GATEWAY_URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);

        //设置请求参数

        AlipayTradeRefundRequest alipayRequest =new AlipayTradeRefundRequest();

        Order order=orderService.get(Integer.parseInt(oid));

        OrderItem orderItem =orderItemService.getOrderItem(order);

        //商户订单号,必填

        String out_trade_no =new String(order.getOrderCode());

        //需要退款的金额,该金额不能大于订单金额,必填

        String refund_amount = String.valueOf(orderItem.getNumber()*orderItem.getProduct().getPromotePrice());

        //标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传

        String out_request_no = order.getOrderCode();

        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","

                +"\"trade_no\":\""+ order.getAliCode() +"\","

                +"\"refund_amount\":\""+ refund_amount +"\","

                +"\"out_request_no\":\""+ out_request_no +"\"}");

        //请求

        String result = alipayClient.execute(alipayRequest).getBody();

        //输出

        out.println(result);

        //订单退款代码

        order.setStatus("refund");

        orderService.add(order);

        return "admin/refundPage";

    }

}

支付宝开放平台开发助手点击生成密钥

支付宝开放平台助手

你可能感兴趣的:(支付宝沙箱支付、退款)