微信JSAPI支付(v3)
开发指引(微信官方文档开发指引-JSAPI支付 | 微信支付商户平台文档中心)
支付业务流程图
支付代码(Java)
封装支付参数
public Map<String, Object> h5PayNow(HttpServletRequest res, BigDecimal orderPaymentAll, String orderNum,String openid) {Map<String, Object> maps = new HashMap<String, Object>();try {//初始化支付参数int totalFee = orderPaymentAll.multiply(new BigDecimal(100)).intValue();JSONObject param=new JSONObject();param.put("out_trade_no", orderNum);param.put("appid", wechatpay_h5_appid);param.put("mchid", wechatpay_mch_id);param.put("description", "产品说明");JSONObject amount=new JSONObject();amount.put("total", totalFee);param.put("amount", amount);JSONObject payer=new JSONObject();payer.put("openid", openid);param.put("payer", payer);param.put("notify_url", wechatpay_notify_url);String s = WXPayUtil.obj2json(param);//发送预支付请求String result = WXPayUtil.wxDoPostJson(wechatpay_h5_payUrl, s);System.out.println("result=======================" + result);JSONObject prepayObject = JSONObject.parseObject(result);String prepay_id =prepayObject.get("prepay_id").toString();JSONObject jsonObject = WxSignV3Utils.WxTuneUp(prepay_id, wechatpay_h5_appid);return jsonObject;} catch (Exception e) {e.printStackTrace();return null;} }
//相关工具类
import com.alibaba.fastjson.JSONObject; import com.qijinzhi.project.website.modules.business.pay.wxpay.KeyPairFactory; import com.squareup.okhttp.HttpUrl; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;import java.io.UnsupportedEncodingException; import java.security.*; import java.security.spec.InvalidKeySpecException; import java.util.*;/*** @ClassName WxSignV3Utils* @Description* @Date 2023/3/3 18:35* @Version 1.0*/ @Component public class WxSignV3Utils {//V3主商户IDprivate static String merchantId;//微信商户平台APIv3证书序列号private static String certificateSerialNo;//私钥//cert_p12_Pathprivate static String certP12Path;// 自己配置文件的mchid_路径@Value("${wx.pay.mchId}")public void setMerchantId(String merchantId) {WxSignV3Utils.merchantId = merchantId;}@Value("${wx.pay.certificate_Serial_No}")public void setCertificateSerialNo(String certificateSerialNo) {WxSignV3Utils.certificateSerialNo = certificateSerialNo;}@Value("${wx.pay.cert_p12_Path}")public void setCertP12Path(String certP12Path) {WxSignV3Utils.certP12Path = certP12Path;}/*** 使用方法** @param method 请求方法* @param url 请求url* @param body 请求内容* @return*/public static HashMap<String, String> getSignMap(String method, String url, String body) throws InvalidKeySpecException, NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException, SignatureException {String authorization = getSign(method, url, body);HashMap<String, String> headsMap = new HashMap<>();headsMap.put("Authorization", authorization);headsMap.put("Content-Type", "application/json");headsMap.put("Accept", "application/json");return headsMap;}public static String getSign(String method, String url, String body) throws NoSuchAlgorithmException, SignatureException, InvalidKeySpecException, InvalidKeyException, UnsupportedEncodingException {return "WECHATPAY2-SHA256-RSA2048 " + getToken(method, HttpUrl.parse(url), body);}public static String getToken(String method, HttpUrl url, String body) throws UnsupportedEncodingException, SignatureException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {String nonceStr = nonceString();long timestamp = System.currentTimeMillis() / 1000;String message = buildMessage(method, url, timestamp, nonceStr, body);String signature = sign(message.getBytes("utf-8"));return "mchid=\"" + merchantId + "\","+ "nonce_str=\"" + nonceStr + "\","+ "timestamp=\"" + timestamp + "\","+ "serial_no=\"" + certificateSerialNo + "\","+ "signature=\"" + signature + "\"";}public static String sign(byte[] message) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {Signature sign = Signature.getInstance("SHA256withRSA");//sign.initSign(getPKCS8PrivateKey(privateKey));KeyPair pkcs12 = new KeyPairFactory().createPKCS12(certP12Path, merchantId);PrivateKey aPrivate = pkcs12.getPrivate();sign.initSign(aPrivate);sign.update(message);return Base64.getEncoder().encodeToString(sign.sign());}public static String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {String canonicalUrl = url.encodedPath();if (url.encodedQuery() != null) {canonicalUrl += "?" + url.encodedQuery();}return method + "\n"+ canonicalUrl + "\n"+ timestamp + "\n"+ nonceStr + "\n"+ body + "\n";}public static String nonceString() {String currTime = String.format("%d", (long) System.currentTimeMillis() / 1000);String strTime = currTime.substring(8, currTime.length());Random random = new Random();int num = (int) (random.nextDouble() * (1000000 - 100000) + 100000);String code = String.format("%06d", num);String nonce_str = currTime.substring(2) + code;return nonce_str;}/*** 微信调起支付参数* 返回参数如有不理解 请访问微信官方文档* https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_1_4.shtml** @param prepayId 微信下单返回的prepay_id* @param appId 应用ID(appid)* @return 当前调起支付所需的参数* @throws Exception*/public static JSONObject WxTuneUp(String prepayId, String appId) throws Exception {String time = System.currentTimeMillis() / 1000 + "";String nonceStr = UUID.randomUUID().toString().replace("-", "");String packageStr = "prepay_id=" + prepayId;ArrayList<String> list = new ArrayList<>();list.add(appId);list.add(time);list.add(nonceStr);list.add(packageStr);//加载签名String packageSign = sign(buildSignMessage(list).getBytes());JSONObject jsonObject = new JSONObject();jsonObject.put("appid", appId);jsonObject.put("timeStamp", time);jsonObject.put("nonceStr", nonceStr);jsonObject.put("packages", packageStr);jsonObject.put("signType", "RSA");jsonObject.put("paySign", packageSign);return jsonObject;}/*** 构造签名串** @param signMessage 待签名的参数* @return 构造后带待签名串*/static String buildSignMessage(ArrayList<String> signMessage) {if (signMessage == null || signMessage.size() <= 0) {return null;}StringBuilder sbf = new StringBuilder();for (String str : signMessage) {sbf.append(str).append("\n");}return sbf.toString();}}
//WXPayUtil工具类
import com.qijinzhi.project.website.modules.business.pay.WxSignV3Utils; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.apache.http.impl.client.HttpClients;import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.*; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SignatureException; import java.security.spec.InvalidKeySpecException; import java.util.*; import com.fasterxml.jackson.databind.ObjectMapper;public class WXPayUtil {private static ObjectMapper objectMapper=new ObjectMapper();/*** XML格式字符串转换为Map** @param strXML XML字符串* @return XML数据转换后的Map* @throws Exception*/public static Map<String, String> xmlToMap(String strXML) throws Exception {try {Map<String, String> data = new HashMap<String, String>();DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));org.w3c.dom.Document doc = documentBuilder.parse(stream);doc.getDocumentElement().normalize();NodeList nodeList = doc.getDocumentElement().getChildNodes();for (int idx = 0; idx < nodeList.getLength(); ++idx) {Node node = nodeList.item(idx);if (node.getNodeType() == Node.ELEMENT_NODE) {org.w3c.dom.Element element = (org.w3c.dom.Element) node;data.put(element.getNodeName(), element.getTextContent());}}try {stream.close();} catch (Exception ex) {// do nothing}return data;} catch (Exception ex) {WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);throw ex;}}/*** 将Map转换为XML格式的字符串* @param data Map类型数据* @return XML格式的字符串* @throws Exception*/public static String mapToXml(Map<String, String> data) throws Exception {DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder();org.w3c.dom.Document document = documentBuilder.newDocument();org.w3c.dom.Element root = document.createElement("xml");document.appendChild(root);for (String key: data.keySet()) {String value = data.get(key);if (value == null) {value = "";}value = value.trim();org.w3c.dom.Element filed = document.createElement(key);filed.appendChild(document.createTextNode(value));root.appendChild(filed);}TransformerFactory tf = TransformerFactory.newInstance();Transformer transformer = tf.newTransformer();DOMSource source = new DOMSource(document);transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");transformer.setOutputProperty(OutputKeys.INDENT, "yes");StringWriter writer = new StringWriter();StreamResult result = new StreamResult(writer);transformer.transform(source, result);String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");try {writer.close();}catch (Exception ex) {}return output;}/*** 日志* @return*/public static Logger getLogger() {Logger logger = LoggerFactory.getLogger("wxpay java sdk");return logger;}/** 将SortedMap<Object,Object> 集合转化成 xml格式*/@SuppressWarnings("rawtypes")public static String getRequestXml(SortedMap<Object,Object> parameters){StringBuffer sb = new StringBuffer();sb.append("<xml>");Set<?> es = parameters.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 ("attach".equalsIgnoreCase(k)||"body".equalsIgnoreCase(k)||"sign".equalsIgnoreCase(k)) {sb.append("<"+k+">"+"<![CDATA["+v+"]]></"+k+">");}else {sb.append("<"+k+">"+v+"</"+k+">");}}sb.append("</xml>");return sb.toString(); }public static String obj2json(Object obj) throws Exception {return objectMapper.writeValueAsString(obj);}/* * 发送post请求,携带json类型数据* 如:{"name":"jok","age":"10"}** @param url 请求地址* @param json json格式参数* @return*/public static String wxDoPostJson(String url, String json) {// 创建Httpclient对象CloseableHttpClient httpClient = HttpClients.createDefault();CloseableHttpResponse response = null;String resultString = "";try {// 创建Http Post请求HttpPost httpPost = new HttpPost(url);//获取签名请求头HashMap<String, String> heads = null;try {heads = WxSignV3Utils.getSignMap("POST", url, json);} catch (InvalidKeySpecException e) {e.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (SignatureException e) {e.printStackTrace();}httpPost.addHeader("Authorization", heads.get("Authorization"));httpPost.addHeader("Accept", heads.get("Accept"));httpPost.addHeader("Content-Type",heads.get("Content-Type"));// 创建请求内容StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);httpPost.setEntity(entity);// 执行http请求response = httpClient.execute(httpPost);resultString = EntityUtils.toString(response.getEntity(), "utf-8");} catch (Exception e) {e.printStackTrace();} finally {try {response.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}return resultString;}
微信JSAPI支付(v3)相关推荐
- php微信jsapi支付小结,ThinkPHP接入微信支付 - JSAPI支付
一.支付准备 二.获取用户openid 首先,到微信公众平台后台 - 设置 - 网页授权域名(别忘了添加开发者) // 在头部引入WechatPubService.php文件,见附录一 use app ...
- 微信JSAPI支付 跟 所遇到的那些坑
首先介绍一下我在调用微信支付接口使用的是 weixin.senparc SDK,非常方便好用开源的一个微信开发SDK. weixin.senparc SDK 官网:http://weixin.senp ...
- 微信JSApi支付~订单号和微信交易号
返回目录 谈谈transactionId和out_trade_no 前一篇微信JSApi支付~坑和如何填坑文章反映不错,所以又写了个后篇,呵呵. 每个第三方在线支付系统中都会有至少两类订单号,其一为支 ...
- 微信JSAPI支付对接流程及支付接口设计
文章目录 前言 一.JSAPI支付场景及逻辑 二.开发步骤 1.设置支付目录 2.设置授权域名 3.业务流程 三.代码设计 1. 支付页面 2. Controller 3. JS调起支付 4. 工具类 ...
- 关于微信JSAPI支付成功后,点击完成后没有返回值并且页面被自动关闭问题
微信JSAPI支付成功后,点击完成后没有返回值并且页面被自动关闭 简介 解决方式 错误的处理方式 总结 简介 最近很多人可能都遇到一个问题,在使用微信JSAPI支付成功后,不走成功的回调方法,只有支付 ...
- JAVA+微信JSAPI支付
JAVA+微信JSAPI支付 引入依赖 获取请求ip 组装微信支付请求 回调处理 引入依赖 <dependency><groupId>com.github.binarywang ...
- php接入微信JSAPI支付,微信内拉起支付,基于thinkPHP框架 WeChatDeveloper支付类包
文章:php接入微信支付,扫码支付和H5支付(非微信浏览器),基于thinkPHP框架 WeChatDeveloper支付类包 踩坑指南 文章:php快速接入支付宝即时支付,PC网站支付和手机网站支付 ...
- php 微信统一下单接口,微信JSAPI支付,统一下单接口
微信JSAPI支付,统一下单接口 今天小编给大家分享一下微信支付的统一下单接口,其实微信官网上也有SDK和DEMO下载了,但是不太好理解,小编就自己整理一份容易理解的代码,看不懂官方的,就来看看小编这 ...
- C# .NETMVC 微信JSAPI支付
C# .NET MVC微信JSAPI支付 经过本人不断翻找资料和百度终于结合一些大佬的经验和思路弄出来一个MVC的微信支付了. 再弄微信支付之前我们需要先有一个商户号,并且开通了微信支付的JSAPI支 ...
- Java 微信jsapi支付
spring boot微信jsapi支付 话不多说,撸起袖子就是干,下面上源码 pom.xml 配置文件 resources/wx.properties 配置类 service(WechatPaySe ...
最新文章
- 计算机无法打开策略,windows电脑本地计算机策略打不开该怎么解决?
- 独家 | Meta的新学习算法可以教AI进行多任务处理
- 【Python-ML】无监督线性降维PCA方法
- NYOJ 20 吝啬的国度 (搜索)
- SQL Server 2005 cmd工具的使用
- 荣耀magic3会用鸿蒙,赵明:荣耀Magic3芯片领先行业,大家看到以后会换掉手机!...
- Introduce Null Object(引入Null 对象)
- Websocket判断逻辑Bug
- 聚焦技术前沿 | 字节跳动年薪百万测试开发关注的前沿技术
- IOS 10 微信 ajax readystate=0 status=0 解决方法
- 苹果pns推送和唤醒
- spring cloud config-server 高可用配置中心
- Layui Ajax请求时加上 load 加载效果
- STM32F407控制舵机
- adams语句_ADAMS简单教程(上)讲解.ppt
- 聊天室后台 java php_PHP实现简单聊天室(附源码)
- android framework手机系统改机相关知识简单方案
- 数字图像处理 调色板图像
- 修改Google浏览器默认打开是金山毒霸网址
- 用友t3系统打印机如何连接到服务器,用友T3打印设置方法
热门文章
- centos rpm不小心被卸载了怎么办?
- 八一八:布谷鸟短视频蒸蒸日上,一对一源码“风骨犹存”
- Ubuntu MongoDB 安装及简单使用
- 针对猫狗大战输出结果都是猫的问题
- 写一个函数,输入一个4位数字,要求输出这四个数字字符,但每两个数字间空两个空格。 如输入1990,应输出“1 9 9 0”
- 如何用easybcd从硬盘安装ubuntu 10.0
- 潇洒老师总结的汽车发动机结构种类汇总
- 3D投影变换(含透视投影Perspective Projection)
- Python 正则表达式练习
- Latex 文献引用不显示的问题