【微信支付】jsApi支付 V3版本(附代码)

article/2025/9/13 18:41:37

1、接入前的准备

官方文档地址
jsapi下单官方文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_1.shtml

jsapi调起支付官方文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_4.shtml

jsapi支付通知回调文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_5.shtml

接入前的准备:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_1.shtml

公众号绑定商户号(略)

登录商户号配置v3秘钥
在这里插入图片描述

登录商户号配置商户证书
流程比较多,可以看官方提供的步骤操作,操作完后本地会生成三个证书文件
在这里插入图片描述

登录商户号设置支付授权目录
在这里插入图片描述

登录公众号后台设置授权域名
在这里插入图片描述

2、引入jar

我这里用的是gradle

implementation 'com.github.wechatpay-apiv3:wechatpay-apache-httpclient:0.4.2'
implementation group: 'com.github.binarywang', name: 'weixin-java-common', version: '3.3.0'

3、创建三个工具方法

构造jsApi下单请求参数


/*** 构造微信JsApi付款的json* @param appid* @param mchid* @param description* @param out_trade_no* @param notify_url* @param amount* @return*/public static JSONObject buildWxJsApiPayJson(String appid , String mchid , String description , String out_trade_no , String notify_url , String amount, String openId){//订单金额jsonJSONObject amountJson = new JSONObject();amountJson.put("total",Integer.valueOf(amount));amountJson.put("currency","CNY");//支付者jsonJSONObject payerJson = new JSONObject();payerJson.put("openid",openId);//基础信息jsonJSONObject json = new JSONObject();json.put("appid",appid);json.put("mchid",mchid);json.put("description",description);json.put("out_trade_no",out_trade_no);json.put("notify_url",notify_url);json.put("amount",amountJson);json.put("payer",payerJson);return json;}

创建下单httpClient方法:

/**
*wxMchid商户号
*wxCertno证书编号
*wxCertPath证书地址
*wxPaternerKey   v3秘钥
*url jsapi下单地址
*body 构造好的消息体
*/
public static JSONObject doPostWexinV3(String wxMchid,String wxCertno,String wxCertPath,String wxPaternerKey,String url, String body) {// 自动更新证书功能AutoUpdateCertificatesVerifier verifier = null;try {// 名词解释:CERTNO:证书序列号;CERTPATH:证书在你服务器的地址(apiclient_key.pem)verifier = new AutoUpdateCertificatesVerifier(new WechatPay2Credentials(wxMchid, new PrivateKeySigner(wxCertno,PemUtil.loadPrivateKey(new FileInputStream(wxCertPath)))),wxPaternerKey.getBytes("utf-8"));} catch (FileNotFoundException e) {System.err.println("证书未找到!=====================");e.printStackTrace();} catch (UnsupportedEncodingException e) {System.err.println("文件流错误!=====================");e.printStackTrace();}WechatPayHttpClientBuilder builder = null;try {builder = WechatPayHttpClientBuilder.create().withMerchant(wxMchid,wxCertno, PemUtil.loadPrivateKey(new FileInputStream(wxCertPath))).withValidator(new WechatPay2Validator(verifier));} catch (FileNotFoundException e) {System.err.println("证书未找到!=====================");e.printStackTrace();}HttpClient httpClient = builder.build();HttpPost httpPost  = new HttpPost(url);httpPost.addHeader("Content-Type","application/json;chartset=utf-8");httpPost.addHeader("Accept", "application/json");try{if(body==null){throw  new IllegalArgumentException("data参数不能为空");}StringEntity stringEntity = new StringEntity(body,"utf-8");httpPost.setEntity(stringEntity);// 直接执行execute方法,官方会自动处理签名和验签,并进行证书自动更新HttpResponse httpResponse = httpClient.execute(httpPost);HttpEntity httpEntity = httpResponse.getEntity();if(httpResponse.getStatusLine().getStatusCode() == 200){String jsonResult = EntityUtils.toString(httpEntity);return JSONObject.parseObject(jsonResult);}else{System.err.println("微信支付错误信息"+EntityUtils.toString(httpEntity));}}catch (Exception e){e.printStackTrace();}return null;}

获取签名方法

/**
*wxCertPath证书地址
*prepay_id jsapi下单接口返回的参数
*/
public static JSONObject getTokenWeixin (String appId,String wxCertPath, String prepay_id) throws IOException, SignatureException, NoSuchAlgorithmException, InvalidKeyException, java.security.InvalidKeyException {// 获取随机字符串String nonceStr = getNonceStr();// 获取微信小程序支付packageString packagestr = "prepay_id=" + prepay_id;long timestamp = System.currentTimeMillis() / 1000;//签名,使用字段appId、timeStamp、nonceStr、package计算得出的签名值String message = buildMessageTwo(appId,timestamp,nonceStr,packagestr);//获取对应的签名String signature = sign(wxCertPath,message.getBytes("utf-8"));// 组装返回JSONObject json = new JSONObject();json.put("timeStamp", String.valueOf(timestamp));json.put("nonceStr", nonceStr);json.put("package", packagestr);json.put("signType", "RSA");json.put("paySign", signature);json.put("appId", appId);return json;}public static String getNonceStr(){return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);}private static String buildMessageTwo(String appId, long timestamp, String nonceStr, String packag) {return appId + "\n"+ timestamp + "\n"+ nonceStr + "\n"+ packag + "\n";}private static String sign(String wxCertPath,byte[] message) throws NoSuchAlgorithmException, SignatureException, IOException, InvalidKeyException, java.security.InvalidKeyException {Signature sign = Signature.getInstance("SHA256withRSA"); //SHA256withRSAsign.initSign(PemUtil.loadPrivateKey(new FileInputStream(wxCertPath))); // 微信证书私钥sign.update(message);return Base64.getEncoder().encodeToString(sign.sign());}

4、获取微信加密签名控制层接口

给当前url鉴权,否则前端无法唤起支付窗口

    /*** 获取微信加密签名* @return*/@PostMapping("getSignPackage")public ResponseResult getSignPackage(String url) {ResponseResult result = new ResponseResult<>();WxJsapiSignature jsapiSignature;if (StringUtils.isEmpty(url)) {return result.error(500,"缺少参数!");}try{jsapiSignature = createJsapiSignature(url);}catch (Exception e){logger.error("getSignPackage_error:"+e.getMessage());return result.error(500,"请求异常!");}return result.success(jsapiSignature);}/*** 微信加密签名参数拼装* @param url* @return* @throws Exception*/public WxJsapiSignature createJsapiSignature(String url) throws Exception {long timestamp = System.currentTimeMillis() / 1000L;String randomStr = RandomUtils.getRandomStr();String jsapiTicket =getAccessToken();String signature = SHA1.genWithAmple(new String[]{"jsapi_ticket=" + jsapiTicket, "noncestr=" + randomStr, "timestamp=" + timestamp, "url=" + url});WxJsapiSignature jsapiSignature = new WxJsapiSignature();jsapiSignature.setAppId(wxAppid);jsapiSignature.setTimestamp(timestamp);jsapiSignature.setNonceStr(randomStr);jsapiSignature.setUrl(url);jsapiSignature.setSignature(signature);return jsapiSignature;}

5、创建下单控制层接口

//拼接微信支付参数
JSONObject requestJson = buildWxJsApiPayJson(wxAppid,wxMchid,rechargeType.getMealName(),orderNo,notifyUrl,amount,openid);
//发送post请求"统一下单接口"返回预支付id:prepay_id
//下单接口:https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi
JSONObject stringObjectJson = doPostWexinV3(wxMchid,wxCertno,wxCertPath,wxPaternerKey,wxJsApiurl, requestJson.toJSONString());
JSONObject resJson = getTokenWeixin(wxAppid,wxCertPath, String.valueOf(stringObjectJson.get("prepay_id")));return result.success(resJson);

6、创建支付回调控制层接口

/*** 微信回调接口* @param body* @param request* @return*/@RequestMapping("wxJsApiCallback")public Map wxJsApiCallback(@RequestBody Map body, HttpServletRequest request) {Map<String, Object> result = new HashMap();//1:获取微信支付回调的获取签名信息String timestamp = request.getHeader("Wechatpay-Timestamp");String nonce = request.getHeader("Wechatpay-Nonce");ObjectMapper objectMapper = new ObjectMapper();try {// 2: 开始解析报文体String data = objectMapper.writeValueAsString(body);String message = timestamp + "\n" + nonce + "\n" + data + "\n";//3:获取应答签名String sign = request.getHeader("Wechatpay-Signature");//4:获取平台对应的证书String serialNo = request.getHeader("Wechatpay-Serial");Map<String, String> resource = (Map) body.get("resource");// 5:回调报文解密AesUtil aesUtil = new AesUtil(wxPaternerKey.getBytes());//解密后json字符串String decryptToString = aesUtil.decryptToString(resource.get("associated_data").getBytes(),resource.get("nonce").getBytes(),resource.get("ciphertext"));//6:获取微信支付返回的信息com.alibaba.fastjson.JSONObject jsonData = com.alibaba.fastjson.JSONObject.parseObject(decryptToString);logger.info("wxJsApiCallback responseJson:" + jsonData.toJSONString());//7: 支付状态的判断 如果是success就代表支付成功if ("SUCCESS".equals(jsonData.get("trade_state"))) {// 8:获取支付的交易单号,流水号,和附属参数String out_trade_no = jsonData.get("out_trade_no").toString();String transaction_id = jsonData.get("transaction_id").toString();com.alibaba.fastjson.JSONObject amount = jsonData.getJSONObject("amount");// 订单金额信息int payMoney = amount.getIntValue("payer_total"); //实际支付金额// 成功处理}else{// 失败处理}result.put("code", "SUCCESS");result.put("message", "成功");} catch (Exception e) {result.put("code", "fail");result.put("message", "系统错误");e.printStackTrace();}return result;}

http://chatgpt.dhexx.cn/article/rFsbi8Il.shtml

相关文章

JAVA版微信支付V3—JSAPI支付

本人用的开发框架是:struts2&#xff08;用了struts2的0配置&#xff0c;对于struts的0配置不熟悉的可以看看这个博客了解下 http://www.cnblogs.com/fpjason/archive/2009/08/01/1536671.html&#xff09; 本人做的是微信V3版本的微信支付&#xff0c;也是目前最新的微信支付…

PHP微信支付JSAPI网页支付Native原生支付

微信JsApi网页支付链接&#xff08;微信中打开&#xff09;&#xff1a;微信安全支付 微信Native原生支付产生二维码链接&#xff1a;微信扫描支付样例 资源下载路径&#xff1a;PHP实现微信支付&#xff0c;支付宝支付对接_支付对接如何设置-PHP文档类资源-CSDN下载 使用PHP…

PHP实现微信支付(jsapi支付)流程

最近接触到一个项目&#xff0c;涉及到微信支付&#xff0c;搞微信开发这么久以来&#xff0c;还没搞过支付&#xff0c;之前也就搞过公众号发红包&#xff0c;感谢前辈们的探索&#xff0c;我看了他们的博文&#xff0c;让我少走了很多弯路。 前期准备&#xff1a; 1.微信认证…

【微信公众号】微信 jsapi 支付大概流程

文章目录 一、个人对微信 jsapi 支付的介绍二、微信支付需要的数据库表&#xff08;例子&#xff09;1. 订单表2. 支付信息表3. 退款信息表 三、微信支付必须的参数&#xff08;配置文件&#xff09;四、WxPayConfig.java1. MAVEN 依赖2. Java 代码&#xff08;商户私钥、签名验…

微信小程序支付V2版之JSAPI支付

文章目录 一、微信支付环境搭建1 企业微信小程序的开通2. 企业商户号的开通3 小程序号与商户号关联 二、微信小程序的支付流程1 JSAPI支付流程2 微信小程序获取openid3 微信小程序下单4 后台服务程序对订单的处理5 微信小程序发起支付6 支付结果的通知 三、微信支付API的使用1 …

Java实现微信支付(微信公众号JSAPI支付)

Java实现微信支付&#xff08;微信公众号JSAPI支付&#xff09; 第一步 开发环境准备 在接入微信支付之前&#xff0c;需要现在微信支付商户平台入驻&#xff0c;成为商家&#xff0c;才能继续后续的开发。 微信支付商户平台网址&#xff1a;https://pay.weixin.qq.com不过&…

微信 JSAPI 支付流程

微信支付分为5种&#xff1a; Jsapi支付&#xff0c;二维码支付&#xff0c;H5支付&#xff0c;小程序支付&#xff0c;App支付 Jsapi支付流程&#xff1a; (1) 通过oauth协议获取open_id a.第一步&#xff1a;用户同意授权&#xff0c;获取code 在确保微信公众账号拥有授权…

微信小程序微信支付《JSAPI支付》APIV3详细教程

文章目录 前提整体介绍我的maven依赖1、整体流程2、openid 的获取3、统一下单Controller&#xff08;预支付订单&#xff09;4、配置类和配置文件5、工具类6、前端接收到必要的参数&#xff0c;进行调起支付页面7、微信支付通知&#xff0c;notify_url的回调Controller8、前端小…

java对接微信支付:JSAPI支付(微信公众号支付)

本文是【微信JSAPI支付】文章&#xff0c;主要讲解商户对接微信支付&#xff0c;简洁版测试 文章目录 一、JSAPI支付接入前准备 二、代码片段 1.引入Maven依赖 2.后端业务请求接口 3.前端调起支付请求方法 总结 一、JSAPI支付接入前准备 1、JSAPI支付首先需要注册、认证一个公…

微信 JSAPI 支付流程

微信支付&#xff0c;开发文档地址&#xff1a; https://pay.weixin.qq.com/wiki/doc/api/index.html JSAPI支付文档地址&#xff1a; https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter9_2 微信支付分为5种&#xff1a; Jsapi支付&#xff0c;二维码支付&#xf…

微信公众号支付(JSAPI)

六年代码两茫茫&#xff0c;不思量&#xff0c;自难忘 6年资深前端主管一枚&#xff0c;只分享技术干货&#xff0c;项目实战分享 关注博主不迷路~ 文章目录 JSAPI支付简介应用场景支付的对接准备工作开发流程必填参数预支付统一下单公众号授权获取用户信息微信支付&#xff08…

微信支付之JSAPI支付

首先看一下&#xff0c;微信支付关于jsapi的官方文档&#xff0c;相关接口&#xff0c;一共有下单&#xff0c;查询订单&#xff0c;关闭订单&#xff0c;调起jsapi支付&#xff0c;支付结果通知&#xff0c;申请退款&#xff0c;查询单笔退款&#xff0c;退款结果通知&#xf…

微信支付JSAPI

一、什么是JSAPI支付 JSAPI支付是指商户通过调用微信支付提供的JSAPI接口&#xff0c;在支付场景中调起微信支付模块完成收款。 应用场景有&#xff1a; 线下场所&#xff1a;调用接口生成二维码&#xff0c;用户扫描二维码后在微信浏览器中打开页面后完成支付 公众号场景&…

微信支付之JSAPI支付开发流程

JSAPI支付 前言准备开发1.流程说明2.下单&#xff08;预支付&#xff09;3.前端调起支付4.支付结果异步通知5.退款申请6.退款结果异步通知 结语 前言 最近项目涉及到微信支付的功能&#xff0c;在这里简单分享下整体的开发流程,这里要介绍的是JSAPI支付。 JSAPI网页支付&#…

FME是一个好东东

FME产品分为三个层次&#xff1a; 一、入门级 1、特点&#xff1a;支持常见的GIS软件的数据交换&#xff0c;如 MapInfo TAB, DGN, DXF, DWG, SDTS, SHP, and TIGER&#xff1b;可以运行大部分函数&#xff08;Funtion和Factory&#xff09;&#xff1b;不支持由Plug-in开发的第…

黑马程序员Maven学习笔记

前言 这里是黑马程序员Maven学习笔记分享&#xff0c;这是视频链接。 我还有其它前端内容的笔记&#xff0c;有需要可以查看。 文章目录 前言基础Maven简介Maven是什么Maven的作用 Maven的下载Maven的基础概念仓库坐标本地仓库配置远程仓库的配置 第一个Maven项目Maven的项目…

MAEKDOWN

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

谷粒商城前端笔记

前端笔记 JavaScript ES6 ECMAScript6.0&#xff08;以下简称ES6&#xff0c;ECMAScript是一种由Ecma国际通过ECMA-262标准化的脚本&#xff09;&#xff0c;是JavaScript语言的下一代标准&#xff0c;2015年6月正式发布&#xff0c;从ES6开始的版本号采用年号&#xff0c;如…

谷粒商城-分布式基础【业务编写】

谷粒商城-分布式基础篇【环境准备】谷粒商城-分布式基础【业务编写】谷粒商城-分布式高级篇【业务编写】持续更新谷粒商城-分布式高级篇-ElasticSearch谷粒商城-分布式高级篇-分布式锁与缓存项目托管于gitee 一、三级分类 此处三级分类最起码得启动renren-fast、nacos、gate…

1. 谷粒商城架构

架构图 解析 客户通过任意客户端&#xff08;app/Web&#xff09;向服务器发送请求&#xff0c; 请求首先来到Nginx集群&#xff0c;Nginx将请求转交给Api网关&#xff08;SpringCloud Gateway&#xff09;, Api网关&#xff1a; 可以根据当前请求&#xff0c;动态路由到指…