公众号支付-从服务号申请到支付调用爬坑

栏目: 后端 · 前端 · 发布时间: 5年前

内容简介:需要准备的材料1、先申请服务号2、通过后,申请微信支付

需要准备的材料

  • 认证的服务号,300块一年认证费用
  • 营业执照
  • 公司对公银行账号

1、先申请服务号

2、通过后,申请微信支付

微信支付不同行业需要收手续费,一般0.6%

2、配置

之前没有接触过,看官网文档调用的图也是一脸懵,只知道有个预下单的操作获取prepay_id,用户支付完成之后,有微信回调的操作。

公众号支付-从服务号申请到支付调用爬坑

公众号和商户平台需要配置项

  • 支付需要获取用户的openid,因此在公众号设置-功能设置-网页授权域名中加入域名

加入域名时, 需要将下载的文件放到项目中 ,使填写的域名能访问到。我是放到了静态资源中,没有写其他目录,直接使用域名就可访问。

公众号支付-从服务号申请到支付调用爬坑
  • 商户平台中公众号支付需要配置域名,产品中心-开发配置-支付配置
公众号支付-从服务号申请到支付调用爬坑
  • 商户平台中需要设置API密钥和API证书,因为是第一次设置,所以需要按照提示操作,若已经有了密钥和证书,那就不要设置了。
公众号支付-从服务号申请到支付调用爬坑

3、开发

流程:

用户--->>打开页面确认授权获取CODE--->>跳转到订单页面--->>点击支付--->>将CODE发送到后台获取openid,拼装商品参数,调用微信预下单,获取到prepay_id,并将prepay_id发送到前端--->>获取prepay_id拉起支付界面,输入密码--->>支付成功,微信回调接口,并通知微信交易成功,停止微信回调。

后台配置

  • 1、需要将商户平台配置的证书文件和公众号设置的授权文件,放到项目中
公众号支付-从服务号申请到支付调用爬坑
  • 2、配置公众号相关信息
公众号支付-从服务号申请到支付调用爬坑

后台代码

关键后台代码

@Autowired
    private BestPayServiceImpl bestPayService;

    private static final String get_openid="https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";

    @Autowired
    private WechatAccountConfig accountConfig;

    /**
     * 授权获取CODE
     * @return
     */
    @GetMapping(value = "/pay")
    public ModelAndView pay() {
        return new ModelAndView("authon.html");
    }

    /**
     * 发起支付
     * 通过code, 获取openid,
     */
    @GetMapping(value = "/goodspay")
    public ModelAndView goodspay(@RequestParam("code") String code,String money,
                            Map<String, Object> map) {
        String uri=String.format(get_openid,accountConfig.getMpAppId(),accountConfig.getSecret(),code);
        log.info("【获取openid】request={}", uri);
        String json=HttpUtil.get(uri);
        log.info("【获取openid】request={}", json);
        JSONObject jsonobj=JSONObject.parseObject(json);
        log.info("openid={}",jsonobj.get("openid"));
        String openid= (String) jsonobj.get("openid");
        return pay(openid,money,map);
    }


    /**
     * 发起支付
     */
    public ModelAndView pay(String openid,String money,
                            Map<String, Object> map) {
        PayRequest request = new PayRequest();
        Random random = new Random();

        //支付请求参数
        request.setPayTypeEnum(BestPayTypeEnum.WXPAY_H5);
        request.setOrderId(String.valueOf(random.nextInt(1000000000)));
        if(StringUtils.isNotEmpty(money)){
            request.setOrderAmount(new Double(money));
        }else{
            request.setOrderAmount(0.01);
        }
        request.setOrderName("支付测试");
        request.setOpenid(openid);
        log.info("【发起支付】request={}", JsonUtil.toJson(request));

        PayResponse payResponse = bestPayService.pay(request);
        log.info("【发起支付】response={}", JsonUtil.toJson(payResponse));

        map.put("payResponse", payResponse);

        return new ModelAndView("pay/create", map);
    }

    /**
     * 异步回调
     */
    @PostMapping(value = "/notify")
    public ModelAndView notify(@RequestBody String notifyData) throws Exception {
        log.info("【异步回调】request={}", notifyData);
        PayResponse response = bestPayService.asyncNotify(notifyData);
        log.info("【异步回调】response={}", JsonUtil.toJson(response));

        return new ModelAndView("pay/success");
    }


复制代码

前端代码

获取用户授权页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>授权跳转中....</title>
</head>
<script>
    var appid = "wxdaa292459af12ea1";
    var redirect_uri = encodeURIComponent("http://ixq66a.natappfree.cc/goods.html");
    window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appid + "&redirect_uri=" + redirect_uri + "&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect"
</script>
<body>

</body>
</html>
复制代码

点击支付页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>转账</title>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <link rel="stylesheet" href="//res.layui.com/layui/dist/css/layui.css"  media="all">
</head>
<body>

    <form action="/goodspay" method="get">
        <input  value="" id="code1" name="code" hidden/>

        <fieldset class="layui-elem-field site-demo-button" style="margin-top: 20%;margin-bottom: -30%;">
            <legend style="font-size: 50px;">下单支付0.01元</legend>
            <div style="margin-top: 70px;margin-left: 20px;margin-right: 20px;margin-bottom: 30px;">
                <button class="layui-btn layui-btn-primary" style="width: 100%;height: auto;background-color: #36e0d2;
                    font-size: 100px;">微信支付</button>
            </div>
        </fieldset>
    </form>

    <form action="/goodspay" method="get" style="padding-top: 15%;">
        <input  value="" id="code2" name="code" hidden/>

        <fieldset class="layui-elem-field site-demo-button" style="margin-top: 30%;margin-bottom: -30%;">
            <legend style="font-size: 50px;">输入金额下单支付</legend>
            <input  value="" id="money" name="money" style="width: 50%;height: 100px;font-size: 100px;"   placeholder="输入金额"/>
            <div style="margin-top: 70px;margin-left: 20px;margin-right: 20px;margin-bottom: 30px;">
                <button class="layui-btn layui-btn-primary" style="width: 100%;height: auto;background-color: #36e0d2;
                    font-size: 100px;">微信支付</button>
            </div>
        </fieldset>
    </form>


<script>
    //转码
    function parse_url(url) { //定义函数
        var pattern = /(\w+)=(\w+)/ig; //定义正则表达式
        var parames = {}; //定义数组
        url.replace(pattern, function (a, b, c) {
            parames[b] = c;
        });
        return parames; //返回这个数组.
    }
    //获取当前url   取到code
    var url = window.location.href;
    var params = parse_url(url);
    $("#code1").val(params.code);
    $("#code2").val(params.code);

</script>
</body>

</html>
复制代码

拉起支付页面

<script>
    function onBridgeReady(){
        WeixinJSBridge.invoke(
                'getBrandWCPayRequest', {
                    "appId":"${payResponse.appId}",     //公众号名称,由商户传入
                    "timeStamp":"${payResponse.timeStamp}",         //时间戳,自1970年以来的秒数
                    "nonceStr":"${payResponse.nonceStr}", //随机串
                    "package":"${payResponse.packAge}",
                    "signType":"MD5",         //微信签名方式:
                    "paySign":"${payResponse.paySign}" //微信签名
                },
                function(res){
                    if(res.err_msg == "get_brand_wcpay_request:ok" ) {
                        alert('支付成功');
                    }else if(res.err_msg == "get_brand_wcpay_request:cancel") {
                        alert('支付过程中用户取消');
                    }else if(res.err_msg == "get_brand_wcpay_request:fail") {
                        alert('支付失败');
                    }else {
                        alert('未知异常');
                    }
                    WeixinJSBridge.call('closeWindow');
                }
        );
    }
    if (typeof WeixinJSBridge == "undefined"){
        if( document.addEventListener ){
            document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
        }else if (document.attachEvent){
            document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
            document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
        }
    }else{
        onBridgeReady();
    }
</script>
复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数学建模(原书第5版)

数学建模(原书第5版)

[美] Frank R. Giordano、[美] William P.Fox、[美] Steven B.Horton / 叶其孝、姜启源 / 机械工业出版社 / 2014-10-1 / 99.00元

《华章数学译丛:数学建模(原书第5版)》旨在指导学生初步掌握数学建模的思想和方法,共分两大部分:离散建模和连续建模,通过本书的学习,学生将有机会在创造性模型和经验模型的构建、模型分析以及模型研究方面进行实践,增强解决问题的能力。 《华章数学译丛:数学建模(原书第5版)》对于用到的数学知识力求深入浅出,涉及的应用领域相当广泛,适合作为高等院校相关专业的数学建模教材和参考书,也可作为参加国内外数......一起来看看 《数学建模(原书第5版)》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具