Java实现微信支付之Native模式
前言
微信支付以前就听说过,身边的同事也有弄过,但是自己因为没有遇到相关业务因此也没有去研究过。最近工作上可能会遇到微信支付因此也进行了些许研究,只是做到了接口掉通而已,并没有太深入,对微信支付已经很熟悉的同学请绕道走。
微信支付你需要了解内容
1.微信支付常用支付模式
JSAPI支付
JSAPI支付是指商户通过调用微信支付提供的JSAPI接口,在支付场景中调起微信支付模块完成收款。
APP支付
APP支付是指商户通过在移动端应用APP中集成开放SDK调起微信支付模块来完成支付。目前微信支付支持手机系统有:IOS(苹果)、Android(安卓)和WP(Windows Phone)
Native支付
Native支付是指商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”完成支付的模式。
小程序支付
商户已有微信小程序,用户通过好友分享或扫描二维码在微信内打开小程序时,可以调用微信支付完成下单购买的流程。
2.各种模式使用场景
支付模式 | 使用场景 |
---|---|
JSAPI支付 | 线下场所、公众号场景和PC网站场景。 |
APP支付 | APP支付适用于在移动端APP中集成微信支付功能的场景 |
Native支付 | Native支付适用于PC网站、实体店单品或订单、媒体广告支付等场景 |
小程序支付 | 小程序中唤起支付界面 |
付款码支付 | ----- |
3.个人理解(C端-用户,B端-商家)
JSAPI支付:C端使用B端程序,B端直接拉起支付界面,由C端完成支付,如:微信支付中手机话费充值
APP支付:C端使用B端开发的APP时,在APP中拉起支付界面
Native支付:由B端生成一个支付二维码,然后C端进行扫码拉起支付界面支付,如:菜市场买菜时微信支付
小程序支付:和APP支付一个道理
4.支付接口联调准备参数
由于支付涉及到商家,因此必须搞到商家相关的几个参数(自己注册成为商家是需要营业执照的,因此各位同学自己想办法吧),我测试的时候是直接用的别的企业的相关参数,所以不能共享出来的,所需参数内容,如下:
参数名称 | 参数讲解 |
---|---|
APPID | 由微信生成的应用ID,全局唯一。 |
商户号 | 直连商户的商户号,由微信支付生成并下发。 |
支付密钥 | 由商户提供用于进行验证支付 |
回调函数 | 由商户提供一个可外网访问的接口用于接收支付结果(不可带参数) |
商户订单号 | 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一 |
5.支付接口认识
微信支付其实对每个支付模式都提供了一套完整的api接口,每个支付模式在官网都有非常详情的Api文档,此处我研究的是Native支付,因此提供一个Native的文档参考地址。
提示:微信支付并不是我们所想的简单的调用一下接口就OK了,比如Native支付是需要我们先调用下单接口(自己指定一个不重复的订单号),生成一个订单并返回二维码链接,用户扫码支付完成后,微信会自动调用我们提供的回调地址,将支付结果反馈给我们。我们下单生成的订单也是有用处的,比如进行支付的订单查询,退款等等
接口调用
此处我只实现了Native方式中的下单和回调函数的开发,至于其他接口也是同样的道理,大家可以举一反三。
1.下单接口
@GetMapping("/pay/{orderId}")public void wxPay(@PathVariable("orderId")String orderId, HttpServletResponse response) throws Exception {// 产品相关参数WeChatParams ps = new WeChatParams();ps.setBody("商品描述");// 商品价格,注意是以分为单位,后面不能有小数点ps.setTotal_fee("1");// 订单IDps.setOut_trade_no(orderId);// 附加参数,随便设置ps.setAttach(UUID.randomUUID().toString().replace("-",""));/**构造请求参数*/SortedMap<Object, Object> packageParams = new TreeMap<>();packageParams.put("appid", WeChatProperties.appId);packageParams.put("mch_id", WeChatProperties.mchId);// 随机字符串 【备注:每次发起请求都需要随机的字符串,否则失败。】packageParams.put("nonce_str", UUID.randomUUID().toString().replace("-",""));// 支付的商品名称packageParams.put("body", ps.getBody());// 商户订单号packageParams.put("out_trade_no", ps.getOut_trade_no());// //支付金额packageParams.put("total_fee", ps.getTotal_fee());// 客户端主机packageParams.put("spbill_create_ip", PayForUtil.localIp());// 回调地址packageParams.put("notify_url", WeChatProperties.weChat_notify_url_pc);// 支付方式packageParams.put("trade_type", WeChatProperties.tradeType);// 限制用户不能使用信用卡packageParams.put("limit_pay", "no_credit");// 设备号packageParams.put("device_info", "WEB");// //额外的参数packageParams.put("attach", ps.getAttach());// 设置签名String sign = PayForUtil.createSign("UTF-8", packageParams, WeChatProperties.apiKey);packageParams.put("sign", sign);String requestXML = PayForUtil.getRequestXml(packageParams);System.out.println("支付下单接口请求参数:" + requestXML);/**调用微信统一下单API返回二维码的code*/String resXml = HttpUtil.postData(WeChatProperties.ufdoderUrl, requestXML);Map map = XMLUtil.doXMLParse(resXml);System.out.println("微信下单接口响应结果:" + resXml);if (map.get("return_code").equals("SUCCESS") && map.get("result_code").equals("SUCCESS")) {// 二维码地址String result = (String) map.get("code_url");//生成二维码输出给前台encodeQrcode(result, response);} else {throw new RuntimeException(map.get("err_code_des").toString());}/*//测试把二维码输出到本地,正式环境通过流给前端HashMap<EncodeHintType, String> map = new HashMap<>();map.put(EncodeHintType.CHARACTER_SET, "utf-8");BitMatrix bitMatrix;bitMatrix = new MultiFormatWriter().encode(urlCode, BarcodeFormat.QR_CODE, 250, 250,map );StringBuilder path =new StringBuilder();path.append("C:\\Users\\Administrator\\Desktop\\demo\\");path.append("wx22.jpg");Path file = new File(path.toString()).toPath();MatrixToImageWriter.writeToPath(bitMatrix, "jpg", file);*/}
2.将地址生成二维码工具方法
@SuppressWarnings({"unchecked", "rawtypes"})public static void encodeQrcode(String content, HttpServletResponse response) {if (StringUtils.isBlank(content)) {return;}MultiFormatWriter multiFormatWriter = new MultiFormatWriter();Hashtable hints = new Hashtable();//设置容错级别最高hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);//设置字符编码为utf-8hints.put(EncodeHintType.CHARACTER_SET, "utf-8");//二维码空白区域,最小为0也有白边,只是很小,最小是6像素左右hints.put(EncodeHintType.MARGIN, 1);BitMatrix bitMatrix = null;try {bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 250, 250, hints);BufferedImage image = toBufferedImage(bitMatrix);//输出二维码图片流try {response.setHeader("Content-Type", "image/jpeg");ImageIO.write(image, "png", response.getOutputStream());} catch (IOException e) {e.printStackTrace();}} catch (WriterException e1) {e1.printStackTrace();}}private static BufferedImage toBufferedImage(BitMatrix matrix) {int width = matrix.getWidth();int height = matrix.getHeight();BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {image.setRGB(x, y, matrix.get(x, y) == true ? BLACK : WHITE);}}return image;}
3.回调方法
@RequestMapping("/notify")public void wechatNotifyUrlPc(HttpServletRequest request, HttpServletResponse response) throws Exception {BufferedReader reader = request.getReader();StringBuffer buffer = new StringBuffer();String line = "";while ((line = reader.readLine()) != null) {buffer.append(line);}String xmlString = buffer.toString();request.getReader().close();// 验证签名前不要修改reqParam中的键值对的内容,否则会验签不过if (!WXPayUtil.isSignatureValid(xmlString, WeChatProperties.apiKey)) {System.out.println("验证签名结果[失败].");} else {Map<String, String> map = XMLUtil.doXMLParse(xmlString);String resultCode = map.get("result_code");if ("SUCCESS".equalsIgnoreCase(resultCode)) {// TODO 支付成功,做后续业务逻辑处理System.out.println("支付成功,请继续作业");} else {// TODO 失败,做失败业务逻辑处理System.out.println("支付失败,请排查原因");}}// 响应微信端,阻止其持续调用response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>");}
小结
本文只是简单的贴出来核心的代码,并不是很全面,需要全面的代码的同学请移步到码云下载我的源码哈。本文的内容,经过清测,是可以调用并接收通知的,请大家放心使用。
源码地址:https://gitee.com/zhaobolan/wechat_pay_native
Java实现微信支付之Native模式相关推荐
- 【Java 实现微信支付、Native 支付流程】,从编写代码到支付成功,一步到位!
文章目录 1. 项目环境介绍 2. 微信支付文档 2.1 业务流程说明 3. 准备信息 3.1 微信公众账号如何获取? 3.2 商户号如何获取? 3.3 API密钥如何获取? 3.4 准备工具类 4. ...
- ThinkPHP整合微信支付之Native 扫码支付 模式二
大家好,这篇文章是继微信支付之Native 扫码支付 模式一之后的微信支付系列教程第三篇:扫码支付之模式二 介绍下扫码支付目前有两种模式,模式一比模式二稍微复杂点,至于模式一与模式二的具体内容,流程, ...
- 2022微信支付v3 - Native
Native支付介绍 参考文档:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_7_0.shtml Native支付是指商户系统按 ...
- Java对接微信支付(完整全流程)
Java对接微信支付及支付回调通知的全流程 一.所用框架.对接微信支付我们技术组用的是payment框架,因为该框架已整合springboot因此很方便快捷 <dependency>< ...
- java对接微信支付收不到支付通知问题(亲身实践)
问题描述: 用java对接微信支付时,统一下单接口正常.但是用户扫码付款成功后,设置用于回调的notify_url对应的接口并没有收到请求(这个url测试过,是正常的且外网能访问的). 由于官方文档没 ...
- 实现微信支付(Native支付),使用WebSocket进行推送——3.创建支付订单,接收付款结果
实现微信支付(Native支付),使用WebSocket进行推送--3.创建支付订单,接收付款结果 注:本实验使用springboot框架 一.创建订单 1.流程 2.创建支付订单所需参数 2. AP ...
- 微信小程序-JAVA实现微信支付功能(微信支付2.0)
微信小程序-JAVA实现微信支付功能(微信支付2.0) 一.前言 本博客主要介绍JAVA后台与微信小程序(UNI-APP或者原生微信小程序)的微信支付的实现,如果是APP或者H5的开发暂时不支持,具体 ...
- 实现微信支付(Native支付),使用WebSocket进行推送——1.简单介绍
实现微信支付(Native支付),使用WebSocket进行推送--1.简单介绍 一.实现逻辑 1.由于本人的项目是web版本的,因此选用native实现微信支付,在网站生成支付二维码,然后用户在手机 ...
- 实现微信支付(Native支付),使用WebSocket进行推送 ——4.配置SpringBoot支持WebSocket,推送结果
实现微信支付(Native支付),使用WebSocket进行推送 --4.配置SpringBoot支持WebSocket,推送结果 依赖 <dependency><groupId&g ...
最新文章
- NanoPi NEO Air使用十六:使用python做开发
- jenkins参数化构建过程
- 广佛肇城轨年内通车 佛山西站预计2017年中通车
- 2003服务器远程桌面连不上解决办法
- keil 查看 stm32 io波形_你知道 KEIL 自带示波器吗?
- 正则表达式符号解释1
- pydicom 显示jpeg压缩图像_图像原理 jpg png tga bmp 存储格式
- ORA-16009: 远程归档日志目标必须为备用数据库
- 智能小车-红外循迹篇
- 服务器行业深度解析:服务器未来需求知多少
- tampermonkey 下载
- 平均值,标准差,方差,协方差,期望,均方误差
- 最流行十大在线客服系统排行榜-市场常见客服系统软件排行-2023最新
- 二极管在LDO电路中的几种常见用法
- Spring中的事务控制(Transacion Management with Spring)
- html中如何做出生年月日,出生年月日怎么换成生辰八字
- Openwrt/lede软路由设置为ap模式
- 一些写英文简历的词汇
- Spring实战 | 第一部分 Spring的核心(第四章 面向切面的Spring)
- 萌新入门第三天,css第一天,小白新手入门必看
热门文章
- 元宵节的记忆——灯笼
- 在Mac OS X下获得电脑屏幕中任意颜色的RGB值
- 思必驰DUI集成指南
- 《TextBoxes: A Fast Text Detector with a Single Deep Neural Network》论文笔记
- Cocos2d 官网介绍,新手必看!!!!!!!!!!!!!!!!!!!!!!!!!
- 四十二、SPSS方差分析,相关分析和回归分析
- 腾讯!网易!那些混不下去的互联网公司
- 解除iphone下载200M上限
- 基于matlab数字基带传输系统,通信原理基于MATLAB Simulink 基带传输系统仿真实现...
- 应用关键词的搜索量和难度