JAVA小程序微信支付

2023-11-18

微信支付有专门的文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1
当时找的时候都是前台如何,后来才发现后台需要做的就是统一下单
一、
先到微信下载两个证书,然后把证书放到resources下,cart是我自己建的
在这里插入图片描述
二、因为需要调用微信接口所以我们需要一个调用接口的工具类,下面是我的工具类
1.工具类需要的pom文件

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.48</version>
		</dependency>

		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.5.2</version>
		</dependency>

2.工具类

package com.weizhang.until;

import net.sf.json.JSONObject;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.Set;


/**
 *HttpClient为网络请求的工具类,网络请求的超时时间为5秒。超时、连接出现错误等,响应码非200均返回null。
 *
 * <b>传入的Map参数会自动转换成json格式的数据发送<b/>
 *
 */
public class HttpClient {
    private HttpClient(){}
    public static final String METHOD_POST = "POST";
    public static final String METHOD_GET = "GET";
    private static final int TIME_OUT = 5000;


    /**
     * POST请求url,返回String 类型的结果,5秒超时,出现异常返回null
     * @param url 请求路径
     * @param map 请求参数封装到map中
     * @return
     */
    public static String forStringResult(String url,Map<String,Object> map){
        return forStringResult(url,map,METHOD_POST);
    }

    /**
     * 获取网络请求,5秒超时,出现异常返回null
     * @param urlStr 请求地址
     * @param map 参数封装到map
     * @param method 请求方式GET或POST
     * @return
     */
    public static String forStringResult(String urlStr,Map<String,Object> map,String method){
        String param = null;
        if(map!=null){
            JSONObject obj = new JSONObject();
            Set<Map.Entry<String, Object>> set = map.entrySet();
            for(Map.Entry<String,Object> entry :set){
                obj.put(entry.getKey(),entry.getValue());
            }
            param = obj.toString();
        }

        return getResult(urlStr,param,method);
    }

    /**
     * 返回JSON格式的结果,5秒超时,出现异常返回null
     * @param url 请求url
     * @param map 将参数封装到map中
     * @return
     */
    public static JSONObject forJsonResult(String url, Map<String,Object> map){
        return forJsonResult(url,map,METHOD_POST);
    }


    /**
     * 返回json格式的结果,5秒超时,出现异常返回null
     * @param urlStr 请求url
     * @param map 参数封装到map中
     * @param method 请求方式GET或POST
     * @return
     */
    public static JSONObject forJsonResult(String urlStr,Map<String,Object> map,String method){
        String result = forStringResult(urlStr,map,method);
        if(result==null){
            return null;
        }
        JSONObject jsonObject = JSONObject.fromObject(result);
        return jsonObject;
    }

    /**
     *获取网路请求,5秒超时,出现异常返回null
     * @param url 请求地址
     * @param param  请求参数
     * @return
     */
    public static String forStringResult(String url,String param){
        return  getResult(url,param,null);
    }

    /**
     * 获取网络请求结果,5秒超时,出现异常返回null
     * @param urlStr
     * @param param
     * @param method
     * @return
     */
    private static String getResult(String urlStr,String param,String method){
        String result = null;
        HttpURLConnection connection = null;
        try {
            if(method==null){
                method = METHOD_POST;
            }
            // 创建连接
            URL url = new URL(urlStr);
            connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(TIME_OUT);//5秒超时
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod(method);
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestProperty("Content-Type", "multipart/form-data");
            connection.connect();
            if(param!=null){
                // POST请求
                DataOutputStream out = new DataOutputStream(connection.getOutputStream());
                out.writeBytes(param);
                out.flush();
                out.close();
            }
            int responseCode = connection.getResponseCode();
            if(responseCode==200){
                result = inputStreamToString(connection.getInputStream());
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
        	// 断开连接
            connection.disconnect();
        }
        return result;
    }
    /**
     * 输入流转为String
     * @param is
     * @return
     */
    private static String inputStreamToString(InputStream is){

        // 读取响应
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        String lines = "";
        StringBuffer sb = new StringBuffer();
        try {
            while ((lines = reader.readLine()) != null) {
                lines = new String(lines.getBytes(), "utf-8");
                sb.append(lines);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return  sb.toString();
    }
}

三、因为微信有签名所以需要加密工具,我这里使用的事md5加密
1.pom文件

	<!--MD5-->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.3.2</version>
		</dependency>

2.md5工具类

package com.weizhang.until;


import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by admin on 2019/7/31.
 */
public class DM5 {
    //写一个md5加密的方法
    public static String md5(String plainText) {
        //定义一个字节数组
        byte[] secretBytes = null;
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            //对字符串进行加密
            md.update(plainText.getBytes());
            //获得加密后的数据
            secretBytes = md.digest();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("没有md5这个算法!");
        }
        //将加密后的数据转换为16进制数字
        String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
        // 如果生成数字未满32位,需要前面补0
        for (int i = 0; i < 32 - md5code.length(); i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }
}

四、下面开始正文,上代码
1.因为微信里有很多参数是固定值,所以创建一个实体类放这些值

package com.weizhang.wxpay;

/**
 * Created by admin on 2019/11/11.
 */
public class Aaa {
    public static String appid="小程序appid";
    public static String mch_id="商户号";
    public static String pay_key="商户号key";
    public static String body="描述";
    public static String out_trade_no="订单号";
    public static Integer total_fee=金额;
    public static String notify_url="回调地址,必须是外网能访问到的地址,微信需要根据这个地址调用我们的接口";
    public static String trade_type="JSAPI";//请求类型  JSAPI是小程序 其他去微信文档里找
}

2.准备工作都做好了就可以直接调用了

package com.weizhang.wxpay;

import com.weizhang.until.DM5;
import com.weizhang.until.HttpClient;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * Created by admin on 2019/11/11.
 */
public class WeiXinPay {
    private String url="https://api.mch.weixin.qq.com/pay/unifiedorder";//统一下单接口
    public void WeiXinPayA(String IP,String openid){
        Map<String,String> map = new HashMap<>();//我将所有参数放到map中了
        map.put("appid",Aaa.appid);
        map.put("mch_id",Aaa.mch_id);
        try {
            map.put("body",new String(Aaa.body.getBytes("UTF-8")));//这里需要注意,body需要提前进行utf-8转换,否则微信会报错
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        map.put("out_trade_no",Aaa.out_trade_no);
        map.put("total_fee",String.valueOf(Aaa.total_fee*100));
        map.put("notify_url",Aaa.notify_url);
        map.put("trade_type",Aaa.trade_type);
        map.put("spbill_create_ip",IP);
        map.put("openid",openid);//小程序必须穿openid
        String nonce_str =  UUID.randomUUID().toString().substring(0,32);//生成的32位随机数
        map.put("nonce_str",nonce_str);
        /*这里需要将上面我们所有的参数按照字典顺序排序,必须严格按照微信文档里签名规则来*/
        String signA="appid="+map.get("appid")+"&body="+map.get("body")+"&mch_id="+map.get("mch_id")+"&nonce_str="+
                map.get("nonce_str")+"&notify_url="+map.get("notify_url")+"&openid="+map.get("openid")+"&out_trade_no="+map.get("out_trade_no")+
                "&spbill_create_ip="+map.get("spbill_create_ip")+"&total_fee="+map.get("total_fee")+"&trade_type="+
                map.get("trade_type");
        String signB=signA+"&key="+Aaa.pay_key;//前面拼接完,最后拼接商户号的key
        String sign= DM5.md5(signB).toUpperCase();//将所有拼接的字符串进行md5加密,加密完转成大写
        map.put("sign",sign);
        /*微信传参需要穿xml格式,所以要将所有参数拼接成xml格式*/
        StringBuilder xml = new StringBuilder();
        xml.append("<xml>\n");
        for (Map.Entry<String, String> entry : map.entrySet()) {
            if ("body".equals(entry.getKey()) || "sign".equals(entry.getKey())) {
                xml.append("<" + entry.getKey() + "><![CDATA[").append(entry.getValue()).append("]]></" + entry.getKey() + ">\n");
            } else {
                xml.append("<" + entry.getKey() + ">").append(entry.getValue()).append("</" + entry.getKey() + ">\n");
            }
        }
        xml.append("</xml>");
		
        String cc = HttpClient.forStringResult(url,xml.toString());//调用微信统一下单接口
        System.out.println(cc);
    }
}

这样主要的工作就完成了,微信回调我们接口传的也是xml格式参数,只需要接收进行一下验证是否成功就行了,然后将前台需要的参数传给前台就OK了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAVA小程序微信支付 的相关文章

  • docker 命令(日常笔记)

    1 docker images 列出本地镜像 参数说明 xff1a a 列出本地所有的镜像 xff08 含中间映像层 xff0c 默认情况下 xff0c 过滤掉中间映像层 xff09 xff1b digests 显示镜像的摘要信息 xff1
  • linux时间校准步骤记录

    记录一下校准时间操作的执行步骤 首先使用 date 查看当前时间是否准确 校准时间命令 ntpdate cn pool ntp org 如果没有权限 sudo i 会出现输入密码 直接输入密码即可 再次执行校准时间操作命令 ntpdate
  • java 后台 小程序微信支付

    java 后台 小程序微信支付 步骤说明 微信公众平台支付接口调试工具 1 生成字符串 appid appId body 测试商品名称 mch id 商户号 nonce str bf0d5ffe64fc44a3b0c101ead5a6a56
  • pppd程序的参数——man手册翻译

    文章目录 pppd全称 摘要 描述 常用的选项 ttyname 串口名 speed 波特率 asyncmap map auth call name connect script 连接脚本 crtscts defaultroute defau
  • table完成动态表头与动态数据

  • build_ext --inplace和build_ext install

    安装pycocotools的时候 有一个build ext inplace和 build ext install 两者的区别 all install pycocotools locally python setup py build ext
  • springboot配置双mysql数据源

    这两天一直在配置双数据源 找了网上很多资料 有的资料写的太乱而且注释不清楚 类不全 像我这样的刚开始配置的新手很难看明白 今天终于配置成功了 我把我总结的整理一下 做个日志以防以后遇到问题 一 创建一个springboot项目其中需要的po
  • laravel-admin整合wangEditor2及上传图片

    小伙伴说MD编辑器不好用 因为复制粘贴不方便 所以我换了一个编辑器整合 选择了老朋友wangEditor 下面为大家介绍怎么在laravel v6 9 laravel admin v1 7 wangEditor2的情况下上传图片 第一步 c
  • springboot整合mysql和mongodb双数据源

    因为业务需求 需要在一个项目中同时使用myslq和mongodb数据库 在网上找了好久都没有 只有相同数据库的双数据源 当时就想如果按照相同数据库的双数据源配置分别配置myslq和mongodb 一 先看一下pom文件
  • Android BaseQuickAdapter万能适配器

    RecycleView万能适配器 一导入 implementation com github CymChad BaseRecyclerViewAdapterHelper 2 9 24 implementation com android s
  • BeanCreationException异常,注入Bean异常

    org springframework beans factory BeanCreationException Error creating bean with name XXX 注入bean异常 出现这个异常就是找不到对应的JavaBea
  • 无效的数值参数“/Wno-cpp”

    问题背景 在windows下执行python setup py build ext inplace 提示命令行 error D8021 无效的数值参数 Wno cpp 仅供参考的解决办法 修改编译参数为如下所示 extra compile
  • matlab相关性分析(皮尔逊,肯德尔,斯皮尔曼)

    代码 clc clear load CRO C3 mat data GPP DT VUT REF EVI NDVI NIRv kNDVI LSWI FPAR TA F VPD F SW IN F rho corr data type pea
  • 私域流量对比:微信公众号、小程序、APP,谁更有价值?

    在数字化时代 流量已经成为了互联网企业最重要的资源之一 而对于企业来说 获取到流量只是第一步 如何将流量转化为价值才是最终目的 对于私域流量的获取和转化 微信公众号 小程序和APP是目前最常见的三种方式 那么 这三种私域流量各有什么优缺点呢
  • 微信支付sign签名工具类

    secretKey为商户平台设置的密钥key params为非空参数集合 public static String genSignature String secretKey Map
  • JAVA小程序微信支付

    微信支付有专门的文档 https pay weixin qq com wiki doc api wxa wxa api php chapter 9 1 当时找的时候都是前台如何 后来才发现后台需要做的就是统一下单 一 先到微信下载两个证书
  • 僵尸进程的多种处理方式-图文详细教程

    问题引起原因 yum更新导致无法使用yum 于是将占用进程kill掉 导致 ps A ostat ppid pid cmd grep e Zz ps ef no headers k8s环境kubelet服务异常 systemd1服务超时 导
  • 向数据库插入数据报错Error updating database. Cause: java.sql.SQLException: Incorrect string value: '\xE5\xA4\

    之前连接数据库都没问题 可是今天新加一个表之后 向这个表中加入数据就报错 2018 08 25 14 54 59 082 WARN 8136 nio 8090 exec 7 m m a ExceptionHandlerExceptionRe
  • shell批量查看文件的MD5值

    ls faces pkl xargs md5sum 执行结果 57dcc90d201e5f5e1c028afd6be43e5e faces lgr2 jpg pkl 3e3c547d0a79d77e4e14d33df45bcce3 face
  • shell批量查看文件的MD5值

    ls faces pkl xargs md5sum 执行结果 57dcc90d201e5f5e1c028afd6be43e5e faces lgr2 jpg pkl 3e3c547d0a79d77e4e14d33df45bcce3 face

随机推荐

  • 安装nedo.js 'npm'不是内部或外部命令,也不是可运行的程序 或批处理文件

    npm 不是内部或外部命令 也不是可运行的程序 或批处理文件 问题 没有npm命令需要按需node js npm 不是内部或外部命令 也不是可运行的程序 或批处理文件 一 下载安装node js nodejs官网 https nodejs
  • Spring Boot Metrics使用

    Spring Boot 使用Metrics监控 导入pom依赖
  • 2021年第八届大唐杯全国大学生移动通信5G技术大赛省赛

    2021年第八届大唐杯全国大学生移动通信5G技术大赛省赛 实验背景 勘站规划 网络部署 开通调测 业务认证摘自 https www bilibili com video BV1Hr4y1Y7m8 spm id from 333 337 se
  • vue+$emit调用父级方法,添加其他参数

    前言 我们在vue中子组件调用父组件的方法使用的是this emit 方法名 参数 但是在某些特定场合 我们还希望可以在父组件那里添加其他参数 实现方法
  • 新手学习Python要注意的13个问题

    作为一门易学的编程语言 Python对初学者来说确实是一个非常好的选择 不过 初学者在学习Python的过程中可能会遇到一些常见的问题 以下是一些常见的Python学习问题 语法错误 语法错误是最常见的问题之一 初学者经常会忘记冒号 括号
  • llvm之IR设计

    llvm之IR设计 引言 1 逻辑关系 2 class Module 3 class IRBuilder 4 class Instruction 5 class Constant 6 class Function 引言 llvm IR是ll
  • v-if与v-show的区别=====》面试题

    共同点 都是控制元素显示或隐藏的指令 区别 v show 控制元素无论是true还是false都会被渲染出来 通过diaplay none控制元素隐藏 v if控制元素是true渲染 是false不渲染 在dom树结构中不显示 加分回答 应
  • [STM32系列]一、HAL库的串口中断接收

    STM32系列 一 HAL库的串口中断任意长度接收 1 前言 2 回调函数 3 HAL库中断接收函数使用 1 前言 HAL即硬件抽象层 英语 Hardware Abstraction Layer 实现了不同硬件的统一接口操作 这就极大的简化
  • 极简Json格式剖析与fastjson下载和使用

    Json存在的意义 Json主要用来做数据的传输 例如发送java中的一个对象 由于对象是存储在内存里的 不能直接将内存里的对象发送出去 这时需要使用序列化 持久化 手段 将对象转换为一系列字符串 比如说Json 在字符串送达目的地时再使用
  • HTTP协议和Tomcat服务器

    目录 1 HTTP 是什么 2 HTTP 工作过程 2 1 HTTP 协议格式 2 1 1 抓包工具的使用 2 1 2 抓包工具原理 2 1 3 抓包结果分析 2 1 4 协议格式总结 3 HTTP 请求 Request 3 1 请求地址
  • 常用的数组方法整理

    常用的数组方法 1 concat 2 join 3 pop 4 shift 5 unshift 7 reverse 8 sort 9 slice 10 splice 11 toString 12 valueOf 13 IndexOf 14
  • 二、Vue3跨组件调用函数[mitt]

    一 跨组件调用函数 安装 npm install mitt 创建文件并写入 bus js import mitt from mitt export const eventBus mitt 使用方法 import eventBus from
  • 2022年6月8日STM32——SPI读写串行FLASH 和 串行FLASH文件系统FatFs

    此内容是为自己方便回忆 如有错误 欢迎指导 内容来源于野火指南者开发板教程 一 SPI读写串行FLASH SPI Serial Peripheral Interface 串行外围设备接口 是高速全双工的通信总线 通讯速率较高 SPI物理层
  • VS2019中文输出乱码解决方法(C语言)

    现象 VS2019控制台输出中文乱码 第一种解决方法 安装插件Format on Save重启VS2019生效 注意 别装错了 刚开始我就装错了这个UTF 8 No BOM 装了这个插件的同学 记得要删掉 不然还是会出现问题 第二种解决方法
  • 等价类

    动态测试方法是指通过运行被测程序 检查运行结果与预期结果的差异 并分析运行效率 正确性和健壮性等性能 这种方法由三部分组成 构造测试用例 执行程序 分析程序的输出结果 静态方法是指不运行被测程序本身 仅通过分析或检查源程序的语法 结构 过程
  • 无线通信原理之OFDM技术

    补充一个完整的OFDM系统结构图 包括收发天线 目录 1 OFDM的基本原理 2 OFDM系统模型 3 循环前缀和导频 4 OFDM系统参数 1 OFDM的基本原理 OFDM即正交频分复用 Orthogonal Frequency Divi
  • React-错误边界与组件通信方式概述

    错误边界 错误边界 Error boundary 用来捕获后代组件错误 渲染出备用页面 注意 只在生产环境 项目上线 起效 特点 只能捕获后代组件生命周期产生的错误 不能捕获自己组件产生的错误和其他组件在合成事件 定时器中产生的错误 简单理
  • DevOps是什么

    DevOps 英文Development和Operations的组合 是一组过程 方法与系统的统称 用于促进开发 应用程序 软件工程 技术运营和质量保障 QA 部门之间的沟通 协作与整合 它的出现是由于软件行业日益清晰地认识到 为了按时交付
  • JavaBean SpringBean是对象还是类

    JavaBean SpringBean是对象还是类 什么是JavaBean 什么是SpringBean 首先先说结论 Bean可以理解为对象 这几天在学习Spring源码的时候 观察到底层反复的对Bean的操作 于是就去网上搜索Bean到底
  • JAVA小程序微信支付

    微信支付有专门的文档 https pay weixin qq com wiki doc api wxa wxa api php chapter 9 1 当时找的时候都是前台如何 后来才发现后台需要做的就是统一下单 一 先到微信下载两个证书