Java PC端微信、支付宝扫码支付(二)

Java PC端微信、支付宝扫码支付(二)

前几天写了微信支付,附上链接 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();
        }

    }

上面就是支付宝扫码支付全部的代码了,有什么遗漏的地方可以在下面评论,我会在第一时间补充。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值