微信支付模式二java
这个星期写了下微信支付模式二,在这里进行下整理
微信支付官方文档
1. 需要的配置..具体看下面的链接.
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=3_1
2. 熟悉微信的支付流程(模式二)
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5
3.将下面的配置填好,我是写在yml里面.第一个没用到,说是公众号那里用到了,可以不用
.
4.下载微信里面的sdk,然后全部放入项目里面

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1

下面就是具体的代码...微信支付模式二是先将金额订单号等一些参数放入二维码中,这个二维码只有2个小时,然后顾客扫码支付
需要的jar包
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jdom/jdom -->
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/xml-apis/xml-apis -->
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.4.01</version>
</dependency>
5.先是写二维码的
util ---2个
/**
* @ClassName: QRCodeUtil
* @Description: 二维码工具类
*/
public class QRCodeUtil {
/**
* 生成base64二维码
*
* @param content
* @return
* @throws Exception
*/
public static String createQrCode(String content) throws Exception {
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.MARGIN, 1);
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, 400, 400, hints);
int width = bitMatrix.getWidth();
int height = bitMatrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
}
}
ImageIO.write(image, "JPG", out);
return Base64.encodeBase64String(out.toByteArray());
}
}
}
public class CommonUtil {
public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
try {
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求方式(GET/POST)
conn.setRequestMethod(requestMethod);
conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
// 当outputStr不为null时向输出流写数据
if (null != outputStr) {
OutputStream outputStream = conn.getOutputStream();
// 注意编码格式
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 从输入流读取返回内容
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
// 释放资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect();
return buffer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
controller ----这里可以直接传参数,订单号,类型

serviceImpl
@Override
public ApiResult toPay(String orderUserId, String payType) {
OrderUserInfoDto orderUserInfoDto = orderUserInfoService.getByPk(orderUserId);
if (Checker.BeNull(orderUserInfoDto)) {
return ApiResult.result(ApiResult.defaultErrorCode, "未知的订单号");
}
if (!"0".equals(orderUserInfoDto.getPayStatus())) {
return ApiResult.result(ApiResult.defaultErrorCode, "未知的支付状态");
}
if(!"3".equals(orderUserInfoDto.getStatus())){
return ApiResult.result(ApiResult.defaultErrorCode,"未知的订单状态");
}
// 1为微信支付
if ("1".equals(payType)) {
SortedMap<String, String> parameters = new TreeMap<String, String>();
// 公众账号ID-------appId
parameters.put("appid", weChatConfig.getWxAppId());
// 商户号---------mch_id
parameters.put("mch_id", weChatConfig.getWxMchId());
// 随机字符串------nonce_str
parameters.put("nonce_str", WXPayUtil.generateNonceStr());
// 商品描述-------body
parameters.put("body", weChatConfig.getBody());
// 商户订单号------out_trade_no
parameters.put("out_trade_no", orderUserId);
// 标价币种-------fee_type(默认为人民币)
parameters.put("fee_type", "CNY");
// 标价金额-------total_fee(默认为分)
BigDecimal transValue = new BigDecimal("100");
// 计算微信的总金额乘以100
BigDecimal bTotalPrice = orderUserInfoDto.getTotalPrice().multiply(transValue);
int totalFee = bTotalPrice.intValue();
parameters.put("total_fee", String.valueOf(totalFee));
// 通知地址-------notify_url(回调地址)
parameters.put("notify_url", weChatConfig.getNotifyUrl());
// 交易类型-----trade_type
parameters.put("trade_type", "NATIVE");
// 签名-----------sign
String generateSignature = null;
try {
generateSignature = WXPayUtil.generateSignature(parameters, weChatConfig.getWxApiKey(),
WXPayConstants.SignType.MD5);
} catch (Exception e) {
e.printStackTrace();
}
parameters.put("sign", generateSignature);
String generateSignedXml = null;
try {
generateSignedXml = WXPayUtil.generateSignedXml(parameters, weChatConfig.getWxApiKey());
} catch (Exception e) {
e.printStackTrace();
}
log.info("二维码信息------" + generateSignedXml);
String result = CommonUtil.httpsRequest(weChatConfig.getWxPayUnifiedorderUrl(), "POST", generateSignedXml);
Map<String, String> map;
try {
map = WXPayUtil.xmlToMap(result);
String returnCode = map.get("return_code");
String resultCode = map.get("result_code");
if (returnCode.equalsIgnoreCase("SUCCESS") && resultCode.equalsIgnoreCase("SUCCESS")) {
String content = map.get("code_url");
String imgs = QRCodeUtil.createQrCode(content);
return ApiResult.result("data:image/jpeg;base64," + imgs);
} else {
return ApiResult.result(ApiResult.defaultErrorCode, "微信签名错误");
}
} catch (Exception e) {
e.printStackTrace();
}
}
return ApiResult.result(ApiResult.defaultErrorCode, "未知错误");
}
6,支付回调-----就是二维码的那个回调地址,如果是本地测试的话,可能下载个花生壳将本地的地址映射出去
controller

serviceImpl --->这里主要注意就是第一次回调成功的话,要把正确的信息返回给微信,不然微信会在那几个时间一直回调,这个回调就会一直改状态
public String weChatNotify(HttpServletRequest request, HttpServletResponse response) {
// 读取参数
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();
// 解析xml成map
Map<String, String> map = WXPayUtil.xmlToMap(sb.toString());
log.info("支付回调---" + map.toString());
String res = "OK";
String resXml = "<xml>" + "<return_code><![CDATA["+map.get("return_code").toString()+"]]></return_code>"
+ "<return_msg><![CDATA["+res+"]]></return_msg>" + "</xml>";
// 判断签名是否正确
if (WXPayUtil.isSignatureValid(map, weChatConfig.getWxApiKey())) {
if ("SUCCESS".equals(map.get("return_code").toString())) {
// 用户订单号
String orderUserId = (String) map.get("out_trade_no");
// 微信支付订单号
String payOrderId = (String) map.get("transaction_id");
// 支付时间
String endTime = (String) map.get("time_end");
// 支付金额
BigDecimal total_fee = new BigDecimal(map.get("total_fee").toString());
/**
* 1,判断是否有这个订单号 2,判断支付金额与用于订单表的金额是否一致 3,修改支付状态,并修改商户的状态,
*/
log.info("用户订单id--------"+orderUserId);
OrderUserInfoDto orderUserInfoDto = orderUserInfoService.getByPk(orderUserId);
if (Checker.BeNull(orderUserInfoDto)) {
return "未知的订单号";
}
if (!"0".equals(orderUserInfoDto.getPayStatus())) {
return "未知的支付状态";
}
if (!"3".equals(orderUserInfoDto.getStatus())) {
return "未知的订单状态";
}
if (total_fee.compareTo(orderUserInfoDto.getTotalPrice().multiply(new BigDecimal("100"))) != 0) {
return "支付金额与用户订单金额不一致";
}
// 用户订单表的修改
OrderUserInfoDto orderUserInfoDto1 = new OrderUserInfoDto();
orderUserInfoDto1.setId(orderUserId);
orderUserInfoDto1.setStatus("4");
orderUserInfoDto1.setPayStatus("1");
orderUserInfoDto1.setPayType("1");
orderUserInfoDto1.setPaySerial(payOrderId);
log.info("----------------时间---"+endTime);
orderUserInfoDto1.setPayTime(dateTime(endTime));
orderUserInfoService.updateByPk(orderUserInfoDto1);
// 商户订单表的修改
List<OrderMerchantInfoDto> orderMerchantInfoDtoList = orderMerchantInfoService
.listByField("order_user_info_id", orderUserId);
for (OrderMerchantInfoDto merchantInfoDto : orderMerchantInfoDtoList) {
if ("3".equals(merchantInfoDto.getStatus())) {
String id = merchantInfoDto.getId();
OrderMerchantInfoDto orderMerchantInfoDto = new OrderMerchantInfoDto();
orderMerchantInfoDto.setId(id);
orderMerchantInfoDto.setStatus("4");
orderMerchantInfoDto.setPayStatus("1");
orderMerchantInfoDto.setPayTime(dateTime(endTime));
orderMerchantInfoService.updateByPk(orderMerchantInfoDto);
}
}
log.info(resXml);
return resXml;
} else {
return "错误的签名";
}
}
return "未知错误";
}
7,客户支付成功了,但是状态没改,可以写个定时任务,查询当天未支付的订单是否支付,我这里只写了通过订单号和类型查询单个的是否支付
controller

serviceImpl
@Override
public ApiResult weChatNotifyDto(String orderUserId, String payType) {
/**
* 1,数据库进行查询,如果显示已支付则直接返回成功
* 2,未支付,调用微信接口
*/
OrderUserInfoDto orderUserInfoDto = orderUserInfoService.getByPk(orderUserId);
if("1".equals(orderUserInfoDto.getPayStatus())){
return ApiResult.result("支付已完成");
}
Map<String,String> data = new HashMap<>();
data.put("appid", weChatConfig.getWxAppId());
data.put("mch_id", weChatConfig.getWxMchId());
data.put("nonce_str", WXPayUtil.generateNonceStr());
data.put("out_trade_no", orderUserId);
// 签名-----------sign
String generateSignature = null;
try {
generateSignature = WXPayUtil.generateSignature(data, weChatConfig.getWxApiKey(),
WXPayConstants.SignType.MD5);
} catch (Exception e) {
e.printStackTrace();
}
data.put("sign", generateSignature);
Map<String, String> result = null;
try {
result = wxPay.orderQuery(data);
} catch (Exception e) {
e.printStackTrace();
}
// 如果用户已支付
if("SUCCESS".equals(result.get("return_code")) && "SUCCESS".equals(result.get("trade_state"))){
//修改状态
// 微信支付订单号
String payOrderId = result.get("transaction_id");
// 支付时间
String endTime = result.get("time_end");
// 用户订单表的修改
OrderUserInfoDto orderUserInfoDto1 = new OrderUserInfoDto();
orderUserInfoDto1.setId(orderUserId);
orderUserInfoDto1.setStatus("4");
orderUserInfoDto1.setPayStatus("1");
orderUserInfoDto1.setPayType("1");
orderUserInfoDto1.setPaySerial(payOrderId);
orderUserInfoDto1.setPayTime(dateTime(endTime));
orderUserInfoService.updateByPk(orderUserInfoDto1);
// 商户订单表的修改
List<OrderMerchantInfoDto> orderMerchantInfoDtoList = orderMerchantInfoService
.listByField("order_user_info_id", orderUserId);
for (OrderMerchantInfoDto merchantInfoDto : orderMerchantInfoDtoList) {
if ("3".equals(merchantInfoDto.getStatus())) {
String id = merchantInfoDto.getId();
OrderMerchantInfoDto orderMerchantInfoDto = new OrderMerchantInfoDto();
orderMerchantInfoDto.setId(id);
orderMerchantInfoDto.setStatus("4");
orderMerchantInfoDto.setPayStatus("1");
orderMerchantInfoDto.setPayTime(dateTime(endTime));
orderMerchantInfoService.updateByPk(orderMerchantInfoDto);
}
}
return ApiResult.result("支付已完成");
}
return ApiResult.result(ApiResult.defaultErrorCode, "订单未支付");
}
暂时先这样,有时间再补充
微信支付模式二java的更多相关文章
- JAVA微信扫码支付模式二功能实现完整例子
概述 本例子实现微信扫码支付模式二的支付功能,应用场景是,web网站微信扫码支付.实现从点击付费按钮.到弹出二维码.到用户用手机微信扫码支付.到手机上用户付费成功.web网页再自动调整到支付成功后的页 ...
- Java之微信支付(扫码支付模式二)案例实战
摘要:最近的一个项目中涉及到了支付业务,其中用到了微信支付和支付宝支付,在做的过程中也遇到些问题,所以现在总结梳理一下,分享给有需要的人,也为自己以后回顾留个思路. 一:微信支付接入准备工作: 首先, ...
- 微信公众号 扫码支付 模式二 demo
扫码支付 本文附有代码,在下方,如果不熟悉场景的可以看看下面的场景介绍 场景介绍 官网介绍地址:https://pay.weixin.qq.com/wiki/doc/api/native.php?ch ...
- 微信支付Native扫码支付模式二之CodeIgniter集成篇
CI:3.0.5 微信支付API类库来自:https://github.com/zhangv/wechat-pay 请先看一眼官方场景及支付时序图:https://pay.weixin.qq.com/ ...
- C# 微信扫码支付API (微信扫码支付模式二)
一.SDK下载地址:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1,下载.NET C#版本: 二.微信相关设置:(微信扫码 ...
- PHP微信支付开发之扫描支付(模式二)后如何回调
其实在写这篇文章的时候感觉自己已经落伍了,不过笔者在百度上搜索"微信支付开发之扫描支付(模式二)后如何回调"寻找答案时,发现依旧有很多朋友没有解决这个问题,所以就把自己的解决思路分 ...
- .NET MVC结构框架下的微信扫码支付模式二 API接口开发测试
直接上干货 ,我们的宗旨就是为人民服务.授人以鱼不如授人以渔.不吹毛求疵.不浮夸.不虚伪.不忽悠.一切都是为了社会共同进步,繁荣昌盛,小程序猿.大程序猿.老程序猿还是嫩程序猿,希望这个社会不要太急功近 ...
- .NET微信扫码支付模式二API接口开发测试
主要实现微信扫码支付,官网的SDKdemo 就不要使用 一直不能调试通过的,还是自己按照API接口文档一步一步来实现,吐槽下微信一点责任感都木有,能不能demo搞个正常的吗,不要坑惨了一大群码农们有点 ...
- thinkphp5.0 微信扫码支付模式二
仅供个人参考,方便大家. 一.1)https://pay.weixin.qq.com/index.php/core/home/login 复制此地址 打开微信商户平台. 2)下载安全操作证书(最好在 ...
- 【weixin】微信支付---Native支付模式二(PC端支付大多采用此模式)
[模式二]:商户后台系统调用微信支付[统一下单API]生成预付交易,将接口返回的链接生成二维码,用户扫码后输入密码完成支付交易.注意:该模式的预付单有效期为2小时,过期后无法支付 模式二与模式一相比, ...
随机推荐
- 力扣---213. 打家劫舍 II
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金.这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的.同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房 ...
- element ui el-date-picker 禁止选择指定日期
1.日期选择器组件代码 <el-col :span="20"> <el-form-item label="活动起始日期值" prop=&quo ...
- Rpc-实现Client对ZooKeeper的服务监听
1.前言 在上一篇文章中,完成了ZooKeeper注册中心.但是在上一篇中,ZooKeeper添加了一个简单的本地缓存,存在一些问题: 当本地缓存OK,ZooKeeper对应服务有新的实例时,本地缓存 ...
- JavaScript的this指向详解
一.概念: 函数的上下文(this)由调用函数的方式决定,function是"运行时上下文"策略: 函数如果不调用,则不能确定函数的上下文. 二.规则: 对象打点调用它的方法函数, ...
- Winform 程序多开
在使用应用程序的过程中,经常要求应用程序只能运行一次.如果发现重复开启,应从系统进程列表中搜索到已经开启的进程,并将该进程窗口移到最前端显示. 记录一下过程. 实现过程 在 Program.cs 文件 ...
- 益赛普等TNFi持续治疗强直性脊柱炎的长期疗效观察(≥3年)
北大深圳医院风湿免疫科在2021年发表了益赛普等TNFi持续治疗强直性脊柱炎的长期(≥3年)疗效观察[1]. 入排条件严苛,坚持随访不容易 观察对象是2009-2019年间就诊于该科室的AS患者,需有 ...
- Python批量绘制遥感影像数据的直方图
本文介绍基于Python中gdal模块,实现对大量栅格图像批量绘制直方图的方法. 首先,明确一下本文需要实现的需求:现需对多幅栅格数据文件进行依据其像元数值的直方图绘制,具体绘制内容即各栅格图 ...
- git拉取新分支、删除分支、修改远程分支
1.拉取新分支 git checkout master 切换到master分支 git pull 更新到最新代码 ...
- Cesium渲染调度
1. 引言 Cesium是一款三维地球和地图可视化开源JavaScript库,使用WebGL来进行硬件加速图形,使用时不需要任何插件支持,基于Apache2.0许可的开源程序,可以免费用于商业和非商业 ...
- php链接access并查询列出
<?php$odbc = "Driver={Microsoft Access Driver (*.mdb)};Dbq=".realpath("db.mdb" ...