微信支付-Native支付(网页二维码扫码微信支付)简单示例

news2024/10/9 12:24:24

目录

概述

 界面展示 & 前端代码(Vue)

后端实现(SpringBoot)

 Maven依赖 

 下单接口(主要功能代码)

支付成功回调接口

测试(后端线上环境)


概述

本篇博文主要演示和说明网页扫码实现微信支付的功能。

Native支付?

Native支付是指商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”完成支付的模式。

使用前提?

已注册成为微信商户,在微信商户平台开通"Native支付",获取API证书和API密匙等参数,如果对于注册微信商户有所疑惑,请看博文:http://t.csdn.cn/BCecm,博文有讲解从零到商户的注册过程要求说明。

主要流程概述

Native支付的流程很简单,主要为:

1.前端传入金额等参数。

2.后端拿着参数向微信服务器创建预支付订单,取回一个支付地址,传回前端。

3.前端拿着支付地址生成二维码,微信扫码完成支付。

 界面展示 & 前端代码(Vue)

关于支付地址转为二维码

在此使用的是QRCode,使用方式很简单,导入,声明二维码放置节点元素,实例化QRCode生成二维码。具体使用方式看示例代码,或文档地址:

github地址

中文使用说明地址

js文件地址

输入金额,点击"捐助",调用后端接口获取支付地址,生成支付二维码。



<template>
  <div id="container">
    <!-- 图片 -->
    <div id="imgJuan"></div>
    <!-- 表单 -->
    <div id="input_box"><input type="text" id="my_input" v-model="total" :placeholder="iptText"><button @click="payHandle">捐助</button></div>
    <!-- 占位 -->
    <div style="height: 10px;"></div>
    <!-- 二维码 -->
    <div id="qrcode" ref="qrCodeBox" v-show="showFlag"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, getCurrentInstance } from "vue"
import axios from "axios";

// 获取二维码盒子节点(如下两种方式均可)
// 方式一、获取当前组件实例,通过实例获取节点
const { proxy } = getCurrentInstance()
// 方式二、通过ref获取节点
const qrCodeBox = ref(null);

// 支付二维码显示控制
let showFlag = ref(false);

// 输入框内容
const iptText = "请输入捐助金额(元)"

// 输入金额
let total = ref('');

// 触发下单支付
async function payHandle(){
  // 将金额单位转为分
  let total_F = parseFloat(total.value) * 100

  // 发送请求,获取支付地址
  const res = await axios.get(`http://后端接口地址/pay/nativePay?total=${total_F}`);
  console.log(res.data);
  // 将支付地址转为二维码,显示(QRCode参数为(二维码展示的盒子节点元素,显示的内容))
  // 这是vue项目,我将QRCode.min.js文件下载并在index.html引入了,因此在此文件看不到引入  
  const qrObj = new QRCode(qrCodeBox.value, res.data);
  showFlag.value = true;
}

</script>

<style scoped>
#container {
  border: solid red 1px;
  border-radius: 10px;
  /* width: fit-content; */
  width: 600px;
  margin: 0 auto;
  overflow: hidden;
}

#qrcode{
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 10px 0px;
}

button {
  border: none;
  background-color: #ce5944;
  color: white;
  font-weight: 600;
  height: 37px;
  width: 90px;
  position: relative;
  top: 1px;
  margin-left: 5px;
  border-radius: 5px;
  cursor: pointer;
}

button:hover{
  background-color: #d14e37;

}

#imgJuan {
  /* border: solid red 1px; */
  height: 300px;
  width: 100%;
  background: url("/juan.jpg") no-repeat center center;
  background-size: cover;
  border-radius: 5px;
}

#input_box {
  width: fit-content;
  margin: 0 auto;
  margin-top: 20px;
}

#my_input {
  border-radius: 3px;
  border: solid 1px #1c591f;
  height: 32px;
  width: 268px;
  padding-left: 5px;
}
</style>

后端实现(SpringBoot)

说明:在此,后端仅编写展示两个接口:"下单接口","支付回调接口"

 接口皆是根据官方SDK API文档实现,如果想要获取更多接口信息,例如"查单接口",请查看官网文档示例地址:微信Native支付及接口描述 & JavaSDK示例(githup地址)

 Maven依赖 

<dependency>
	<groupId>com.github.wechatpay-apiv3</groupId>
	<artifactId>wechatpay-java</artifactId>
	<version>0.2.11</version>
</dependency>

 使用官方提供的Java SDK,文档地址:微信支付 Java SDK

 下单接口(主要功能代码)

/**
     * Native支付下单,获取支付地址
     * @param total 金额
     * @return 支付地址,前端用于生成支付二维码
     */
    public String nativePay(Integer total){
        // 使用自动更新平台证书的RSA配置
        Config config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(merchantId) // 商户号
                        .privateKeyFromPath(NativeUtil.getResourcesPath() + "apiclient_key.pem")  // API证书地址(此处的路径自己调试一下,能找到就行)
                        .merchantSerialNumber(merchantSerialNumber) // API证书序列号
                        .apiV3Key(apiV3Key) // API密匙
                        .build();
        // 构建service
        NativePayService service = new NativePayService.Builder().config(config).build();
        // request.setXxx(val)设置所需参数,具体参数可见Request定义
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(total); // 金额
        request.setAmount(amount);  
        request.setAppid(appId); // 应用ID
        request.setMchid(merchantId);  // 商户号
        request.setDescription("Native测试商品标题");  // 商品描述
        request.setNotifyUrl("http://后端地址/pay/notifyNative");  // 支付成功的回调地址
        // 生成模拟系统内部订单号(yyyyMMddHHmmssSSS)
        request.setOutTradeNo(DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_PATTERN));  // 自己后端的唯一订单号,此处使用时间模拟
        // 调用下单方法,得到应答
        try {
            // 发送请求
            PrepayResponse response = service.prepay(request);
            // 使用微信扫描 code_url 对应的二维码,即可体验Native支付
            System.out.println(response.getCodeUrl());
            // 将支付地址返回
            return response.getCodeUrl();
        }catch (Exception e){
            System.out.println(e.getMessage());
            return e.getMessage();
        }
    }

支付成功回调接口

回调地址?

回调地址为:当前端生成的二维码被微信扫描并成功支付之后,微信服务器会将支付的信息发送到这个地址上。如有疑惑,文档地址:支付通知

/**
     * 成功支付的回调
     * @param request ·
     * @param response ·
     * @throws IOException ·
     */
    public void notifyNative(HttpServletRequest request, HttpServletResponse response) throws IOException {

        // 获取请求体原内容(此时获取的数据是加密的)
        BufferedReader reader = request.getReader();
        StringBuilder requestBody = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            requestBody.append(line);
        }

        // 获取请求携带的数据,构造参数
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(request.getHeader("Wechatpay-Serial")) // 微信支付平台证书的序列号
                .nonce(request.getHeader("Wechatpay-Nonce")) // 签名中的随机数
                .signature(request.getHeader("Wechatpay-Signature"))  // 应答的微信支付签名
                .timestamp(request.getHeader("Wechatpay-Timestamp")) // 签名中的时间戳
                .body(requestBody.toString()) // 请求体内容(原始内容,不要解析)
                .build();

        // 初始化RSAAutoCertificateConfig
        NotificationConfig config = new RSAAutoCertificateConfig.Builder()
                .merchantId(merchantId) // 商户号
                // API证书路径,路径自己调试,能找到就行(NativeUtil为自定义工具类)
                .privateKeyFromPath(NativeUtil.getResourcesPath() + "apiclient_key.pem") 
                .merchantSerialNumber(merchantSerialNumber) // 证书序列号
                .apiV3Key(apiV3Key) // APIV3密匙
                .build();

        // 初始化 NotificationParser
        NotificationParser parser = new NotificationParser(config);
        // 解析为Transaction对象(解密数据)
        Transaction transaction = parser.parse(requestParam, Transaction.class);
        // 获取支付单号
        log.info("支付成功,回调信息:{}", transaction);
        // 打印其中的"微信支付单号"字段,可用于查单操作
        log.info("微信支付单号:{}", transaction.getTransactionId());
    }

测试(后端线上环境)

测试内容

1.前端输入金额,点击【捐助】按钮,查看是否显示支付二维码。

2.微信扫码支付,查看回到接口是是否被调用,查看控制台输出。

 访问  

 输入金额,点击【捐助】

 微信扫码支付 

 

 查看控制台 

 至此,测试完毕。 

最后

此博文仅展示了从二维码到支付成功的过程,至于后续处理,如成功支付之后"如何通知前端页面做修改",这类后续处理需要读者根据自己实际情况进行处理,例如使用轮询还是WebSocket这类方式检查支付状态,都是没问题的。

最后,如文章有不足之处请指出,感谢访问。

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

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

相关文章

SpringSecurity学习

1.认证 密码校验用户 密码加密存储 Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter {Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}} 我们没有这个配置&#xff0c;默认明文存储, {id}password;实现…

html 学习 之 文本标签

下面是一些常见的HTML文本标签&#xff08;&#xff0c;&#xff0c;&#xff0c;&#xff0c;和&#xff09;以及它们的作用&#xff1a; 标签 (Emphasis - 强调): 作用&#xff1a;用于在文本中表示强调或重要性。 示例&#xff1a; <p>这是一段文本&#xff0c;&l…

python将dataframe按需绘制折线图、柱状图、双坐标图

目录 绘制TI折线图绘制 import matplotlib.pyplot as plt# 设置中文显示 plt.rcParams[font.sans-serif] [SimHei] # 指定默认字体 plt.rcParams[axes.unicode_minus] False # 解决负号显示问题绘制TI折线图 def draw_TI(df_TI_night, output_TI_png, sector_id, terrain, …

代码随想录算法训练营第五十九天| 503.下一个更大元素II,42. 接雨水

代码随想录算法训练营第五十九天| 503.下一个更大元素II&#xff0c;42. 接雨水 503.下一个更大元素II42. 接雨水暴力解法双指针优化单调栈解法 503.下一个更大元素II 题目链接 视频讲解 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &a…

腾讯云优惠券:定义、领取方法及使用教程

腾讯云作为国内知名的云计算服务提供商&#xff0c;经常为用户提供各种优惠活动&#xff0c;本文将详细介绍腾讯云优惠券的定义、领取方法及使用教程&#xff0c;助力大家轻松上云&#xff01; 一、腾讯云优惠券定义介绍 腾讯云优惠券是什么&#xff1f;腾讯云优惠券是腾讯云推…

谈一谈对string容器的赋值重载的更深一步理解

先来看一看我写的string容器&#xff08;包含了基本的构造&#xff0c;析构&#xff0c;赋值&#xff0c;拷贝&#xff09;。 class String { public://构造/*explicit*/ String(const char* arr "") {assert(arr);//判别不会传入空指针cout << "String…

markdown pdf报错问题

vscode的md文件转pdf的插件 右键可以直接转换 但是很久没用&#xff0c;现在重新使用出现了报错 ERROR: Failed to download Chromium! If you are behind a proxy, set the http.proxy option to settings.json and restart Visual Studio Code. 解决办法 首…

万字C语言之分支语句和循环语句

前言&#xff1a; &#x1f4d5;作者简介&#xff1a;热爱编程的小七&#xff0c;致力于C、Java、Python等多编程语言&#xff0c;热爱编程和长板的运动少年&#xff01; &#x1f4d8;相关专栏Java基础语法&#xff0c;JavaEE初阶&#xff0c;数据库&#xff0c;数据结构和算法…

OpenCV DNN深度学习简介

&#x1f482; 个人主页:风间琉璃&#x1f91f; 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 前言 本文基本上来自以下官方手册&#xff1a;https://learnopencv.com/deep-l…

9月8日扒面经

慢sql日志的排查和调优 开启慢查询日志&#xff1a;首先需要确保数据库的慢查询日志功能已经开启。在MySQL中&#xff0c;可以通过设置slow_query_log参数为1来开启慢查询日志&#xff0c;并设置long_query_time参数来定义慢查询的阈值。定位慢查询语句&#xff1a;根据慢查询…

.kann勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复

引言&#xff1a; 在数字化时代&#xff0c;勒索病毒已经成为了网络安全的严重威胁&#xff0c;其中 .kann 勒索病毒是最新的一种。这种恶意软件通过加密您的数据文件&#xff0c;然后勒索您支付赎金以获取解密密钥。本文将深入探讨 .kann 勒索病毒、如何恢复被它加密的数据文件…

【多线程】Synchronized 用法详解

Synchronized 用法详解 一. synchronized 的特性1. 互斥2. 刷新内存3. 可重入 二. synchronized 的使用1. 直接修饰普通方法2. 修饰静态方法3. 修饰代码块 三. Java 标准库中的线程安全类 synchronized: 又叫监视器锁 monitor lock一. synchronized 的特性 1. 互斥 (保证原子…

SpringBoot整合WebSocket【代码】

系列文章目录 一、SpringBoot连接MySQL数据库实例【tk.mybatis连接mysql数据库】 二、SpringBoot连接Redis与Redisson【代码】 三、SpringBoot整合WebSocket【代码】 文章目录 系列文章目录代码下载地址一、效果演示二、引入依赖三、WebSocketConfig四、SessionWrap五、WebSoc…

这样的接口千万别暴露,小心横向越权。

前言 谈不上是多么厉害的知识&#xff0c;但可能确实有人不清楚或没见过。 我还是分享一下&#xff0c;就当一个小知识点。 如果知道的&#xff0c;就随便逛逛&#xff0c;不知道的&#xff0c;Get到了记得顺手点个赞哈。 正文 1、接口别随便暴露 当一个项目的维护周期拉长的时…

zustand实践与源码阅读

如何管理数据? 日常使用&#xff1a;发布订阅、context、redux… zustand是一个轻量、快速、可扩展的状态管理库。 目前在社区非常流行&#xff0c;现在github上有30K的star。npm包的下载量&#xff0c;现在也仅次于redux&#xff0c;位于mobx之上&#xff0c;并且差距日益扩大…

客户端SDK测试是什么?如何测?

01 是什么 客户端SDK是为第三方开发者提供的软件开发工具包&#xff0c;包括SDK接口、开发文档和Demo示例等。SDK和应用之间是什么关系呢&#xff1f;以云信即时消息服务为例&#xff0c;如下图所示&#xff0c;应用客户端通过调用云信SDK接口&#xff0c;进行消息等数据查询存…

华为云云耀云服务器L实例评测 | 零门槛入门使用教学

近年来&#xff0c;随着企业应用上云&#xff0c;云服务器一直备受用户的关注。特别是对于大多数的中小企业在上云的过程中&#xff0c;都希望能使用的是一种快速、简洁高效的云服务器。因为这样能尽可能地减轻企业运维的成本&#xff0c;同时又能方便企业的信息技术人员管理。…

Set和Map及哈希表介绍

搜索方式介绍TreeMapMap使用 TreeSetSet使用 Set和Map常用方法练习(后面补充)练习之Set/Mapoj练习&#xff08;后面补充&#xff09;哈希表哈希冲突避免冲突-哈希函数设计避免冲突-负载因子调节避免冲突-闭散列避免冲突-开散列 模拟实现哈希表哈希Map源码分析 搜索方式介绍 哈…

mysql的索引分类

索引分类 在 MySQL 数据库&#xff0c;将索引的具体类型主要分为以下几类&#xff1a;主键索引、唯一索引、常规索引、全文索引。 分类 含义 特点 关键字 主键 索引 针对于表中主键创建的索引 默认自动创建 , 只能 有一个 PRIMARY 唯一 索引 避免同一个表中某数据列中…

C语言“牵手”速卖通商品详情数据方法,速卖通商品详情API接口,速卖通API申请指南

速卖通是全球最大的自营式电商企业之一&#xff0c;在线销售计算机、手机及其它数码产品、家电、汽车配件、服装与鞋类、奢侈品、家居与家庭用品、化妆品与其它个人护理用品、食品与营养品、书籍与其它媒体产品、母婴用品与玩具、体育与健身器材以及虚拟商品等。 速卖通平台的…