SpringBoot2.0小程序支付功能实现weixin-java-pay

WxJava - 微信开发 Java SDK(开发工具包); 支持包括微信支付、开放平台、公众号、企业微信/企业号、小程序等微信功能的后端开发。

第一步: SDK使用方式

Maven方式引入:

  1. <dependency>
      <groupId>com.github.binarywang</groupId>
      <artifactId>(不同模块参考下文)</artifactId>
      <version>3.3.0</version>
    </dependency>

各模块的artifactId:

  • 微信小程序:weixin-java-miniapp
  • 微信支付:weixin-java-pay
  • 微信开放平台:weixin-java-open
  • 公众号(包括订阅号和服务号):weixin-java-mp
  • 企业号/企业微信:weixin-java-cp

第二步:配置微信相关信息

application.yml

  1. #微信小程序配置
    wx:
      miniapp:
        configs:
            - appid: #微信公众号或者小程序等的appid 必填
              secret: #微信公众号或者小程序等的secret 必填
              token: #微信小程序消息服务器配置的token
              aesKey: #微信小程序消息服务器配置的EncodingAESKey
              msgDataFormat: JSON
      pay:
        appId:  #微信公众号或者小程序等的appid 必填
        mchId:  #微信支付商户号    必填
        mchKey: #微信支付商户密钥
        subAppId: #服务商模式下的子商户公众账号ID
        subMchId: #服务商模式下的子商户号
        keyPath: classpath:cert/apiclient_cert.p12 # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
      notifyUrl: https://www.xxx.com/wx/notify #微信支付回调地址 自己定义但是必须放到外网微信可以访问的到

第三步:编写统一订单接口业务

调用统一下单支付接口:wxService.createOrder(orderRequest)

  1. /**
     * @Title: WxUserVedioController.java
     * @Package io.renren.modules.wx.controller
     * @Description: 
     * Copyright: Copyright (c) 2019 www.codepeople.cn Inc. All rights reserved. 
     * Website: www.codepeople.cn
     * 注意:本内容仅限于海南科澜技术信息有限公司内部传阅,禁止外泄以及用于其他的商业目 
     * @Author 刘仁
     * @DateTime 2019年4月6日 上午11:54:08
     * @version V1.0
     */
  2. package io.renren.modules.wx.controller;
  3. import java.math.BigDecimal;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
  4. import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
  5. import org.apache.commons.io.IOUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
  6. import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
    import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
    import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
    import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
    import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
    import com.github.binarywang.wxpay.constant.WxPayConstants;
    import com.github.binarywang.wxpay.exception.WxPayException;
    import com.github.binarywang.wxpay.service.WxPayService;
  7. import io.renren.common.utils.DateUtils;
    import io.renren.common.utils.IPUtils;
    import io.renren.common.utils.PageUtils;
    import io.renren.common.utils.R;
    import io.renren.modules.soft.entity.AuthorizationEntity;
    import io.renren.modules.soft.entity.HospitalEntity;
    import io.renren.modules.soft.entity.OrderEntity;
    import io.renren.modules.soft.entity.PayFlowEntity;
    import io.renren.modules.soft.entity.PurchaseRecordEntity;
    import io.renren.modules.soft.entity.RefundRecordEntity;
    import io.renren.modules.soft.service.AuthorizationService;
    import io.renren.modules.soft.service.BedBaseService;
    import io.renren.modules.soft.service.DeviceService;
    import io.renren.modules.soft.service.HospitalService;
    import io.renren.modules.soft.service.OrderService;
    import io.renren.modules.soft.service.PayFlowService;
    import io.renren.modules.soft.service.PurchaseRecordService;
    import io.renren.modules.soft.service.RefundRecordService;
    import io.renren.modules.soft.service.StatementService;
    import io.renren.modules.soft.service.ThirdUserService;
    import io.renren.modules.soft.service.UserAuthorizationService;
    import io.renren.modules.soft.service.UserService;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiImplicitParam;
    import io.swagger.annotations.ApiImplicitParams;
    import io.swagger.annotations.ApiOperation;
    import lombok.extern.slf4j.Slf4j;
  8. /**
     * @ClassName: WxUserVedioController
     * @Description: 
     * @Author 刘仁
     * @DateTime 2019年4月6日 上午11:54:08 
     */
    @Api(tags = "普通用户操作接口")
    @RestController
    @RequestMapping("/wx")
    @Slf4j
    public class WxxxxUserVedioController {
        @Value("${wx.notifyUrl}")
        private String notifyUrl;
        @Autowired
        private WxPayService wxService;
        @Autowired
        private HospitalService hospitalService;
        @Autowired
        private PayFlowService payFlowService;
        @Autowired
        private OrderService orderService;
  9.     /**
         * @Title: createOrder
         * @Description: 
         * @Author 刘仁
         * @DateTime 2019年4月6日 下午12:12:11
         * @param
         * @return
         */
        @PostMapping("/user/createOrder")
        public R createOrder(HttpServletRequest request,@RequestBody Map<String,String> map)  throws WxPayException{
            String bed_id = map.get("bedId");
            log.info("参数的bed_id:{}", bed_id);
            if (StringUtils.isAnyBlank(bed_id)) {
                return R.error("参数不能为null");
            }
            Long bedId = Long.valueOf(bed_id).longValue();
            //根据bedId 查找所属医院的价格
            HospitalEntity hospitalEntity = hospitalService.hospitalByBedId(bed_id.trim());
            BigDecimal money = hospitalEntity.getCharge();
  10.         HttpSession session = request.getSession();
            String mobile = (String) session.getAttribute("userphone");
            String userId = (String) session.getAttribute("userId");
            // TODO 插入订单记录
            // TODO 记录用户的购买记录
            // TODO 调用统一生成订单接口
            WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
            orderRequest.setSignType(WxPayConstants.SignType.MD5);
            orderRequest.setBody("短信主体");
            orderRequest.setOutTradeNo(order_No); //自己生成order_No
            orderRequest.setTradeType(WxPayConstants.TradeType.JSAPI);
    //        orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(yuanMoney));//直接分
            orderRequest.setTotalFee(money.intValue());//直接分
            orderRequest.setOpenid(userEntity.getOpenid()); // 获取微信支付用户的openId
            orderRequest.setSpbillCreateIp(IPUtils.getIpAddr(request));
            Date now = new Date();
            Date afterDate = DateUtils.addDateMinutes(now, 10);//10分钟后
            orderRequest.setTimeStart(DateUtils.format(now, "yyyyMMddHHmmss"));
            orderRequest.setTimeExpire(DateUtils.format(afterDate, "yyyyMMddHHmmss"));
            orderRequest.setNotifyUrl(notifyUrl);
            Object order = wxService.createOrder(orderRequest);
  11.         return R.ok().put("order", order);
        }
  12.     @ApiOperation("微信支付回调地址")
        @ResponseBody
        @PostMapping("/notify")
        public String payNotify(HttpServletRequest request, HttpServletResponse response) {
          try {
            /*HttpSession session = request.getSession();
            String mobile = (String) session.getAttribute("userphone");
            if (StringUtils.isBlank(mobile)) {
                return R.error(401, "session获取不到授权手机号!");
            }
              //获取用户手机号,根据用户手机号获取用户ID
              AuthorizationEntity user = authorizationService.getOneByMobile(mobile);*/
            String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
            WxPayOrderNotifyResult notifyResult = wxService.parseOrderNotifyResult(xmlResult);
            // 结果正确 outTradeNo
            String orderId = notifyResult.getOutTradeNo();
            String tradeNo = notifyResult.getTransactionId();
            String totalFee = BaseWxPayResult.fenToYuan(notifyResult.getTotalFee());
            if("SUCCESS".equals(notifyResult.getResultCode())) {
                PayFlowEntity entity = new PayFlowEntity();
                entity.setPayFee(BigDecimal.valueOf(notifyResult.getCashFee()));
                entity.setPayFlowNo(orderId);
                entity.setPayUserInfo(notifyResult.getOpenid());
                entity.setThreeInNo(tradeNo);
                payFlowService.save(entity);
                OrderEntity order_entity = new OrderEntity();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                order_entity.setCreateTime(new Date());
                //更新订单信息
                UpdateWrapper<OrderEntity> updateWrapper = new UpdateWrapper<>();
                updateWrapper.set("order_status", "1");
                updateWrapper.set("pay_id", notifyResult.getOpenid());
                updateWrapper.set("pay_status", "1");
                updateWrapper.set("pay_end_time", sdf.parse(notifyResult.getTimeEnd()));
                updateWrapper.eq("order_no",notifyResult.getOutTradeNo());
                orderService.update(updateWrapper);
            }
            //自己处理订单的业务逻辑,需要判断订单是否已经支付过,否则可能会重复调用
             return WxPayNotifyResponse.success("成功");
          } catch (Exception e) {
            log.error("微信回调结果异常,异常原因{}", e.getMessage());
           // WxPayNotifyResponse.fail(e.getMessage());
  13.         return WxPayNotifyResponse.success("code:"+9999+"微信回调结果异常,异常原因:"+e.getMessage());
          }
        }
  14. }

第四步:小程序端可以操作了

小程序端主要先调用小程序接口获取用户信息主要是code,然后传给后台,后台通过code获取openid获取方式:

  1. WxMaService  wxService = WxMaConfiguration.getMaService(appid);
                WxMaJscode2SessionResult wx_session = wxService.getUserService().getSessionInfo(code);
                openId = wx_session.getOpenid();
                log.info("通过微信获取用户的openId==>{}", openId);

然后根据回调地址返回的数据,小程序就可以对数据进行解析封装调用支付接口进行付款了。

这里主要讲的后端的使用方法

==================================================================

博客地址https://www.codepeople.cn

==================================================================

SpringBoot2.0小程序支付功能实现weixin-java-pay的更多相关文章

  1. 微信小程序 --- 完成小程序支付功能

    最近开发小程序,一直在看小程序的支付.经过一天的努力,小程序支付功能最终实现了. 下面感谢 csdn 博主:千堆雪惹尘埃 发布的 " 小程序与php 实现微信支付 " 原文地址: ...

  2. 微信小程序支付功能 C# .NET开发

    微信小程序支付功能的开发的时候坑比较多,不过对于钱的事谨慎也是好事.网上关于小程序支付的实例很多,但是大多多少有些问题,C#开发的更少.此篇文档的目的是讲开发过程中遇到的问题做一个备注,也方便其他开发 ...

  3. 微信小程序支付功能前端流程

    只是分享一下小程序支付功能的前端流程和代码, 仅供参考(使用的是uni app). handleCreate () { /** 第一步:前台将商品数据发送到后台,后台创建订单入库并返回订单id等信息 ...

  4. 微信小程序支付功能讲解(2)

    小程序支付 业务流程时序图 官方文档 步骤: 1. Openid 在小程序初次加载的时候就已经获取(详情见 小程序登录) 2. 生成商户订单 1.商品信息由小程序端提供 2.提供支付统一下单接口所需参 ...

  5. Python实现微信小程序支付功能

    由于最近自己在做小程序的支付,就在这里简单介绍一下讲一下用python做小程序支付这个流程.当然在进行开发之前还是建议读一下具体的流程,清楚支付的过程. 1.支付交互流程 当然具体的参数配置可以参考官 ...

  6. 微信小程序支付功能讲解(1)

    前言:虽然小程序做过很多,但是一直觉得微信支付功能很是神秘,现在终于有机会接触心里还是有点小激动的,经过一番折腾发现支付也不过如此,在此记录下支付功能的实现过程 小程序的官方文档介绍到发起微信支付即调 ...

  7. 微信小程序支付功能讲解

    前言:虽然小程序做过很多,但是一直觉得微信支付功能很是神秘,现在终于有机会接触心里还是有点小激动的,经过一番折腾发现支付也不过如此,在此记录下支付功能的实现过程 小程序的官方文档介绍到发起微信支付即调 ...

  8. 微信小程序 支付功能(前端)的实现

    只提供微信小程序端代码: var app = getApp(); Page({ data: {}, onLoad: function (options) { // 页面初始化 options为页面跳转 ...

  9. 微信小程序 支付功能 服务器端(TP5.1)实现

    首先下载微信支付SDK ,将整个目录的文件放在 /application/extend/WxPay 目录下 在使用SDK之前我们需要对 WxPay.Config.php 进行配置 <?php n ...

随机推荐

  1. 数位dp 模板

    不能有49 #include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i ...

  2. bufferedwriter写json文件中文乱码

    需要用writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"utf-8& ...

  3. 给力的移动 FZU - 2287

    你的弟弟给你安排了一个任务,他给了你1到N个数字的乱序排列,现在你想给你的弟弟秀一波操作,操作最少的次数把序列变成1到N的顺序排列,每次操作你可以选择序列中的一个数字并把它移动到序列的头部或尾部. I ...

  4. vue实例属性之el,template,render

    一.el,template,render属性优先性当Vue选项对象中有render渲染函数时,Vue构造函数将直接使用渲染函数渲染DOM树,当选项对象中没有render渲染函数时,Vue构造函数首先通 ...

  5. Redis自学笔记:3.2入门-字符串类型

    3.2字符串类型 实际上redis不只是数据库,更多的公司和团队将redis用作缓存和 队列系统 3.2.1介绍 字符串类型是redis最基本的数据类型,它能存储任何形式的字符串, 包括二进制数据.你 ...

  6. Codeforces.578E.Walking(构造)

    题目链接 \(Description\) 给定一个长为\(n\)的足迹序列(只包含\(L,R\)两种字符),你需要\(LRLRLR...\)这样交替在\(L\)和\(R\)上走(第一步可以选择\(L\ ...

  7. 潭州课堂25班:Ph201805201 django 项目 第十课 自定义错误码,完成图片验证码,用户是否被注册功能 (课堂笔记)

    把 视图传到前台的  JsonResponse(data=data) 先进行处理,之后再传到前台, 处理:引用自定义错误代码,把错误代码返回给前台,前台根据错误代码中文提示 class Code: O ...

  8. React Native小白入门学习路径——二

    万万没想到,RN组仅剩的一个学长也走了,刚进实验室没几天就被告知这样的事情,一下子还真的有点接受不了,现在RN组就成了为一个没有前辈带的组了,以后学习就更得靠自己了吧.唉,看来得再努力一点了. 这一周 ...

  9. MySQL(七)

    视图 对于复杂的查询,在多次使用后,维护是一件非常麻烦的事情 解决:定义视图 视图本质就是对查询的一个封装 定义视图 create view stuscore as select students.* ...

  10. 编程菜鸟的日记-初学尝试编程-C++ Primer Plus 第4章编程练习5

    #include <iostream>using namespace std;struct CandyBar{ char kind[20]; float weight; int calor ...