• 微信支付(小程序)-java实现与小程序实现


    一:java配置

    微信支付(小程序)-java配置

    二:工具类:获取本地IP与Enum类 与订单支付返回数据

    1: 获取本地IP工具类
    2:订单 Enum类

    package com.io.common.enums;
    
    public enum OrderStatusEnum {
        CANCEL(0,"已取消"),
        NOT_YET_SHIPPED(1,"待支付"),
        PART_OF_THE_SHIPMENT(2,"待发货"),
        WAIT_RECEIVING(3,"待收货"),
        ACHIEVE(4,"已完成"),
        ;
        private Integer key;
        private String desc;
    
        OrderStatusEnum(Integer key, String desc){
            this.key = key;
            this.desc = desc;
        }
    
        public Integer getKey() {
            return key;
        }
    
        public String getDesc() {
            return desc;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    3:支付方式Enum类

    package com.io.common.enums;
    
    public enum PayTypeEnum {
    
        WX_PAY(1, "微信支付"),
    
        ;
    
        private Integer key;
        private String desc;
    
        PayTypeEnum(Integer key, String desc) {
            this.key = key;
            this.desc = desc;
        }
    
        public Integer getKey() {
            return key;
        }
    
        public String getDesc() {
            return desc;
        }
    
        public static String getDesc(Integer key) {
            for (PayTypeEnum c : PayTypeEnum.values()) {
                if (c.key.equals(key)) {
                    return c.getDesc();
                }
            }
            return null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    4:微信支付form提交数据

    package com.io.order.form;
    
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Data;
    
    import java.math.BigDecimal;
    
    /**
     * @author ts
     * @version 1.0
     * @date 2022/08/05
     */
    @Data
    public class WxPayForm {
    
        private Integer orderId;
    
        @ApiModelProperty("订单号")
        private String orderNo;
    
        @ApiModelProperty("支付订单号")
        private String orderPayNo;
    
        @ApiModelProperty("实际支付金额")
        private BigDecimal payAmount;
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    5:微信支付订单返回数据

    package com.io.order.vo;
    
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Data;
    
    
    @Data
    public class AfterPayVO {
    
        @ApiModelProperty("timeStamp")
        private String timeStamp;
    
        @ApiModelProperty("nonceStr")
        private String nonceStr;
    
        @ApiModelProperty("packageValue")
        private String packageValue;
    
        @ApiModelProperty("signType")
        private String signType;
    
        @ApiModelProperty("paySign")
        private String paySign;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    三:service与controller

    1:支付 service类

    package com.io.order.service;
    
    import com.github.binarywang.wxpay.exception.WxPayException;
    import com.io.order.form.WxPayForm;
    import com.io.order.vo.AfterPayVO;
    
    import javax.servlet.http.HttpServletResponse;
    
    public interface PayService {
    
        /**
         * 微信支付
         * @param form 订单数据
         * @param userId // 用户id
         * @param wxId // 微信用户id
         * @return
         * @throws
         */
        AfterPayVO pay(WxPayForm form, String userId,Integer wxId) throws WxPayException;
    
        /**
         * 微信支付回调
         * @param appid
         * @param xmlData
         * @param response
         * @throws Exception
         */
        void payNotify(String appid, String xmlData, HttpServletResponse response) throws Exception;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    2:支付 service类实现

    package com.io.order.service.impl;
    
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
    import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
    import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
    import com.github.binarywang.wxpay.config.WxPayConfig;
    import com.github.binarywang.wxpay.exception.WxPayException;
    import com.github.binarywang.wxpay.service.WxPayService;
    import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
    import com.io.common.enums.OrderStatusEnum;
    import com.io.common.enums.PayTypeEnum;
    import com.io.entity.WxUserEntity;
    import com.io.exception.RRException;
    import com.io.order.config.WxPayProperties;
    import com.io.order.dao.OrderDao;
    import com.io.order.entity.OrderEntity;
    import com.io.order.form.WxPayForm;
    import com.io.order.service.PayService;
    import com.io.order.vo.AfterPayVO;
    import com.io.order.vo.RefundVO;
    import com.io.service.WxUserService;
    import com.io.util.ConvertUtils;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletResponse;
    import java.io.BufferedOutputStream;
    import java.time.LocalDateTime;
    import java.util.Objects;
    
    @Service
    @Slf4j
    public class PayServiceImpl implements PayService {
    
        @Autowired
        private WxUserService wxUserService;
    
        @Value("${he.wx.appid}")
        private String wxAppid;
    
        private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
        @Override
        public AfterPayVO pay(WxPayForm form, String userId, Integer wxId) throws WxPayException {
            // 查询根据微信id(存微信用户表的id)查询MySQL数据库获取当前用户的微信数据
            WxUserEntity byId = wxUserService.getById(wxId);
            if (Objects.isNull(byId)){
                log.info("微信支付用户wxId:" + wxId);
                throw new RRException("无该微信用户");
            }
            WxPayService wxPayService = this.getWxPayService(wxAppid);
    
            WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
            orderRequest.setBody("商品付款");
            orderRequest.setOutTradeNo(form.getOrderPayNo());
            orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(form.getPayAmount().toString()));//元转成分
            orderRequest.setOpenid(byId.getXwOpenId()); // 支付微信用户 微信openId
            orderRequest.setSpbillCreateIp(IpUtils.getAddrIp()); // 本地ip设置
            orderRequest.setSpbillCreateIp("114.55.114.66");
            orderRequest.setNotifyUrl(String.format(properties.getNotifyUrl(), "payNotify", byId.getXwOpenId())); // 支付回调路径与参数拼接设置
            // 支付方式
            orderRequest.setTradeType("JSAPI");
    
            orderRequest.setAppid(wxAppid);
    
            Object result = wxPayService.createOrder(orderRequest);
            AfterPayVO afterPayVO = ConvertUtils.sourceToTarget(result, AfterPayVO.class);
            return afterPayVO;
        }
    
        @Override
        public void payNotify(String appid, String xmlData, HttpServletResponse response) throws Exception {
    
            WxPayService wxPayService = this.getWxPayService(appid);
            final WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
            log.info("支付订单号:" + notifyResult.getOutTradeNo());
    
            // 小程序支付成功后回调这个接口 后的订单业务逻辑 (请根据项目来编写)
            LambdaQueryWrapper<OrderEntity> lambdaQueryWrapper =new LambdaQueryWrapper<OrderEntity>();
            lambdaQueryWrapper.eq(OrderEntity::getOrderPayNo,notifyResult.getOutTradeNo());
            OrderEntity orderEntity = orderDao.selectOne(lambdaQueryWrapper);
            //订单状态
            if (OrderStatusEnum.NOT_YET_SHIPPED.getKey().equals(orderEntity.getOrderStatus())){
                orderEntity.setOrderStatus(OrderStatusEnum.PART_OF_THE_SHIPMENT.getKey());
                orderEntity.setPaymentType(PayTypeEnum.WX_PAY.getKey());
                orderEntity.setPaymentTime(LocalDateTime.now());
                orderDao.updateById(orderEntity);
            }
    
            //回复微信防止重复回调
            StringBuilder resXml = new StringBuilder();
            resXml.append("");
            resXml.append("");
            resXml.append("");
            resXml.append("");
            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            out.write(resXml.toString().getBytes());
            out.flush();
            out.close();
        }
        
        /** 获取商户号配置并生成 WxPayService 
         * getWxPayService
         * @param appid
         * @return
         */
        private WxPayService getWxPayService(String appid){
            WxPayConfig payConfig = new WxPayConfig();
            payConfig.setAppId(appid);
            payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));
            payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey()));
            payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));
            // 可以指定是否使用沙箱环境
            payConfig.setUseSandboxEnv(false);
    
            WxPayService wxPayService = new WxPayServiceImpl();
            wxPayService.setConfig(payConfig);
            return wxPayService;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127

    3: Controller类

    package com.io.order.controller;
    
    import com.io.base.BaseController;
    import com.io.order.service.PayService;
    import com.io.util.R;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    import javax.servlet.http.HttpServletResponse;
    
    @RestController
    @RequestMapping("/pay")
    @Api(tags = "支付接口")
    @Slf4j
    public class PayController{
    
        @Autowired
        private PayService payService;
    
        @PostMapping("/payNotify/{appid}")
        @ApiOperation("支付回调")
        public R payNotify(@PathVariable String appid, @RequestBody String xmlData, HttpServletResponse response) throws Exception {
            payService.payNotify(appid, xmlData, response);
            return R.ok();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    三:小程序调用 支付接口

    官方文档:wx.requestPayment

    注:res.data.purchase  是先走下单逻辑(去后台下单并且调用了 支付接口)
    返回参数: AfterPayVO;
    小程序前端所用到的参数是 订单支付返回的参数
    wx.requestPayment({
      timeStamp: res.data.purchase.timeStamp,
      nonceStr: res.data.purchase.nonceStr,
      package: res.data.purchase.packageValue,
      signType: 'MD5',
      paySign: res.data.purchase.paySign,
      success (res) {
        支付成功
      },
      fail (res) {
        支付取消或失败
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2: 开发工具中测试支付接口 所展示的样子
    在这里插入图片描述
    3:正式环境样式

    在这里插入图片描述

  • 相关阅读:
    实训笔记——Spark计算框架
    【java8】Optional的使用
    机器学习第八课--决策树
    莫队
    服务器文件备份
    SSM+基于SSM的课堂考勤管理系统的设计与实现 毕业设计-附源码191617
    monaco-editor 实现SQL编辑器
    最全ROS 入门
    项目开发好用工具
    Oracle 逻辑备份(数据迁移)
  • 原文地址:https://blog.csdn.net/weixin_49200545/article/details/126505900