spring boot+vue实现JSAPI微信支付的完整步骤

目录
  • 微信支付
    • 微信支付前的准备
    • 后台开发
    • vue前端
  • 总结

微信支付

最近公司要在微信公众号上做一个活动预报名,活动的门票等需要在微信中支付。

微信支付前的准备

微信支付需要一个微信支付商务号(https://pay.weixin.qq.com/index.php/apply/applyment_home/guide_normal),请自行去商务平台申请。商务号申请完后,需要在 “微信公众号平台–>微信支付” 中接入。接入成功后还需要在 微信公众号平台–>设置–>公众号设置–>功能设置 中将你的域名设置好,域名格式:http://baidu.com/ ,并将你的服务器ip设置成白名单,设置好之后 就可以开始开发微信支付了,

后台开发

话不多说,直接上代码吧,如果想细了解的请看官方文档

微信支付

控制层

@RequestMapping(value = "/wxpay", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Map<String, Object> weixinPrePay(@RequestBody Pay pay,HttpServletRequest request) throws Exception  {
    	Map<String,Object> maps = new HashMap<String,Object>();
    	// 前端传值总是会多一个: 后台截取掉 这个看情况 可能你不存在这种情况的
    	pay.setOpenid(pay.getOpenid().substring(0, pay.getOpenid().length()-1));
    	System.out.println(pay.getOpenid());
    	// 前端传来的金额  后台需要将它变成 元
    	Double prices = pay.getPrice()*100;
    	Integer total_fee = prices.intValue();
        System.out.println(prices+"----"+pay.getPrice()+"----"+total_fee);
    	// 生成唯一订单号
    	Integer out_trade_no = (int) (System.currentTimeMillis() / 1000+970516);
        SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();
        parameterMap.put("appid", Parm.APPID);  //微信公众号的appid
        parameterMap.put("mch_id", Parm.MCH_ID/*PayCommonUtil.MCH_ID*/);  //商户号
        parameterMap.put("device_info", "WEB");
        parameterMap.put("nonce_str", randomString);  // 随机字符串
        parameterMap.put("body", "cheshi"); // 商品描述
        parameterMap.put("out_trade_no", out_trade_no);  // 商户订单号(唯一) 我是用当前时间戳+随意数字生成的
        parameterMap.put("fee_type", "CNY");  //货币类型 CNY:人民币
        parameterMap.put("total_fee", total_fee);   // 总金额  分为单位
        parameterMap.put("notify_url", wxnotify);   // 支付成功后的回调地址 填你
        parameterMap.put("trade_type", "JSAPI");//JSAPI--JSAPI支付(或小程序支付)、NATIVE--Native支付、APP--app支付,MWEB--H5支付,不同trade_type决定了调起支付的方式
        //trade_type为JSAPI是 openid为必填项
        parameterMap.put("openid", ASEUtil.AESdecrypt(pay.getOpenid()));
        // 加密格式  MD5 微信底层默认加密是HMAC-SHA256  具体你可以去看微信的支付底层代码(https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1)
        parameterMap.put("sign_type", "MD5");
        // 生成支付签名 参数值的参数按照参数名ASCII码从小到大排序(字典序)
        String sign = PayCommonUtil.createSign("UTF-8", parameterMap);
        parameterMap.put("sign", sign);
        System.out.println(parameterMap);
        // 微信的统一下单接口 需要将集合中的参数 拼接成<xml></xml> 格式
        String requestXML = PayCommonUtil.getRequestXml(parameterMap);
        System.out.println(requestXML);
        // 调用微信的统一下单接口
        String result = PayCommonUtil.httpsRequest(
                "https://api.mch.weixin.qq.com/pay/unifiedorder", "POST",
                requestXML);
        // 返回的数据是 xml 格式的数据
        System.out.println(result);
        Map<String, Object> map = null;
        try {
            // 微信统一下单接口返回的数据 也是xml 格式的  所以需要把它转成map 集合,因为我们只需要当中的一个统一下单编号 prepay_id
            map = PayCommonUtil.doXMLParse(result);
            // 时间戳 需要转换成秒
            map.put("timestamp", System.currentTimeMillis() / 1000);
            // 二次签名 微信支付签名需要签名两次,第一次是用来获取统一下单的订单号
            if ("SUCCESS".equals(map.get("result_code"))) {
            	SortedMap<String, Object> map2 = new TreeMap<String, Object>();
            	// 第二次支付签名的 参数 需要将 第一次签名中的 订单号带入签名中
                map2.put("appId", map.get("appid"));
                map2.put("timeStamp", map.get("timestamp"));
                //这边的随机字符串必须是第一次生成sign时,微信返回的随机字符串,不然支付时会报签名错误
                map2.put("nonceStr", map.get("nonce_str"));
                // 订单详情扩展字符串 统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=***
                map2.put("package", "prepay_id=" + map.get("prepay_id"));
                // 签名方式 要和第一次签名方式一直
                map2.put("signType", "MD5");
                // 支付签名
                String sign2 = PayCommonUtil.createSign("UTF-8", map2);
                // 将你前端需要的数据 放在集合中
                Map<String,Object> payInfo = new HashMap<String,Object>();
                payInfo.put("appId", map.get("appid"));
                payInfo.put("timeStamp", map.get("timestamp"));
                payInfo.put("nonceStr", map.get("nonce_str"));
                payInfo.put("prepay_id",map.get("prepay_id"));
                payInfo.put("signType", "MD5");
                payInfo.put("paySign", sign2);
                // 返回给前端的集合数据
                maps.put("status", 200);
                maps.put("msg", "统一下单成功!");
                maps.put("data", payInfo);
            }else {
            	maps.put("status", 500);
                maps.put("msg", "服务器忙,请稍后再试");
                maps.put("data", null);
            }
        } catch (JDOMException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return maps;
    }

工具类(参考这个网址,或者使用微信官方提供的那个demo中的微信工具类)怎么选择,看你个人

vue前端

// 微信支付
    onBridgeReady() {
      let that = this;
      let param = {
        openid: sessionStorage.getItem("openid"),  // 当前用户微信的openid
        price: that.ruleForm.price  // 应付金额
      };
      // 后台支付签名接口
      weixinPrePay(param).then(ref => {
        console.log(ref.data);
        if (ref.data.status == 200) {
          WeixinJSBridge.invoke(
            "getBrandWCPayRequest",
            {
              appId: ref.data.data.appId, // 微信的appid
              timeStamp: ref.data.data.timeStamp, //时间戳
              nonceStr: ref.data.data.nonceStr, //随机串
              package: "prepay_id=" + ref.data.data.prepay_id,  // 订单号
              signType: "MD5", //微信签名方式:
              paySign: ref.data.data.paySign //微信签名
            },
            function(res) {
              if (res.err_msg == "get_brand_wcpay_request:ok") {
                // 使用以上方式判断前端返回,微信团队郑重提示:
                //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
                var equipments = "";
                if (that.ruleForm.region === 1) {
                  equipments = "单人套餐(门票一张,帐篷一顶)";
                } else {
                  equipments = "双人套餐(门票两张,帐篷一顶)";
                }
                let params = {
                  SysUser: {
                    name: that.ruleForm.username,
                    mobile: that.ruleForm.phone,
                    openid: sessionStorage.getItem("openid")
                  },
                  Info_id: that.ruleForm.info,
                  Participants: that.ruleForm.numbers,
                  Equipments: equipments,
                  price: that.ruleForm.price
                };
                console.log(params);
                // 将支付用户加入数据库中 保存
                insertForecast(params).then(ref => {
                  if (ref.data.status == 200) {
                    that.$router.push({
                      path: "/ForeacstList"
                    });
                  } else {
                    that.$message.error("预报名失败");
                  }
                });
              } else {
                that.$message.error("支付失败,请重新支付");
              }
            }
          );
        } else {
          that.$message.error(ref.data.msg);
        }
      });
    },
    // 微信支付
    WeixinJs() {
      console.log(this.ruleForm.price);
      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 {
        this.onBridgeReady();
      }
    }

微信支付就到此结束了。

总结

到此这篇关于spring boot+vue实现JSAPI微信支付的文章就介绍到这了,更多相关springboot vue实现微信支付内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue+SpringBoot实现支付宝沙箱支付的示例代码

    首先去下载支付宝沙箱的一系列东西,具体的配置什么的我就不说了,有很多博客都讲了,还有蚂蚁金服官方也说的很详细,我就直接说怎么样把后端的支付页面显示到Vue前端来: 在你配置好AlipayConfig这个文件后,就可以写前端的逻辑了,前端是采用支付宝的页面如下: 下面展示一些 内联代码片. /* 以下是支付确认html */ <div style="text=#000000 bgColor=#ffffff leftMargin=0 topMargin=4"> <head

  • springboot+vue+对接支付宝接口+二维码扫描支付功能(沙箱环境)

    1. 什么是支付宝接口(沙箱环境)? 记录时间:2020年10月15日3:55 现如今,手机支付已相当普遍,而作为开发人员应该对手机支付操作有所了解.而支付宝接口是支付宝提供的一个接口,用来对接软件应用程序在进行金钱交易使用.然后对于编程爱好者而言,想学习这一点就有点难,因为要想使用支付宝接口,必须前提是使用软件应用程序,软件应用程序需要向支付宝申请,提交一系列资料,这一点是实现不了的.这就对开发者增加了一定的难度,因为产品没有上线,然后需要对接支付宝接口就是很大的问题,所以出现了沙箱环境,具有

  • spring boot+vue实现JSAPI微信支付的完整步骤

    目录 微信支付 微信支付前的准备 后台开发 vue前端 总结 微信支付 最近公司要在微信公众号上做一个活动预报名,活动的门票等需要在微信中支付. 微信支付前的准备 微信支付需要一个微信支付商务号(https://pay.weixin.qq.com/index.php/apply/applyment_home/guide_normal),请自行去商务平台申请.商务号申请完后,需要在 “微信公众号平台–>微信支付” 中接入.接入成功后还需要在 “微信公众号平台–>设置–>公众号设置–>

  • Spring Boot项目中集成微信支付v3

    1. 前言 最近忙的一批,难得今天有喘气的机会就赶紧把最近在开发中的一些成果分享出来.前几日分享了自己写的一个微信支付V3的开发包payment-spring-boot-starter,就忙里偷闲完善了一波.期间给微信支付提交了6个BUG,跟微信支付的产品沟通了好几天. 项目地址: https://github.com/NotFound403/payment-spring-boot 别忘记给个Star啊. 那么都完善了哪些内容呢?胖哥来一一介绍. 2. Maven 中央仓库 是的,不用再自行编译

  • Spring boot拦截器实现IP黑名单的完整步骤

    一·业务场景和需要实现的功能 以redis作为IP存储地址实现. 业务场景:针对秒杀活动或者常规电商业务场景等,防止恶意脚本不停的刷接口. 实现功能:写一个拦截器拦截掉黑名单IP,额外增加一个接口,将ip地址添加到redis中,并且返回redis中当前全部ip 二·Springboot中定义一个拦截器 @Order(0) @Aspect @Component public class AopInterceptor { /** * 定义拦截器规则 */ @Pointcut("execution(*

  • 在Spring Boot中加载XML配置的完整步骤

    开篇 在SpringBoot中我们通常都是基于注解来开发的,实话说其实这个功能比较鸡肋,但是,SpringBoot中还是能做到的.所以用不用是一回事,会不会又是另外一回事. 涛锅锅在个人能力能掌握的范围之内,一般是会得越多越好,都是细小的积累,发生质的改变,所以今天和小伙伴们一起分享一下. 实践 1.首先我们新建一个SpringBoot Project ,工程名为 xml 2.添加web依赖,点击Finish完成构建 3.我们新建一个类 SayHello 不做任何配置 package org.t

  • Spring Boot利用Docker快速部署项目的完整步骤

    1.简介 建议阅读本文最好对Dokcer有一些了解 首先我们先了解一下Docker是什么 Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口.它是目前最流行的 Linux 容器解决方案. Docker 将应用程序与该程序的依赖,打包在一个文件里面.运行这个文件,就会生成一个虚拟容器.程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样.有了 Docker,就不用担心环境问题. 总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器.

  • Spring Boot/VUE中路由传递参数的实现代码

    在路由时传递参数,一般有两种形式,一种是拼接在url地址中,另一种是查询参数.如:http://localhost:8080/router/tang/101?type=spor&num=12.下面根据代码看一下,VUE 和 Spring Boot 中各自是如何处理传递和接受参数的. Spring Boot package com.tang.demo1.controller; import org.springframework.web.bind.annotation.*; @RestContro

  • spring boot+vue 的前后端分离与合并方案实例详解

    springboot和vue结合的方案网络上的主要有以下两种: 1. [不推荐]在html中直接使用script标签引入vue和一些常用的组件,这种方式和以前传统的开发是一样的,只是可以很爽的使用vue的双向数据绑定,这种方式只适合于普通的全栈开发. 2.[推荐]使用vue官方的脚手架创建单独的前端工程项目,做到和后端完全独立开发和部署,后端单独部署一个纯restful的服务,而前端直接采用nginx来部署,这种称为完全的前后端分离架构开发模式,但是在分离中有很多api权限的问题需要解决,包括部

  • Spring Boot 项目发布到 Tomcat 服务器的操作步骤

    第 1 步:将这个 Spring Boot 项目的打包方式设置为 war. <packaging>war</packaging> SpringBoot 默认有内嵌的 tomcat 模块,因此,我们要把这一部分排除掉. 即:我们在 spring-boot-starter-web 里面排除了 spring-boot-starter-tomcat ,但是我们为了在本机测试方便,我们还要引入它,所以我们这样写: <dependency> <groupId>org.s

  • Spring Boot Admin 动态修改日志级别的方法步骤

    [前言] 之前关于线上输出日志一直有个困惑:如何可以动态调整的日志级别,来保证系统在正常运行时性能同时又能在出现问题时打印详细的信息来快速定位问题:最近研究一下Spring Boot Admin中动态日志级别调整,并集成项目中,在此与大家共享: [动态修改日志级别]          一.生产环境日志输出的状况 1.生产环境日志输出的困惑 A.设置日志输出级别为info: (1)优点:可以详细的打印日志,有利于排错: (2)缺点:日志消耗系统的性能较大:只能针对整个系统整体设置日志输出较多,定位

  • Spring Boot 打包上传Docker 仓库的详细步骤

    重要提示:学习本文之前需要提前了解docker容器相关的知识,了解和熟练运用常用的docker操作命令,如果已经了解了docker容器相关的知识那我们就开搞吧! 以下是完成标题所述功能的大致步骤: 搭建docker镜像仓库 修改Spring Boot 配置文件添加docker仓库配置,打包,上传至docker 镜像仓库 从自己搭的docker镜像仓库拉取上传的镜像文件并运行 Step1 搭建docker镜像私有仓库 搭建docker镜像仓库我们需要依赖docker-registry工具 ,doc

随机推荐