springboot微信小程序支付
今天有项目开发用到多个微信商户进行支付的场景,使用微信的SDK不太方便,以下大概使用了微信支付的示例仅供参考:
微信支付在请求接口时都要生成请求头,直接上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /** * 构造请求签名串 * @param method * @param url * @param timestamp * @param nonceStr * @param body * @return */ 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" ; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /** * 生成签名 * @param message 签名串 * @param privateKey 商户私钥 * @return * @throws RemoteException * @throws RuntimeException */ static String sign( byte [] message, String privateKey) throws RemoteException,RuntimeException{ Signature sign = null ; String stringSign = null ; try { sign = Signature.getInstance( "SHA256withRSA" ); try { sign.initSign(PemUtil.loadPrivateKeyFromString(privateKey)); try { sign.update(message); stringSign = Base64.getEncoder().encodeToString(sign.sign()); } catch (SignatureException e) { throw new RemoteException(e.getMessage()); } } catch (InvalidKeyException e) { throw new RemoteException(e.getMessage()); } } catch (NoSuchAlgorithmException e) { throw new RemoteException(e.getMessage()); } return stringSign; } |
支付示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | /** * 支付 * @param privateKeyPath * @param privateKey * @return * @throws RemoteException */ public static JSONObject pay() throws RemoteException{ //应用appid String appid = "wxd*****3f" ; //支付商户id String merchantId = "163***20" ; //支付密钥 String apiV3Key = "5dc*******413" ; //商户系列号 String merchantSerialNumber = "62C345476F*****3E71981" ; //商户商户私钥路径 String privateKeyPath = this .getClass().getResource( "/static/wechat/apiclient_key.pem" ).getPath(); //使用hutool获取证书文件内容 privateKey FileReader fileReader = new FileReader(privateKeyPath); String privateKey = fileReader.readString(); //微信支付下单API String url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi" ; HttpUrl httpurl = HttpUrl.parse(url); JSONObject data = new JSONObject(); JSONObject amount = new JSONObject(); JSONObject payer = new JSONObject(); //随机数 这里示例我先用hutool随机生成 String nonce_str = String.valueOf(RandomUtil.randomInt( 1043243 , 100432432 )); //订单号 这里示例我先用hutool随机生成 String out_trade_no = String.valueOf(RandomUtil.randomInt( 1043243 , 100432432 )); //当前时间戳 long timestamp = System.currentTimeMillis()/ 1000 ; data.put( "mchid" ,merchantId); data.put( "out_trade_no" ,out_trade_no); data.put( "appid" ,appid); data.put( "description" , "支付测试" ); data.put( "notify_url" , "https://notify_url" ); amount.put( "total" , 1 ); amount.put( "currency" , "CNY" ); payer.put( "openid" , "oYZ*******HAhG8" ); data.put( "amount" ,amount); data.put( "payer" ,payer); String message = buildMessage( "POST" , httpurl, timestamp, nonce_str, data.toJSONString()); String signature = null ; try { //获取请求签名 signature = sign(message.getBytes( "utf-8" ),privateKey); } catch (UnsupportedEncodingException e) { throw new RemoteException(e.getMessage()); } //生成请求头 String header = buildHeader(merchantId,nonce_str,signature,timestamp,merchantSerialNumber); //发起请求 String result = HttpRequest.post(url) .body(data.toJSONString()) .header( "Content-Type" , "application/json" ) .header( "Accept" , "application/json" ) .header( "Authorization" ,header) .execute().body(); JSONObject resultJson = JSONObject.parseObject(result); JSONObject requestData = new JSONObject(); if (resultJson.get( "code" ) != null ){ requestData.put( "code" , 100 ); requestData.put( "msg" ,resultJson.getString( "message" )); } else { String prepay_id = resultJson.getString( "prepay_id" ); JSONObject payData = payData(appid,timestamp,nonce_str,prepay_id,privateKey); requestData.put( "code" , 200 ); requestData.put( "res" ,payData); } return requestData; } /** * JSAPI调起支付 * @param appid * @param timestamp * @param nonceStr * @param prepayId * @param privateKey * @return * @throws RemoteException */ public static JSONObject payData(String appid, long timestamp, String nonceStr, String prepayId,String privateKey) throws RemoteException{ String payMessage = payMessage(appid,timestamp,nonceStr,prepayId); JSONObject data = new JSONObject(); try { String paySign = sign(payMessage.getBytes( "utf-8" ),privateKey); data.put( "appId" ,appid); data.put( "timeStamp" ,timestamp); data.put( "package" , "prepay_id=" +prepayId); data.put( "signType" , "RSA" ); data.put( "paySign" ,paySign); data.put( "nonceStr" ,nonceStr); } catch (UnsupportedEncodingException e) { throw new RemoteException(e.getMessage()); } return data; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)