微信-Native支付(扫二维码支付)工具类 2023最新保姆教程

0、照着微信开发文档 取到证书、秘钥等  好几个key

1、获取商户号merchantId
账户中心->商户信息->微信支付商户号

3、获取商户证书序列号merchantSerialNumber
账户中心->API安全->API证书管理

5、获取appID
产品中心->AppID账号管理

1、这个链接教你获取各种key   

Java接入微信支付APIV3(Native)_java native微信支付-CSDN博客

 2、导入依赖
<!--微信支付依赖-->
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-java</artifactId>
            <version>0.2.5</version>
        </dependency>
        <!-- hutool -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.16</version>
        </dependency>
3、工具类直接复制 配置好各种key  就可以直接调用了

import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.partnerpayments.nativepay.model.Transaction;
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
import com.wechat.pay.java.service.payments.nativepay.model.Amount;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;

/**
 * Native 支付工具类  获取支付地址、解析支付数据
 */
@Slf4j
public class PayUtils {
    //商户号
    public static String merchantId = "16***";
    //商户API私钥路径 服务器里的路径 
    public static String privateKeyPath = "/home/jx****rvice/apiclient_key.pem";
    //商户证书序列号
    public static String merchantSerialNumber = "*******";
    //商户APIV3密钥
    public static String apiV3key = "iK8fl7*3";
    public static String appId = "wx0*****7e";

    // 使用自动更新平台证书的RSA配置
    public static Config config = new RSAAutoCertificateConfig.Builder()
            .merchantId(merchantId) // 商户号
            .privateKeyFromPath(privateKeyPath)  // API证书地址(此处的路径自己调试一下,能找到就行)
            .merchantSerialNumber(merchantSerialNumber) // API证书序列号
            .apiV3Key(apiV3key) // API密匙
            .build();
    // 初始化 解析器 NotificationParser
    public static NotificationParser parser = new NotificationParser((NotificationConfig) config);
    /**
     * 获取支付地址 设置回调路径
     *
     * @param total     【总金额】 订单总金额,单位为分
     * @param desc      商品描述
     * @param notifyUrl 回调地址(必须是http)   如:"http://*7.*2.***.2**:8081/pay/notifyNative"
     * @return
     * @Param orderNo 自己后端的唯一订单号
     */
    public static String nativePayAddr(Integer total, String desc, String notifyUrl, String orderNo, String attach) {
        // 构建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(desc);  // 商品描述
        request.setNotifyUrl(notifyUrl);  // 支付成功的回调地址
        request.setAttach(attach);
        // 生成模拟系统内部订单号(yyyyMMddHHmmssSSS)
        request.setOutTradeNo(orderNo);  // 自己后端的唯一订单号,此处使用时间模拟
        // 调用下单方法,得到应答
        try {
            // 发送请求
            PrepayResponse response = service.prepay(request);
            // 使用微信扫描 code_url 对应的二维码,即可体验Native支付
            System.out.println(response.getCodeUrl());
            // 将支付地址返回
            return response.getCodeUrl();
        } catch (Exception e) {
            System.out.println("获取支付的url失败:" + e.getMessage());
            return e.getMessage();
        }
    }



    /**
     * 解析器 解密微信给的数据
     *
     * @param request
     * @return
     */
    public Transaction parser(HttpServletRequest request) {
        try {
            // 获取请求体原内容(此时获取的数据是加密的)
            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();
            // 解析为Transaction对象(解密数据)
            Transaction transaction = parser.parse(requestParam, Transaction.class);
            //解密完成后的数据
            return transaction;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
4、具体调用  复制直接用 

swagger-ui 、ipUtil工具类 、@Slf4j  哪里报红删哪里 

实体类、支付记录表 自己设计吧 记得把支付日志表给我一份 




import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jxn.mapper.PayLogMapper;
import com.jxn.pojo.PayLog;
import com.jxn.utils.IpUtils;
import com.jxn.utils.PayUtils;
import com.jxn.utils.Result;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.partnerpayments.nativepay.model.Transaction;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.DynamicParameter;
import io.swagger.annotations.DynamicParameters;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

/**
 * @author szl
 * @date 2023/11/2 0002 10:30
 */
@Slf4j
@Api(tags = "支付")
@RestController
@CrossOrigin
@RequestMapping("/pay")
public class WechatPayController {

    @Autowired
    PayLogMapper payLogMapper;

    /**
     * Native支付下单,获取支付地址
     *
     * @param
     * @return 支付地址,前端用于生成支付二维码
     */
    @ApiOperation(value = "预支付,获取支付地址", response = Result.class)
    @DynamicParameters(name = "data", properties = {
            @DynamicParameter(name = "total", value = "页码", example = "1", required = true),
            @DynamicParameter(name = "userId", value = "条数", example = "10", required = true),
    })
    @PostMapping("/getNativePayAddr")
    public String nativePayAddr(HttpServletRequest request, @RequestBody JSONObject data) {
        //String ipAddr = IpUtils.getIpAddr(request);
        Integer total = data.getInteger("total");
        String userId = data.getString("userId");
        JSONObject attach = new JSONObject();
        attach.put("userId", userId);
        //attach.put("ipAddr", ipAddr);
        String notifyUrl = "http://4*.*2.1*2.2**:8081/pay/notifyNative";
        String orderNo = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_PATTERN);
        //调用支付工具类,获取支付的url(也就是二维码)
        String payAddr = PayUtils.nativePayAddr(total, "测试xxx商品简述", notifyUrl, orderNo, attach.toString());
        return payAddr;
    }

    @ApiOperation(value = "成功支付的回调", response = Result.class)
    @PostMapping("/notifyNative")
    public void notifyNative(HttpServletRequest request, HttpServletResponse response) throws IOException {
    
        //String ipAddr = IpUtils.getIpAddr(request);
        //log.info("ipaddr:" + ipAddr);
        String a = "{\"transaction_id\":\"1217752501201407033233368018\",\"amount\":{    \"payer_total\":100,    \"total\":100,    \"currency\":\"CNY\",    \"payer_currency\":\"CNY\"},\"mchid\":\"1230000109\",\"trade_state\":\"SUCCESS\",\"bank_type\":\"CMC\",\"promotion_detail\":[    {        \"amount\":100,        \"wechatpay_contribute\":0,        \"coupon_id\":\"109519\",        \"scope\":\"GLOBAL\",        \"merchant_contribute\":0,        \"name\":\"单品惠-6\",        \"other_contribute\":0,        \"currency\":\"CNY\",        \"stock_id\":\"931386\",        \"goods_detail\":[            {                \"goods_remark\":\"商品备注信息\",                \"quantity\":1,                \"discount_amount\":1,                \"goods_id\":\"M1006\",                \"unit_price\":100            },            {                \"goods_remark\":\"商品备注信息\",                \"quantity\":1,                \"discount_amount\":1,                \"goods_id\":\"M1006\",                \"unit_price\":100            }        ]    },    {        \"amount\":100,        \"wechatpay_contribute\":0,        \"coupon_id\":\"109519\",        \"scope\":\"GLOBAL\",        \"merchant_contribute\":0,        \"name\":\"单品惠-6\",        \"other_contribute\":0,        \"currency\":\"CNY\",        \"stock_id\":\"931386\",        \"goods_detail\":[            {                \"goods_remark\":\"商品备注信息\",                \"quantity\":1,                \"discount_amount\":1,                \"goods_id\":\"M1006\",                \"unit_price\":100            },            {                \"goods_remark\":\"商品备注信息\",                \"quantity\":1,                \"discount_amount\":1,                \"goods_id\":\"M1006\",                \"unit_price\":100            }        ]    }],\"success_time\":\"2018-06-08T10:34:56+08:00\",\"payer\":{    \"openid\":\"oUpF8uMuAJO_M2pxb1Q9zNjWeS6o\"},\"out_trade_no\":\"1217752501201407033233368018\",\"AppID\":\"wxd678efh567hg6787\",\"trade_state_desc\":\"支付成功\",\"trade_type\":\"MICROPAY\",\"attach\":\"自定义数据\",\"scene_info\":{    \"device_id\":\"013467007045764\"}\n}";
        Transaction transaction = JSON.parseObject(a, Transaction.class);
        //Transaction transaction = new PayUtils().parser(request);
        log.info("解析后的数据:" + transaction.toString());
        // 获取支付单号
        log.info("支付成功,回调信息:{}", transaction);
        // 打印其中的"微信支付单号"字段,可用于查单操作
        log.info("微信支付单号:{}", transaction.getTransactionId());
        //解密完成后的数据
        PayLog payLog = new PayLog();
        payLog.setPayStatus(transaction.getTradeStateDesc());
        payLog.setCreateTime(transaction.getSuccessTime());
        payLog.setTotal(transaction.getAmount().getTotal());
        payLog.setTransactionId(transaction.getTransactionId());//微信支付系统生成的订单号
        payLog.setOrderNo(transaction.getOutTradeNo());//自己系统的订单号
        payLog.setPayType(transaction.getTradeType().toString());//支付类型
        if ("SUCCESS".equals(transaction.getTradeState().toString())) {
            payLog.setPayStatus("1");//交易状态
        } else {
            payLog.setPayStatus("0");//交易状态
        }
        payLog.setOpenid(transaction.getPayer().getSubOpenid() + transaction.getPayer().getSpOpenid());//支付人信息 包含openid
        String goodsName = transaction.getPromotionDetail().get(0).getName();
        payLog.setReturnData(transaction.toString());
        log.info("插入支付日志:{}", payLog.toString());
        payLogMapper.insert(payLog);
    }
}

这是官方的地址 微信回调给到你的数据  解析后存到自己 的支付记录表   

支付通知 - Native支付 | 微信支付商户文档中心

5、最后

1、拿到支付的url,搜索在线生成二维码,粘贴url 生成二维码

2、扫码支付后,触发回调,解析Transaction,取有用的数据,存到日志表

回调时  Transaction transaction  取得是demo数据,记得注释掉

有问题评论 在线答复。记得 支付日志表设计完 给我一份

饭在锅里,钱在抽屉里,工具类在这里,具体使用在那里,配置类在开发者文档里,我出去办点事

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于卷积神经网络的抗压强度预测,基于卷积神经网络的抗折强度预测

目录 背影 卷积神经网络CNN的原理 卷积神经网络CNN的定义 卷积神经网络CNN的神经元 卷积神经网络CNN的激活函数 卷积神经网络CNN的传递函数 卷积神经网络CNN抗压强度预测 完整代码:基于卷积神经网络的抗压强度和抗折强度预测,基于CNN的抗压强度和抗折强度预测(代码完整,数据…

CAN报文的信号和信号组传递的意义

CAN将数据发送到COM层&#xff0c;在这个过程中报文是如何传递的&#xff1f; 0x105指的是一帧CAN报文&#xff0c;信号组指的是一帧CAN报文里的所有数据&#xff0c;信号指的是一帧CAN报文里的每一个信号&#xff0c;PDU代表了一帧CAN报文&#xff0c;它由报文ID&#xff08;I…

MySQL(7):单行函数

不同DBMS函数的差异 内置函数&#xff1a; 系统内置的通用函数。 自定义函数&#xff1a; 根据自己的需要编写的函数。 大多数 DBMS 使用&#xff08;||&#xff09;或者&#xff08;&#xff09;来做拼接符&#xff0c;而在 MySQL 中的字符串拼接函数为concat()。 大部分 D…

Kafka(二)消息系统设计

文章目录 前言整体设计时序图时序图解释 最后 前言 当多个系统之间通过Kafka来解耦时&#xff0c;在系统设计初期&#xff0c;基本的要求都是相似的&#xff0c;只不过是消费消息时的业务逻辑可能不同。 本文以业务系统和邮件系统解耦作为示例。业务系统需要发送邮件时&#…

后端接口接收对象和文件集合,formdata传递数组对象

0 问题 后端接口需要接收前端传递过来的对象和文件集合&#xff1b;对象中存在数组对象 1 前端和后端 前端只能使用formdata来传递参数&#xff0c;后端不使用RequestBody注解 2 formdata传递数组对象 2.1 多个参数对象数组 addForm: {contactInfo: [{contactPerson: ,…

黑客入门 15 个必杀技能!

互联网新兴技术不断涌现&#xff0c;在给人类带来巨大财富和便捷的同时&#xff0c;也带来了非常严峻的网络安全问题。 侵害个人隐私、侵犯知识产权、网络犯罪等时有发生&#xff0c;网络监听、网络攻击、网络恐怖主义活动等成为**全球公害。 习主席在全国网络安全和信息化工…

[Docker]四.Docker部署nodejs项目,部署Mysql,部署Redis,部署Mongodb

一.部署nodejs项目,映射端口,挂载数据卷 可以到https://hub.docker.com/去搜索node镜像,然后下载,也可以直接通过docker pull node下载镜像,然后用这个node镜像启动容器node,这样系统就集成了node服务了,在这里挂载www/node目录到容器中,并指定端口映射,运行nodejs程序,安装npm…

PMIC、电源管理MAX77646ANP、MAX77647AANP、MAX77675AEWE、MAX77847AEWL DC-DC 开关稳压器

一、MAX77646ANP、MAX77647AANP 低IQ SIMO PMIC支持原电池应用的1.8V工作电压 MAX77646/MAX77647为尺寸和效率至关重要的低功耗应用提供电源解决方案。该IC集成单电感多输出(SIMO)降压/升压稳压器&#xff0c;可通过单个电感提供三个可独立编程的电源轨&#xff0c;尽可能地减…

原地封神!一个只用套模板即可制作电子相册的网站

对于忙碌的年轻人来说&#xff0c;一键操作的模板意味着无需复杂的操作步骤&#xff0c;就能轻松制作出精美的电子相册。 但是一个好的工具也是事关重要&#xff0c;最近发现了一款非常适合年轻人的模板---FLBOOK在线制作电子杂志平台&#xff0c;只需要找到合适的模板即可制作…

计算虚拟化2——内存虚拟化

目录 物理机内存访问过程 虚拟地址VA和物理地址PA概念 MUU实现VA到PA所使用的映射表 内存虚拟化类型 内存软件辅助虚拟化 内存硬件辅助虚拟化 内存虚拟化-内存超分配 内存共享 内存置换 内存气泡 物理机内存访问过程 内存的基本知识 内存都是从物理地址0开始的&…

2023腾讯云双11优惠3年轻量2核2G4M服务器366.6元,三年价哦!

腾讯云3年轻量应用服务器配置为2核2G4M带宽、50GB SSD系统盘双11优惠价格366.6元三年、108元一年&#xff0c;只是限制月流量&#xff0c;套餐自带300GB月流量。腾讯云百科txybk.com分享2023腾讯云双11优惠活动3年轻量2核2G4M带宽优惠价格、购买条件&#xff1a; 3年轻量2核2G…

ubuntu无网络连接,没有网络标识,快速解决方法

在这里插入代码片当我们装虚拟机的时候&#xff0c;需要用到网络时发现没有网络连接&#xff0c;且右上角没有网络标识符&#xff0c;这时只需要简单的输入一下三个命令即可 sudo nmcli networking offsudo nmcli networking onsudo service network-manager restart然后重启客…

非递归方法实现二叉树前、中、后序遍历

文章目录 非递归实现二叉树前、中、后序遍历一、非递归实现前序遍历1.思路2.代码 二、非递归实现二叉树的中序遍历1.思路2.代码 三、非递归实现二叉树的后序遍历1.思路2.代码 非递归实现二叉树前、中、后序遍历 一、非递归实现前序遍历 1.思路 前序遍历的顺序是 &#xff1a;根…

JVM离线分析-使用MAT分析dump堆文件

1. MAT&#xff08;Memory Analyzer Tool&#xff09;的介绍 官方介绍 The Eclipse Memory Analyzer is a fast and feature-rich Java heap analyzer that helps you find memory leaks and reduce memory consumption. Use the Memory Analyzer to analyze productive heap …

软件设计模式原则(二)开闭原则

继续讲解第二个重要的设计模式原则——开闭原则~ 一.定义 开闭原则&#xff0c;在面向对象编程领域中&#xff0c;规定“软件中的对象&#xff08;类&#xff0c;模块&#xff0c;函数等等&#xff09;应该对于扩展是开放的&#xff0c;但是对于修改是封闭的”&#xff0c;这意…

springboot中使用redis管理session

前言 使用软件&#xff1a; redis&#xff1a; linux版本下载 windows版本下载 安装redis 下载redis http://download.redis.io/releases/ 源码安装redis&#xff08;ubuntu&#xff09; #将指定版本的redis上传到服务器#解压 sudo tar -xzvf redis-6.2.4.tar.gzcd re…

牛客项目(五)-使用kafka实现发送系统通知

kafka入门以及与spring整合 Message.java import java.util.Date;public class Message {private int id;private int fromId;private int toId;private String conversationId;private String content;private int status;private Date createTime;public int getId() {retur…

Springboot搭建微服务案例之Eureka注册中心

一、父工程依赖管理 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org…

服务器经常被攻击的原因

很多中小型企业都是选择虚拟主机服务器&#xff0c;是把一个服务器分成很多个给很多企业一起共用&#xff0c;可能同一个 IP服务器上就有很多个不同企业的网站&#xff0c;这个时候如果跟你同一个IP服务器的网站遭到DDoS攻击&#xff0c;就很有可能会影响到你的网站也无法正常访…

学习笔记二十七:K8S控制器Statefulset入门到企业实战应用

这里写目录标题 Statefulset控制器&#xff1a;概念、原理解读Statefulset资源清单文件编写技巧查看定义Statefulset资源需要的字段查看statefulset.spec字段如何定义&#xff1f;查看statefulset的spec.template字段如何定义 Statefulset使用案例&#xff1a;部署web站点State…