微信Native支付
微信Native支付对接(扫码)
由于有业务需求对接了微信和paypal支付,这边做个记录
微信支付开发文档:https://pay.weixin.qq.com/wiki/doc/api/index.html
一、支付方式
这边有个坑,微信h5支付和Native支付都是微信外部使用的支付方式,但是h5支付适用于移动端,因为支付时是从外部唤醒本地移动端的微信app进行支付;而Native支付则是在pc端生成订单后,用户使用移动端的微信app扫码完成支付
- 付款码支付:需要用户有扫码枪.如:肯德基,麦当劳的支付
- JSAPI支付: 主要服务于微信内部调用的支付接口
- Native支付:扫码支付
- h5支付:手机浏览器调用的支付
二、支付流程介绍

用户:客户
前端:ui界面,客户端
后端:java写的服务端
微信系统:包括生产订单的接口等
流程:
- 用户点击前端的支付按钮
- 前端将对应的订单信息发送给后端
- 后端预处理订单的信息(如在数据库中生成对应的记录),然后调用微信支付系统生成订单的接口
- 微信支付系统返回对应订单的支付地址给后端
- 后端将该订单地址返还给前端,前端调用QRCode工具生成二维码
- 用户打开手机微信app扫码完成支付(由于和我们业务并没有直接的相关性,这个过程没有直接在上图中表现出来)
- 微信系统异步(有延时)收到微信支付成功的回调,回调函数中应该包括对于验证订单的有效性(如果被人攻破就麻烦了),存储数据库(确认订单已结算),回复微信系统(否则微信会在一天之内多次发送回调信息)等步骤
- 后端可以通知前端订单完成,以便后续的操作(具体的做法可以是从订单生成之后,前端可以以一定的时间间隔询问订单的状态)
注:其它支付手段的流程应该也是大致相同的
三、准备工作
首先必然是下载sdk(software development kit).值的注意的一点是,对比于网上的许多旧的微信博客,可以发现微信的api有了极大的改进,我们只要调用少许的接口即可完成开发.同时api的命名目前也是比较统一的
申请一个商机号
注:商家号的申请是需要相关的营业执照的
上微信商户号中开通Native支付的服务
准备调用订单支付接口相关的参数(这里只展示一下必填项)
字段名 变量名 描述 公众账号ID appid 微信支付分配的公众账号ID 商户号 mch_id 微信支付分配的商户号 随机字符串 nonce_str 由内置的随机数生成算法生成 签名 sign 由内置的签名算法生成 商品描述 body 商品的简单描述 商品订单号 out_trade_no 可以直接用订单id 标价金额 total_fee 单位为分(CNY) 终端IP spbill_creat 服务器IP 通知地址 notify_url 异步回调的地址(回调不能在本地测试) 交易类型 trade_type NATIVE -Native支付 商品ID product_id 商品id,Native必填 密匙 key 商家自行设置的密匙 - 在微信商户号后台获得appid,mch_id,设置key
- out_trade_no必须大于10,不能重复
- total_fee不能有小数点(正常情况也不应该有小数点)
- nonce_str变量用于提高生成的sign不确定
- sign的算法是先将所有的参数进行排序,然后按key=value的形式拼接为字符串,最后加上key.最后,对拼接后字符串进行加密,加密方式一种是用MD5,一种使用HMAC-SHA256.具体的过程可以查看sdk原码,实际使用只要传入参数map给相关的api即可,但是了解一下有助于调试,另外附加一个微信官方的签名校验工具
- key是保证整个支付过程加密以及回调地址不被攻破的关键!
- 可以用额外的attach附加参数,如订单id
sdk下载地址(maven的相关地址大家可以自己去找找):https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1
四、开发工作
这里主要说明一下后端接口的调用
调用接口生成订单
public String getWxQrCode(HashMap<String,Object> paraMap) throws Exception {
/*数据库操作*/
Integer maxId = userMapper.getMaxUserId();
Integer id = maxId==null?1:maxId+1;
paraMap.put("user_id",id);
userMapper.addUser(paraMap);
/*获得code_url*/
Map<String, String> map = new HashMap<>();
map.put("appid",wxPayConfigBean.getAppID());
map.put("mch_id",wxPayConfigBean.getMchID());
map.put("body",wxPayConfigBean.getBody());
map.put("out_trade_no",id.toString());
map.put("total_fee",paraMap.get("order_amount").toString());
map.put("spbill_create_ip",paraMap.get("ip").toString());
map.put("notify_url",wxPayConfigBean.getNotifyUrl());
map.put("trade_type",wxPayConfigBean.getTradeType());
map.put("attach",id.toString());
//Native必传
map.put("product_id",paraMap.get("order_productid").toString());
//获得sign
WXPay wxPay = new WXPay(wxPayConfigBean);
Map<String, String> backMap = wxPay.unifiedOrder(map);
HashMap<String, Object> resMap = new HashMap<>();
resMap.put("url",backMap.get("code_url"));
resMap.put("id",id);
return JsonUtil.toJsonString(resMap);
}
回调
public void wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception { //拿到微信回调信息(以字节流的方式)
InputStream inputStream = request.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
//String是字符串变量,StringBuffer是字符串变量
StringBuffer sb = new StringBuffer();
//将字节流转换为字符串
String line;
while ((line = in.readLine()) != null){
//每次用line读取一行的字节流,如果这一行不为空就扩展到sb上
sb.append(line);
}
System.out.println("*****************************sb**************************");
System.out.println(sb);
System.out.println("*****************************sb**************************");
//关闭
in.close();
inputStream.close();
String strXml = sb.toString();
Map<String, String> toMap = WXPayUtil.xmlToMap(strXml);
System.out.println(toMap); //获取业务信息
String outTradeNo = toMap.get("out_trade_no");
String totalFee = toMap.get("total_fee");
String appId = toMap.get("appId");
String mchId = toMap.get("mch_id");
String resultCode = toMap.get("result_code");
String attach = toMap.get("attach"); //附加数据 //该对象用于通知微信
PrintWriter writer = response.getWriter(); //验签
String res = null;
Map<String,String> paraMap = WXPayUtil.xmlToMap(strXml);
boolean signatureValid = WXPayUtil.isSignatureValid(paraMap, wxPayConfigBean.getKey(), WXPayConstants.SignType.HMACSHA256); //注:注意返回时有nonce_str
if (signatureValid){
System.out.println("验证成功~");
if ("SUCCESS".equals(toMap.get("result_code"))){
System.out.println("返回的是SUCCESS");
/*自己的业务逻辑*/
}
//返回值——仍然有问题,不断刷回复
String noticeStr = setXML("SUCCESS","");
writer.write(noticeStr);
writer.flush(); //情况缓存区,并完成文件写入操作
}
}else{
System.out.println("验证失败");
String noticeStr = setXML("FATL","");
writer.write(noticeStr);
writer.flush();
};
}
private static String setXML(String return_code, String return_msg) {
return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg + "]]></return_msg></xml>";
}
注:
- 有时候回调好像没有正确地返还个微信支付系统,对java的输入输出不太了解,麻烦有大佬知道问题的请留言
- 在最开始尝试对接微信支付时查阅了较多的博客,代码,在这里表示感谢.但因为实在太过庞杂,就不一一列出了.
微信Native支付的更多相关文章
- (用微信扫的静态链接二维码)微信native支付模式官方提供的demo文件中的几个bug修正
native支付模式一demo(用微信扫的静态链接二维码)BUG修复,一共4个BUG 1.native_call_qrcode.php这个文件中的代码无法生存native支付的短地址2.WxPayPu ...
- 微信支付开发(4) 动态链接Native支付
关键字:微信支付 微信支付v3 动态native支付 统一支付 Native支付 prepay_id 作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/wxpa ...
- 微信支付开发(2) 静态链接Native支付
关键字:微信支付 微信支付v3 native支付 统一支付 Native支付 prepay_id 作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/wxpayv ...
- 微信支付开发(11) Native支付
关键字:微信公众平台 微信支付 Native原生支付作者:方倍工作室原文:http://www.cnblogs.com/txw1958/p/wxpay-native.html 由于微信支付接口更新,本 ...
- 微信原生支付 Native扫码支付( V3.3.7 版本)
原文:微信原生支付 Native扫码支付( V3.3.7 版本) [尊重别人的劳动成果,转载请注明出处:一缕晨光工作室,www.wispdawn.com] 前言 辛苦研究三天,遇到各种困难,最终还是克 ...
- 微信支付v2开发(11) Native支付
关键字:微信公众平台 微信支付 Native原生支付 作者:方倍工作室 原文:http://www.cnblogs.com/txw1958/p/wxpay-native.html 在这篇微信公众平台开 ...
- 微信移动支付V3开发详细教程服务端采用.net mvc webapi(C#)
转自:http://www.kwstu.com/ArticleView/netmvc_201511132050268716 最近开发手机app需要实现移动支付功能,由于考虑支付安全将微信支付生成签名写 ...
- 微信app支付android客户端以及.net服务端实现
由于公司运营需要,需要在客户端(android/ios)增加微信以及支付宝支付,在调用微信app支付时遇到一些问题,也算是一些踩过的坑,记录下来 ,希望能对.net开发者服务端网站更快的集成微信app ...
- 【第二十篇】C#微信H5支付 非微信内浏览器H5支付 浏览器微信支付
微信开发者文档 微信H5支付官方文档 请阅读清楚 最起码把所有参数看一遍 这个地方也可以看看 微信案例 http://wxpay.wxutil.com/mch/pay/h5.v2.php,请在微 ...
随机推荐
- CTO(技术总监)平时都在做些什么?
目前创业,最后一家公司任职医疗科技公司的研发中心总经理,之前也在几家公司的任职研发/技术总监岗位,在我理解的范围,目前国内中小企业对于CTO/技术总监的岗位区别没有那么明确的职能区分. 1. 先总结 ...
- JVM内存结构的组成、各部分功能作用
一.程序计数器 作用:是记住下一条jvm指令的执行地址 特点: 是线程私有的 不会存在內存溢出 二.虚拟机栈 每个线程运行时所需要的内存,称为虚拟机栈 每个栈由多个栈帧(Frame) 组成,对应着 ...
- k8s功能、各组件介绍以及pod创建流程
一.什么是Kubernetes Kubernetes(k跟s中间隔了8个字母又称k8s) 是谷歌开源的容器集群管理系统,是 Google 多年大规模容器管理技术Borg 的开源版本,主要功能包括: 基 ...
- 【C# 异常处理】调试器 管理异常
装载自:https://docs.microsoft.com/zh-cn/visualstudio/debugger/managing-exceptions-with-the-debugger?vie ...
- 【C# IO 操作】C#修改文件或文件夹的权限,为指定用户、用户组添加完全控制权限
代码实现 在C盘添加一个文件夹,并在文件夹内部,新建一个文本文件,如图所示: 该文件夹下,新建一个文本文件,如图所示: 为文件添加完全控制权限: /// <summary> /// 为文件 ...
- 相等性 比较【ReferenceEquals、静态Equals、==(ceq)、实例eEquals】
感觉 最近学习学疯了,突然对以前熟悉的东西感到陌生.然后又回头重新挖掘一下 什么是相等性呢?以前一直用== 默认是值相等,从未去考虑,是地址相等还值相等.今天就详细的研究一下. .net 平台提供了4 ...
- 用 UI 多线程处理 WPF 大量渲染的解决方案
众所周知, WPF 的 UI 渲染是单线程的,所以如果我们异步或者新建线程去进行数据处理的时候,处理完,想要更新 UI 的时候,需要调用一下 Dispatcher.Invoke,将处理完的数据推入到 ...
- Linux图形界面和命令界面切换
转至:https://blog.csdn.net/weixin_43683466/article/details/85727723 1.若虚拟机内热键被占用,可通过下图所示修改,移出快捷键ctrl+a ...
- MySql的事务及数据的导入导出
Mysql的事务及应用 1.补充数据库的导入与导出 导入 mysql -u root -p database < E:/SS/Test.sql -- 即执行sql文件 导出 -- 结构+数据 m ...
- Mysql的用户管理与授权
Mysql用户管理 本人使用的是Mysql8.0的版本,可能会有一些语句不兼容: 1.用户管理 在Mysql中支持创建账户,并给账户分配权限:例如只拥有数据库A操作的权限.只拥有数据库B中某些表的权限 ...