首页 > 编程语言 >微信小程序集成微信支付开发,后端是springboot项目

微信小程序集成微信支付开发,后端是springboot项目

时间:2023-05-22 22:25:12浏览次数:44  
标签:springboot 后端 renren 微信 modules io import soft

一、准备工作

首先是进入到小程序后台关联微信支付商户、以及接入微信支付申请

 

二、小程序端代码

主要是用到了 wx.requestPayment API

2.1 在wxml文件中添加支付按钮

<button bindtap="requestPayment">支付</button>

2.2 在wxss文件中定义支付按钮样式

button {
  background-color: #00bfff;
  color: #fff;
  border: none;
  border-radius: 4px;
  padding: 10rpx;
  font-size: 16rpx;
}

2.3 在js文件中编写调起支付接口的函数

const app = getApp();

Page({
  data: {
    // 支付参数
    paymentParams: {}
  },

  // 点击支付按钮触发的函数
  requestPayment() {
    wx.request({
      url: 'https://yourdomain.com/user/createOrder', // 后端服务获取支付参数
      success: (res) => {
        const paymentParams = res.data.paymentParams;
        wx.requestPayment({
          nonceStr: paymentParams.nonceStr,
          package: paymentParams.package,
          paySign: paymentParams.paySign,
          signType: paymentParams.signType,
          timeStamp: paymentParams.timeStamp,
          success: (res) => {
            // 支付成功后的处理逻辑
          },
          fail: (res) => {
            // 支付失败后的处理逻辑
          }
        })
      },
      fail: (res) => {
        // 获取支付参数失败后的处理逻辑
      }
    });
  }
});

三、后端服务代码

这边后端是用Java开发的,SpringBoot2.0小程序支付功能实现weixin-java-pay,主要是用到了第三方封装好的微信支付SDK

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

3.1 SDK使用方式

Maven方式引入:

<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

3.2 配置微信相关信息

application.yml

#微信小程序配置
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 #微信支付回调地址 自己定义但是必须放到外网微信可以访问的到

3.3 编写统一订单接口业务

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

/**
 * @Author 夏威夷8080
 * @DateTime 2019年4月6日 上午11:54:08
 * @version V1.0
 */


import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

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;

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;

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;

/**
 * @ClassName: WxUserVedioController
 * @Description: 
 * @Author 夏威夷8080
 * @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;

    /**
     * @Title: createOrder
     * @Description: 
     * @Author 夏威夷8080
     * @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();

        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);

        return R.ok().put("order", order);
    }

    @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());

        return WxPayNotifyResponse.success("code:"+9999+"微信回调结果异常,异常原因:"+e.getMessage());
      }
    }

}

 四、总结

梳理下简单流程 后端生成预订单返回给前端 -> 前端拿到订单信息调用 wx.requestPayment API进行支付  ->  支付成功,跳转到回调地址  ->  在回调url里处理支付成功后的业务逻辑

 

标签:springboot,后端,renren,微信,modules,io,import,soft
From: https://www.cnblogs.com/shamo89/p/17421896.html

相关文章

  • SpringBoot配置文件
    概述初始化SpringBoot项目时,在resources目录下有一个默认的全局配置文件application.properties。SpringBoot通过配置文件来修改SpringBoot自动配置的默认值SpringBoot支持两种格式的配置文件application.yml和application.propertiesapplication.properties写法appl......
  • 微信小程序web-view与H5 通信方式探索
    小程序简介小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验。需求微信小程序H5混合开发就是 在一个小程序中,采用部分小程序原生页面,部分通过Webview内嵌H5页面¹,二者配合实现完整业务逻辑的方案。image.png 为什么需......
  • idea 中springboot同一服务启动不同端口号
    编辑服务配置2.copy原服务配置一份指定对应端口号启动服务......
  • 基于JAVA的springboot+vue“智慧食堂”设计与实现,食堂管理系统,附源码+数据库+lw文档+P
    1、项目介绍本系统的用户可分为用户模块和管理员模块两大界面组成。一个界面用于管理员登录,管理员可以管理系统内所有功能,主要有首页,个人中心,用户管理,菜品分类管理,菜品信息管理,留言板管理,系统管理,订单管理等功能;另一界面用于用户登录,用户进入系统可以实现首页,菜品信息,留言板,个人......
  • 关于springboot上传完文件读取时资源目录未更新的情况
    之前在实现教学视频上传功能的时候碰到了一个问题,那就是每上传完一个视频文件,页面找不到对应的路径,必须重新构建项目才能找到相应的文件今天在课堂上向老师咨询,才明白javaweb项目读取资源并不是读取实际的本地资源,而是读取target对应目录下的,每个项目都会生成一个对象的target目......
  • Springboot文件上传接口
    Springboot文件上传接口文件entiypackagecom.qingge.springboot.entity;importcom.baomidou.mybatisplus.annotation.IdType;importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableName;importlombok.Data;@Data......
  • springboot添加@Scheduled定时任务多线程执行
    packagecom.example.demo;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.EnableAutoConfiguration;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.boot.autoc......
  • java前后端分离有详细内容吗?
    微服务架构java前后端分离都有哪些具体内容?目前,有不少客户朋友经常询问我们类似的问题。其实,在新的经济发展形势下,提质增效的低代码开发平台微服务架构早已成为不少新老客户的选择,它们不仅能提高办公协作效率,而且还能助力企业实现办公自动化快速发展。1、java前后端分离到底有啥......
  • uniapp微信小程序昵称和头像更新
    问题:微信小程序更新昵称和头像1.昵称更新前端:<inputclass="font_1text_2tex"v-model="nickname"type="nickname"@blur="bindblur"placeholder-style="color:#fff"placeholder="编辑资料"@input="bindinput&quo......
  • springboot 接入通用tkmapper和pagehelper,boot starter版,mysql5.7,boot2.7.9
    1、pom文件引入<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.6</version></dependency><dependency><groupId......