parent
db4982112b
commit
ccf71b60a7
12 changed files with 620 additions and 19 deletions
@ -0,0 +1,43 @@ |
||||
package org.springblade.weixin.controller; |
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage; |
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
||||
import lombok.AllArgsConstructor; |
||||
import org.springblade.core.mp.support.Condition; |
||||
import org.springblade.core.mp.support.Query; |
||||
import org.springblade.core.tool.api.R; |
||||
import org.springblade.core.tool.utils.Func; |
||||
import org.springblade.weixin.entity.WeChatAddress; |
||||
import org.springblade.weixin.entity.WeChatUser; |
||||
import org.springblade.weixin.service.IWeChatAddressService; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
@RestController |
||||
@AllArgsConstructor |
||||
@RequestMapping("/address") |
||||
public class WeChatAddressController { |
||||
|
||||
private final IWeChatAddressService weChatAddressService; |
||||
|
||||
@GetMapping("/list") |
||||
public R<IPage<WeChatAddress>> list(WeChatUser weChatUser, Query query) { |
||||
// return R.data(weChatAddressService.getPage(weChatUser, Condition.getPage(query)));
|
||||
return R.data(weChatAddressService.page(Condition.getPage(query), Wrappers.<WeChatAddress>lambdaQuery().eq(weChatUser.getId() != null, WeChatAddress::getUserId, weChatUser.getId()))); |
||||
} |
||||
|
||||
@PostMapping("/save") |
||||
public R save(@RequestBody WeChatAddress weChatAddress) { |
||||
return R.status(weChatAddressService.add(weChatAddress)); |
||||
} |
||||
|
||||
@PostMapping("/update") |
||||
public R update(@RequestBody WeChatAddress weChatAddress) { |
||||
return R.status(weChatAddressService.edit(weChatAddress)); |
||||
} |
||||
|
||||
@PostMapping("/delete") |
||||
public R delete(@RequestParam String ids) { |
||||
return R.status(weChatAddressService.deleteLogic(Func.toLongList(ids))); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,42 @@ |
||||
package org.springblade.weixin.entity; |
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName; |
||||
import lombok.Data; |
||||
import org.springblade.core.mp.base.BaseEntity; |
||||
|
||||
@Data |
||||
@TableName("eh_address") |
||||
public class WeChatAddress extends BaseEntity { |
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* 用户id |
||||
*/ |
||||
private Long userId; |
||||
|
||||
/** |
||||
* 收货人 |
||||
*/ |
||||
private String consignee; |
||||
|
||||
/** |
||||
* 手机号码 |
||||
*/ |
||||
private String phone; |
||||
|
||||
/** |
||||
* 所在地区 |
||||
*/ |
||||
private String area; |
||||
|
||||
/** |
||||
* 详细地址 |
||||
*/ |
||||
private String address; |
||||
|
||||
/** |
||||
* 是否默认地址(0否 1是) |
||||
*/ |
||||
private Integer isDefault; |
||||
|
||||
} |
||||
@ -0,0 +1,33 @@ |
||||
/* |
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* Neither the name of the dreamlu.net developer nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* Author: Chill 庄骞 (smallchill@163.com) |
||||
*/ |
||||
package org.springblade.weixin.mapper; |
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
import com.baomidou.mybatisplus.core.metadata.IPage; |
||||
import org.springblade.weixin.entity.WeChatAddress; |
||||
import org.springblade.weixin.entity.WeChatUser; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* Mapper 接口 |
||||
* @author BladeX |
||||
*/ |
||||
public interface WeChatAddressMapper extends BaseMapper<WeChatAddress> { |
||||
|
||||
List<WeChatAddress> getPage(IPage<WeChatAddress> page, WeChatUser weChatUser); |
||||
} |
||||
@ -0,0 +1,23 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
<mapper namespace="org.springblade.weixin.mapper.WeChatAddressMapper"> |
||||
|
||||
<select id="getPage" resultType="org.springblade.weixin.entity.WeChatAddress"> |
||||
SELECT |
||||
ad.id, |
||||
ad.consignee, |
||||
ad.phone, |
||||
ad.area, |
||||
ad.address, |
||||
ad.is_default, |
||||
ad.status |
||||
FROM eh_wx_user AS us |
||||
LEFT JOIN eh_address AS ad ON us.id = ad.user_id |
||||
WHERE |
||||
us.is_deleted = 0 AND ad.is_deleted = 0 |
||||
<if test="weChatUser.openId != null and weChatUser.openId != ''"> |
||||
AND us.open_id = #{weChatUser.openId} |
||||
</if> |
||||
ORDER BY ad.create_time DESC |
||||
</select> |
||||
</mapper> |
||||
@ -0,0 +1,36 @@ |
||||
/* |
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* Neither the name of the dreamlu.net developer nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* Author: Chill 庄骞 (smallchill@163.com) |
||||
*/ |
||||
package org.springblade.weixin.service; |
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage; |
||||
import org.springblade.core.mp.base.BaseService; |
||||
import org.springblade.weixin.entity.WeChatAddress; |
||||
import org.springblade.weixin.entity.WeChatUser; |
||||
|
||||
/** |
||||
* 服务类 |
||||
* |
||||
* @author BladeX |
||||
*/ |
||||
public interface IWeChatAddressService extends BaseService<WeChatAddress> { |
||||
|
||||
IPage<WeChatAddress> getPage(WeChatUser weChatUser, IPage<WeChatAddress> page); |
||||
|
||||
boolean add(WeChatAddress weChatAddress); |
||||
|
||||
boolean edit(WeChatAddress weChatAddress); |
||||
} |
||||
@ -0,0 +1,71 @@ |
||||
/* |
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* Neither the name of the dreamlu.net developer nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* Author: Chill 庄骞 (smallchill@163.com) |
||||
*/ |
||||
package org.springblade.weixin.service.impl; |
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage; |
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
||||
import lombok.AllArgsConstructor; |
||||
import org.springblade.core.mp.base.BaseServiceImpl; |
||||
import org.springblade.weixin.entity.WeChatAddress; |
||||
import org.springblade.weixin.entity.WeChatUser; |
||||
import org.springblade.weixin.mapper.WeChatAddressMapper; |
||||
import org.springblade.weixin.service.IWeChatAddressService; |
||||
import org.springframework.stereotype.Service; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
|
||||
/** |
||||
* 服务实现类 |
||||
*/ |
||||
@Service |
||||
@AllArgsConstructor |
||||
public class WeChatAddressServiceImpl extends BaseServiceImpl<WeChatAddressMapper, WeChatAddress> implements IWeChatAddressService { |
||||
|
||||
private final WeChatAddressMapper weChatAddressMapper; |
||||
|
||||
@Override |
||||
public IPage<WeChatAddress> getPage(WeChatUser weChatUser, IPage<WeChatAddress> page) { |
||||
return page.setRecords(weChatAddressMapper.getPage(page, weChatUser)); |
||||
} |
||||
|
||||
@Override |
||||
@Transactional(rollbackFor = Exception.class) |
||||
public boolean add(WeChatAddress weChatAddress) { |
||||
weChatAddress.setIsDefault(0); |
||||
// if (weChatAddress.getIsDefault() == 1) {
|
||||
// WeChatAddress address = this.getOne(Wrappers.<WeChatAddress>lambdaQuery().eq(WeChatAddress::getUserId, weChatAddress.getUserId()).eq(WeChatAddress::getIsDefault, 1));
|
||||
// if (address != null) {
|
||||
// address.setIsDefault(0);
|
||||
// this.updateById(address);
|
||||
// }
|
||||
// }
|
||||
return this.save(weChatAddress); |
||||
} |
||||
|
||||
@Override |
||||
@Transactional(rollbackFor = Exception.class) |
||||
public boolean edit(WeChatAddress weChatAddress) { |
||||
if (weChatAddress.getIsDefault() == 1) { |
||||
WeChatAddress address = this.getOne(Wrappers.<WeChatAddress>lambdaQuery().eq(WeChatAddress::getUserId, weChatAddress.getUserId()).eq(WeChatAddress::getIsDefault, 1)); |
||||
if (address != null && !address.getId().equals(weChatAddress.getId())) { |
||||
address.setIsDefault(0); |
||||
this.updateById(address); |
||||
} |
||||
} |
||||
return this.updateById(weChatAddress); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,329 @@ |
||||
package org.springblade.weixin.utils; |
||||
|
||||
import com.alibaba.fastjson.JSON; |
||||
import com.alibaba.fastjson.JSONObject; |
||||
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder; |
||||
import com.wechat.pay.contrib.apache.httpclient.auth.*; |
||||
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil; |
||||
import org.apache.http.client.methods.CloseableHttpResponse; |
||||
import org.apache.http.client.methods.HttpPost; |
||||
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 java.io.ByteArrayInputStream; |
||||
import java.io.IOException; |
||||
import java.net.URLEncoder; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.security.*; |
||||
import java.util.*; |
||||
|
||||
public class WxPayUtils { |
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(WxPayUtils.class); |
||||
|
||||
//appId 微信公众号里创建的AppId,这里的公众号需要关联到微信支付上,
|
||||
// 微信公众平台-基本配置-开发者ID(AppID),这个绑定到微信支付-产品中心-AppID账号管理-关联AppID.这里关联公众号的AppId
|
||||
public static String appId = "wx432c2efe6df3b97a"; |
||||
|
||||
//微信支付商户号 微信支付-账户中心-商户信息-微信支付商户号.查看
|
||||
public static String mchId = "1650865884"; |
||||
|
||||
// 微信下单回调地址,支付成功后会回调这个地址。
|
||||
//对应文档 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_1_5.shtml
|
||||
public static String callbackUri = "http://www.baidu.com"; |
||||
|
||||
//APIv3密钥 在微信支付商户平台-账户中心-API安全里设置,如果设置了不知道,就只有修改
|
||||
public static String apiV3Key = "2q5w8e3a6s9d1eeeeee8p5M6N9a09"; |
||||
|
||||
// 第三方用户唯一凭证密钥,即appsecret 微信公众平台-基本配置-开发者密码(AppSecret) 公众号基本配置里查询
|
||||
public static String appSecret = "859df8b167e74223e9237dee1b344524"; |
||||
|
||||
// JSApi下单url地址
|
||||
public static String JSApiPayUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi"; |
||||
|
||||
// 商户私钥 获取对应的签名需要 在微信支付商户平台-账户中心-API安全里设置 养宠物那边复制的
|
||||
// 对应文档 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/open/pay/chapter2_1.shtml
|
||||
private static String privateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC3qbz0hDWoilpKR6vYnyi4q+CCjmQUjZVIO9R9QE3OfU4qVIaUYavTL/QReO9QfMZcU3LN8JrfKBRedleBfObXXVTP9e1FZh078LEYOiI9Kdzipf3NvSzjaJqkweMe7gOaGWj60zUBQyIVN9+kQVIcqA/2oNgq3Pz88fRFaOgV91okPTj4yfE5mVZujsuHN1ov1Bbky+cbd77SIA5Vl0dXDVUB+A7ZSpc3GXeXPxbEUvHeeeeeeebOpZzcVYsnR82BfTyKmfKIhvHhQjJpHVwmjw/USxxyblLh7Nc1td7pjoommr9yvBn/knq52mPolurmUTHloOCUyxLFDfUeeeepF9iogaSswxGw6B2qK+Jd1ZOoUHnHS2XrazMwKnG1RuvZ9S6On2/lJBXxjWOcvAeKm0c/Nza3lGxcNFwD6CjiXwo+2cq82L9Y3aBiSJRQKb1"; |
||||
|
||||
//商户证书序列号
|
||||
// 对应文档 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/open/pay/chapter2_1.shtml
|
||||
private static String mchSerialNo = "23BC1D2F580D5eeeeeeF63D95837CC5"; |
||||
|
||||
private static CloseableHttpClient httpClient; |
||||
|
||||
/** |
||||
* 第一步:获取code |
||||
* 获取用户openID第一步,获取下一个接口的code参数 |
||||
* 访问这个url后,页面将跳转至 redirect_uri/?code=CODE&state=STATE。 |
||||
* 跳转的url携带code参数 |
||||
* 官方文档路径 |
||||
* https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
|
||||
* |
||||
* @return url |
||||
*/ |
||||
public static String getCodeUrl(String reUrl) { |
||||
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"; |
||||
url = url.replace("APPID", appId).replace("REDIRECT_URI", URLEncoder.encode(reUrl)); |
||||
return url; |
||||
} |
||||
|
||||
|
||||
/** |
||||
*第二部:获取AccessToken,里面包含openId |
||||
* 根据微信公众号的信息获取微信的accessToken |
||||
* {"access_token":"61_SiCTd--EFgkIpWZ4MrciAKJN0N_Dv-qdZLnJyh-","expires_in":7870,"refresh_token":"-kpaMn5czZelR87thefNLEC2WK_-","openid":"5vrCjeeMz36PQkCK57bo","scope":"snsapi_base"} |
||||
* 官方文档路径 |
||||
* https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
|
||||
*/ |
||||
// public static String getAccessToken(String code) {
|
||||
// String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
|
||||
// url = url.replace("APPID", appId).replace("SECRET", appSecret).replace("CODE",code);
|
||||
// System.out.println(url);
|
||||
// String res = HttpRequestsUtils.sendGet(url, "");
|
||||
// System.out.println(res);
|
||||
// return res;
|
||||
// }
|
||||
|
||||
/** |
||||
* 第三步:JSAPI下单 |
||||
* 使用官方开发库请求下单 |
||||
* |
||||
* @param openId openId |
||||
* @return {"prepay_id": "wx2611215250487459928b000"} |
||||
* 官方文档路径 |
||||
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/open/pay/chapter2_1.shtml
|
||||
*/ |
||||
public static String createOrderJSApiV3(String openId) { |
||||
payLoading(); |
||||
//请求URL
|
||||
HttpPost httpPost = new HttpPost(JSApiPayUrl); |
||||
// 请求body参数
|
||||
StringEntity entity = new StringEntity(JSONObject.toJSONString(buildWxJsApiV3PayJson(openId, 0)), "utf-8"); |
||||
entity.setContentType("application/json"); |
||||
httpPost.setEntity(entity); |
||||
httpPost.setHeader("Accept", "application/json"); |
||||
|
||||
//完成签名并执行请求
|
||||
CloseableHttpResponse response = null; |
||||
try { |
||||
response = httpClient.execute(httpPost); |
||||
int statusCode = response.getStatusLine().getStatusCode(); |
||||
if (statusCode == 200) { |
||||
return EntityUtils.toString(response.getEntity()); |
||||
} else if (statusCode == 204) { |
||||
return ""; |
||||
} else { |
||||
System.out.println("failed,resp code = " + statusCode + ",return body = " + EntityUtils.toString(response.getEntity())); |
||||
throw new IOException("request failed"); |
||||
} |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} finally { |
||||
try { |
||||
assert response != null; |
||||
response.close(); |
||||
httpClient.close(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
return ""; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 第四步:生成支付参数 |
||||
* 生成支付所需的参数 |
||||
* |
||||
* @param prepay_id 下单接口返回的参数 预支付交易会话标识 |
||||
* @return JSONObject |
||||
* @throws Exception e |
||||
*/ |
||||
public static JSONObject getTokenWeiXin(String prepay_id) { |
||||
// 获取随机字符串
|
||||
String nonceStr = getNonceStr(); |
||||
// 获取微信小程序支付package
|
||||
String packagestr = "prepay_id=" + prepay_id; |
||||
long timestamp = System.currentTimeMillis() / 1000; |
||||
//签名,使用字段appId、timeStamp、nonceStr、package计算得出的签名值
|
||||
String message = buildMessageTwo(appId, timestamp, nonceStr, packagestr); |
||||
//获取对应的签名
|
||||
String signature = sign(message.getBytes(StandardCharsets.UTF_8)); |
||||
// 组装返回
|
||||
JSONObject json = new JSONObject(new JSONObject()); |
||||
json.put("appId", appId); |
||||
json.put("timeStamp", String.valueOf(timestamp)); |
||||
json.put("nonceStr", nonceStr); |
||||
json.put("package", packagestr); |
||||
json.put("signType", "RSA"); |
||||
json.put("paySign", signature); |
||||
return json; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 先调用下单,然后调用生成支付参数 |
||||
* |
||||
* @param openId openId |
||||
* @return 支付参数 |
||||
*/ |
||||
public static Object getPayParam(String openId) { |
||||
JSONObject jsonObject = JSON.parseObject(createOrderJSApiV3(openId)); |
||||
return getTokenWeiXin(jsonObject.getString("prepay_id")); |
||||
|
||||
} |
||||
|
||||
|
||||
/** |
||||
* 构造下单的json(第三步需要) |
||||
* |
||||
* @param description 商品描述 |
||||
* @param amount 订单金额 |
||||
* @param openId 用户ID onAky51Fojn3NoLrnKwcY |
||||
* @return JSONObject |
||||
*/ |
||||
public static JSONObject buildWxJsApiV3PayJson(String description, String amount, String openId) { |
||||
|
||||
//订单金额json
|
||||
JSONObject amountJson = new JSONObject(); |
||||
amountJson.put("total", Integer.valueOf(amount)); |
||||
amountJson.put("currency", "CNY"); |
||||
|
||||
//支付者json
|
||||
JSONObject payerJson = new JSONObject(); |
||||
payerJson.put("openid", openId); |
||||
|
||||
//基础信息json
|
||||
JSONObject json = new JSONObject(); |
||||
// 微信公众号里创建的APPID
|
||||
json.put("appid", appId); |
||||
// 直连商户号 微信支付-账户中心-商户信息查看
|
||||
json.put("mchid", mchId); |
||||
json.put("description", description); |
||||
// 商户订单号 自己生成
|
||||
json.put("out_trade_no", generateNonceStr()); |
||||
json.put("notify_url", callbackUri); |
||||
json.put("amount", amountJson); |
||||
json.put("payer", payerJson); |
||||
return json; |
||||
} |
||||
|
||||
/** |
||||
* 根据商品goodsId构造下单的json (第三步需要) |
||||
* |
||||
* @return JSONObject |
||||
*/ |
||||
public static JSONObject buildWxJsApiV3PayJson(String openId, Integer goodsId) { |
||||
return buildWxJsApiV3PayJson("测试商品", "1", openId); |
||||
} |
||||
|
||||
/** |
||||
* 构造下单的json 无参数 |
||||
* |
||||
* @return JSONObject |
||||
*/ |
||||
public static JSONObject buildWxJsApiV3PayJson() { |
||||
return buildWxJsApiV3PayJson("测试商品", "1", "123123123124"); |
||||
} |
||||
|
||||
/** |
||||
* 初始化httpClient的通用方法(第三步:JSAPI下单) |
||||
* 微信支付官方开发库 |
||||
* 创建加载商户私钥、加载平台证书 |
||||
*/ |
||||
public static void payLoading() { |
||||
logger.info("----------初始化httpClient-----------"); |
||||
// 加载商户私钥(privateKey:私钥字符串)
|
||||
PrivateKey merchantPrivateKey = PemUtil |
||||
.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes(StandardCharsets.UTF_8))); |
||||
|
||||
// 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)
|
||||
AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier( |
||||
new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)), apiV3Key.getBytes(StandardCharsets.UTF_8)); |
||||
|
||||
// 初始化httpClient
|
||||
httpClient = WechatPayHttpClientBuilder.create() |
||||
.withMerchant(mchId, mchSerialNo, merchantPrivateKey) |
||||
.withValidator(new WechatPay2Validator(verifier)).build(); |
||||
} |
||||
|
||||
/** |
||||
* 看情况调用 ,关闭httpClient客户端 |
||||
* |
||||
* @throws IOException e |
||||
*/ |
||||
public void after() throws IOException { |
||||
httpClient.close(); |
||||
logger.info("----------关闭httpClient-----------"); |
||||
} |
||||
|
||||
/** |
||||
* 根据微信公众号的信息获取微信的Token(没有使用) |
||||
* 官方文档:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
|
||||
*/ |
||||
// public static String getToken() {
|
||||
// String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
|
||||
// url = url.replace("APPID", appId).replace("APPSECRET", appSecret);
|
||||
//
|
||||
// String result = HttpRequestsUtils.sendGet(url,"");
|
||||
// System.out.println(result);
|
||||
// JSONObject jsonObject = JSON.parseObject(result);
|
||||
// return jsonObject.getString("access_token");
|
||||
// }
|
||||
public static void main(String[] args) { |
||||
System.out.println(WxPayUtils.getCodeUrl("")); |
||||
// String str = WxPayUtils.getAccessToken();
|
||||
// System.out.println(str);
|
||||
} |
||||
|
||||
|
||||
// 获取随机字符串
|
||||
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"; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 生成签名 |
||||
* 官方文档:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_0.shtml
|
||||
* |
||||
* @param message message |
||||
* @return String |
||||
*/ |
||||
private static String sign(byte[] message) { |
||||
Signature sign = null; |
||||
try { |
||||
sign = Signature.getInstance("SHA256withRSA"); |
||||
sign.initSign(PemUtil.loadPrivateKey(privateKey)); |
||||
sign.update(message); |
||||
return Base64.getEncoder().encodeToString(sign.sign()); |
||||
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
return null; |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 随机字符串 订单号 |
||||
* |
||||
* @return |
||||
*/ |
||||
public static String generateNonceStr() { |
||||
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue