为了实现一码多付 

生成一个通用二维码  通过支付宝或者微信都可以支付

1 使用支付宝扫码支付

支付宝提供了 扫码枪,用户扫商户动态生成的码 这样会根据用户不同或者金额不同需要动态的码,这样显然是不可以的

所以要实现商户生成一个静态码,并且商户能获取订单信息,后台通知只有实现一码多付   JSAPI

支付宝官方文档:https://openclub.alipay.com/read.php?tid=5458&fid=56

总结下来文档无非就是一下几点:

 1 申请一个账号(我申请的是一个沙箱环境的),需要生产环境的自行去申请即可,简单

 2 一码多付使用到支付宝的【alipay.trade.create-统一收单交易创建接口】需要签约当面付接口才能有这个接口的权限

 3 使用【用户信息授权接口】只需要在appid添加功能即可不需要签约。 步骤二 需要用到 buyer_id 用户支付宝账号

这样就是一个正常流程了

 第二步创建统一收单订单,buyer_id 不能为空,所以这就依赖第三步的用户信息授权获取用户的id

需要用户授权获取用户id   https://docs.open.alipay.com/289/105656

参数名是否必须长度描述
app_id16开发者应用的app_id; 相同支付宝账号下,不同的app_id获取的token切忌混用。
scope不定,取决于请求授权时scope个数接口权限值,目前只支持auth_user(获取用户信息网站支付宝登录)、auth_base(用户信息授权)、auth_ecard(商户会员卡)、auth_invoice_info(支付宝闪电开票)、auth_puc_charge(生活缴费)五个值;多个scope时用”,”分隔,如scope为”auth_user,auth_ecard”时,此时获取到的access_token,既可以用来获取用户信息,又可以给用户发送会员卡。
redirect_uri100授权回调地址,是经过URLENCODE转义 的url链接(url必须以http或者https开头); 在请求之前,开发者需要先到开发者中心对应应用内,配置授权回调地址。 redirect_uri与应用配置的授权回调地址域名部分必须一致。
state100商户自定义参数,用户授权后,重定向到redirect_uri时会原样回传给商户。 为防止CSRF攻击,建议开发者请求授权时传入state参数,该参数要做到既不可预测,又可以证明客户端和当前第三方网站的登录认证状态存在关联。

scope: auth_user 能获取用户的所有信息,auth_base(这个也叫静默授权:对用户来讲是没有感知的,不会弹出授权页面,但是这个只能获到用户的用户ID,无法获取用户的其他信息,这个也正是我们需要的)

https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=2018062060405677&scope=auth_base&redirect_uri=你的授权回调地址(后面可以拼接参数:http://www.baidu.com?业务参数=xxxx)

这样获取到了用户的authCode: 支付宝就会回调配置的授权回调地址 

例如: 授权回调地址?业务参数=xxx&auchCode=XXXXX

下一步:auth_code换取access_token与user_id

AlipaySystemOauthTokenResponse oauthTokenResponse = alipayClient.execute(request);
LogHelper.debug(logger, "用户ID userId={0}", oauthTokenResponse.getUserId());
resoponse=oauthTokenResponse.getBody();
requestData.put("buyer_id", oauthTokenResponse.getUserId());

到这里基本上完成三分之一了

下一步创建订单:这个没啥特别的直接上代码 

this.initPaymentConfig(orderInfoModel.getProjectId().toString(), PaymentChannelEnum.ALIPAY);
Map<String, String> param = this.getRequestParam(orderInfoModel, null);
AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
request.setNotifyUrl(this.notifyUrl);
request.setBizContent("{" +
        "\"out_trade_no\":\"" +orderInfoModel.getOrderId()+"\","+
        "\"total_amount\":\"" +param.get("amount")+"\","+
        "\"subject\":\""+param.get("subject")+"\"," +
        "\"buyer_id\":\""+param.get("buyer_id")+"\"," +
        "\"timeout_express\":\"30m\"" +
        "  }");
    AlipayTradeCreateResponse response = alipayClient.execute(request);
    if(response.isSuccess()){
        return response.getTradeNo();
      }

返回订单的订单号 TradeNo: 在H5页面 通过订单号唤起收银台

一共会涉及到两个页面: 第一个页面用户扫码 (中转页面:用户获取用户的code)

1 页面

window.location.href=https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=2018062060405677&scope=auth_base&redirect_uri=你的授权回调地址(后面可以拼接参数:http://www.baidu.com?业务参数=xxxx)

支付宝会将auth_code 传递到 设置的授权回调地址,然后输入金额的页面,最后再js页面拉起收银台输入金额支付

2 页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>付款</title>
</head>
<body>
<div class="mobile-box">
    <div class="mobile-top ">
        <div class="back">
            <i class="fa fa-angle-left fa-2x"></i>
        </div>
<#--
        <h2 class="top-center color21 text-center">付款</h2>
-->
        <div class="back"></div>
    </div>
    <div class="mobile-content">
        <h3 class="color21 font">
            <img src="http://img1.52mamahome.com/hotel/homes.png" class="mr10" alt="">您正在向 ${(projectName)!}付款</h3>
        <div class="input-num">
            <input type="number" class="w-100" id="amount" placeholder="请输入要支付的金额">
            <span class="color21 text-center">元</span>
        </div>
        <p class="text-center pay pay-click" id="goPay" onclick="pay()">支付</p>
    </div>

</div>
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="https://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.min.js"></script>
<script>
    function pay() {
        var amount = $("#amount").val();
       var exp = /^(([1-9]\d*)|\d)(\.[1-9]{1,2})?$/;
        if(!exp.test(amount)){
            alert('金额格式不正确');
            return;
        }
        var projectId=$("#projectId").val();
        var code=$("#code").val();
        //获得渠道
        var paymentType;
        if (navigator.userAgent.indexOf("AlipayClient") > 0) {
            paymentType="ALIPAY";
        } else if (navigator.userAgent.indexOf("MicroMessenger") > 0) {
            paymentType="WEIXIN";
        }else{
            alert("请使用微信或者支付宝支付");
            return;
        }
       var orderUrl=amount="+amount+"&code="+code+"&projectId="+projectId+"&source="+paymentType;
        $.ajax({
            url: orderUrl,
            type: "GET",
            dataType: "json",
            cache: false,
            success: function (data) {
                if(paymentType=='ALIPAY'){
                    //支付宝支付
                    alipayIsAlready();
                    AlipayJSBridge.call("tradePay", {
                        tradeNO: data.result
                    }, function (result) {
                        if ("9000" == result.resultCode) {
                            window.location.href=rootUrl+"success?amount="+amount;
                        }else{
                            window.location.href=rootUrl+"failed";
                        }
                    });
                }else if(paymentType=='WEIXIN'){
                    //微信支付
                    wxIsAlready(JSON.parse(data.result));
                }
            },
            error: function (data) {
                window.location.href=rootUrl+"failed";
            }
        });
    }

    function alipayIsAlready(callback) {
        // 如果jsbridge已经注入则直接调用
        if (window.AlipayJSBridge) {
            callback && callback();
        } else {
            // 如果没有注入则监听注入的事件
            document.addEventListener('AlipayJSBridgeReady', callback, false);
        }
    }

    /**
     * @Description: 微信初始化参数
     * @return
     */
    function wxIsAlready(responseData) {
        if (typeof WeixinJSBridge == "undefined") {
            if (document.addEventListener) {
                document.addEventListener('WeixinJSBridgeReady', weixinPay(responseData), false);
            } else if (document.attachEvent) {
                document.attachEvent('WeixinJSBridgeReady', weixinPay(responseData));
                document.attachEvent('onWeixinJSBridgeReady', weixinPay(responseData));
            }
        }else{
            weixinPay(responseData);
        }
    }

    function weixinPay(responseData) {
        WeixinJSBridge.invoke(
                'getBrandWCPayRequest', {
                    "appId":responseData.appId,     //公众号名称,由商户传入
                    "timeStamp":responseData.timeStamp,         //时间戳,自1970年以来的秒数
                    "nonceStr":responseData.nonceStr, //随机串
                    "package":responseData.package,   //prepay_id = ?
                    "signType":'MD5',        //微信签名方式:
                    "paySign":responseData.paySign //微信签名
                },
                function (res) {
                    if (res.err_msg == "get_brand_wcpay_request:ok") { // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。
                        window.location.href=rootUrl+"success?amount="+amount;
                    } else {
                        window.location.href=rootUrl+"failed";
                    }
                }
        );
    }
</script>
</body>
</html>

上面是调用支付宝和微信收银台的js 代码

 

    
    https://docs.open.alipay.com/common/105591
    支付宝静默授权: https://www.jianshu.com/p/665e398a66e4
    参考文档:https://blog.csdn.net/a718515028/article/details/80684228
    
    
    
    微信静默授权:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
    参考文档:https://blog.csdn.net/qq_29863725/article/details/78620198
    https://blog.csdn.net/qq_32404273/article/details/78126829
 

 

 

 

 

 

 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐