开发所需工具类
开发所需jar
具体的代码不贴了,说明下PayConfigUtil中的参数
APP_ID和APP_SECRET在公众平台
MCH_ID和API_KEY在商户平台,其中API_KEY是自己设置的,并不是自动生成的。
Controller
通过此方法,前往可以生成二维码的页面
//微信前往支付页面
@RequestMapping(value = "towxPay")
public ModelAndView towxPay(ModelMap map,HttpServletRequest request,String chapterId,String chapterName,String price) throws IOException{
ModelAndView mav = new ModelAndView();
mav.setViewName("jsp/pay/weixinpayma");
HttpSession session = request.getSession();
session.setAttribute("chapterId", chapterId);
session.setAttribute("chapterName", chapterName);
session.setAttribute("price", price);
return mav;
}
返回的页面如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
Insert title here
/* ajax轮回,不停的访问Controller,直到wxPayType=1时,付款成功 */
var num = 0;
$(function(){
panduanWXPay();
});
function panduanWXPay(){
$.post("<%=basePath%>index/panduanPay",function(data){
var wxPayType = data.wxPayType;
if(wxPayType==1){
/* 成功 */
window.location.href='<%=basePath%>index/gouMai';
}else if(wxPayType==0 && num!=400){
num++;
panduanWXPay();
}else{
alert("支付超时");
}
});
}
payImg方法
//微信支付,生成二维码
@RequestMapping(value = "payImg")
public void payImg(HttpServletRequest request, HttpServletResponse response) throws IOException{
HttpSession session = request.getSession();
String chapterName=(String)session.getAttribute("chapterName");
String price=(String)session.getAttribute("price");
int defaultWidthAndHeight=200;
String nonce_str = PayCommonUtil.getNonce_str();
long time_stamp = System.currentTimeMillis() / 1000;
String product_id = chapterName+"*"+price;//订单名字和价钱,拼到了一起,后面用到的时候再拆
String key = PayConfigUtil.API_KEY; // key
SortedMap packageParams = new TreeMap();
packageParams.put("appid", PayConfigUtil.APP_ID);
packageParams.put("mch_id", PayConfigUtil.MCH_ID);
packageParams.put("time_stamp", String.valueOf(time_stamp));
packageParams.put("nonce_str", nonce_str);
packageParams.put("product_id", product_id);
// packageParams.put("chapterId", chapterId);
// packageParams.put("price", price);
String sign = PayCommonUtil.createSign("UTF-8", packageParams,key);//MD5哈希
packageParams.put("sign", sign);
//生成参数
String str = ToUrlParams(packageParams);
String payurl = "weixin://wxpay/bizpayurl?" + str;
// logger.info("payurl:"+payurl);
//生成二维码
Map hints=new HashMap();
// 指定纠错等级
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
// 指定编码格式
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.MARGIN, 1);
try {
BitMatrix bitMatrix = new MultiFormatWriter().encode(payurl,BarcodeFormat.QR_CODE, defaultWidthAndHeight, defaultWidthAndHeight, hints);
OutputStream out = response.getOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix, "png", out);//输出二维码
out.flush();
out.close();
} catch (WriterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String ToUrlParams(SortedMap packageParams){
//实际可以不排序
StringBuffer sb = new StringBuffer();
Set es = packageParams.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
if (null != v && !"".equals(v)) {
sb.append(k + "=" + v + "&");
}
}
sb.deleteCharAt(sb.length()-1);//删掉最后一个&
return sb.toString();
}
扫码时触动此方法,会在手机端显示付款信息
要将此方法的路径配置到回调url里,微信公众平台–>微信支付–>开发配置
//微信扫码的时候,触发此方法
@RequestMapping(value = "Re_notify")
public void Re_notify(HttpServletRequest request, HttpServletResponse response) throws IOException{
HttpSession session = request.getSession();
String chapterId=(String)session.getAttribute("chapterId");
String chapterName=(String)session.getAttribute("chapterName");
String price=(String)session.getAttribute("price");
System.out.println(chapterId+":"+chapterName+":"+price);
// 读取xml
InputStream inputStream;
StringBuffer sb = new StringBuffer();
inputStream = request.getInputStream();
String s;
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
while ((s = in.readLine()) != null) {
sb.append(s);
}
in.close();
inputStream.close();
SortedMap packageParams = PayCommonUtil.xmlConvertToMap(sb.toString());
// logger.info(packageParams);
// 账号信息
String key = PayConfigUtil.API_KEY; // key
String resXml="";//反馈给微信服务器
// 验签
if (PayCommonUtil.isTenpaySign("UTF-8", packageParams, key)) {
//appid openid mch_id is_subscribe nonce_str product_id sign
//统一下单
String openid = (String)packageParams.get("openid");
String product_id = (String)packageParams.get("product_id");
//解析product_id,计算价格等
String thePricce = product_id.substring(product_id.lastIndexOf("*")+1);
String newProductId = product_id.substring(0, product_id.indexOf("*"));
String out_trade_no = String.valueOf(System.currentTimeMillis()); // 订单号
String order_price = thePricce; // 价格"1" 注意:价格的单位是分
String body = newProductId; // 商品名称product_id 这里设置为product_id
String attach = "十倍课"; //附加数据
String nonce_str0 = PayCommonUtil.getNonce_str();
// 获取发起电脑 ip
String spbill_create_ip = PayConfigUtil.CREATE_IP;
String trade_type = "NATIVE";
SortedMap unifiedParams = new TreeMap();
unifiedParams.put("appid", PayConfigUtil.APP_ID); // 必须
unifiedParams.put("mch_id", PayConfigUtil.MCH_ID); // 必须
unifiedParams.put("out_trade_no", out_trade_no); // 必须
unifiedParams.put("product_id", product_id);
unifiedParams.put("body", body); // 必须
unifiedParams.put("attach", attach);
unifiedParams.put("total_fee", order_price); // 必须
unifiedParams.put("nonce_str", nonce_str0); // 必须
unifiedParams.put("spbill_create_ip", spbill_create_ip); // 必须
unifiedParams.put("trade_type", trade_type); // 必须
unifiedParams.put("openid", openid);
unifiedParams.put("notify_url", PayConfigUtil.NOTIFY_URL);//异步通知url
String sign0 = PayCommonUtil.createSign("UTF-8", unifiedParams,key);
unifiedParams.put("sign", sign0); //签名
String requestXML = PayCommonUtil.getRequestXml(unifiedParams);
// logger.info(requestXML);
//统一下单接口
String rXml = HttpUtil.postData(PayConfigUtil.UFDODER_URL, requestXML);
//统一下单响应
SortedMap reParams = PayCommonUtil.xmlConvertToMap(rXml);
// logger.info(reParams);
//验签
if (PayCommonUtil.isTenpaySign("UTF-8", reParams, key)) {
// 统一下单返回的参数
String prepay_id = (String)reParams.get("prepay_id");//交易会话标识 2小时内有效
String nonce_str1 = PayCommonUtil.getNonce_str();
SortedMap resParams = new TreeMap();
resParams.put("return_code", "SUCCESS"); // 必须
resParams.put("return_msg", "OK");
resParams.put("appid", PayConfigUtil.APP_ID); // 必须
resParams.put("mch_id", PayConfigUtil.MCH_ID);
resParams.put("nonce_str", nonce_str1); // 必须
resParams.put("prepay_id", prepay_id); // 必须
resParams.put("result_code", "SUCCESS"); // 必须
resParams.put("err_code_des", "OK");
String sign1 = PayCommonUtil.createSign("UTF-8", resParams,key);
resParams.put("sign", sign1); //签名
resXml = PayCommonUtil.getRequestXml(resParams);
// logger.info(resXml);
}else{
// logger.info("签名验证错误");
resXml = "" + ""
+ "" + " ";
}
}else{
// logger.info("签名验证错误");
resXml = "" + ""
+ "" + " ";
}
//------------------------------
//处理业务完毕
//------------------------------
BufferedOutputStream out = new BufferedOutputStream(
response.getOutputStream());
out.write(resXml.getBytes());
out.flush();
out.close();
}
微信支付成功时访问的方法
密码错误等未支付成功的情况下,不会访问。
此路径是PayConfigUtil中配置的
int wxPayType = 0;
//微信扫码支付回调
@RequestMapping(value = "Notify1")
public void Notify1(HttpServletRequest request, HttpServletResponse response) throws IOException{
InputStream inputStream;
StringBuffer sb = new StringBuffer();
inputStream = request.getInputStream();
String s;
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
while ((s = in.readLine()) != null) {
sb.append(s);
}
in.close();
inputStream.close();
SortedMap packageParams = PayCommonUtil.xmlConvertToMap(sb.toString());
// logger.info(packageParams);
// 账号信息
String key = PayConfigUtil.API_KEY; // key
String resXml = ""; // 反馈给微信服务器
// 判断签名是否正确
if (PayCommonUtil.isTenpaySign("UTF-8", packageParams, key)) {
// ------------------------------
// 处理业务开始
// ------------------------------
if ("SUCCESS".equals((String) packageParams.get("result_code"))) {
// 这里是支付成功
// 执行自己的业务逻辑
String mch_id = (String) packageParams.get("mch_id");
String openid = (String) packageParams.get("openid");
String is_subscribe = (String) packageParams.get("is_subscribe");
String out_trade_no = (String) packageParams.get("out_trade_no");
String total_fee = (String) packageParams.get("total_fee");
将用于标记是否成功的全局变量wxPayType设置为1,ajax轮回时,可以获取到其变化,从而进行页面跳转
wxPayType=1;
System.out.println("33333333333333333333333333333:"+wxPayType);
// "支付成功"
// 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
resXml = "" + ""
+ "" + " ";
} else {
// logger.info("支付失败,错误信息:" + packageParams.get("err_code"));
resXml = "" + ""
+ "" + " ";
}
} else {
// logger.info("签名验证错误");
resXml = "" + ""
+ "" + " ";
}
// ------------------------------
// 处理业务完毕
// ------------------------------
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
out.write(resXml.getBytes());
out.flush();
out.close();
}
ajax不停轮回,判断是否登录成功的方法
@RequestMapping(value = "panduanPay")
@ResponseBody
public Map panduanPay(HttpServletRequest request) throws IOException{
Map map = new HashMap();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//给页面返回wxPayType值,成功是返回的是1;还未支付成功,返回的是初始值0
map.put("wxPayType",wxPayType);
return map;
}
成功后页面跳转的方法
//购买成功,存入购买表中
@RequestMapping(value="gouMai")
@ResponseBody
public ModelAndView gouMai(HttpServletRequest req,String a,String urlName,String couName,ModelMap map){
ModelAndView mav = new ModelAndView();
Map mapp1 = new HashMap();
// SysUserTab login_user = sysuserService.getSysUserById(userId);
HttpSession session = req.getSession();
SysUserTab login_user1 = (SysUserTab) session.getAttribute("login_user");
String userId = login_user1.getUserId();
// session.setAttribute("login_user", login_user);
String chapterId = (String) session.getAttribute("chapterId");
mapp1.put("userId", userId);
mapp1.put("chapterId", chapterId);
int num = sysBuyService.getBuyCount(mapp1);
if(num==0){
mapp1.put("buyId", UUID.randomUUID().toString().replace("-", ""));
sysBuyService.insertBuy(mapp1);
}
Java高架构师、分布式架构、高可扩展、高性能、高并发、性能优化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分布式项目实战学习架构师视频免费学习加群:835638062 点击链接加入群聊【Java高级架构】:https://jq.qq.com/?_wv=1027&k=5S3kL3v
文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态
文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境
文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn
文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker
文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机
文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk
文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入
文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。 Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。
文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动
文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计
文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;gt;Jni-&amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图
文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法