微信小程序实现拉起微信支付功能-最简单版

里面有很多逻辑需要大家自己写啊,比如订单获取啊,生成订单啊,变更订单状态,退款啊,等等的,我这里就实现了一个基本的功能,就是拉起支付,支付到账这样的,大家根据需求自己编写就行。我这里提供的基本上都是复制了直接就能用的那种啊,前提是你要有商户号,要生成秘钥证书这些啊

首先需要去注册商户号啊,这个过程比较复杂啊,然后微信平台上有引导的,大家跟着做就行

就是这个位置啊,然后需要提交的材料准备好就行,基本上当天就会批下来,费率的话每个行业都是不一样的啊,然后在小程序里关联到商户号就行,

代码编写 只附部分核心程序,他是需要拿着openid去后台获取相应的参数的啊,这里的orderId我直接前端随机了,正常应该写在后端的啊,大家额注意一下。有些参数没明白的,可以去微信平台的文档里看一下啊,都是一一对应的啊,然后我这个也不需要下载什么jdk,maven的话也是springboot那一套啊,没什么特殊的

data: {phoneNumber: '', // 存储手机号openid: '', // 用户的 openidorderId: '', // 订单 IDpaymentData: null, // 存储从后端获取的支付参数statu:'点击支付',isButtonDisabled: false // 默认按钮是可点击的},generateOrderId: function() {// 获取当前时间戳const timestamp = new Date().getTime();// 生成一个随机数const randomNum = Math.floor(Math.random() * 100000);// 拼接时间戳和随机数生成订单号return timestamp.toString() + randomNum.toString();},/*** 生命周期函数--监听页面加载*/onLoad(options) {const orderId = this.generateOrderId();const openId = wx.getStorageSync('openId')this.setData({openid: openId,orderId: orderId});},// 发起支付函数startPayment: function () {const that = this;// 先从后端获取支付参数wx.request({url: url+'api/getPaymentParams',method: 'POST',data: {openid: this.data.openid,orderId: this.data.orderId},success: function (res) {if (res.data && res.data.success) {const paymentData = res.data.paymentData;console.log(res.data.paySign)// 调用微信支付接口wx.requestPayment({timeStamp: paymentData.timeStamp,nonceStr: paymentData.nonceStr,package: paymentData.package,signType: paymentData.signType,paySign: res.data.paySign,success: (res) => { // 使用箭头函数that.setData({statu: '已支付',isButtonDisabled: true // 将按钮设置为不可点击});console.log('支付成功', res);wx.request({url: url + 'api/setOrder?orderId=' + that.data.orderId, //仅为示例,并非真实的接口地址method: 'GET',header: { 'content-type': 'application/json' },success: (res) => {// 处理成功请求的回调}});// 支付成功后的操作,如跳转页面或其他逻辑},fail: (res) => { // 使用箭头函数console.log('支付失败', res);// 支付失败后的操作,如提示用户重新支付}});} else {wx.showToast({title: '此订单已支付',icon: 'none'});console.error('获取支付参数失败', res);}},fail: function (err) {wx.showToast({title: '此订单已支付', icon: 'none'});console.error('请求支付参数失败', err);}});
},
Java:服务器端private static final String APPID = "";
private static final String APPSECRET = "";
private  static  final String MCHID="";//商户号
private  static  final String NOTIFYURL="";//回执地址
private  static  final String  MCHKEY="";//秘钥@PostMapping("/getPaymentParams")
public @ResponseBody Map<String, Object> getPaymentParams(@RequestBody Map<String, String> request) {String openid = request.get("openid");String orderId = request.get("orderId");String money="1";//目前模拟数据,后续需要通过支付金额表或者是通过第三方获取支付金额,通过OPENID去user表找到手机号,然后通过手机号查询金额表// 创建统一下单请求参数Map<String, String> params = new HashMap<>();params.put("appid", APPID);params.put("mch_id",MCHID );params.put("nonce_str", WXPayUtil.generateNonceStr());params.put("body", "订单支付");params.put("out_trade_no", orderId);params.put("total_fee", money); // 单位为分params.put("spbill_create_ip", "127.0.0.1");params.put("notify_url", NOTIFYURL);params.put("trade_type", "JSAPI");params.put("openid", openid);try {String sign = WXPayUtil.generateSignature(params, MCHKEY);params.put("sign", sign);String xml = WXPayUtil.mapToXml(params);String response = HttpUtil.post("https://api.mch.weixin.qq.com/pay/unifiedorder", xml);Map<String, String> result = WXPayUtil.xmlToMap(response);if ("SUCCESS".equals(result.get("return_code")) && "SUCCESS".equals(result.get("result_code"))) {String prepayId = result.get("prepay_id");Map<String, String> payMap = new HashMap<>();payMap.put("appId", APPID);payMap.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));payMap.put("nonceStr", WXPayUtil.generateNonceStr());payMap.put("package", "prepay_id=" + prepayId);payMap.put("signType", "MD5");String paySign = WXPayUtil.generateSignature(payMap, MCHKEY);Map<String, Object> responseMap = new HashMap<>();responseMap.put("success", true);responseMap.put("paymentData", payMap);responseMap.put("paySign", paySign);Order order=new Order();order.setOrderId(orderId);order.setOpenId(openid);order.setPayTime(new Date());order.setMoney(money);orderService.add(order);return responseMap;} else {Map<String, Object> responseMap = new HashMap<>();responseMap.put("success", false);responseMap.put("errMsg", result.get("err_code_des"));return responseMap;}} catch (Exception e) {e.printStackTrace();Map<String, Object> responseMap = new HashMap<>();responseMap.put("success", false);responseMap.put("errMsg", e.getMessage());return responseMap;}
}

util类,用来生成随机字符串,加密,验证签名等作用的

public class WXPayUtil {

    public static String generateNonceStr() {
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
    }

    public static String generateSignature(Map<String, String> data, String key) throws Exception {
        // 1. Sort the parameters in dictionary order
        Map<String, String> sortedData = new TreeMap<>(data);

        // 2. Concatenate the parameters as per the format: key1=value1&key2=value2...
        String stringA = sortedData.entrySet().stream()
                .map(entry -> entry.getKey() + "=" + entry.getValue())
                .collect(Collectors.joining("&"));

        // 3. Append the key
        String stringSignTemp = stringA + "&key=" + key;

        // 4. Sign the concatenated string using MD5
        return MD5(stringSignTemp).toUpperCase();
    }

    public static String mapToXml(Map<String, String> data) {
        StringBuilder xml = new StringBuilder();
        xml.append("<xml>");
        for (Map.Entry<String, String> entry : data.entrySet()) {
            xml.append("<").append(entry.getKey()).append(">");
            xml.append(entry.getValue());
            xml.append("</").append(entry.getKey()).append(">");
        }
        xml.append("</xml>");
        return xml.toString();
    }

    public static Map<String, String> xmlToMap(String strXML) throws Exception {
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(new StringReader(strXML));
        Element root = doc.getRootElement();
        List<Element> children = root.getChildren();
        Map<String, String> data = new HashMap<>();
        for (Element child : children) {
            data.put(child.getName(), child.getTextNormalize());
        }
        return data;

    }

    private static String MD5(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte b : array) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

    /**
     * 验证签名
     * @param data 通知数据
     * @param key 密钥
     * @return 签名是否有效
     * @throws Exception
     */
    public static boolean isSignatureValid(Map<String, String> data, String key) throws Exception {
        if (!data.containsKey("sign")) {
            return false;
        }
        String sign = data.get("sign");
        return generateSignature(data, key).equals(sign);
    }
}
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1483730.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

一分钟了解半导体行业国产通讯方案

随着半导体行业的快速发展,半导体通讯设备国产化的需求日益强烈,ZLG致远电子基于行业需求,推出系统的DeviceNet主从站控制和网关通讯方案。 ▌半导体行业中DeviceNet的应用 半导体行业中设备一般分为前道设备和后道设备。前道是指晶圆制造厂的加工过程,在空白的硅片完成电…

SAPUI5基础知识15 - 理解控件的本质

1. 背景 经过一系列的练习&#xff0c;通过不同的SAPUI5控件&#xff0c;我们完成了对应用程序界面的初步设计&#xff0c;在本篇博客中&#xff0c;让我们一起总结下SAPUI5控件的相关知识点&#xff0c;更深入地理解SAPUI5控件的本质。 通常而言&#xff0c;一个典型UI5应用…

网络编程-TCP 协议的三次握手和四次挥手做了什么

TCP 协议概述 1. TCP 协议简介 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议。 TCP 协议提供可靠的通信服务&#xff0c;通过校验和、序列号、确认应答、重传等机制保证数据传输…

Uniapp 组件 props 属性为 undefined

问题 props 里的属性值都是 undefined 代码 可能的原因 组件的名字要这样写&#xff0c;这个官方文档有说明

美图WHEE AI:包括文生图、图生图、风格模型训练多种模式图片创作绘画创作平台

美图WHEE AI是一款基于MiracleVision模型的创作平台&#xff0c;提供文生图和图生图功能。用户可以通过输入文字或上传照片生成画作&#xff0c;并自定义风格。美图通过收购站酷网&#xff0c;增强了模型商店和版权能力&#xff0c;丰富了产品线。 美图WHEE功能演示观看请到喜…

华为“铁三角模式”在数据类项目中的应用和价值

引言&#xff1a;随着信息技术的飞速发展&#xff0c;企业纷纷踏上数字化转型的道路&#xff0c;希望通过数据分析和智能决策来提升企业竞争力。在这一过程中&#xff0c;数据类项目成为关键&#xff0c;它们旨在构建高效的数据治理和分析平台&#xff0c;为企业决策提供有力支…

MSVC2017+Qt 打包

在环境变量下配置好 QT 和 MSVC 的路径 相关搜索&#xff1a; 找不到msvcp140.dll 1.搜索 Qt 选择在编译器路径下打开 2. Windeployqt 生成打包&#xff0c;正常情况下生成 VC 相关package&#xff0c; 即 msvcp140.dll 等MSVC 相关 但是lz尝试没有生成 解决办法 先将生成…

【开源 Mac 工具推荐之 2】洛雪音乐(lx-music-desktop):免费良心的音乐平台

旧版文章&#xff1a;【macOS免费软件推荐】第6期&#xff1a;洛雪音乐 Note&#xff1a;本文在旧版文章的基础上&#xff0c;新更新展示了一些洛雪音乐的新功能&#xff0c;并且描述更为详细。 简介 洛雪音乐&#xff08;GitHub 名&#xff1a;lx-music-desktop &#xff09;…

CTF-Web习题:[BJDCTF2020]ZJCTF,不过如此

题目链接&#xff1a;[BJDCTF2020]ZJCTF&#xff0c;不过如此 解题思路 访问靶场链接&#xff0c;出现的是一段php源码&#xff0c;接下来做一下代码审阅&#xff0c;发现这是一道涉及文件包含的题 主要PHP代码语义&#xff1a; file_get_contents($text,r); 把$text变量所…

One-Class SVM

前提知识&#xff1a;支持向量机&#xff08;SVM&#xff09;-CSDN博客 主要思想 找一个超平面将样本中的正例圈出来&#xff0c;预测就是用这个超平面做决策&#xff0c;在圈内的样本就认为是正样本&#xff0c;圈外的是其他样本&#xff0c;如图1所示&#xff1a; 图1 OSVM…

Blender4.2版本正式上线,新版本的5个主要功能!

​Blender刚刚推出了备受瞩目的 Blender 4.2 版本&#xff0c;这款软件专为那些在视觉特效、动画制作、游戏开发和可视化设计领域工作的艺术家们量身打造。作为最新的长期稳定更新&#xff0c;Blender 4.2 不仅稳定可靠&#xff0c;还引入了备受期待的“Eevee Next”实时渲染引…

基于深度残差网络迁移学习的浸润性导管癌检测

1. 引言 癌症是一种异常细胞不受控制地分裂损害健康组织的疾病。皮肤或覆盖我们内脏的组织中的癌细胞被称为癌。乳房中的大多数癌是导管癌。侵袭性导管癌(Invasive Ductal Carcinoma, IDC)始于乳管&#xff0c;侵犯乳房周围纤维组织&#xff0c;晚期可通过血液扩散至淋巴结或身…

【Linux】线程——线程池、线程池的实现、线程安全的线程池、单例模式的概念、饿汉和懒汉模式、互斥锁、条件变量、信号量、自旋锁、读写锁

文章目录 Linux线程7. 线程池7.1 线程池介绍7.2 线程池的实现7.3 线程安全的线程池7.3.1 单例模式的概念7.3.2 饿汉和懒汉模式 8. 常见锁使用汇总8.1 互斥锁&#xff08;Mutex&#xff09;8.2 条件变量&#xff08;Condition Variable&#xff09;8.3 信号量&#xff08;Semaph…

华为云GaussDB部署指南:主备架构的常见问题与解决方案

文章目录 华为云GaussDB部署指南&#xff1a;主备架构的常见问题与解决方案背景介绍部署步骤1.修改主机名2.软件安装检查3.禁用交换内存4.创建数据目录并挂载5.配置NTP时钟同步6.添加资源限制参数7.修改网卡的MTU8.上传安装工具包9.编辑集群配置文件10.修改集群安装模板11.安装…

ROS、pix4、gazebo、qgc仿真ubuntu20.04

一、ubuntu、ros安装教程比较多&#xff0c;此文章不做详细讲解。该文章基于ubuntu20.04系统。 pix4参考地址&#xff1a;https://docs.px4.io/main/zh/index.html 二、安装pix4 1. git clone https://github.com/PX4/PX4-Autopilot.git --recursive 2. bash ./PX4-Autopilot…

可视化剪辑,账号矩阵,视频分发,聚合私信一体化营销工具 源----代码开发部署方案

可视化剪辑&#xff1a; 为了实现可视化剪辑功能&#xff0c;可以使用流行的视频编辑软件或者开发自己的视频编辑工具。其中&#xff0c;通过设计用户友好的界面&#xff0c;用户可以简单地拖拽和放大缩小视频片段&#xff0c;剪辑出满足需求的视频。在开发过程中&#xff0c;可…

SpringBoot框架学习笔记(四):yaml 介绍及其使用

1 yaml 介绍 百度百科&#xff1a;YAML 是 “YAML Aint a Markup Language”&#xff08;YAML 不是一种标记语言&#xff09;的递归缩写。在开发这种语言时&#xff0c;YAML 的意思其实是&#xff1a;“Yet Another Markup Language”&#xff08;仍是一种标记语言&#xff09…

电流测量分流电阻

电流测量分流电阻 测量电流的设备称为安培计。大多数现代安培计测量已知电阻的精密电阻上的电压降。电流的计算使用欧姆定律&#xff1a;我五R 大多数电流表都内置电阻器来测量电流。但是&#xff0c;当电流对于电流表来说太高时&#xff0c;需要不同的设置。解决方案是将电流…

使用 Flask 3 搭建问答平台(三):注册页面模板渲染

前言 前端文件下载 链接https://pan.baidu.com/s/1Ju5hhhhy5pcUMM7VS3S5YA?pwd6666%C2%A0 知识点 1. 在路由中渲染前端页面 2. 使用 JinJa 2 模板实现前端代码复用 一、auth.py from flask import render_templatebp.route(/register, methods[GET]) def register():re…

= null 和 is null;SQL中关于NULL处理的4个陷阱;三值逻辑

一、概述 1、NULL参与的所有的比较和算术运算符(>,,<,<>,<,>,,-,*,/) 结果为unknown&#xff1b; 2、unknown的逻辑运算(AND、OR、NOT&#xff09;遵循三值运算的真值表&#xff1b; 3、如果运算结果直接返回用户&#xff0c;使用NULL来标识unknown 4、如…