headers,
+ String data)
+ throws WxErrorException;
+
/**
+ *
+ *
*
* 设置当微信系统响应系统繁忙时,要等待多少 retrySleepMillis(ms) * 2^(重试次数 - 1) 再发起重试.
* 默认:1000ms
@@ -151,6 +166,8 @@ public interface WxMaService extends WxService {
void setRetrySleepMillis(int retrySleepMillis);
/**
+ *
+ *
*
* 设置当微信系统响应系统繁忙时,最大重试次数.
* 默认:5次
@@ -177,7 +194,7 @@ public interface WxMaService extends WxService {
/**
* Map里 加入新的 {@link WxMaConfig},适用于动态添加新的微信公众号配置.
*
- * @param miniappId 小程序标识
+ * @param miniappId 小程序标识
* @param configStorage 新的微信配置
*/
void addConfig(String miniappId, WxMaConfig configStorage);
@@ -190,8 +207,8 @@ public interface WxMaService extends WxService {
void removeConfig(String miniappId);
/**
- * 注入多个 {@link WxMaConfig} 的实现. 并为每个 {@link WxMaConfig} 赋予不同的 {@link String mpId} 值
- * 随机采用一个{@link String mpId}进行Http初始化操作
+ * 注入多个 {@link WxMaConfig} 的实现. 并为每个 {@link WxMaConfig} 赋予不同的 {@link String mpId} 值 随机采用一个{@link
+ * String mpId}进行Http初始化操作
*
* @param configs WxMaConfig map
*/
@@ -200,7 +217,7 @@ public interface WxMaService extends WxService {
/**
* 注入多个 {@link WxMaConfig} 的实现. 并为每个 {@link WxMaConfig} 赋予不同的 {@link String label} 值
*
- * @param configs WxMaConfig map
+ * @param configs WxMaConfig map
* @param defaultMiniappId 设置一个{@link WxMaConfig} 所对应的{@link String defaultMiniappId}进行Http初始化
*/
void setMultiConfigs(Map configs, String defaultMiniappId);
@@ -328,9 +345,7 @@ public interface WxMaService extends WxService {
*/
WxMaPluginService getPluginService();
- /**
- * 初始化http请求对象.
- */
+ /** 初始化http请求对象. */
void initHttp();
/**
@@ -403,7 +418,6 @@ public interface WxMaService extends WxService {
*/
WxMaShopAfterSaleService getShopAfterSaleService();
-
/**
* 返回小程序交易组件-物流服务接口
*
@@ -411,7 +425,6 @@ public interface WxMaService extends WxService {
*/
WxMaShopDeliveryService getShopDeliveryService();
-
/**
* 返回小程序交易组件-订单服务接口
*
@@ -544,18 +557,21 @@ public interface WxMaService extends WxService {
* @return getWxMaOpenApiService
*/
WxMaOpenApiService getWxMaOpenApiService();
+
/**
* 小程序短剧管理
*
* @return getWxMaVodService
*/
WxMaVodService getWxMaVodService();
+
/**
* 小程序虚拟支付
*
* @return getWxMaXPayService
*/
WxMaXPayService getWxMaXPayService();
+
WxMaExpressDeliveryReturnService getWxMaExpressDeliveryReturnService();
/**
@@ -564,4 +580,14 @@ public interface WxMaService extends WxService {
* @return WxMaPromotionService
*/
WxMaPromotionService getWxMaPromotionService();
+
+ String postWithSignature(String url, Object obj) throws WxErrorException;
+
+ String postWithSignature(String url, JsonObject jsonObject) throws WxErrorException;
+
+ /**
+ * 微信物流服务 -- 同城配送
+ * https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/express/business/intracity_service.html
+ */
+ WxMaIntracityService getIntracityService();
}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java
index 6b67b3c28..a9114465a 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java
@@ -1,16 +1,35 @@
package cn.binarywang.wx.miniapp.api.impl;
import cn.binarywang.wx.miniapp.api.*;
+import cn.binarywang.wx.miniapp.bean.WxMaApiResponse;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
+import cn.binarywang.wx.miniapp.executor.ApiSignaturePostRequestExecutor;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
+import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyFactory;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.PSSParameterSpec;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
import java.util.function.Function;
+import javax.crypto.Cipher;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.CommonUploadParam;
@@ -25,26 +44,65 @@ import me.chanjar.weixin.common.service.WxImgProcService;
import me.chanjar.weixin.common.service.WxOcrService;
import me.chanjar.weixin.common.util.DataUtils;
import me.chanjar.weixin.common.util.crypto.SHA1;
-import me.chanjar.weixin.common.util.http.RequestExecutor;
-import me.chanjar.weixin.common.util.http.RequestHttp;
-import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
-import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
+import me.chanjar.weixin.common.util.http.*;
import me.chanjar.weixin.common.util.json.GsonParser;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import org.apache.commons.lang3.StringUtils;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-
/**
* @author Binary Wang
* @see #doGetAccessTokenRequest
*/
@Slf4j
public abstract class BaseWxMaServiceImpl implements WxMaService, RequestHttp {
+ /**
+ * 开启API签名验证后需要API签名的接口,根据 https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/
+ * 整理,uri包含下这些字符串且配置了api signature aes ras key 自动用签名接口
+ */
+ protected static final String[] urlPathSupportApiSignature =
+ new String[] {
+ "cgi-bin/clear_quota",
+ "cgi-bin/openapi/quota/get",
+ "cgi-bin/openapi/rid/get",
+ "wxa/getpluginopenpid",
+ "wxa/business/checkencryptedmsg",
+ "wxa/business/getuserencryptkey",
+ "wxa/business/getuserphonenumber",
+ "wxa/getwxacode",
+ "wxa/getwxacodeunlimit",
+ "cgi-bin/wxaapp/createwxaqrcode",
+ "cgi-bin/message/custom/send",
+ "cgi-bin/message/wxopen/updatablemsg/send",
+ "wxaapi/newtmpl/deltemplate",
+ "cgi-bin/message/subscribe/send",
+ "wxaapi/newtmpl/addtemplate",
+ "wxa/msg_sec_check",
+ "wxa/media_check_async",
+ "wxa/getuserriskrank",
+ "datacube/getweanalysisappidweeklyretaininfo",
+ "datacube/getweanalysisappidmonthlyretaininfo",
+ "datacube/getweanalysisappiddailyretaininfo",
+ "datacube/getweanalysisappidmonthlyvisittrend",
+ "datacube/getweanalysisappiddailyvisittrend",
+ "datacube/getweanalysisappidweeklyvisittrend",
+ "datacube/getweanalysisappiddailysummarytrend",
+ "datacube/getweanalysisappidvisitpage",
+ "datacube/getweanalysisappiduserportrait",
+ "wxa/business/performance/boot",
+ "datacube/getweanalysisappidvisitdistribution",
+ "wxa/getwxadevinfo",
+ "wxaapi/log/get_performance",
+ "wxaapi/log/jserr_detail",
+ "wxaapi/log/jserr_list",
+ "wxa/devplugin",
+ "wxa/plugin",
+ "cgi-bin/express/business/account/getall",
+ "cgi-bin/express/business/delivery/getall",
+ "cgi-bin/express/business/printer/getall",
+ "wxa/servicemarket",
+ "cgi-bin/soter/verify_signature"
+ };
+
protected static final Gson GSON = new Gson();
private final WxMaMsgService kefuService = new WxMaMsgServiceImpl(this);
private final WxMaMediaService materialService = new WxMaMediaServiceImpl(this);
@@ -75,26 +133,33 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH
private final WxMaShopCatService shopCatService = new WxMaShopCatServiceImpl(this);
private final WxMaShopImgService shopImgService = new WxMaShopImgServiceImpl(this);
private final WxMaShopAuditService shopAuditService = new WxMaShopAuditServiceImpl(this);
- private final WxMaShopAfterSaleService shopAfterSaleService = new WxMaShopAfterSaleServiceImpl(this);
+ private final WxMaShopAfterSaleService shopAfterSaleService =
+ new WxMaShopAfterSaleServiceImpl(this);
private final WxMaShopDeliveryService shopDeliveryService = new WxMaShopDeliveryServiceImpl(this);
private final WxMaLinkService linkService = new WxMaLinkServiceImpl(this);
- private final WxMaReimburseInvoiceService reimburseInvoiceService = new WxMaReimburseInvoiceServiceImpl(this);
- private final WxMaDeviceSubscribeService deviceSubscribeService = new WxMaDeviceSubscribeServiceImpl(this);
+ private final WxMaReimburseInvoiceService reimburseInvoiceService =
+ new WxMaReimburseInvoiceServiceImpl(this);
+ private final WxMaDeviceSubscribeService deviceSubscribeService =
+ new WxMaDeviceSubscribeServiceImpl(this);
private final WxMaMarketingService marketingService = new WxMaMarketingServiceImpl(this);
- private final WxMaImmediateDeliveryService immediateDeliveryService = new WxMaImmediateDeliveryServiceImpl(this);
+ private final WxMaImmediateDeliveryService immediateDeliveryService =
+ new WxMaImmediateDeliveryServiceImpl(this);
private final WxMaShopSharerService shopSharerService = new WxMaShopSharerServiceImpl(this);
private final WxMaProductService productService = new WxMaProductServiceImpl(this);
private final WxMaProductOrderService productOrderService = new WxMaProductOrderServiceImpl(this);
private final WxMaShopCouponService wxMaShopCouponService = new WxMaShopCouponServiceImpl(this);
private final WxMaShopPayService wxMaShopPayService = new WxMaShopPayServiceImpl(this);
- private final WxMaOrderShippingService wxMaOrderShippingService = new WxMaOrderShippingServiceImpl(this);
+ private final WxMaOrderShippingService wxMaOrderShippingService =
+ new WxMaOrderShippingServiceImpl(this);
private final WxMaOpenApiService wxMaOpenApiService = new WxMaOpenApiServiceImpl(this);
private final WxMaVodService wxMaVodService = new WxMaVodServiceImpl(this);
private final WxMaXPayService wxMaXPayService = new WxMaXPayServiceImpl(this);
- private final WxMaExpressDeliveryReturnService wxMaExpressDeliveryReturnService = new WxMaExpressDeliveryReturnServiceImpl(this);
+ private final WxMaExpressDeliveryReturnService wxMaExpressDeliveryReturnService =
+ new WxMaExpressDeliveryReturnServiceImpl(this);
private final WxMaPromotionService wxMaPromotionService = new WxMaPromotionServiceImpl(this);
+ private final WxMaIntracityService intracityService = new WxMaIntracityServiceImpl(this);
private Map configMap = new HashMap<>();
private int retrySleepMillis = 1000;
@@ -107,7 +172,7 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH
@Override
public String getPaidUnionId(String openid, String transactionId, String mchId, String outTradeNo)
- throws WxErrorException {
+ throws WxErrorException {
Map params = new HashMap<>(8);
params.put("openid", openid);
@@ -123,7 +188,8 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH
params.put("out_trade_no", outTradeNo);
}
- String responseContent = this.get(GET_PAID_UNION_ID_URL, Joiner.on("&").withKeyValueSeparator("=").join(params));
+ String responseContent =
+ this.get(GET_PAID_UNION_ID_URL, Joiner.on("&").withKeyValueSeparator("=").join(params));
WxError error = WxError.fromJson(responseContent, WxType.MiniApp);
if (error.getErrorCode() != 0) {
throw new WxErrorException(error);
@@ -141,12 +207,14 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH
params.put("js_code", jsCode);
params.put("grant_type", "authorization_code");
- String result = get(JSCODE_TO_SESSION_URL, Joiner.on("&").withKeyValueSeparator("=").join(params));
+ String result =
+ get(JSCODE_TO_SESSION_URL, Joiner.on("&").withKeyValueSeparator("=").join(params));
return WxMaJscode2SessionResult.fromJson(result);
}
@Override
- public void setDynamicData(int lifespan, String type, int scene, String data) throws WxErrorException {
+ public void setDynamicData(int lifespan, String type, int scene, String data)
+ throws WxErrorException {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("lifespan", lifespan);
jsonObject.addProperty("query", WxGsonBuilder.create().toJson(ImmutableMap.of("type", type)));
@@ -211,7 +279,6 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH
*/
protected abstract String doGetAccessTokenRequest() throws IOException;
-
/**
* 通过网络请求获取稳定版接口调用凭据
*
@@ -225,14 +292,33 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH
return execute(SimpleGetRequestExecutor.create(this), url, queryParam);
}
+ private boolean isApiSignatureRequired(String url) {
+ return this.getWxMaConfig().getApiSignatureAesKey() != null
+ && Arrays.stream(urlPathSupportApiSignature).anyMatch(part -> url.contains(part));
+ }
+
@Override
public String post(String url, String postData) throws WxErrorException {
- return execute(SimplePostRequestExecutor.create(this), url, postData);
+ if (isApiSignatureRequired(url)) {
+ // 接口需要签名
+ log.debug("已经配置接口需要签名,接口{}将走加密访问路径", url);
+ JsonObject jsonObject = GSON.fromJson(postData, JsonObject.class);
+ return postWithSignature(url, jsonObject);
+ } else {
+ return execute(SimplePostRequestExecutor.create(this), url, postData);
+ }
}
@Override
public String post(String url, Object obj) throws WxErrorException {
- return this.execute(SimplePostRequestExecutor.create(this), url, WxGsonBuilder.create().toJson(obj));
+ if (isApiSignatureRequired(url)) {
+ // 接口需要签名
+ log.debug("已经配置接口需要签名,接口{}将走加密访问路径", url);
+ return postWithSignature(url, obj);
+ } else {
+ return this.execute(
+ SimplePostRequestExecutor.create(this), url, WxGsonBuilder.create().toJson(obj));
+ }
}
@Override
@@ -240,34 +326,67 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH
return this.post(url, obj.toJson());
}
- @Override
- public String upload(String url, CommonUploadParam param) throws WxErrorException {
- RequestExecutor executor = CommonUploadRequestExecutor.create(getRequestHttp());
- return this.execute(executor, url, param);
- }
-
@Override
public String post(String url, JsonObject jsonObject) throws WxErrorException {
return this.post(url, jsonObject.toString());
}
- /**
- * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求
- */
@Override
- public T execute(RequestExecutor executor, String uri, E data) throws WxErrorException {
+ public String upload(String url, CommonUploadParam param) throws WxErrorException {
+ RequestExecutor executor =
+ CommonUploadRequestExecutor.create(getRequestHttp());
+ return this.execute(executor, url, param);
+ }
+
+ /** 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 */
+ @Override
+ public R execute(RequestExecutor executor, String uri, T data)
+ throws WxErrorException {
+ String dataForLog;
+ if (data instanceof String) {
+ dataForLog = DataUtils.handleDataWithSecret((String) data);
+ } else {
+ dataForLog = data.toString();
+ }
+ return excuteWithRetry(
+ (uriWithAccessToken) -> executor.execute(uriWithAccessToken, data, WxType.MiniApp),
+ uri,
+ dataForLog);
+ }
+
+ @Override
+ public WxMaApiResponse execute(
+ ApiSignaturePostRequestExecutor executor,
+ String uri,
+ Map headers,
+ String data)
+ throws WxErrorException {
+ String dataForLog = "Headers: " + headers.toString() + " Body: " + data;
+ return excuteWithRetry(
+ (uriWithAccessToken) -> executor.execute(uriWithAccessToken, headers, data, WxType.MiniApp),
+ uri,
+ dataForLog);
+ }
+
+ private static interface ExecutorAction {
+ R execute(String urlWithAccessToken) throws IOException, WxErrorException;
+ }
+
+ private R excuteWithRetry(ExecutorAction executor, String uri, String dataForLog)
+ throws WxErrorException {
int retryTimes = 0;
do {
try {
- return this.executeInternal(executor, uri, data, false);
+ return this.executeInternal(executor, uri, dataForLog, false);
} catch (WxErrorException e) {
if (retryTimes + 1 > this.maxRetryTimes) {
log.warn("重试达到最大次数【{}】", maxRetryTimes);
- //最后一次重试失败后,直接抛出异常,不再等待
- throw new WxErrorException(WxError.builder()
- .errorCode(e.getError().getErrorCode())
- .errorMsg("微信服务端异常,超出重试次数!")
- .build());
+ // 最后一次重试失败后,直接抛出异常,不再等待
+ throw new WxErrorException(
+ WxError.builder()
+ .errorCode(e.getError().getErrorCode())
+ .errorMsg("微信服务端异常,超出重试次数!")
+ .build());
}
WxError error = e.getError();
@@ -290,8 +409,9 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH
throw new WxRuntimeException("微信服务端异常,超出重试次数");
}
- private T executeInternal(RequestExecutor executor, String uri, E data, boolean doNotAutoRefreshToken) throws WxErrorException {
- E dataForLog = DataUtils.handleDataWithSecret(data);
+ private R executeInternal(
+ ExecutorAction executor, String uri, String dataForLog, boolean doNotAutoRefreshToken)
+ throws WxErrorException {
if (uri.contains("access_token=")) {
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri);
@@ -302,10 +422,10 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH
uri = uri.replace("https://api.weixin.qq.com", this.getWxMaConfig().getApiHostUrl());
}
- String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken;
-
+ String uriWithAccessToken =
+ uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken;
try {
- T result = executor.execute(uriWithAccessToken, data, WxType.MiniApp);
+ R result = executor.execute(uriWithAccessToken);
log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result);
return result;
} catch (WxErrorException e) {
@@ -324,10 +444,11 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH
lock.unlock();
}
if (this.getWxMaConfig().autoRefreshToken() && !doNotAutoRefreshToken) {
- log.warn("即将重新获取新的access_token,错误代码:{},错误信息:{}", error.getErrorCode(), error.getErrorMsg());
- //下一次不再自动重试
- //当小程序误调用第三方平台专属接口时,第三方无法使用小程序的access token,如果可以继续自动获取token会导致无限循环重试,直到栈溢出
- return this.executeInternal(executor, uri, data, true);
+ log.warn(
+ "即将重新获取新的access_token,错误代码:{},错误信息:{}", error.getErrorCode(), error.getErrorMsg());
+ // 下一次不再自动重试
+ // 当小程序误调用第三方平台专属接口时,第三方无法使用小程序的access token,如果可以继续自动获取token会导致无限循环重试,直到栈溢出
+ return this.executeInternal(executor, uri, dataForLog, true);
}
}
@@ -337,7 +458,8 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH
}
return null;
} catch (IOException e) {
- log.warn("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage());
+ log.warn(
+ "\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage());
throw new WxRuntimeException(e);
}
}
@@ -712,6 +834,164 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH
@Override
public WxMaPromotionService getWxMaPromotionService() {
- return this.wxMaPromotionService;
+ return this.wxMaPromotionService;
+ }
+
+ @Override
+ public String postWithSignature(String url, Object obj) throws WxErrorException {
+ Gson gson =
+ new GsonBuilder()
+ .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
+ .create();
+ JsonObject jsonObject = gson.toJsonTree(obj).getAsJsonObject();
+ return this.postWithSignature(url, jsonObject);
+ }
+
+ private String generateNonce() {
+ byte[] nonce = generateRandomBytes(16);
+ return base64Encode(nonce).replace("=", "");
+ }
+
+ private byte[] generateRandomBytes(int length) {
+ byte[] bytes = new byte[length];
+ new SecureRandom().nextBytes(bytes);
+ return bytes;
+ }
+
+ private String base64Encode(byte[] data) {
+ return Base64.getEncoder().encodeToString(data);
+ }
+
+ @Override
+ public String postWithSignature(String url, JsonObject jsonObject) throws WxErrorException {
+ long timestamp = System.currentTimeMillis() / 1000;
+ String appId = this.getWxMaConfig().getWechatMpAppid();
+ String rndStr = UUID.randomUUID().toString().replace("-", "").substring(0, 30);
+ String aesKey = this.getWxMaConfig().getApiSignatureAesKey();
+ String aesKeySn = this.getWxMaConfig().getApiSignatureAesKeySn();
+
+ jsonObject.addProperty("_n", rndStr);
+ jsonObject.addProperty("_appid", appId);
+ jsonObject.addProperty("_timestamp", timestamp);
+
+ String plainText = jsonObject.toString();
+ String urlPath;
+ if (url.contains("?")) {
+ urlPath = url.substring(0, url.indexOf("?"));
+ } else {
+ urlPath = url;
+ }
+ String aad = urlPath + "|" + appId + "|" + timestamp + "|" + aesKeySn;
+ byte[] realKey;
+ try {
+ realKey = Base64.getDecoder().decode(aesKey);
+ } catch (Exception ex) {
+ log.error("解析AESKEY失败 {}", aesKey, ex);
+ throw new SecurityException("解析AES KEY失败,请检查ApiSignatureAesKey是否正确", ex);
+ }
+ byte[] realIv = generateRandomBytes(12);
+ byte[] realAad = aad.getBytes(StandardCharsets.UTF_8);
+ byte[] realPlainText = plainText.getBytes(StandardCharsets.UTF_8);
+
+ try {
+ // 加密内容 AES
+ Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+ SecretKeySpec aesKeySpec = new SecretKeySpec(realKey, "AES");
+ GCMParameterSpec parameterSpec = new GCMParameterSpec(128, realIv);
+ cipher.init(Cipher.ENCRYPT_MODE, aesKeySpec, parameterSpec);
+ cipher.updateAAD(realAad);
+
+ byte[] ciphertext = cipher.doFinal(realPlainText);
+ byte[] encryptedData = Arrays.copyOfRange(ciphertext, 0, ciphertext.length - 16);
+ byte[] authTag = Arrays.copyOfRange(ciphertext, ciphertext.length - 16, ciphertext.length);
+
+ JsonObject reqData = new JsonObject();
+ reqData.addProperty("iv", base64Encode(realIv));
+ reqData.addProperty("data", base64Encode(encryptedData));
+ reqData.addProperty("authtag", base64Encode(authTag));
+ String requestJson = reqData.toString();
+
+ // 计算签名 RSA
+ String payload = urlPath + "\n" + appId + "\n" + timestamp + "\n" + requestJson;
+ byte[] dataBuffer = payload.getBytes(StandardCharsets.UTF_8);
+ RSAPrivateKey priKey;
+ try {
+ String rsaPrivateKey = this.getWxMaConfig().getApiSignatureRsaPrivateKey();
+ rsaPrivateKey = rsaPrivateKey.replace("-----BEGIN PRIVATE KEY-----", "");
+ rsaPrivateKey = rsaPrivateKey.replace("-----END PRIVATE KEY-----", "");
+ rsaPrivateKey = rsaPrivateKey.replaceAll("\\s+", "");
+ byte[] decoded = Base64.getDecoder().decode(rsaPrivateKey.getBytes(StandardCharsets.UTF_8));
+ PKCS8EncodedKeySpec rsaKeySpec = new PKCS8EncodedKeySpec(decoded);
+ priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(rsaKeySpec);
+ } catch (Exception ex) {
+ log.error("解析RSA KEY失败 {}", aesKey, ex);
+ throw new SecurityException("解析RSA KEY失败,请检查ApiSignatureRsaPrivateKey是否正确,需要PKCS8格式私钥", ex);
+ }
+ Signature signature = Signature.getInstance("RSASSA-PSS");
+ // salt长度,需与SHA256结果长度(32)一致
+ PSSParameterSpec pssParameterSpec =
+ new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1);
+ signature.setParameter(pssParameterSpec);
+ signature.initSign(priKey);
+ signature.update(dataBuffer);
+ byte[] sigBuffer = signature.sign();
+ String signatureString = base64Encode(sigBuffer);
+
+ Map header = new HashMap<>();
+ header.put("Wechatmp-Signature", signatureString);
+ header.put("Wechatmp-Appid", appId);
+ header.put("Wechatmp-TimeStamp", String.valueOf(timestamp));
+ log.debug("发送请求uri:{}, headers:{}, postData:{}", url, header, requestJson);
+ WxMaApiResponse response =
+ this.execute(ApiSignaturePostRequestExecutor.create(this), url, header, requestJson);
+ String respTs = response.getHeaders().get("Wechatmp-TimeStamp");
+ String respAad = urlPath + "|" + appId + "|" + respTs + "|" + aesKeySn;
+ if (!appId.equals(response.getHeaders().get("Wechatmp-Appid"))) {
+ throw new RuntimeException("响应的appId不符 " + response.getHeaders().get("Wechatmp-Appid"));
+ }
+ // 省略验证平台签名部分,直接解密内容,返回明文
+ String decryptedData = aesDecodeResponse(response, respAad, aesKeySpec);
+ log.debug("解密后的响应:{}", decryptedData);
+ WxError error = WxError.fromJson(decryptedData, WxType.MiniApp);
+ if (error.getErrorCode() != 0) {
+ log.debug("调用API出错, uri:{}, postData:{}, response:{}", url, plainText, error);
+ throw new WxErrorException(error);
+ }
+ return decryptedData;
+ } catch (WxErrorException | SecurityException ex) {
+ throw ex;
+ } catch (Exception e) {
+ log.error("postWithSignature", e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ private String aesDecodeResponse(WxMaApiResponse response, String aad, SecretKeySpec aesKeySpec)
+ throws Exception {
+ Map, ?> map = GSON.fromJson(response.getContent(), Map.class);
+ String iv = (String) map.get("iv");
+ String data = (String) map.get("data");
+ String authTag = (String) map.get("authtag");
+
+ byte[] dataBytes = Base64.getDecoder().decode(data);
+ byte[] authTagBytes = Base64.getDecoder().decode(authTag);
+ byte[] newDataBytes = new byte[dataBytes.length + authTagBytes.length];
+ System.arraycopy(dataBytes, 0, newDataBytes, 0, dataBytes.length);
+ System.arraycopy(authTagBytes, 0, newDataBytes, dataBytes.length, authTagBytes.length);
+ byte[] aadBytes = aad.getBytes(StandardCharsets.UTF_8);
+ byte[] ivBytes = Base64.getDecoder().decode(iv);
+
+ Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+ GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, ivBytes);
+ cipher.init(Cipher.DECRYPT_MODE, aesKeySpec, gcmParameterSpec);
+ cipher.updateAAD(aadBytes);
+ byte[] decryptedBytes = cipher.doFinal(newDataBytes);
+
+ return new String(decryptedBytes, StandardCharsets.UTF_8);
+ }
+
+ @Override
+ public WxMaIntracityService getIntracityService() {
+ return this.intracityService;
}
}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaIntracityServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaIntracityServiceImpl.java
new file mode 100644
index 000000000..46a728eca
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaIntracityServiceImpl.java
@@ -0,0 +1,276 @@
+package cn.binarywang.wx.miniapp.api.impl;
+
+import static cn.binarywang.wx.miniapp.constant.WxMaApiUrlConstants.Intracity;
+import static me.chanjar.weixin.common.api.WxConsts.ERR_CODE;
+
+import cn.binarywang.wx.miniapp.api.WxMaIntracityService;
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.intractiy.*;
+import com.google.gson.*;
+import com.google.gson.reflect.TypeToken;
+import java.lang.reflect.Type;
+import java.util.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.enums.WxType;
+import me.chanjar.weixin.common.error.WxError;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.json.GsonParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@RequiredArgsConstructor
+@Slf4j
+public class WxMaIntracityServiceImpl implements WxMaIntracityService {
+ private final WxMaService wxMaService;
+ private static final Logger logger = LoggerFactory.getLogger(WxMaIntracityServiceImpl.class);
+
+ private final Gson gson =
+ new GsonBuilder()
+ .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
+ .create();
+
+ private void checkStringResponse(String response) throws WxErrorException {
+ JsonObject respObj = GsonParser.parse(response);
+ if (respObj.get(ERR_CODE).getAsInt() != 0) {
+ throw new WxErrorException(WxError.fromJson(response, WxType.MiniApp));
+ }
+ }
+
+ @Override
+ public void apply() throws WxErrorException {
+ String response = this.wxMaService.post(Intracity.APPLY_URL, "{}");
+ checkStringResponse(response);
+ }
+
+ @Override
+ public String createStore(WxMaStore store) throws WxErrorException {
+ if (store.getOutStoreId() == null) {
+ throw new IllegalArgumentException("创建门店时outStoreId不能为空");
+ }
+ if (store.getWxStoreId() != null) {
+ throw new IllegalArgumentException("创建门店时wxStoreId只能是null");
+ }
+ String response = this.wxMaService.postWithSignature(Intracity.CREATE_STORE_URL, store);
+ Map, ?> map = gson.fromJson(response, Map.class);
+ return (String) map.get("wx_store_id");
+ }
+
+ @Override
+ public void updateStore(WxMaStore store) throws WxErrorException {
+ if (store.getWxStoreId() == null && store.getOutStoreId() == null) {
+ throw new IllegalArgumentException("更新门店时wxStoreId 或 outStoreId 至少要有一个不为null");
+ }
+ JsonObject request = new JsonObject();
+ Map keys = new HashMap<>();
+ if (store.getWxStoreId() != null) {
+ keys.put("wx_store_id", store.getWxStoreId());
+ } else {
+ keys.put("out_store_id", store.getOutStoreId());
+ }
+ request.add("keys", gson.toJsonTree(keys));
+ Map updateContent = new HashMap<>();
+ if (store.getStoreName() != null) {
+ updateContent.put("store_name", store.getStoreName());
+ }
+ if (store.getOrderPattern() == 1 || store.getOrderPattern() == 2) {
+ updateContent.put("order_pattern", store.getOrderPattern());
+ }
+ if (store.getServiceTransPrefer() != null) {
+ updateContent.put("service_trans_prefer", store.getServiceTransPrefer());
+ }
+ if (store.getAddressInfo() != null) {
+ updateContent.put("address_info", store.getAddressInfo());
+ }
+ request.add("content", gson.toJsonTree(updateContent));
+ String response = this.wxMaService.postWithSignature(Intracity.UPDATE_STORE_URL, request);
+ checkStringResponse(response);
+ }
+
+ @Override
+ public List listAllStores() throws WxErrorException {
+ return queryStore(null, null);
+ }
+
+ @Override
+ public WxMaStore queryStoreByWxStoreId(String wxStoreId) throws WxErrorException {
+ List list = queryStore(wxStoreId, null);
+ return list.isEmpty() ? null : list.get(0);
+ }
+
+ @Override
+ public List queryStoreByOutStoreId(String outStoreId) throws WxErrorException {
+ return queryStore(null, outStoreId);
+ }
+
+ private List queryStore(String wxStoreId, String outStoreId) throws WxErrorException {
+ Map map = new HashMap<>();
+ if (wxStoreId != null) {
+ map.put("wx_store_id", wxStoreId);
+ } else if (outStoreId != null) {
+ map.put("out_store_id", outStoreId);
+ }
+ String response = this.wxMaService.postWithSignature(Intracity.QUERY_STORE_URL, map);
+ JsonObject jsonObject = gson.fromJson(response, JsonObject.class);
+ Type listType = new TypeToken>() {}.getType();
+ return gson.fromJson(jsonObject.getAsJsonArray("store_list"), listType);
+ }
+
+ @Override
+ public String storeCharge(WxMaStoreChargeRequest request) throws WxErrorException {
+ String response = this.wxMaService.postWithSignature(Intracity.STORE_CHARGE, request);
+ Map, ?> map = gson.fromJson(response, Map.class);
+ return (String) map.get("payurl");
+ }
+
+ @Override
+ public int storeRefund(WxMaStoreRefundRequest request) throws WxErrorException {
+ String response = this.wxMaService.postWithSignature(Intracity.STORE_REFUND, request);
+ Map, ?> map = gson.fromJson(response, Map.class);
+ return ((Number) map.get("refund_amount")).intValue();
+ }
+
+ @Override
+ public WxMaStoreFlowResponse extends WxMaStoreFlowResponse.BasicFlowRecord> queryFlow(
+ WxMaQueryFlowRequest request) throws WxErrorException {
+ if (request == null || request.getWxStoreId() == null) {
+ throw new IllegalArgumentException("查询请求 wxStoreId 不可为空");
+ }
+ WxMaStoreFlowResponse extends WxMaStoreFlowResponse.BasicFlowRecord> inst =
+ getFlowInstanceByType(request.getFlowType());
+ if (inst == null) {
+ throw new IllegalArgumentException("查询请求 flowType 不正确,只能是1、2、3之一");
+ }
+
+ String response = this.wxMaService.postWithSignature(Intracity.QUERY_FLOW, request);
+
+ WxMaStoreFlowResponse extends WxMaStoreFlowResponse.BasicFlowRecord> flowResponse;
+ flowResponse =
+ (WxMaStoreFlowResponse extends WxMaStoreFlowResponse.BasicFlowRecord>)
+ gson.fromJson(response, inst.getClass());
+ logger.debug("queryFlow: {}", flowResponse);
+ return flowResponse;
+ }
+
+ private WxMaStoreFlowResponse extends WxMaStoreFlowResponse.BasicFlowRecord>
+ getFlowInstanceByType(int flowType) {
+ WxMaStoreFlowResponse extends WxMaStoreFlowResponse.BasicFlowRecord> inst;
+ if (flowType == 1) {
+ inst = new WxMaStoreFlowResponse();
+ } else if (flowType == 2) {
+ inst = new WxMaStoreFlowResponse();
+ } else if (flowType == 3) {
+ inst = new WxMaStoreFlowResponse();
+ } else {
+ return null;
+ }
+ return inst;
+ }
+
+ @Override
+ public WxMaStoreBalance balanceQuery(String wxStoreId, String serviceTransId, PayMode payMode)
+ throws WxErrorException {
+ if (wxStoreId == null && (payMode != null && payMode != PayMode.STORE)) {
+ throw new IllegalArgumentException("payMode是PAY_MODE_STORE或null时,必须传递wxStoreId");
+ }
+ Map request = new HashMap<>();
+ if (wxStoreId != null) {
+ request.put("wx_store_id", wxStoreId);
+ }
+ if (serviceTransId != null) {
+ request.put("service_trans_id", serviceTransId);
+ }
+ if (payMode != null) {
+ request.put("pay_mode", payMode);
+ }
+ String response = this.wxMaService.postWithSignature(Intracity.BALANCE_QUERY, request);
+ WxMaStoreBalance balance = gson.fromJson(response, WxMaStoreBalance.class);
+ logger.debug("balance: {}", balance);
+ return balance;
+ }
+
+ public void setPayMode(PayMode payMode) throws WxErrorException {
+ Map request = new HashMap<>();
+ request.put("pay_mode", payMode);
+ request.put("appid", wxMaService.getWxMaConfig().getAppid());
+ String response = this.wxMaService.postWithSignature(Intracity.SET_PAY_MODE, request);
+ checkStringResponse(response);
+ }
+
+ public WxMaGetPayModeResponse getPayMode() throws WxErrorException {
+ Map request = new HashMap<>();
+ request.put("appid", wxMaService.getWxMaConfig().getAppid());
+ String response = this.wxMaService.postWithSignature(Intracity.GET_PAY_MODE, request);
+ return gson.fromJson(response, WxMaGetPayModeResponse.class);
+ }
+
+ @Override
+ public WxMaAddOrderResponse preAddOrder(WxMaPreAddOrderRequest request) throws WxErrorException {
+ String response = this.wxMaService.postWithSignature(Intracity.PRE_ADD_ORDER, request);
+ return gson.fromJson(response, WxMaAddOrderResponse.class);
+ }
+
+ @Override
+ public WxMaAddOrderResponse addOrder(WxMaAddOrderRequest request) throws WxErrorException {
+ String response = this.wxMaService.postWithSignature(Intracity.ADD_ORDER, request);
+ return gson.fromJson(response, WxMaAddOrderResponse.class);
+ }
+
+ @Override
+ public WxMaOrder queryOrderByWxOrderId(String wxOrderId) throws WxErrorException {
+ Map map = new HashMap<>();
+ map.put("wx_order_id", wxOrderId);
+ String response = this.wxMaService.postWithSignature(Intracity.QUERY_ORDER, map);
+ return gson.fromJson(response, WxMaOrder.class);
+ }
+
+ @Override
+ public WxMaOrder queryOrderByStoreOrderId(String wxStoreId, String storeOrderId)
+ throws WxErrorException {
+ Map map = new HashMap<>();
+ map.put("wx_store_id", wxStoreId);
+ map.put("store_order_id", storeOrderId);
+ String response = this.wxMaService.postWithSignature(Intracity.QUERY_ORDER, map);
+ return gson.fromJson(response, WxMaOrder.class);
+ }
+
+ @Override
+ public WxMaCancelOrderResponse cancelOrderByWxOrderId(
+ String wxOrderId, int cancelReasonId, String cancelReason) throws WxErrorException {
+ Map map = new HashMap<>();
+ map.put("wx_order_id", wxOrderId);
+ map.put("cancel_reason_id", cancelReasonId);
+ if (cancelReason != null) {
+ map.put("cancel_reason", cancelReason);
+ }
+ String response = this.wxMaService.postWithSignature(Intracity.CANCEL_ORDER, map);
+ return gson.fromJson(response, WxMaCancelOrderResponse.class);
+ }
+
+ @Override
+ public WxMaCancelOrderResponse cancelOrderByStoreOrderId(
+ String wxStoreId, String storeOrderId, int cancelReasonId, String cancelReason)
+ throws WxErrorException {
+ Map map = new HashMap<>();
+ map.put("wx_store_id", wxStoreId);
+ map.put("store_order_id", storeOrderId);
+ map.put("cancel_reason_id", cancelReasonId);
+ if (cancelReason != null) {
+ map.put("cancel_reason", cancelReason);
+ }
+ String response = this.wxMaService.postWithSignature(Intracity.CANCEL_ORDER, map);
+ return gson.fromJson(response, WxMaCancelOrderResponse.class);
+ }
+
+ @Override
+ public List getCity(String serviceTransId) throws WxErrorException {
+ Map map = new HashMap<>();
+ if (serviceTransId != null) {
+ map.put("service_trans_id", serviceTransId);
+ }
+ String response = this.wxMaService.postWithSignature(Intracity.GET_CITY, map);
+ JsonObject jsonObject = gson.fromJson(response, JsonObject.class);
+ Type listType = new TypeToken>() {}.getType();
+ return gson.fromJson(jsonObject.getAsJsonArray("support_list"), listType);
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaApiResponse.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaApiResponse.java
new file mode 100644
index 000000000..47345ba40
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaApiResponse.java
@@ -0,0 +1,34 @@
+package cn.binarywang.wx.miniapp.bean;
+
+import java.util.Map;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WxMaApiResponse {
+ private static final Logger logger = LoggerFactory.getLogger(WxMaApiResponse.class);
+
+ private String content;
+ private Map headers;
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public Map getHeaders() {
+ return headers;
+ }
+
+ public void setHeaders(Map headers) {
+ this.headers = headers;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/BasicWxMaOrder.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/BasicWxMaOrder.java
new file mode 100644
index 000000000..868cf5e5c
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/BasicWxMaOrder.java
@@ -0,0 +1,128 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+class BasicWxMaOrder {
+
+ private String wxStoreId;
+ private String userName;
+ private String userPhone;
+ private double userLng;
+ private double userLat;
+ private String userAddress;
+ private int useSandbox;
+
+ public String getWxStoreId() {
+ return wxStoreId;
+ }
+
+ public void setWxStoreId(String wxStoreId) {
+ this.wxStoreId = wxStoreId;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getUserPhone() {
+ return userPhone;
+ }
+
+ public void setUserPhone(String userPhone) {
+ this.userPhone = userPhone;
+ }
+
+ public double getUserLng() {
+ return userLng;
+ }
+
+ public void setUserLng(double userLng) {
+ this.userLng = userLng;
+ }
+
+ public double getUserLat() {
+ return userLat;
+ }
+
+ public void setUserLat(double userLat) {
+ this.userLat = userLat;
+ }
+
+ public String getUserAddress() {
+ return userAddress;
+ }
+
+ public void setUserAddress(String userAddress) {
+ this.userAddress = userAddress;
+ }
+
+ public int isUseSandbox() {
+ return useSandbox;
+ }
+
+ public void setUseSandbox(int useSandbox) {
+ this.useSandbox = useSandbox;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+ static class Cargo {
+ private String cargoName;
+ private int cargoWeight;
+ private int cargoType;
+ private int cargoNum;
+ private int cargoPrice;
+
+ public String getCargoName() {
+ return cargoName;
+ }
+
+ public void setCargoName(String cargoName) {
+ this.cargoName = cargoName;
+ }
+
+ public int getCargoWeight() {
+ return cargoWeight;
+ }
+
+ public void setCargoWeight(int cargoWeight) {
+ this.cargoWeight = cargoWeight;
+ }
+
+ public int getCargoType() {
+ return cargoType;
+ }
+
+ public void setCargoType(int cargoType) {
+ this.cargoType = cargoType;
+ }
+
+ public int getCargoNum() {
+ return cargoNum;
+ }
+
+ public void setCargoNum(int cargoNum) {
+ this.cargoNum = cargoNum;
+ }
+
+ public int getCargoPrice() {
+ return cargoPrice;
+ }
+
+ public void setCargoPrice(int cargoPrice) {
+ this.cargoPrice = cargoPrice;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/BasicWxMaStoreChargeRefundRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/BasicWxMaStoreChargeRefundRequest.java
new file mode 100644
index 000000000..f9140ad57
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/BasicWxMaStoreChargeRefundRequest.java
@@ -0,0 +1,49 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+class BasicWxMaStoreChargeRefundRequest {
+
+ /** 微信门店编号 pay_mode = PAY_MODE_STORE时必传,不传pay_mode时必传wx_store_id */
+ private String wxStoreId;
+
+ /**
+ * 充值/扣费主体
+ * 门店:PAY_MODE_STORE;小程序:PAY_MODE_APP;服务商:PAY_MODE_COMPONENT,不传pay_mode默认pay_mode=PAY_MODE_STORE
+ */
+ private PayMode payMode;
+
+ /**
+ * 运力Id,必填。运力ID请参考:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/express/business/intracity_service.html#_6-%E8%BF%90%E5%8A%9B%E5%88%97%E8%A1%A8
+ */
+ private String serviceTransId;
+
+ public String getWxStoreId() {
+ return wxStoreId;
+ }
+
+ public void setWxStoreId(String wxStoreId) {
+ this.wxStoreId = wxStoreId;
+ }
+
+ public PayMode getPayMode() {
+ return payMode;
+ }
+
+ public void setPayMode(PayMode payMode) {
+ this.payMode = payMode;
+ }
+
+ public String getServiceTransId() {
+ return serviceTransId;
+ }
+
+ public void setServiceTransId(String serviceTransId) {
+ this.serviceTransId = serviceTransId;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/PayMode.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/PayMode.java
new file mode 100644
index 000000000..bf779e21f
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/PayMode.java
@@ -0,0 +1,16 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import com.google.gson.annotations.SerializedName;
+
+/** 充值、扣费主体 */
+public enum PayMode {
+ /** 门店 */
+ @SerializedName("PAY_MODE_STORE")
+ STORE,
+ /** 小程序 */
+ @SerializedName("PAY_MODE_APP")
+ APP,
+ /** 服务商 */
+ @SerializedName("PAY_MODE_COMPONENT")
+ COMPONENT;
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaAddOrderRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaAddOrderRequest.java
new file mode 100644
index 000000000..6e27c5780
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaAddOrderRequest.java
@@ -0,0 +1,133 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import java.util.List;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WxMaAddOrderRequest extends BasicWxMaOrder {
+ private static final Logger logger = LoggerFactory.getLogger(WxMaAddOrderRequest.class);
+ private String storeOrderId;
+ private String userOpenid;
+ private String orderSeq;
+
+ /** 验证码类型 0:不生成 1:生成取货码 2:生成收货码 3:两者都生成 */
+ private int verifyCodeType;
+
+ private String orderDetailPath;
+ private String callbackUrl;
+ private Cargo cargo;
+
+ public String getStoreOrderId() {
+ return storeOrderId;
+ }
+
+ public void setStoreOrderId(String storeOrderId) {
+ this.storeOrderId = storeOrderId;
+ }
+
+ public String getUserOpenid() {
+ return userOpenid;
+ }
+
+ public void setUserOpenid(String userOpenid) {
+ this.userOpenid = userOpenid;
+ }
+
+ public String getOrderSeq() {
+ return orderSeq;
+ }
+
+ public void setOrderSeq(String orderSeq) {
+ this.orderSeq = orderSeq;
+ }
+
+ public int getVerifyCodeType() {
+ return verifyCodeType;
+ }
+
+ public void setVerifyCodeType(int verifyCodeType) {
+ this.verifyCodeType = verifyCodeType;
+ }
+
+ public String getOrderDetailPath() {
+ return orderDetailPath;
+ }
+
+ public void setOrderDetailPath(String orderDetailPath) {
+ this.orderDetailPath = orderDetailPath;
+ }
+
+ public String getCallbackUrl() {
+ return callbackUrl;
+ }
+
+ public void setCallbackUrl(String callbackUrl) {
+ this.callbackUrl = callbackUrl;
+ }
+
+ public Cargo getCargo() {
+ return cargo;
+ }
+
+ public void setCargo(Cargo cargo) {
+ this.cargo = cargo;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+ public static class Cargo extends BasicWxMaOrder.Cargo {
+ private List itemList;
+
+ public List getItemList() {
+ return itemList;
+ }
+
+ public void setItemList(List itemList) {
+ this.itemList = itemList;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+ }
+
+ public static class ItemDetail {
+ private String itemName;
+ private String itemPicUrl;
+ private int count;
+
+ public String getItemName() {
+ return itemName;
+ }
+
+ public void setItemName(String itemName) {
+ this.itemName = itemName;
+ }
+
+ public String getItemPicUrl() {
+ return itemPicUrl;
+ }
+
+ public void setItemPicUrl(String itemPicUrl) {
+ this.itemPicUrl = itemPicUrl;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public void setCount(int count) {
+ this.count = count;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaAddOrderResponse.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaAddOrderResponse.java
new file mode 100644
index 000000000..7155c1153
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaAddOrderResponse.java
@@ -0,0 +1,115 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+public class WxMaAddOrderResponse {
+ private String wxOrderId;
+ private String storeOrderId;
+ private String wxStoreId;
+
+ /** 配送运力 */
+ private String serviceTransId;
+
+ /** 配送距离 单位:米 */
+ private int distance;
+
+ /** 运力订单号 */
+ private String transOrderId;
+
+ /** 运力配送单号 */
+ private String waybillId;
+
+ /** 配送费 */
+ private int fee;
+
+ /** 取货码 */
+ private String fetchCode;
+
+ /** 取货序号 */
+ private String orderSeq;
+
+ public String getWxOrderId() {
+ return wxOrderId;
+ }
+
+ public void setWxOrderId(String wxOrderId) {
+ this.wxOrderId = wxOrderId;
+ }
+
+ public String getStoreOrderId() {
+ return storeOrderId;
+ }
+
+ public void setStoreOrderId(String storeOrderId) {
+ this.storeOrderId = storeOrderId;
+ }
+
+ public String getWxStoreId() {
+ return wxStoreId;
+ }
+
+ public void setWxStoreId(String wxStoreId) {
+ this.wxStoreId = wxStoreId;
+ }
+
+ public String getServiceTransId() {
+ return serviceTransId;
+ }
+
+ public void setServiceTransId(String serviceTransId) {
+ this.serviceTransId = serviceTransId;
+ }
+
+ public int getDistance() {
+ return distance;
+ }
+
+ public void setDistance(int distance) {
+ this.distance = distance;
+ }
+
+ public String getTransOrderId() {
+ return transOrderId;
+ }
+
+ public void setTransOrderId(String transOrderId) {
+ this.transOrderId = transOrderId;
+ }
+
+ public String getWaybillId() {
+ return waybillId;
+ }
+
+ public void setWaybillId(String waybillId) {
+ this.waybillId = waybillId;
+ }
+
+ public int getFee() {
+ return fee;
+ }
+
+ public void setFee(int fee) {
+ this.fee = fee;
+ }
+
+ public String getFetchCode() {
+ return fetchCode;
+ }
+
+ public void setFetchCode(String fetchCode) {
+ this.fetchCode = fetchCode;
+ }
+
+ public String getOrderSeq() {
+ return orderSeq;
+ }
+
+ public void setOrderSeq(String orderSeq) {
+ this.orderSeq = orderSeq;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaCancelOrderResponse.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaCancelOrderResponse.java
new file mode 100644
index 000000000..a2a21d7ff
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaCancelOrderResponse.java
@@ -0,0 +1,67 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+public class WxMaCancelOrderResponse {
+ private String wxOrderId;
+ private String storeOrderId;
+ private String wxStoreId;
+ private String orderStatus;
+ private String appid;
+
+ /** 违约金 */
+ private int deductfee;
+
+ public String getWxOrderId() {
+ return wxOrderId;
+ }
+
+ public void setWxOrderId(String wxOrderId) {
+ this.wxOrderId = wxOrderId;
+ }
+
+ public String getStoreOrderId() {
+ return storeOrderId;
+ }
+
+ public void setStoreOrderId(String storeOrderId) {
+ this.storeOrderId = storeOrderId;
+ }
+
+ public String getWxStoreId() {
+ return wxStoreId;
+ }
+
+ public void setWxStoreId(String wxStoreId) {
+ this.wxStoreId = wxStoreId;
+ }
+
+ public String getOrderStatus() {
+ return orderStatus;
+ }
+
+ public void setOrderStatus(String orderStatus) {
+ this.orderStatus = orderStatus;
+ }
+
+ public String getAppid() {
+ return appid;
+ }
+
+ public void setAppid(String appid) {
+ this.appid = appid;
+ }
+
+ public int getDeductfee() {
+ return deductfee;
+ }
+
+ public void setDeductfee(int deductfee) {
+ this.deductfee = deductfee;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaGetPayModeResponse.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaGetPayModeResponse.java
new file mode 100644
index 000000000..8d49ce088
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaGetPayModeResponse.java
@@ -0,0 +1,42 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WxMaGetPayModeResponse {
+ private static final Logger logger = LoggerFactory.getLogger(WxMaGetPayModeResponse.class);
+
+ private PayMode payMode;
+ private String payAppid;
+ private String componentAppid;
+
+ public PayMode getPayMode() {
+ return payMode;
+ }
+
+ public void setPayMode(PayMode payMode) {
+ this.payMode = payMode;
+ }
+
+ public String getPayAppid() {
+ return payAppid;
+ }
+
+ public void setPayAppid(String payAppid) {
+ this.payAppid = payAppid;
+ }
+
+ public String getComponentAppid() {
+ return componentAppid;
+ }
+
+ public void setComponentAppid(String componentAppid) {
+ this.componentAppid = componentAppid;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaOrder.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaOrder.java
new file mode 100644
index 000000000..fbec5c8c6
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaOrder.java
@@ -0,0 +1,344 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import java.util.Date;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+public class WxMaOrder extends WxMaAddOrderRequest {
+ private String wxOrderId;
+ private int orderStatus;
+ private String appid;
+ private String serviceTransId;
+ private String deliveryNo;
+ private int actualfee;
+ private int deductfee;
+ private long createTime;
+ private long acceptTime;
+ private long fetchTime;
+ private long finishTime;
+ private long cancelTime;
+ private long expectedFinishTime;
+ private String fetchCode;
+ private String recvCode;
+ private TransporterInfo transporterInfo;
+ private StoreInfo storeInfo;
+ private ReceiverInfo receiverInfo;
+ private Cargo cargoInfo;
+
+ public String getWxOrderId() {
+ return wxOrderId;
+ }
+
+ public void setWxOrderId(String wxOrderId) {
+ this.wxOrderId = wxOrderId;
+ }
+
+ public int getOrderStatus() {
+ return orderStatus;
+ }
+
+ public void setOrderStatus(int orderStatus) {
+ this.orderStatus = orderStatus;
+ }
+
+ public String getAppid() {
+ return appid;
+ }
+
+ public void setAppid(String appid) {
+ this.appid = appid;
+ }
+
+ public String getServiceTransId() {
+ return serviceTransId;
+ }
+
+ public void setServiceTransId(String serviceTransId) {
+ this.serviceTransId = serviceTransId;
+ }
+
+ public String getDeliveryNo() {
+ return deliveryNo;
+ }
+
+ public void setDeliveryNo(String deliveryNo) {
+ this.deliveryNo = deliveryNo;
+ }
+
+ public int getActualfee() {
+ return actualfee;
+ }
+
+ public void setActualfee(int actualfee) {
+ this.actualfee = actualfee;
+ }
+
+ public int getDeductfee() {
+ return deductfee;
+ }
+
+ public void setDeductfee(int deductfee) {
+ this.deductfee = deductfee;
+ }
+
+ public long getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(long createTime) {
+ this.createTime = createTime;
+ }
+
+ public long getAcceptTime() {
+ return acceptTime;
+ }
+
+ public void setAcceptTime(long acceptTime) {
+ this.acceptTime = acceptTime;
+ }
+
+ public long getFetchTime() {
+ return fetchTime;
+ }
+
+ public void setFetchTime(long fetchTime) {
+ this.fetchTime = fetchTime;
+ }
+
+ public long getFinishTime() {
+ return finishTime;
+ }
+
+ public void setFinishTime(long finishTime) {
+ this.finishTime = finishTime;
+ }
+
+ public long getCancelTime() {
+ return cancelTime;
+ }
+
+ public void setCancelTime(long cancelTime) {
+ this.cancelTime = cancelTime;
+ }
+
+ public long getExpectedFinishTime() {
+ return expectedFinishTime;
+ }
+
+ public void setExpectedFinishTime(long expectedFinishTime) {
+ this.expectedFinishTime = expectedFinishTime;
+ }
+
+ public String getFetchCode() {
+ return fetchCode;
+ }
+
+ public void setFetchCode(String fetchCode) {
+ this.fetchCode = fetchCode;
+ }
+
+ public String getRecvCode() {
+ return recvCode;
+ }
+
+ public void setRecvCode(String recvCode) {
+ this.recvCode = recvCode;
+ }
+
+ public TransporterInfo getTransporterInfo() {
+ return transporterInfo;
+ }
+
+ public void setTransporterInfo(TransporterInfo transporterInfo) {
+ this.transporterInfo = transporterInfo;
+ }
+
+ public StoreInfo getStoreInfo() {
+ return storeInfo;
+ }
+
+ public void setStoreInfo(StoreInfo storeInfo) {
+ this.storeInfo = storeInfo;
+ }
+
+ public ReceiverInfo getReceiverInfo() {
+ return receiverInfo;
+ }
+
+ public void setReceiverInfo(ReceiverInfo receiverInfo) {
+ this.receiverInfo = receiverInfo;
+ }
+
+ public Cargo getCargoInfo() {
+ return cargoInfo;
+ }
+
+ public void setCargoInfo(Cargo cargoInfo) {
+ this.cargoInfo = cargoInfo;
+ }
+
+ public Date getCreateDate() {
+ return createTime == 0 ? null : new Date(createTime * 1000);
+ }
+
+ public Date getAcceptDate() {
+ return acceptTime == 0 ? null : new Date(acceptTime * 1000);
+ }
+
+ public Date getFetchDate() {
+ return fetchTime == 0 ? null : new Date(fetchTime * 1000);
+ }
+
+ public Date getFinishDate() {
+ return finishTime == 0 ? null : new Date(finishTime * 1000);
+ }
+
+ public Date getCancelDate() {
+ return cancelTime == 0 ? null : new Date(cancelTime * 1000);
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+ public static class TransporterInfo {
+ private String transporterName;
+ private String transporterPhone;
+
+ public String getTransporterName() {
+ return transporterName;
+ }
+
+ public void setTransporterName(String transporterName) {
+ this.transporterName = transporterName;
+ }
+
+ public String getTransporterPhone() {
+ return transporterPhone;
+ }
+
+ public void setTransporterPhone(String transporterPhone) {
+ this.transporterPhone = transporterPhone;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+ }
+
+ public static class StoreInfo {
+ private String storeName;
+ private String wxStoreId;
+ private String address;
+ private double lng;
+ private double lat;
+ private String phoneNum;
+
+ public String getStoreName() {
+ return storeName;
+ }
+
+ public void setStoreName(String storeName) {
+ this.storeName = storeName;
+ }
+
+ public String getWxStoreId() {
+ return wxStoreId;
+ }
+
+ public void setWxStoreId(String wxStoreId) {
+ this.wxStoreId = wxStoreId;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public double getLng() {
+ return lng;
+ }
+
+ public void setLng(double lng) {
+ this.lng = lng;
+ }
+
+ public double getLat() {
+ return lat;
+ }
+
+ public void setLat(double lat) {
+ this.lat = lat;
+ }
+
+ public String getPhoneNum() {
+ return phoneNum;
+ }
+
+ public void setPhoneNum(String phoneNum) {
+ this.phoneNum = phoneNum;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+ }
+
+ public static class ReceiverInfo {
+ private String receiverName;
+ private String address;
+ private String phoneNum;
+ private double lng;
+ private double lat;
+
+ public String getReceiverName() {
+ return receiverName;
+ }
+
+ public void setReceiverName(String receiverName) {
+ this.receiverName = receiverName;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public String getPhoneNum() {
+ return phoneNum;
+ }
+
+ public void setPhoneNum(String phoneNum) {
+ this.phoneNum = phoneNum;
+ }
+
+ public double getLng() {
+ return lng;
+ }
+
+ public void setLng(double lng) {
+ this.lng = lng;
+ }
+
+ public double getLat() {
+ return lat;
+ }
+
+ public void setLat(double lat) {
+ this.lat = lat;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaPreAddOrderRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaPreAddOrderRequest.java
new file mode 100644
index 000000000..88c7fbd5a
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaPreAddOrderRequest.java
@@ -0,0 +1,22 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+public class WxMaPreAddOrderRequest extends BasicWxMaOrder {
+ private Cargo cargo;
+
+ public Cargo getCargo() {
+ return cargo;
+ }
+
+ public void setCargo(Cargo cargo) {
+ this.cargo = cargo;
+ }
+
+ public static class Cargo extends BasicWxMaOrder.Cargo {}
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaQueryFlowRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaQueryFlowRequest.java
new file mode 100644
index 000000000..545be89ae
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaQueryFlowRequest.java
@@ -0,0 +1,88 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import java.util.Date;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WxMaQueryFlowRequest {
+ private static final Logger logger = LoggerFactory.getLogger(WxMaQueryFlowRequest.class);
+
+ private String wxStoreId;
+
+ /** 流水类型: 1:充值流水, 2:消费流水,3:退款流水 */
+ private int flowType = 1;
+
+ /** 运力ID */
+ private String serviceTransId;
+
+ private transient Date beginDate;
+ private transient Date endDate;
+ private long beginTime;
+ private long endTime;
+
+ public String getWxStoreId() {
+ return wxStoreId;
+ }
+
+ public void setWxStoreId(String wxStoreId) {
+ this.wxStoreId = wxStoreId;
+ }
+
+ public int getFlowType() {
+ return flowType;
+ }
+
+ public void setFlowType(int flowType) {
+ this.flowType = flowType;
+ }
+
+ public String getServiceTransId() {
+ return serviceTransId;
+ }
+
+ public void setServiceTransId(String serviceTransId) {
+ this.serviceTransId = serviceTransId;
+ }
+
+ public Date getBeginDate() {
+ return beginDate;
+ }
+
+ public void setBeginDate(Date beginDate) {
+ this.beginDate = beginDate;
+ this.beginTime = beginDate.getTime() / 1000;
+ }
+
+ public Date getEndDate() {
+ return endDate;
+ }
+
+ public void setEndDate(Date endDate) {
+ this.endDate = endDate;
+ this.endTime = endDate.getTime() / 1000;
+ }
+
+ public long getBeginTime() {
+ return beginTime;
+ }
+
+ public void setBeginTime(long beginTime) {
+ this.beginTime = beginTime;
+ this.beginDate = new Date(beginTime * 1000);
+ }
+
+ public long getEndTime() {
+ return endTime;
+ }
+
+ public void setEndTime(long endTime) {
+ this.endTime = endTime;
+ this.endDate = new Date(endTime * 1000);
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaStore.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaStore.java
new file mode 100644
index 000000000..958b078e5
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaStore.java
@@ -0,0 +1,187 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WxMaStore {
+ private static final Logger logger = LoggerFactory.getLogger(WxMaStore.class);
+
+ /** 微信分配的ID,创建时不用填写,查询时返回,根据此ID下单等 */
+ private String wxStoreId;
+
+ /** 自己设置的门店ID,创建时填写,查询时返回,不可修改 */
+ private String outStoreId;
+
+ /** 门店名称,创建时需要,可修改;查询结果微信不返回此字段 */
+ private String storeName;
+
+ /** 创建时不用设置,查询时返回,微信自动设置 */
+ private String cityId;
+
+ /** 1:价格优先,2:运力优先 */
+ private int orderPattern = 1;
+
+ /**
+ * 运力优先时优先使用的运力。运力ID请参考:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/express/business/intracity_service.html#_6-%E8%BF%90%E5%8A%9B%E5%88%97%E8%A1%A8
+ */
+ private String ServiceTransPrefer;
+
+ private AddressInfo addressInfo;
+
+ public String getWxStoreId() {
+ return wxStoreId;
+ }
+
+ public void setWxStoreId(String wxStoreId) {
+ this.wxStoreId = wxStoreId;
+ }
+
+ public String getOutStoreId() {
+ return outStoreId;
+ }
+
+ public void setOutStoreId(String outStoreId) {
+ this.outStoreId = outStoreId;
+ }
+
+ public String getStoreName() {
+ return storeName;
+ }
+
+ public void setStoreName(String storeName) {
+ this.storeName = storeName;
+ }
+
+ public String getCityId() {
+ return cityId;
+ }
+
+ public void setCityId(String cityId) {
+ this.cityId = cityId;
+ }
+
+ public int getOrderPattern() {
+ return orderPattern;
+ }
+
+ public void setOrderPattern(int orderPattern) {
+ this.orderPattern = orderPattern;
+ }
+
+ public String getServiceTransPrefer() {
+ return ServiceTransPrefer;
+ }
+
+ public void setServiceTransPrefer(String serviceTransPrefer) {
+ ServiceTransPrefer = serviceTransPrefer;
+ }
+
+ public AddressInfo getAddressInfo() {
+ return addressInfo;
+ }
+
+ public void setAddressInfo(AddressInfo addressInfo) {
+ this.addressInfo = addressInfo;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+ public static class AddressInfo {
+ /** 省、自治区、直辖市 必填 */
+ private String province;
+
+ /** 地级市 必填 */
+ private String city;
+
+ /** 区/县/县级市 必填 */
+ private String area;
+
+ /** 街道/镇 选填 */
+ private String street;
+
+ /** 路名和门牌号 必填 */
+ private String house;
+
+ /** 门店电话号码 必填 */
+ private String phone;
+
+ /** 纬度 必填 */
+ private double lat;
+
+ /** 经度 必填 */
+ private double lng;
+
+ public String getProvince() {
+ return province;
+ }
+
+ public void setProvince(String province) {
+ this.province = province;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getArea() {
+ return area;
+ }
+
+ public void setArea(String area) {
+ this.area = area;
+ }
+
+ public String getStreet() {
+ return street;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+
+ public String getHouse() {
+ return house;
+ }
+
+ public void setHouse(String house) {
+ this.house = house;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public double getLat() {
+ return lat;
+ }
+
+ public void setLat(double lat) {
+ this.lat = lat;
+ }
+
+ public double getLng() {
+ return lng;
+ }
+
+ public void setLng(double lng) {
+ this.lng = lng;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaStoreBalance.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaStoreBalance.java
new file mode 100644
index 000000000..783c76fcd
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaStoreBalance.java
@@ -0,0 +1,115 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import java.util.Date;
+import java.util.List;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WxMaStoreBalance {
+ private static final Logger logger = LoggerFactory.getLogger(WxMaStoreBalance.class);
+
+ private String wxStoreId;
+ private String appid;
+ private int allBalance;
+
+ private List balanceDetail;
+
+ public String getWxStoreId() {
+ return wxStoreId;
+ }
+
+ public void setWxStoreId(String wxStoreId) {
+ this.wxStoreId = wxStoreId;
+ }
+
+ public String getAppid() {
+ return appid;
+ }
+
+ public void setAppid(String appid) {
+ this.appid = appid;
+ }
+
+ public int getAllBalance() {
+ return allBalance;
+ }
+
+ public void setAllBalance(int allBalance) {
+ this.allBalance = allBalance;
+ }
+
+ public List getBalanceDetail() {
+ return balanceDetail;
+ }
+
+ public void setBalanceDetail(List balanceDetail) {
+ this.balanceDetail = balanceDetail;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+ public static class Detail {
+ private String payorderId;
+ private int chargeAmt;
+ private int unusedAmt;
+ private long beginTime;
+ private long endTime;
+
+ public String getPayorderId() {
+ return payorderId;
+ }
+
+ public void setPayorderId(String payorderId) {
+ this.payorderId = payorderId;
+ }
+
+ public int getChargeAmt() {
+ return chargeAmt;
+ }
+
+ public void setChargeAmt(int chargeAmt) {
+ this.chargeAmt = chargeAmt;
+ }
+
+ public int getUnusedAmt() {
+ return unusedAmt;
+ }
+
+ public void setUnusedAmt(int unusedAmt) {
+ this.unusedAmt = unusedAmt;
+ }
+
+ public Date getBeginDate() {
+ return this.beginTime == 0 ? null : new Date(this.beginTime * 1000);
+ }
+
+ public Date getEndDate() {
+ return this.endTime == 0 ? null : new Date(this.endTime * 1000);
+ }
+
+ public long getBeginTime() {
+ return beginTime;
+ }
+
+ public void setBeginTime(long beginTime) {
+ this.beginTime = beginTime;
+ }
+
+ public long getEndTime() {
+ return endTime;
+ }
+
+ public void setEndTime(long endTime) {
+ this.endTime = endTime;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaStoreChargeRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaStoreChargeRequest.java
new file mode 100644
index 000000000..2f320995f
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaStoreChargeRequest.java
@@ -0,0 +1,22 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+public class WxMaStoreChargeRequest extends BasicWxMaStoreChargeRefundRequest {
+
+ /** 充值金额 单位:分, 50元起充 */
+ private int amount;
+
+ public int getAmount() {
+ return amount;
+ }
+
+ public void setAmount(int amount) {
+ this.amount = amount;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaStoreFlowResponse.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaStoreFlowResponse.java
new file mode 100644
index 000000000..af5769aa5
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaStoreFlowResponse.java
@@ -0,0 +1,318 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import java.util.Date;
+import java.util.List;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WxMaStoreFlowResponse {
+ private static final Logger logger = LoggerFactory.getLogger(WxMaStoreFlowResponse.class);
+
+ /** 总支付金额 */
+ private Long totalPayAmt;
+
+ /** 总退款金额 */
+ private Long totalRefundAmt;
+
+ /** 总违约金 查询消费流水才返回 */
+ private Long totalDeductAmt;
+
+ /** 流水 */
+ private List flowList;
+
+ public List getFlowList() {
+ return flowList;
+ }
+
+ public void setFlowList(List flowList) {
+ this.flowList = flowList;
+ }
+
+ public Long getTotalPayAmt() {
+ return totalPayAmt;
+ }
+
+ public void setTotalPayAmt(Long totalPayAmt) {
+ this.totalPayAmt = totalPayAmt;
+ }
+
+ public Long getTotalRefundAmt() {
+ return totalRefundAmt;
+ }
+
+ public void setTotalRefundAmt(Long totalRefundAmt) {
+ this.totalRefundAmt = totalRefundAmt;
+ }
+
+ public Long getTotalDeductAmt() {
+ return totalDeductAmt;
+ }
+
+ public void setTotalDeductAmt(Long totalDeductAmt) {
+ this.totalDeductAmt = totalDeductAmt;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+ public static class BasicFlowRecord {
+ private int flowType;
+ private String appid;
+ private String wxStoreId;
+ private String payOrderId;
+ private String serviceTransId;
+ private int payAmount;
+ private long payTime;
+ private long createTime;
+
+ public int getFlowType() {
+ return flowType;
+ }
+
+ public void setFlowType(int flowType) {
+ this.flowType = flowType;
+ }
+
+ public String getAppid() {
+ return appid;
+ }
+
+ public void setAppid(String appid) {
+ this.appid = appid;
+ }
+
+ public String getWxStoreId() {
+ return wxStoreId;
+ }
+
+ public void setWxStoreId(String wxStoreId) {
+ this.wxStoreId = wxStoreId;
+ }
+
+ public String getPayOrderId() {
+ return payOrderId;
+ }
+
+ public void setPayOrderId(String payOrderId) {
+ this.payOrderId = payOrderId;
+ }
+
+ public String getServiceTransId() {
+ return serviceTransId;
+ }
+
+ public void setServiceTransId(String serviceTransId) {
+ this.serviceTransId = serviceTransId;
+ }
+
+ public int getPayAmount() {
+ return payAmount;
+ }
+
+ public void setPayAmount(int payAmount) {
+ this.payAmount = payAmount;
+ }
+
+ public Date getPayDate() {
+ return this.payTime == 0 ? null : new Date(this.payTime * 1000);
+ }
+
+ public long getPayTime() {
+ return payTime;
+ }
+
+ public void setPayTime(long payTime) {
+ this.payTime = payTime;
+ }
+
+ public Date getCreateDate() {
+ return this.createTime == 0 ? null : new Date(this.createTime * 1000);
+ }
+
+ public long getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(long createTime) {
+ this.createTime = createTime;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+ }
+
+ /** 充值流水 */
+ public static class ChargeFlowRecord extends BasicFlowRecord {
+ private String payStatus;
+
+ private long consumeDeadline;
+
+ public String getPayStatus() {
+ return payStatus;
+ }
+
+ public void setPayStatus(String payStatus) {
+ this.payStatus = payStatus;
+ }
+
+ public Date getConsumeDeadlineDate() {
+ return this.consumeDeadline == 0 ? null : new Date(this.consumeDeadline * 1000);
+ }
+
+ public long getConsumeDeadline() {
+ return consumeDeadline;
+ }
+
+ public void setConsumeDeadline(long consumeDeadline) {
+ this.consumeDeadline = consumeDeadline;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+ }
+
+ /** 退款流水 */
+ public static class RefundFlowRecord extends BasicFlowRecord {
+ private int refundAmount;
+ private long refundTime;
+ private long consumeDeadline;
+
+ public int getRefundAmount() {
+ return refundAmount;
+ }
+
+ public void setRefundAmount(int refundAmount) {
+ this.refundAmount = refundAmount;
+ }
+
+ public Date getRefundDate() {
+ return this.refundTime == 0 ? null : new Date(this.refundTime * 1000);
+ }
+
+ public long getRefundTime() {
+ return refundTime;
+ }
+
+ public void setRefundTime(long refundTime) {
+ this.refundTime = refundTime;
+ }
+
+ public Date getConsumeDeadlineDate() {
+ return this.consumeDeadline == 0 ? null : new Date(this.consumeDeadline * 1000);
+ }
+
+ public long getConsumeDeadline() {
+ return consumeDeadline;
+ }
+
+ public void setConsumeDeadline(long consumeDeadline) {
+ this.consumeDeadline = consumeDeadline;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+ }
+
+ /** 消费流水 */
+ public static class ConsumeFlowRecord extends BasicFlowRecord {
+ private String wxOrderId;
+ private String openid;
+ private String deliveryStatus;
+ private String payStatus;
+ private String refundStatus;
+ private int refundAmount;
+ private int deductAmount;
+ private String billId;
+ private long deliveryFinishedTime;
+
+ public String getWxOrderId() {
+ return wxOrderId;
+ }
+
+ public void setWxOrderId(String wxOrderId) {
+ this.wxOrderId = wxOrderId;
+ }
+
+ public String getOpenid() {
+ return openid;
+ }
+
+ public void setOpenid(String openid) {
+ this.openid = openid;
+ }
+
+ public String getDeliveryStatus() {
+ return deliveryStatus;
+ }
+
+ public void setDeliveryStatus(String deliveryStatus) {
+ this.deliveryStatus = deliveryStatus;
+ }
+
+ public String getPayStatus() {
+ return payStatus;
+ }
+
+ public void setPayStatus(String payStatus) {
+ this.payStatus = payStatus;
+ }
+
+ public String getRefundStatus() {
+ return refundStatus;
+ }
+
+ public void setRefundStatus(String refundStatus) {
+ this.refundStatus = refundStatus;
+ }
+
+ public int getRefundAmount() {
+ return refundAmount;
+ }
+
+ public void setRefundAmount(int refundAmount) {
+ this.refundAmount = refundAmount;
+ }
+
+ public int getDeductAmount() {
+ return deductAmount;
+ }
+
+ public void setDeductAmount(int deductAmount) {
+ this.deductAmount = deductAmount;
+ }
+
+ public String getBillId() {
+ return billId;
+ }
+
+ public void setBillId(String billId) {
+ this.billId = billId;
+ }
+
+ public Date getDeliveryFinishedDate() {
+ return this.deliveryFinishedTime == 0 ? null : new Date(this.deliveryFinishedTime * 1000);
+ }
+
+ public long getDeliveryFinishedTime() {
+ return deliveryFinishedTime;
+ }
+
+ public void setDeliveryFinishedTime(long deliveryFinishedTime) {
+ this.deliveryFinishedTime = deliveryFinishedTime;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaStoreRefundRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaStoreRefundRequest.java
new file mode 100644
index 000000000..cb4ebec3a
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaStoreRefundRequest.java
@@ -0,0 +1,11 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+public class WxMaStoreRefundRequest extends BasicWxMaStoreChargeRefundRequest {
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaTransCity.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaTransCity.java
new file mode 100644
index 000000000..ff125447f
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/intractiy/WxMaTransCity.java
@@ -0,0 +1,56 @@
+package cn.binarywang.wx.miniapp.bean.intractiy;
+
+import java.util.List;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+public class WxMaTransCity {
+ private String serviceTransId;
+ private List cityList;
+
+ public String getServiceTransId() {
+ return serviceTransId;
+ }
+
+ public void setServiceTransId(String serviceTransId) {
+ this.serviceTransId = serviceTransId;
+ }
+
+ public List getCityList() {
+ return cityList;
+ }
+
+ public void setCityList(List cityList) {
+ this.cityList = cityList;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+ public static class City {
+ private String cityName;
+ private String cityCode;
+
+ public String getCityName() {
+ return cityName;
+ }
+
+ public void setCityName(String cityName) {
+ this.cityName = cityName;
+ }
+
+ public String getCityCode() {
+ return cityCode;
+ }
+
+ public void setCityCode(String cityCode) {
+ this.cityCode = cityCode;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaConfig.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaConfig.java
index 12e1da07b..ba71b931c 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaConfig.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaConfig.java
@@ -1,11 +1,10 @@
package cn.binarywang.wx.miniapp.config;
-import me.chanjar.weixin.common.bean.WxAccessToken;
-import me.chanjar.weixin.common.bean.WxAccessTokenEntity;
-import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
-
import java.util.concurrent.locks.Lock;
import java.util.function.Consumer;
+import me.chanjar.weixin.common.bean.WxAccessToken;
+import me.chanjar.weixin.common.bean.WxAccessTokenEntity;
+import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
/**
* 小程序配置
@@ -14,9 +13,7 @@ import java.util.function.Consumer;
*/
public interface WxMaConfig {
- default void setUpdateAccessTokenBefore(Consumer updateAccessTokenBefore) {
-
- }
+ default void setUpdateAccessTokenBefore(Consumer updateAccessTokenBefore) {}
/**
* Gets access token.
@@ -25,12 +22,12 @@ public interface WxMaConfig {
*/
String getAccessToken();
- //region 稳定版access token
+ // region 稳定版access token
boolean isStableAccessToken();
void useStableAccessToken(boolean useStableAccessToken);
- //endregion
+ // endregion
/**
* Gets access token lock.
@@ -46,9 +43,7 @@ public interface WxMaConfig {
*/
boolean isAccessTokenExpired();
- /**
- * 强制将access token过期掉
- */
+ /** 强制将access token过期掉 */
void expireAccessToken();
/**
@@ -63,7 +58,7 @@ public interface WxMaConfig {
/**
* 应该是线程安全的
*
- * @param accessToken 新的accessToken值
+ * @param accessToken 新的accessToken值
* @param expiresInSeconds 过期时间,以秒为单位
*/
void updateAccessToken(String accessToken, int expiresInSeconds);
@@ -77,10 +72,7 @@ public interface WxMaConfig {
updateAccessToken(accessToken, expiresInSeconds);
}
- default void updateAccessTokenBefore(WxAccessTokenEntity wxAccessTokenEntity) {
-
- }
-
+ default void updateAccessTokenBefore(WxAccessTokenEntity wxAccessTokenEntity) {}
/**
* Gets jsapi ticket.
@@ -103,15 +95,13 @@ public interface WxMaConfig {
*/
boolean isJsapiTicketExpired();
- /**
- * 强制将jsapi ticket过期掉
- */
+ /** 强制将jsapi ticket过期掉 */
void expireJsapiTicket();
/**
* 应该是线程安全的
*
- * @param jsapiTicket 新的jsapi ticket值
+ * @param jsapiTicket 新的jsapi ticket值
* @param expiresInSeconds 过期时间,以秒为单位
*/
void updateJsapiTicket(String jsapiTicket, int expiresInSeconds);
@@ -137,15 +127,13 @@ public interface WxMaConfig {
*/
boolean isCardApiTicketExpired();
- /**
- * 强制将卡券api ticket过期掉.
- */
+ /** 强制将卡券api ticket过期掉. */
void expireCardApiTicket();
/**
* 应该是线程安全的.
*
- * @param apiTicket 新的卡券api ticket值
+ * @param apiTicket 新的卡券api ticket值
* @param expiresInSeconds 过期时间,以秒为单位
*/
void updateCardApiTicket(String apiTicket, int expiresInSeconds);
@@ -236,6 +224,7 @@ public interface WxMaConfig {
/**
* http 请求重试间隔
+ *
*
* {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setRetrySleepMillis(int)}
*
@@ -244,6 +233,7 @@ public interface WxMaConfig {
/**
* http 请求最大重试次数
+ *
*
* {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setMaxRetryTimes(int)}
*
@@ -288,10 +278,35 @@ public interface WxMaConfig {
String getAccessTokenUrl();
/**
- * 设置自定义的获取accessToken地址
- * 可用于设置获取accessToken的自定义服务
+ * 设置自定义的获取accessToken地址 可用于设置获取accessToken的自定义服务
*
* @param accessTokenUrl 自定义的获取accessToken地址
*/
void setAccessTokenUrl(String accessTokenUrl);
+
+ /**
+ * 服务端API签名用到的RSA私钥【pkcs8格式,会以 -----BEGIN PRIVATE KEY-----开头, 'BEGIN RSA PRIVATE
+ * KEY'的是pkcs1格式,需要转换(可用openssl转换)。 设置参考:
+ * https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/getting_started/api_signature.html
+ *
+ * @return rsa private key string
+ */
+ String getApiSignatureRsaPrivateKey();
+
+ /**
+ * 服务端API签名用到的AES密钥
+ * https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/getting_started/api_signature.html
+ *
+ * @return aes key string
+ */
+ String getApiSignatureAesKey();
+
+ /** 密钥对应的序号 */
+ String getApiSignatureAesKeySn();
+
+ /** 密钥对应的序号 */
+ String getApiSignatureRsaPrivateKeySn();
+
+ /** 密钥对应的小程序ID (普通小程序同 appId, 托管第三方平台的是 componentAppId) */
+ String getWechatMpAppid();
}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaDefaultConfigImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaDefaultConfigImpl.java
index bd9a4e20b..ab82d6209 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaDefaultConfigImpl.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaDefaultConfigImpl.java
@@ -2,17 +2,16 @@ package cn.binarywang.wx.miniapp.config.impl;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder;
+import java.io.File;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import me.chanjar.weixin.common.bean.WxAccessTokenEntity;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
-import java.io.File;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.function.Consumer;
-
/**
* 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化
*
@@ -23,30 +22,32 @@ public class WxMaDefaultConfigImpl implements WxMaConfig {
protected volatile String appid;
protected volatile String token;
- /**
- * 是否使用稳定版获取accessToken接口
- */
+ /** 是否使用稳定版获取accessToken接口 */
@Getter(value = AccessLevel.NONE)
private boolean useStableAccessToken;
- /**
- * 小程序原始ID
- */
+ /** 小程序原始ID */
protected volatile String originalId;
+
protected Lock accessTokenLock = new ReentrantLock();
- /**
- * 临时文件目录.
- */
+
+ /** 临时文件目录. */
protected volatile File tmpDirFile;
+
private volatile String msgDataFormat;
private volatile String secret;
private volatile String accessToken;
private volatile String aesKey;
private volatile long expiresTime;
- /**
- * 云环境ID
- */
+ private volatile String apiSignatureRsaPrivateKey;
+ private volatile String apiSignatureAesKey;
+ private volatile String apiSignatureRsaPrivateKeySn;
+ private volatile String apiSignatureAesKeySn;
+ private volatile String wechatMpAppid;
+
+ /** 云环境ID */
private volatile String cloudEnv;
+
private volatile String httpProxyHost;
private volatile int httpProxyPort;
private volatile String httpProxyUsername;
@@ -57,10 +58,10 @@ public class WxMaDefaultConfigImpl implements WxMaConfig {
private volatile String jsapiTicket;
private volatile long jsapiTicketExpiresTime;
- /**
- * 微信卡券的ticket单独缓存.
- */
+
+ /** 微信卡券的ticket单独缓存. */
private volatile String cardApiTicket;
+
private volatile long cardApiTicketExpiresTime;
protected volatile Lock jsapiTicketLock = new ReentrantLock();
protected volatile Lock cardApiTicketLock = new ReentrantLock();
@@ -68,35 +69,24 @@ public class WxMaDefaultConfigImpl implements WxMaConfig {
private String apiHostUrl;
private String accessTokenUrl;
- /**
- * 自定义配置token的消费者
- */
- @Setter
- private Consumer updateAccessTokenBefore;
+ /** 自定义配置token的消费者 */
+ @Setter private Consumer updateAccessTokenBefore;
- /**
- * 开启回调
- */
+ /** 开启回调 */
@Getter(AccessLevel.NONE)
private boolean enableUpdateAccessTokenBefore = true;
- /**
- * 可临时关闭更新token回调,主要用于其他介质初始化数据时,可不进行回调
- */
+ /** 可临时关闭更新token回调,主要用于其他介质初始化数据时,可不进行回调 */
public void enableUpdateAccessTokenBefore(boolean enableUpdateAccessTokenBefore) {
this.enableUpdateAccessTokenBefore = enableUpdateAccessTokenBefore;
}
- /**
- * 会过期的数据提前过期时间,默认预留200秒的时间
- */
+ /** 会过期的数据提前过期时间,默认预留200秒的时间 */
protected long expiresAheadInMillis(int expiresInSeconds) {
return System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
}
- /**
- * 判断 expiresTime 是否已经过期
- */
+ /** 判断 expiresTime 是否已经过期 */
protected boolean isExpired(long expiresTime) {
return System.currentTimeMillis() > expiresTime;
}
@@ -110,7 +100,7 @@ public class WxMaDefaultConfigImpl implements WxMaConfig {
this.accessToken = accessToken;
}
- //region 使用稳定版接口获取accessToken
+ // region 使用稳定版接口获取accessToken
@Override
public boolean isStableAccessToken() {
return this.useStableAccessToken;
@@ -120,8 +110,8 @@ public class WxMaDefaultConfigImpl implements WxMaConfig {
public void useStableAccessToken(boolean useStableAccessToken) {
this.useStableAccessToken = useStableAccessToken;
}
- //endregion
+ // endregion
@Override
public Lock getAccessTokenLock() {
@@ -137,10 +127,10 @@ public class WxMaDefaultConfigImpl implements WxMaConfig {
return isExpired(this.expiresTime);
}
-// @Override
-// public synchronized void updateAccessToken(WxAccessToken accessToken) {
-// updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
-// }
+ // @Override
+ // public synchronized void updateAccessToken(WxAccessToken accessToken) {
+ // updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
+ // }
@Override
public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
@@ -248,6 +238,46 @@ public class WxMaDefaultConfigImpl implements WxMaConfig {
this.aesKey = aesKey;
}
+ public String getApiSignatureRsaPrivateKey() {
+ return apiSignatureRsaPrivateKey;
+ }
+
+ public void setApiSignatureRsaPrivateKey(String apiSignatureRsaPrivateKey) {
+ this.apiSignatureRsaPrivateKey = apiSignatureRsaPrivateKey;
+ }
+
+ public String getApiSignatureAesKey() {
+ return apiSignatureAesKey;
+ }
+
+ public void setApiSignatureAesKey(String apiSignatureAesKey) {
+ this.apiSignatureAesKey = apiSignatureAesKey;
+ }
+
+ public String getApiSignatureRsaPrivateKeySn() {
+ return apiSignatureRsaPrivateKeySn;
+ }
+
+ public void setApiSignatureRsaPrivateKeySn(String apiSignatureRsaPrivateKeySn) {
+ this.apiSignatureRsaPrivateKeySn = apiSignatureRsaPrivateKeySn;
+ }
+
+ public String getApiSignatureAesKeySn() {
+ return apiSignatureAesKeySn;
+ }
+
+ public void setApiSignatureAesKeySn(String apiSignatureAesKeySn) {
+ this.apiSignatureAesKeySn = apiSignatureAesKeySn;
+ }
+
+ public String getWechatMpAppid() {
+ return wechatMpAppid == null ? appid : wechatMpAppid;
+ }
+
+ public void setWechatMpAppid(String wechatMpAppid) {
+ this.wechatMpAppid = wechatMpAppid;
+ }
+
@Override
public String getOriginalId() {
return originalId;
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java
index f1bc84ad7..ab47d3e64 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java
@@ -5,58 +5,62 @@ import lombok.experimental.UtilityClass;
/**
* 小程序接口地址常量.
*
- * @author Binary Wang
- * created on 2021-01-28
+ * @author Binary Wang created on 2021-01-28
*/
@UtilityClass
public class WxMaApiUrlConstants {
- /**
- * openApi管理
- */
+ /** openApi管理 */
public interface OpenApi {
- /**
- * 重置API调用次数
- */
+ /** 重置API调用次数 */
String CLEAR_QUOTA = "https://api.weixin.qq.com/cgi-bin/clear_quota";
- /**
- * 查询API调用额度
- */
- String GET_API_QUOTA = "https://api.weixin.qq.com/cgi-bin/openapi/quota/get";
- /**
- * 查询rid信息
- */
- String GET_RID_INFO = "https://api.weixin.qq.com/cgi-bin/openapi/rid/get";
- /**
- * 使用AppSecret重置 API 调用次数
- */
- String CLEAR_QUOTA_BY_APP_SECRET = "https://api.weixin.qq.com/cgi-bin/clear_quota/v2?appid=%s&appsecret=%s";
+ /** 查询API调用额度 */
+ String GET_API_QUOTA = "https://api.weixin.qq.com/cgi-bin/openapi/quota/get";
+
+ /** 查询rid信息 */
+ String GET_RID_INFO = "https://api.weixin.qq.com/cgi-bin/openapi/rid/get";
+
+ /** 使用AppSecret重置 API 调用次数 */
+ String CLEAR_QUOTA_BY_APP_SECRET =
+ "https://api.weixin.qq.com/cgi-bin/clear_quota/v2?appid=%s&appsecret=%s";
}
public interface Analysis {
- String GET_DAILY_SUMMARY_TREND_URL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailysummarytrend";
- String GET_DAILY_VISIT_TREND_URL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyvisittrend";
- String GET_WEEKLY_VISIT_TREND_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidweeklyvisittrend";
- String GET_MONTHLY_VISIT_TREND_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyvisittrend";
- String GET_VISIT_DISTRIBUTION_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidvisitdistribution";
- String GET_DAILY_RETAIN_INFO_URL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyretaininfo";
- String GET_WEEKLY_RETAIN_INFO_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidweeklyretaininfo";
- String GET_MONTHLY_RETAIN_INFO_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyretaininfo";
+ String GET_DAILY_SUMMARY_TREND_URL =
+ "https://api.weixin.qq.com/datacube/getweanalysisappiddailysummarytrend";
+ String GET_DAILY_VISIT_TREND_URL =
+ "https://api.weixin.qq.com/datacube/getweanalysisappiddailyvisittrend";
+ String GET_WEEKLY_VISIT_TREND_URL =
+ "https://api.weixin.qq.com/datacube/getweanalysisappidweeklyvisittrend";
+ String GET_MONTHLY_VISIT_TREND_URL =
+ "https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyvisittrend";
+ String GET_VISIT_DISTRIBUTION_URL =
+ "https://api.weixin.qq.com/datacube/getweanalysisappidvisitdistribution";
+ String GET_DAILY_RETAIN_INFO_URL =
+ "https://api.weixin.qq.com/datacube/getweanalysisappiddailyretaininfo";
+ String GET_WEEKLY_RETAIN_INFO_URL =
+ "https://api.weixin.qq.com/datacube/getweanalysisappidweeklyretaininfo";
+ String GET_MONTHLY_RETAIN_INFO_URL =
+ "https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyretaininfo";
String GET_VISIT_PAGE_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidvisitpage";
- String GET_USER_PORTRAIT_URL = "https://api.weixin.qq.com/datacube/getweanalysisappiduserportrait";
+ String GET_USER_PORTRAIT_URL =
+ "https://api.weixin.qq.com/datacube/getweanalysisappiduserportrait";
}
public interface Cloud {
- String INVOKE_CLOUD_FUNCTION_URL = "https://api.weixin.qq.com/tcb/invokecloudfunction?env=%s&name=%s";
+ String INVOKE_CLOUD_FUNCTION_URL =
+ "https://api.weixin.qq.com/tcb/invokecloudfunction?env=%s&name=%s";
String DATABASE_COLLECTION_GET_URL = "https://api.weixin.qq.com/tcb/databasecollectionget";
- String DATABASE_COLLECTION_DELETE_URL = "https://api.weixin.qq.com/tcb/databasecollectiondelete";
+ String DATABASE_COLLECTION_DELETE_URL =
+ "https://api.weixin.qq.com/tcb/databasecollectiondelete";
String DATABASE_COLLECTION_ADD_URL = "https://api.weixin.qq.com/tcb/databasecollectionadd";
String GET_QCLOUD_TOKEN_URL = "https://api.weixin.qq.com/tcb/getqcloudtoken";
String BATCH_DELETE_FILE_URL = "https://api.weixin.qq.com/tcb/batchdeletefile";
String BATCH_DOWNLOAD_FILE_URL = "https://api.weixin.qq.com/tcb/batchdownloadfile";
String UPLOAD_FILE_URL = "https://api.weixin.qq.com/tcb/uploadfile";
- String DATABASE_MIGRATE_QUERY_INFO_URL = "https://api.weixin.qq.com/tcb/databasemigratequeryinfo";
+ String DATABASE_MIGRATE_QUERY_INFO_URL =
+ "https://api.weixin.qq.com/tcb/databasemigratequeryinfo";
String DATABASE_MIGRATE_EXPORT_URL = "https://api.weixin.qq.com/tcb/databasemigrateexport";
String DATABASE_MIGRATE_IMPORT_URL = "https://api.weixin.qq.com/tcb/databasemigrateimport";
String UPDATE_INDEX_URL = "https://api.weixin.qq.com/tcb/updateindex";
@@ -73,16 +77,18 @@ public class WxMaApiUrlConstants {
String KEFU_MESSAGE_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/custom/send";
String TEMPLATE_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send";
String SUBSCRIBE_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send";
- String UNIFORM_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send";
- String ACTIVITY_ID_CREATE_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/activityid/create";
- String UPDATABLE_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/updatablemsg/send";
+ String UNIFORM_MSG_SEND_URL =
+ "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send";
+ String ACTIVITY_ID_CREATE_URL =
+ "https://api.weixin.qq.com/cgi-bin/message/wxopen/activityid/create";
+ String UPDATABLE_MSG_SEND_URL =
+ "https://api.weixin.qq.com/cgi-bin/message/wxopen/updatablemsg/send";
}
public interface Code {
- /**
- * 为授权的小程序帐号上传小程序代码.
- */
+ /** 为授权的小程序帐号上传小程序代码. */
String COMMIT_URL = "https://api.weixin.qq.com/wxa/commit";
+
String GET_QRCODE_URL = "https://api.weixin.qq.com/wxa/get_qrcode";
String GET_CATEGORY_URL = "https://api.weixin.qq.com/wxa/get_category";
String GET_PAGE_URL = "https://api.weixin.qq.com/wxa/get_page";
@@ -92,204 +98,158 @@ public class WxMaApiUrlConstants {
String RELEASE_URL = "https://api.weixin.qq.com/wxa/release";
String CHANGE_VISIT_STATUS_URL = "https://api.weixin.qq.com/wxa/change_visitstatus";
String REVERT_CODE_RELEASE_URL = "https://api.weixin.qq.com/wxa/revertcoderelease";
- String GET_SUPPORT_VERSION_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/getweappsupportversion";
- String SET_SUPPORT_VERSION_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/setweappsupportversion";
+ String GET_SUPPORT_VERSION_URL =
+ "https://api.weixin.qq.com/cgi-bin/wxopen/getweappsupportversion";
+ String SET_SUPPORT_VERSION_URL =
+ "https://api.weixin.qq.com/cgi-bin/wxopen/setweappsupportversion";
String UNDO_CODE_AUDIT_URL = "https://api.weixin.qq.com/wxa/undocodeaudit";
String GET_VERSION_INFO_URL = "https://api.weixin.qq.com/wxa/getversioninfo";
}
public interface Express {
- /**
- * 获取支持的快递公司列表
- */
+ /** 获取支持的快递公司列表 */
String ALL_DELIVERY_URL = "https://api.weixin.qq.com/cgi-bin/express/business/delivery/getall";
- /**
- * 获取所有绑定的物流账号
- */
+
+ /** 获取所有绑定的物流账号 */
String ALL_ACCOUNT_URL = "https://api.weixin.qq.com/cgi-bin/express/business/account/getall";
- /**
- * 绑定、解绑物流账号
- */
+
+ /** 绑定、解绑物流账号 */
String BIND_ACCOUNT_URL = "https://api.weixin.qq.com/cgi-bin/express/business/account/bind";
- /**
- * 获取电子面单余额
- */
+
+ /** 获取电子面单余额 */
String GET_QUOTA_URL = "https://api.weixin.qq.com/cgi-bin/express/business/quota/get";
- /**
- * 配置面单打印员
- */
+
+ /** 配置面单打印员 */
String UPDATE_PRINTER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/printer/update";
- /**
- * 获取打印员
- */
+
+ /** 获取打印员 */
String GET_PRINTER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/printer/getall";
- /**
- * 生成运单
- */
+
+ /** 生成运单 */
String ADD_ORDER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/order/add";
- /**
- * 批量获取运单数据
- */
- String BATCH_GET_ORDER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/order/batchget";
- /**
- * 取消运单
- */
+
+ /** 批量获取运单数据 */
+ String BATCH_GET_ORDER_URL =
+ "https://api.weixin.qq.com/cgi-bin/express/business/order/batchget";
+
+ /** 取消运单 */
String CANCEL_ORDER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/order/cancel";
- /**
- * 获取运单数据
- */
+
+ /** 获取运单数据 */
String GET_ORDER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/order/get";
- /**
- * 查询运单轨迹
- */
+
+ /** 查询运单轨迹 */
String GET_PATH_URL = "https://api.weixin.qq.com/cgi-bin/express/business/path/get";
- /**
- * 模拟快递公司更新订单状态
- */
- String TEST_UPDATE_ORDER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/test_update_order";
+
+ /** 模拟快递公司更新订单状态 */
+ String TEST_UPDATE_ORDER_URL =
+ "https://api.weixin.qq.com/cgi-bin/express/business/test_update_order";
}
public interface ImgProc {
- /**
- * 二维码/条码识别
- */
+ /** 二维码/条码识别 */
String QRCODE = "https://api.weixin.qq.com/cv/img/qrcode?img_url=%s";
- /**
- * 二维码/条码识别(文件)
- */
+
+ /** 二维码/条码识别(文件) */
String FILE_QRCODE = "https://api.weixin.qq.com/cv/img/qrcode";
- /**
- * 图片高清化
- */
+
+ /** 图片高清化 */
String SUPER_RESOLUTION = "https://api.weixin.qq.com/cv/img/superresolution?img_url=%s";
- /**
- * 图片高清化(文件)
- */
+
+ /** 图片高清化(文件) */
String FILE_SUPER_RESOLUTION = "https://api.weixin.qq.com/cv/img/superresolution";
- /**
- * 图片智能裁剪
- */
+
+ /** 图片智能裁剪 */
String AI_CROP = "https://api.weixin.qq.com/cv/img/aicrop?img_url=%s&ratios=%s";
- /**
- * 图片智能裁剪(文件)
- */
+
+ /** 图片智能裁剪(文件) */
String FILE_AI_CROP = "https://api.weixin.qq.com/cv/img/aicrop?ratios=%s";
}
public interface Jsapi {
- /**
- * 获得jsapi_ticket的url
- */
+ /** 获得jsapi_ticket的url */
String GET_JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
}
public interface Broadcast {
- /**
- * 直播间管理相关接口
- */
+ /** 直播间管理相关接口 */
interface Room {
- /**
- * 创建直播间
- */
+ /** 创建直播间 */
String CREATE_ROOM = "https://api.weixin.qq.com/wxaapi/broadcast/room/create";
- /**
- * 获取直播间列表
- * 获取直播间回放
- */
+
+ /** 获取直播间列表 获取直播间回放 */
String GET_LIVE_INFO = "https://api.weixin.qq.com/wxa/business/getliveinfo";
- /**
- * 直播间导入商品
- */
+
+ /** 直播间导入商品 */
String ADD_GOODS = "https://api.weixin.qq.com/wxaapi/broadcast/room/addgoods";
- /**
- * 删除直播间
- */
+
+ /** 删除直播间 */
String DELETE_ROOM = "https://api.weixin.qq.com/wxaapi/broadcast/room/deleteroom";
- /**
- * 编辑直播间
- */
+
+ /** 编辑直播间 */
String EDIT_ROOM = "https://api.weixin.qq.com/wxaapi/broadcast/room/editroom";
- /**
- * 获取直播间推流地址
- */
+
+ /** 获取直播间推流地址 */
String GET_PUSH_URL = "https://api.weixin.qq.com/wxaapi/broadcast/room/getpushurl";
- /**
- * 获取直播间分享二维码
- */
+
+ /** 获取直播间分享二维码 */
String GET_SHARED_CODE = "https://api.weixin.qq.com/wxaapi/broadcast/room/getsharedcode";
- /**
- * 添加管理直播间小助手
- */
+
+ /** 添加管理直播间小助手 */
String ADD_ASSISTANT = "https://api.weixin.qq.com/wxaapi/broadcast/room/addassistant";
- /**
- * 修改管理直播间小助手
- */
+
+ /** 修改管理直播间小助手 */
String MODIFY_ASSISTANT = "https://api.weixin.qq.com/wxaapi/broadcast/room/modifyassistant";
- /**
- * 删除管理直播间小助手
- */
+
+ /** 删除管理直播间小助手 */
String REMOVE_ASSISTANT = "https://api.weixin.qq.com/wxaapi/broadcast/room/removeassistant";
- /**
- * 查询管理直播间小助手
- */
- String GET_ASSISTANT_LIST = "https://api.weixin.qq.com/wxaapi/broadcast/room/getassistantlist";
- /**
- * 添加主播副号
- */
+
+ /** 查询管理直播间小助手 */
+ String GET_ASSISTANT_LIST =
+ "https://api.weixin.qq.com/wxaapi/broadcast/room/getassistantlist";
+
+ /** 添加主播副号 */
String ADD_SUBANCHOR = "https://api.weixin.qq.com/wxaapi/broadcast/room/addsubanchor";
- /**
- * 修改主播副号
- */
+
+ /** 修改主播副号 */
String MODIFY_SUBANCHOR = "https://api.weixin.qq.com/wxaapi/broadcast/room/modifysubanchor";
- /**
- * 删除主播副号
- */
+
+ /** 删除主播副号 */
String DELETE_SUBANCHOR = "https://api.weixin.qq.com/wxaapi/broadcast/room/deletesubanchor";
- /**
- * 获取主播副号
- */
+
+ /** 获取主播副号 */
String GET_SUBANCHOR = "https://api.weixin.qq.com/wxaapi/broadcast/room/getsubanchor";
- /**
- * 开启/关闭直播间官方收录
- */
- String UPDATE_FEED_PUBLIC = "https://api.weixin.qq.com/wxaapi/broadcast/room/updatefeedpublic";
- /**
- * 开启/关闭回放功能
- */
+
+ /** 开启/关闭直播间官方收录 */
+ String UPDATE_FEED_PUBLIC =
+ "https://api.weixin.qq.com/wxaapi/broadcast/room/updatefeedpublic";
+
+ /** 开启/关闭回放功能 */
String UPDATE_REPLAY = "https://api.weixin.qq.com/wxaapi/broadcast/room/updatereplay";
- /**
- * 开启/关闭客服功能
- */
+
+ /** 开启/关闭客服功能 */
String UPDATE_KF = "https://api.weixin.qq.com/wxaapi/broadcast/room/updatekf";
- /**
- * 开启/关闭直播间全局禁言
- */
+
+ /** 开启/关闭直播间全局禁言 */
String UPDATE_COMMENT = "https://api.weixin.qq.com/wxaapi/broadcast/room/updatecomment";
- /**
- * 上下架商品
- */
+
+ /** 上下架商品 */
String ONSALE = "https://api.weixin.qq.com/wxaapi/broadcast/goods/onsale";
- /**
- * 删除商品
- */
+
+ /** 删除商品 */
String DELETE_IN_ROOM = "https://api.weixin.qq.com/wxaapi/broadcast/goods/deleteInRoom";
- /**
- * 推送商品
- */
+
+ /** 推送商品 */
String PUSH = "https://api.weixin.qq.com/wxaapi/broadcast/goods/push";
- /**
- * 商品排序
- */
+
+ /** 商品排序 */
String SORT = "https://api.weixin.qq.com/wxaapi/broadcast/goods/sort";
- /**
- * 下载商品讲解视频
- */
+
+ /** 下载商品讲解视频 */
String GET_VIDEO = "https://api.weixin.qq.com/wxaapi/broadcast/goods/getVideo";
}
- /**
- * 直播商品管理相关接口
- */
+ /** 直播商品管理相关接口 */
interface Goods {
String ADD_GOODS = "https://api.weixin.qq.com/wxaapi/broadcast/goods/add";
String RESET_AUDIT_GOODS = "https://api.weixin.qq.com/wxaapi/broadcast/goods/resetaudit";
@@ -298,19 +258,15 @@ public class WxMaApiUrlConstants {
String UPDATE_GOODS = "https://api.weixin.qq.com/wxaapi/broadcast/goods/update";
String GET_GOODS_WARE_HOUSE = "https://api.weixin.qq.com/wxa/business/getgoodswarehouse";
String GET_APPROVED_GOODS = "https://api.weixin.qq.com/wxaapi/broadcast/goods/getapproved";
- /**
- * 直播挂件设置全局 Key
- */
+
+ /** 直播挂件设置全局 Key */
String SET_KEY = "https://api.weixin.qq.com/wxaapi/broadcast/goods/setkey";
- /**
- * 直播挂件获取全局 Key
- */
+
+ /** 直播挂件获取全局 Key */
String GET_KEY = "https://api.weixin.qq.com/wxaapi/broadcast/goods/getkey";
}
- /**
- * 小程序直播成员管理接口
- */
+ /** 小程序直播成员管理接口 */
interface Role {
String ADD_ROLE = "https://api.weixin.qq.com/wxaapi/broadcast/role/addrole";
String DELETE_ROLE = "https://api.weixin.qq.com/wxaapi/broadcast/role/deleterole";
@@ -333,9 +289,7 @@ public class WxMaApiUrlConstants {
String GET_WXACODE_UNLIMIT_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit";
}
- public interface Run {
-
- }
+ public interface Run {}
public interface Scheme {
String GENERATE_SCHEME_URL = "https://api.weixin.qq.com/wxa/generatescheme";
@@ -351,17 +305,13 @@ public class WxMaApiUrlConstants {
String GENERATE_SHORT_LINK_URL = "https://api.weixin.qq.com/wxa/genwxashortlink";
}
- /**
- * 小程序安全
- */
+ /** 小程序安全 */
public interface SecCheck {
String IMG_SEC_CHECK_URL = "https://api.weixin.qq.com/wxa/img_sec_check";
String MSG_SEC_CHECK_URL = "https://api.weixin.qq.com/wxa/msg_sec_check";
String MEDIA_CHECK_ASYNC_URL = "https://api.weixin.qq.com/wxa/media_check_async";
- /**
- * 获取用户安全等级
- */
+ /** 获取用户安全等级 */
String GET_USER_RISK_RANK = "https://api.weixin.qq.com/wxa/getuserriskrank";
}
@@ -371,52 +321,48 @@ public class WxMaApiUrlConstants {
* access_token 为 authorizer_access_token
*/
String MODIFY_DOMAIN_URL = "https://api.weixin.qq.com/wxa/modify_domain";
+
String SET_WEB_VIEW_DOMAIN_URL = "https://api.weixin.qq.com/wxa/setwebviewdomain";
+
/**
* 小程序成员管理:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489140588_nVUgx&token=&lang=zh_CN
* access_token 为 authorizer_access_token
*/
String BIND_TESTER_URL = "https://api.weixin.qq.com/wxa/bind_tester";
+
String UNBIND_TESTER_URL = "https://api.weixin.qq.com/wxa/unbind_tester";
}
- public interface Share {
-
- }
+ public interface Share {}
public interface Subscribe {
- /**
- * 获取模板标题下的关键词列表.
- */
- String GET_PUB_TEMPLATE_TITLE_LIST_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatetitles";
- /**
- * 获取模板标题下的关键词列表.
- */
- String GET_PUB_TEMPLATE_KEY_WORDS_BY_ID_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatekeywords";
- /**
- * 组合模板并添加至帐号下的个人模板库.
- */
+ /** 获取模板标题下的关键词列表. */
+ String GET_PUB_TEMPLATE_TITLE_LIST_URL =
+ "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatetitles";
+
+ /** 获取模板标题下的关键词列表. */
+ String GET_PUB_TEMPLATE_KEY_WORDS_BY_ID_URL =
+ "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatekeywords";
+
+ /** 组合模板并添加至帐号下的个人模板库. */
String TEMPLATE_ADD_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate";
- /**
- * 获取当前帐号下的个人模板列表.
- */
+
+ /** 获取当前帐号下的个人模板列表. */
String TEMPLATE_LIST_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate";
- /**
- * 删除帐号下的某个模板.
- */
+
+ /** 删除帐号下的某个模板. */
String TEMPLATE_DEL_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate";
- /**
- * 获取小程序账号的类目
- */
+
+ /** 获取小程序账号的类目 */
String GET_CATEGORY_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getcategory";
- /**
- * 发送订阅消息
- */
+
+ /** 发送订阅消息 */
String SUBSCRIBE_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send";
}
public interface User {
- String SET_USER_STORAGE = "https://api.weixin.qq.com/wxa/set_user_storage?appid=%s&signature=%s&openid=%s&sig_method=%s";
+ String SET_USER_STORAGE =
+ "https://api.weixin.qq.com/wxa/set_user_storage?appid=%s&signature=%s&openid=%s&sig_method=%s";
String GET_PHONE_NUMBER_URL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber";
}
@@ -459,12 +405,14 @@ public class WxMaApiUrlConstants {
interface Order {
String PRODUCT_ORDER_GET_LIST = "https://api.weixin.qq.com/product/order/get_list";
String PRODUCT_ORDER_DETAIL_URL = "https://api.weixin.qq.com/product/order/get";
- String PRODUCT_ORDER_CHANGE_MERCHANT_NOTES_URL = "https://api.weixin.qq.com/product/order/change_merchant_notes";
+ String PRODUCT_ORDER_CHANGE_MERCHANT_NOTES_URL =
+ "https://api.weixin.qq.com/product/order/change_merchant_notes";
String PRODUCT_DELIVERY_SEND = "https://api.weixin.qq.com/product/delivery/send";
String GET_AFTER_SALE_ORDER = "https://api.weixin.qq.com/product/order/getaftersaleorder";
- String BATCH_GET_AFTER_SALE_ORDER = "https://api.weixin.qq.com/product/order/batchgetaftersaleorder";
+ String BATCH_GET_AFTER_SALE_ORDER =
+ "https://api.weixin.qq.com/product/order/batchgetaftersaleorder";
String AFTER_SALE_ACCEPT_APPLY = "https://api.weixin.qq.com/product/order/acceptapply";
String AFTER_SALE_REJECT_APPLY = "https://api.weixin.qq.com/product/order/rejectrefund";
}
@@ -472,7 +420,8 @@ public class WxMaApiUrlConstants {
interface OTHER {
String GET_CATEGORY = "https://api.weixin.qq.com/product/category/get";
String GET_BRAND = "https://api.weixin.qq.com/product/brand/get";
- String GET_FREIGHT_TEMPLATE = "https://api.weixin.qq.com/product/delivery/get_freight_template";
+ String GET_FREIGHT_TEMPLATE =
+ "https://api.weixin.qq.com/product/delivery/get_freight_template";
String IMG_UPLOAD = "https://api.weixin.qq.com/product/img/upload";
}
}
@@ -502,7 +451,8 @@ public class WxMaApiUrlConstants {
interface Register {
String REGISTER_APPLY = "https://api.weixin.qq.com/shop/register/apply";
String REGISTER_CHECK = "https://api.weixin.qq.com/shop/register/check";
- String REGISTER_FINISH_ACCESS_INFO = "https://api.weixin.qq.com/shop/register/finish_access_info";
+ String REGISTER_FINISH_ACCESS_INFO =
+ "https://api.weixin.qq.com/shop/register/finish_access_info";
String REGISTER_APPLY_SCENE = "https://api.weixin.qq.com/shop/register/apply_scene";
}
@@ -525,7 +475,8 @@ public class WxMaApiUrlConstants {
String AUDIT_BRAND = "https://api.weixin.qq.com/shop/audit/audit_brand";
String AUDIT_CATEGORY = "https://api.weixin.qq.com/shop/audit/audit_category";
String AUDIT_RESULT = "https://api.weixin.qq.com/shop/audit/result";
- String GET_MINIAPP_CERTIFICATE = "https://api.weixin.qq.com/shop/audit/get_miniapp_certificate";
+ String GET_MINIAPP_CERTIFICATE =
+ "https://api.weixin.qq.com/shop/audit/get_miniapp_certificate";
}
interface Delivery {
@@ -539,11 +490,13 @@ public class WxMaApiUrlConstants {
String AFTERSALE_CANCEL = "https://api.weixin.qq.com/shop/ecaftersale/cancel";
String AFTERSALE_UPDATE = "https://api.weixin.qq.com/shop/aftersale/update";
String EC_AFTERSALE_UPDATE = "https://api.weixin.qq.com/shop/ecaftersale/update";
- String AFTERSALE_UPLOAD_RETURN_INFO = "https://api.weixin.qq.com/shop/ecaftersale/uploadreturninfo";
+ String AFTERSALE_UPLOAD_RETURN_INFO =
+ "https://api.weixin.qq.com/shop/ecaftersale/uploadreturninfo";
String AFTERSALE_ACCEPT_REFUND = "https://api.weixin.qq.com/shop/ecaftersale/acceptrefund";
String AFTERSALE_ACCEPT_RETURN = "https://api.weixin.qq.com/shop/ecaftersale/acceptreturn";
String AFTERSALE_REJECT = "https://api.weixin.qq.com/shop/ecaftersale/reject";
- String AFTERSALE_UPLOAD_CERTIFICATES = "https://api.weixin.qq.com/shop/ecaftersale/upload_certificates";
+ String AFTERSALE_UPLOAD_CERTIFICATES =
+ "https://api.weixin.qq.com/shop/ecaftersale/upload_certificates";
String AFTERSALE_UPLOAD_DEADLINE = "https://api.weixin.qq.com/shop/aftersale/update_deadline";
String AFTERSALE_GET_LIST = "https://api.weixin.qq.com/shop/ecaftersale/get_list";
String AFTERSALE_GET = "https://api.weixin.qq.com/shop/aftersale/get";
@@ -552,10 +505,13 @@ public class WxMaApiUrlConstants {
interface Sharer {
String BIND = "https://api.weixin.qq.com/shop/sharer/bind";
- String GET_SHARER_DATA_SUMMARY = "https://api.weixin.qq.com/shop/sharer/get_sharer_data_summary";
+ String GET_SHARER_DATA_SUMMARY =
+ "https://api.weixin.qq.com/shop/sharer/get_sharer_data_summary";
String GET_SHARER_LIST = "https://api.weixin.qq.com/shop/sharer/get_sharer_list";
- String GET_SHARER_LIVE_ORDER_LIST = "https://api.weixin.qq.com/shop/sharer/get_sharer_live_order_list";
- String GET_SHARER_LIVE_SUMMARY_LIST = "https://api.weixin.qq.com/shop/sharer/get_sharer_live_summary_list";
+ String GET_SHARER_LIVE_ORDER_LIST =
+ "https://api.weixin.qq.com/shop/sharer/get_sharer_live_order_list";
+ String GET_SHARER_LIVE_SUMMARY_LIST =
+ "https://api.weixin.qq.com/shop/sharer/get_sharer_live_summary_list";
String SEARCH_SHARER = "https://api.weixin.qq.com/shop/sharer/search_sharer";
String UNBIND = "https://api.weixin.qq.com/shop/sharer/unbind";
}
@@ -570,7 +526,8 @@ public class WxMaApiUrlConstants {
String ADD_USER_COUPON = "https://api.weixin.qq.com/shop/coupon/add_user_coupon";
String GET_USER_COUPON_LIST = "https://api.weixin.qq.com/shop/coupon/get_usercoupon_list";
String UPDATE_USER_COUPON = "https://api.weixin.qq.com/shop/coupon/update_user_coupon";
- String UPDATE_USER_COUPON_STATUS = "https://api.weixin.qq.com/shop/coupon/update_usercoupon_status";
+ String UPDATE_USER_COUPON_STATUS =
+ "https://api.weixin.qq.com/shop/coupon/update_usercoupon_status";
}
interface Pay {
@@ -580,52 +537,41 @@ public class WxMaApiUrlConstants {
}
}
- /**
- * 电子发票报销方
- */
+ /** 电子发票报销方 */
public interface Invoice {
- /**
- * 报销方查询报销发票信息
- */
+ /** 报销方查询报销发票信息 */
String GET_INVOICE_INFO = "https://api.weixin.qq.com/card/invoice/reimburse/getinvoiceinfo";
- /**
- * 报销方批量查询报销发票信息
- */
+ /** 报销方批量查询报销发票信息 */
String GET_INVOICE_BATCH = "https://api.weixin.qq.com/card/invoice/reimburse/getinvoicebatch";
- /**
- * 报销方更新发票状态
- */
- String UPDATE_INVOICE_STATUS = "https://api.weixin.qq.com/card/invoice/reimburse/updateinvoicestatus";
+ /** 报销方更新发票状态 */
+ String UPDATE_INVOICE_STATUS =
+ "https://api.weixin.qq.com/card/invoice/reimburse/updateinvoicestatus";
- /**
- * 报销方批量更新发票状态
- */
- String UPDATE_STATUS_BATCH = "https://api.weixin.qq.com/card/invoice/reimburse/updatestatusbatch";
+ /** 报销方批量更新发票状态 */
+ String UPDATE_STATUS_BATCH =
+ "https://api.weixin.qq.com/card/invoice/reimburse/updatestatusbatch";
}
public interface Internet {
String GET_USER_ENCRYPT_KEY = "https://api.weixin.qq.com/wxa/business/getuserencryptkey";
}
- /**
- * 设备订阅消息
- */
+ /** 设备订阅消息 */
public interface DeviceSubscribe {
- /**
- * 获取设备票据
- */
+ /** 获取设备票据 */
String GET_SN_TICKET_URL = "https://api.weixin.qq.com/wxa/getsnticket";
- /**
- * 发送设备订阅消息
- */
- String SEND_DEVICE_SUBSCRIBE_MSG_URL = "https://api.weixin.qq.com/cgi-bin/message/device/subscribe/send";
+
+ /** 发送设备订阅消息 */
+ String SEND_DEVICE_SUBSCRIBE_MSG_URL =
+ "https://api.weixin.qq.com/cgi-bin/message/device/subscribe/send";
}
/**
* 即时配送相关接口.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/immediate-delivery/overview.html
*
@@ -634,6 +580,7 @@ public class WxMaApiUrlConstants {
/**
* 拉取已绑定账号.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/immediate-delivery/by-business/immediateDelivery.getBindAccount.html
*
@@ -642,6 +589,7 @@ public class WxMaApiUrlConstants {
/**
* 拉取配送单信息.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/immediate-delivery/by-business/immediateDelivery.getOrder.html
*
@@ -650,73 +598,64 @@ public class WxMaApiUrlConstants {
/**
* 模拟配送公司更新配送单状态.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/immediate-delivery/by-business/immediateDelivery.mockUpdateOrder.html
*
*/
- String MOCK_UPDATE_ORDER = "https://api.weixin.qq.com/cgi-bin/express/local/business/test_update_order";
+ String MOCK_UPDATE_ORDER =
+ "https://api.weixin.qq.com/cgi-bin/express/local/business/test_update_order";
- /**
- * 物流服务-查询组件-跟踪物流面单
- * 商户使用此接口向微信提供某交易单号对应的运单号。微信后台会跟踪运单的状态变化
- */
- String TRACE_WAYBILL_URL = "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/trace_waybill";
+ /** 物流服务-查询组件-跟踪物流面单 商户使用此接口向微信提供某交易单号对应的运单号。微信后台会跟踪运单的状态变化 */
+ String TRACE_WAYBILL_URL =
+ "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/trace_waybill";
+ /** 物流服务-查询组件-查询运单接口 query_trace 商户在调用完trace_waybill接口后,可以使用本接口查询到对应运单的详情信息 */
+ String QUERY_WAYBILL_TRACE_URL =
+ "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/query_trace";
- /**
- * 物流服务-查询组件-查询运单接口 query_trace
- * 商户在调用完trace_waybill接口后,可以使用本接口查询到对应运单的详情信息
- */
- String QUERY_WAYBILL_TRACE_URL = "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/query_trace";
+ /** 物流服务-消息组件-传运单接口(订阅消息) follow_waybill 商户在调用完trace_waybill接口后,可以使用本接口查询到对应运单的详情信息 */
+ String FOLLOW_WAYBILL_URL =
+ "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/follow_waybill";
- /**
- * 物流服务-消息组件-传运单接口(订阅消息) follow_waybill
- * 商户在调用完trace_waybill接口后,可以使用本接口查询到对应运单的详情信息
- */
- String FOLLOW_WAYBILL_URL = "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/follow_waybill";
+ /** 物流服务-消息组件-查运单接口(订阅消息) query_follow_trace 商户在调用完trace_waybill接口后,可以使用本接口查询到对应运单的详情信息 */
+ String QUERY_FOLLOW_TRACE_URL =
+ "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/query_follow_trace";
- /**
- * 物流服务-消息组件-查运单接口(订阅消息) query_follow_trace
- * 商户在调用完trace_waybill接口后,可以使用本接口查询到对应运单的详情信息
- */
- String QUERY_FOLLOW_TRACE_URL = "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/query_follow_trace";
+ /** 获取运力id列表get_delivery_list 商户使用此接口获取所有运力id的列表 */
+ String GET_DELIVERY_LIST_URL =
+ "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/get_delivery_list";
- /**
- * 获取运力id列表get_delivery_list
- * 商户使用此接口获取所有运力id的列表
- */
- String GET_DELIVERY_LIST_URL = "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/get_delivery_list";
+ /** 获取运力id列表get_delivery_list 商户使用此接口获取所有运力id的列表 */
+ String UPDATE_WAYBILL_GOODS_URL =
+ "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/update_waybill_goods";
- /**
- * 获取运力id列表get_delivery_list
- * 商户使用此接口获取所有运力id的列表
- */
- String UPDATE_WAYBILL_GOODS_URL = "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/update_waybill_goods";
-
-
- /**
- * 下单接口.
- */
+ /** 下单接口. */
interface PlaceAnOrder {
/**
* 获取已支持的配送公司列表接口.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/immediate-delivery/by-business/immediateDelivery.getAllImmeDelivery.html
*
*/
- String GET_ALL_IMME_DELIVERY = "https://api.weixin.qq.com/cgi-bin/express/local/business/delivery/getall";
+ String GET_ALL_IMME_DELIVERY =
+ "https://api.weixin.qq.com/cgi-bin/express/local/business/delivery/getall";
/**
* 预下配送单接口.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/immediate-delivery/by-business/immediateDelivery.preAddOrder.html
*
*/
- String PRE_ADD_ORDER = "https://api.weixin.qq.com/cgi-bin/express/local/business/order/pre_add";
+ String PRE_ADD_ORDER =
+ "https://api.weixin.qq.com/cgi-bin/express/local/business/order/pre_add";
/**
* 下配送单接口.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/immediate-delivery/by-business/immediateDelivery.addOrder.html
*
@@ -725,6 +664,7 @@ public class WxMaApiUrlConstants {
/**
* 重新下单.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/immediate-delivery/by-business/immediateDelivery.reOrder.html
*
@@ -733,30 +673,31 @@ public class WxMaApiUrlConstants {
/**
* 增加小费.
+ *
*
* 可以对待接单状态的订单增加小费。需要注意:订单的小费,以最新一次加小费动作的金额为准,故下一次增加小费额必须大于上一次小费额.
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/immediate-delivery/by-business/immediateDelivery.addTip.html
*
*/
String ADD_TIP = "https://api.weixin.qq.com/cgi-bin/express/local/business/order/addtips";
-
}
- /**
- * 取消接口.
- */
+ /** 取消接口. */
interface Cancel {
/**
* 预取消配送单接口.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/immediate-delivery/by-business/immediateDelivery.preCancelOrder.html
*
*/
- String PRE_CANCEL_ORDER = "https://api.weixin.qq.com/cgi-bin/express/local/business/order/precancel";
+ String PRE_CANCEL_ORDER =
+ "https://api.weixin.qq.com/cgi-bin/express/local/business/order/precancel";
/**
* 取消配送单接口.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/immediate-delivery/by-business/immediateDelivery.cancelOrder.html
*
@@ -765,18 +706,19 @@ public class WxMaApiUrlConstants {
/**
* 异常件退回商家商家确认收货接口.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/immediate-delivery/by-business/immediateDelivery.abnormalConfirm.html
*
*/
- String ABNORMAL_CONFIRM = "https://api.weixin.qq.com/cgi-bin/express/local/business/order/confirm_return";
-
+ String ABNORMAL_CONFIRM =
+ "https://api.weixin.qq.com/cgi-bin/express/local/business/order/confirm_return";
}
-
}
/**
* 发货信息管理服务相关接口
+ *
*
* 文档地址: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%B8%80%E3%80%81%E5%8F%91%E8%B4%A7%E4%BF%A1%E6%81%AF%E5%BD%95%E5%85%A5%E6%8E%A5%E5%8F%A3
*
@@ -785,6 +727,7 @@ public class WxMaApiUrlConstants {
/**
* 查询小程序是否已开通发货信息管理服务.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%B8%83%E3%80%81%E6%9F%A5%E8%AF%A2%E5%B0%8F%E7%A8%8B%E5%BA%8F%E6%98%AF%E5%90%A6%E5%B7%B2%E5%BC%80%E9%80%9A%E5%8F%91%E8%B4%A7%E4%BF%A1%E6%81%AF%E7%AE%A1%E7%90%86%E6%9C%8D%E5%8A%A1
*
@@ -793,6 +736,7 @@ public class WxMaApiUrlConstants {
/**
* 发货信息录入接口.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%B8%80%E3%80%81%E5%8F%91%E8%B4%A7%E4%BF%A1%E6%81%AF%E5%BD%95%E5%85%A5%E6%8E%A5%E5%8F%A3
*
@@ -801,14 +745,17 @@ public class WxMaApiUrlConstants {
/**
* 发货信息合单录入接口.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%BA%8C%E3%80%81%E5%8F%91%E8%B4%A7%E4%BF%A1%E6%81%AF%E5%90%88%E5%8D%95%E5%BD%95%E5%85%A5%E6%8E%A5%E5%8F%A3
*
*/
- String UPLOAD_COMBINED_SHIPPING_INFO = "https://api.weixin.qq.com/wxa/sec/order/upload_combined_shipping_info";
+ String UPLOAD_COMBINED_SHIPPING_INFO =
+ "https://api.weixin.qq.com/wxa/sec/order/upload_combined_shipping_info";
/**
* 查询订单发货状态.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%BA%8C%E3%80%81%E5%8F%91%E8%B4%A7%E4%BF%A1%E6%81%AF%E5%90%88%E5%8D%95%E5%BD%95%E5%85%A5%E6%8E%A5%E5%8F%A3
*
@@ -817,6 +764,7 @@ public class WxMaApiUrlConstants {
/**
* 查询订单发货状态列表.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E5%9B%9B%E3%80%81%E6%9F%A5%E8%AF%A2%E8%AE%A2%E5%8D%95%E5%88%97%E8%A1%A8
*
@@ -825,20 +773,22 @@ public class WxMaApiUrlConstants {
/**
* 确认收货提醒接口.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%BA%94%E3%80%81%E7%A1%AE%E8%AE%A4%E6%94%B6%E8%B4%A7%E6%8F%90%E9%86%92%E6%8E%A5%E5%8F%A3
*
*/
- String NOTIFY_CONFIRM_RECEIVE = "https://api.weixin.qq.com/wxa/sec/order/notify_confirm_receive";
+ String NOTIFY_CONFIRM_RECEIVE =
+ "https://api.weixin.qq.com/wxa/sec/order/notify_confirm_receive";
/**
* 消息跳转路径设置接口.
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E5%85%AD%E3%80%81%E6%B6%88%E6%81%AF%E8%B7%B3%E8%BD%AC%E8%B7%AF%E5%BE%84%E8%AE%BE%E7%BD%AE%E6%8E%A5%E5%8F%A3
*
*/
String SET_MSG_JUMP_PATH = "https://api.weixin.qq.com/wxa/sec/order/set_msg_jump_path";
-
}
public interface Vod {
@@ -857,46 +807,58 @@ public class WxMaApiUrlConstants {
String COMMIT_UPLOAD_URL = "https://api.weixin.qq.com/wxa/sec/vod/commitupload";
String GET_CDN_USAGE_DATA_URL = "https://api.weixin.qq.com/wxa/sec/vod/getcdnusagedata";
String GET_CDN_LOGS_URL = "https://api.weixin.qq.com/wxa/sec/vod/getcdnlogs";
-
}
/**
* 小程序虚拟支付服务相关接口
+ *
*
* 文档地址: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html#_2-3-%E6%9C%8D%E5%8A%A1%E5%99%A8API
*
*/
public interface XPay {
- String QUERY_USER_BALANCE_URL = "https://api.weixin.qq.com/xpay/query_user_balance?pay_sig=%s&signature=%s";
+ String QUERY_USER_BALANCE_URL =
+ "https://api.weixin.qq.com/xpay/query_user_balance?pay_sig=%s&signature=%s";
String CURRENCY_PAY_URL = "https://api.weixin.qq.com/xpay/currency_pay?pay_sig=%s&signature=%s";
String QUERY_ORDER_URL = "https://api.weixin.qq.com/xpay/query_order?pay_sig=%s";
- String CANCEL_CURRENCY_PAY_URL = "https://api.weixin.qq.com/xpay/cancel_currency_pay?pay_sig=%s&signature=%s";
- String NOTIFY_PROVIDE_GOODS_URL = "https://api.weixin.qq.com/xpay/notify_provide_goods?pay_sig=%s";
+ String CANCEL_CURRENCY_PAY_URL =
+ "https://api.weixin.qq.com/xpay/cancel_currency_pay?pay_sig=%s&signature=%s";
+ String NOTIFY_PROVIDE_GOODS_URL =
+ "https://api.weixin.qq.com/xpay/notify_provide_goods?pay_sig=%s";
String PRESENT_CURRENCY_URL = "https://api.weixin.qq.com/xpay/present_currency?pay_sig=%s";
String DOWNLOAD_BILL_URL = "https://api.weixin.qq.com/xpay/download_bill?pay_sig=%s";
String REFUND_ORDER_URL = "https://api.weixin.qq.com/xpay/refund_order?pay_sig=%s";
- String CREATE_WITHDRAW_ORDER_URL = "https://api.weixin.qq.com/xpay/create_withdraw_order?pay_sig=%s";
- String QUERY_WITHDRAW_ORDER_URL = "https://api.weixin.qq.com/xpay/query_withdraw_order?pay_sig=%s";
+ String CREATE_WITHDRAW_ORDER_URL =
+ "https://api.weixin.qq.com/xpay/create_withdraw_order?pay_sig=%s";
+ String QUERY_WITHDRAW_ORDER_URL =
+ "https://api.weixin.qq.com/xpay/query_withdraw_order?pay_sig=%s";
String START_UPLOAD_GOODS_URL = "https://api.weixin.qq.com/xpay/start_upload_goods?pay_sig=%s";
String QUERY_UPLOAD_GOODS_URL = "https://api.weixin.qq.com/xpay/query_upload_goods?pay_sig=%s";
- String START_PUBLISH_GOODS_URL = "https://api.weixin.qq.com/xpay/start_publish_goods?pay_sig=%s";
- String QUERY_PUBLISH_GOODS_URL = "https://api.weixin.qq.com/xpay/query_publish_goods?pay_sig=%s";
-
+ String START_PUBLISH_GOODS_URL =
+ "https://api.weixin.qq.com/xpay/start_publish_goods?pay_sig=%s";
+ String QUERY_PUBLISH_GOODS_URL =
+ "https://api.weixin.qq.com/xpay/query_publish_goods?pay_sig=%s";
}
/**
* 退货组件
+ *
*
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/express/business/express_sale_return.html
*
*/
public interface ExpressDeliveryReturn {
- String ADD_DELIVERY_RETURN_URL = "https://api.weixin.qq.com/cgi-bin/express/delivery/return/add";
- String GET_DELIVERY_RETURN_URL = "https://api.weixin.qq.com/cgi-bin/express/delivery/return/get";
- String UNBIND_DELIVERY_RETURN_URL = "https://api.weixin.qq.com/cgi-bin/express/delivery/return/unbind";
+ String ADD_DELIVERY_RETURN_URL =
+ "https://api.weixin.qq.com/cgi-bin/express/delivery/return/add";
+ String GET_DELIVERY_RETURN_URL =
+ "https://api.weixin.qq.com/cgi-bin/express/delivery/return/get";
+ String UNBIND_DELIVERY_RETURN_URL =
+ "https://api.weixin.qq.com/cgi-bin/express/delivery/return/unbind";
}
/**
+ *
+ *
* 小程序推广员
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/promoter/instruction/instruction.html
*
@@ -908,7 +870,8 @@ public class WxMaApiUrlConstants {
String PROMOTION_ADD_PROMOTER = "https://api.weixin.qq.com/promoter/addpromoter";
String PROMOTION_GET_PROMOTER = "https://api.weixin.qq.com/promoter/getpromoter";
String PROMOTION_UPDATE_PROMOTER = "https://api.weixin.qq.com/promoter/updatepromoter";
- String PROMOTION_GET_INVITATION_MATERIAL = "https://api.weixin.qq.com/promoter/getinvitationmaterial";
+ String PROMOTION_GET_INVITATION_MATERIAL =
+ "https://api.weixin.qq.com/promoter/getinvitationmaterial";
String PROMOTION_SEND_MSG = "https://api.weixin.qq.com/promoter/sendmsg";
String PROMOTION_SINGLE_SEND_MSG = "https://api.weixin.qq.com/promoter/singlesendmsg";
String PROMOTION_GET_MSG = "https://api.weixin.qq.com/promoter/getmsg";
@@ -918,4 +881,24 @@ public class WxMaApiUrlConstants {
String PROMOTION_GET_ORDER = "https://api.weixin.qq.com/promoter/getorder";
}
+ public interface Intracity {
+ String APPLY_URL = "https://api.weixin.qq.com/cgi-bin/express/intracity/apply";
+ String CREATE_STORE_URL = "https://api.weixin.qq.com/cgi-bin/express/intracity/createstore";
+ String QUERY_STORE_URL = "https://api.weixin.qq.com/cgi-bin/express/intracity/querystore";
+ String UPDATE_STORE_URL = "https://api.weixin.qq.com/cgi-bin/express/intracity/updatestore";
+
+ String STORE_CHARGE = "https://api.weixin.qq.com/cgi-bin/express/intracity/storecharge";
+ String STORE_REFUND = "https://api.weixin.qq.com/cgi-bin/express/intracity/storerefund";
+ String QUERY_FLOW = "https://api.weixin.qq.com/cgi-bin/express/intracity/queryflow";
+ String BALANCE_QUERY = "https://api.weixin.qq.com/cgi-bin/express/intracity/balancequery";
+ String GET_PAY_MODE = "https://api.weixin.qq.com/cgi-bin/express/intracity/getpaymode";
+ String SET_PAY_MODE = "https://api.weixin.qq.com/cgi-bin/express/intracity/setpaymode";
+
+ String PRE_ADD_ORDER = "https://api.weixin.qq.com/cgi-bin/express/intracity/preaddorder";
+ String ADD_ORDER = "https://api.weixin.qq.com/cgi-bin/express/intracity/addorder";
+ String QUERY_ORDER = "https://api.weixin.qq.com/cgi-bin/express/intracity/queryorder";
+ String CANCEL_ORDER = "https://api.weixin.qq.com/cgi-bin/express/intracity/cancelorder";
+
+ String GET_CITY = "https://api.weixin.qq.com/cgi-bin/express/intracity/getcity";
+ }
}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/executor/ApacheApiSignaturePostRequestExecutor.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/executor/ApacheApiSignaturePostRequestExecutor.java
new file mode 100644
index 000000000..3dcf22b10
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/executor/ApacheApiSignaturePostRequestExecutor.java
@@ -0,0 +1,71 @@
+package cn.binarywang.wx.miniapp.executor;
+
+import cn.binarywang.wx.miniapp.bean.WxMaApiResponse;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import me.chanjar.weixin.common.enums.WxType;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler;
+import org.apache.http.Consts;
+import org.apache.http.Header;
+import org.apache.http.HttpHost;
+import org.apache.http.client.config.RequestConfig;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ApacheApiSignaturePostRequestExecutor
+ extends ApiSignaturePostRequestExecutor {
+ private static final Logger logger =
+ LoggerFactory.getLogger(ApacheApiSignaturePostRequestExecutor.class);
+
+ public ApacheApiSignaturePostRequestExecutor(RequestHttp, ?> requestHttp) {
+ super(requestHttp);
+ }
+
+ @Override
+ public WxMaApiResponse execute(
+ String uri, Map headers, String postEntity, WxType wxType)
+ throws WxErrorException, IOException {
+ // logger.debug(
+ // "ApacheApiSignaturePostRequestExecutor.execute uri:{}, headers:{}, postData:{}",
+ // uri,
+ // headers,
+ // postEntity);
+ HttpPost httpPost = new HttpPost(uri);
+ if (requestHttp.getRequestHttpProxy() != null) {
+ RequestConfig config =
+ RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build();
+ httpPost.setConfig(config);
+ }
+
+ if (headers != null) {
+ headers.forEach(httpPost::addHeader);
+ }
+
+ if (postEntity != null) {
+ StringEntity entity = new StringEntity(postEntity, Consts.UTF_8);
+ entity.setContentType("application/json; charset=utf-8");
+ httpPost.setEntity(entity);
+ }
+
+ try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) {
+ String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
+ Map respHeaders = new HashMap<>();
+ Header[] rHeaders = response.getAllHeaders();
+ if (rHeaders != null) {
+ for (Header h : rHeaders) {
+ respHeaders.putIfAbsent(h.getName(), h.getValue());
+ }
+ }
+ return this.handleResponse(wxType, responseContent, respHeaders);
+ } finally {
+ httpPost.releaseConnection();
+ }
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/executor/ApiSignaturePostRequestExecutor.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/executor/ApiSignaturePostRequestExecutor.java
new file mode 100644
index 000000000..8e3ade961
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/executor/ApiSignaturePostRequestExecutor.java
@@ -0,0 +1,69 @@
+package cn.binarywang.wx.miniapp.executor;
+
+import cn.binarywang.wx.miniapp.bean.WxMaApiResponse;
+import java.io.IOException;
+import java.rmi.RemoteException;
+import java.util.Map;
+import me.chanjar.weixin.common.enums.WxType;
+import me.chanjar.weixin.common.error.WxError;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.RequestExecutor;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.ResponseHandler;
+import org.jetbrains.annotations.NotNull;
+
+public abstract class ApiSignaturePostRequestExecutor
+ implements RequestExecutor {
+
+ protected RequestHttp requestHttp;
+
+ public ApiSignaturePostRequestExecutor(RequestHttp requestHttp) {
+ this.requestHttp = requestHttp;
+ }
+
+ @Override
+ public WxMaApiResponse execute(String uri, WxMaApiResponse data, WxType wxType)
+ throws WxErrorException, IOException {
+ throw new RemoteException("method not implemented yet.");
+ }
+
+ @Override
+ public void execute(
+ String uri, WxMaApiResponse data, ResponseHandler handler, WxType wxType)
+ throws WxErrorException, IOException {
+ throw new RemoteException("method not implemented yet.");
+ }
+
+ public abstract WxMaApiResponse execute(
+ String uri, Map headers, String data, WxType wxType)
+ throws WxErrorException, IOException;
+
+ @NotNull
+ public WxMaApiResponse handleResponse(
+ WxType wxType, String responseContent, Map headers) throws WxErrorException {
+ if (responseContent.isEmpty()) {
+ throw new WxErrorException("无响应内容");
+ }
+ WxError error = WxError.fromJson(responseContent, wxType);
+ if (error.getErrorCode() != 0) {
+ throw new WxErrorException(error);
+ }
+ WxMaApiResponse response = new WxMaApiResponse();
+ response.setContent(responseContent);
+ response.setHeaders(headers);
+ return response;
+ }
+
+ public static ApiSignaturePostRequestExecutor create(RequestHttp requestHttp) {
+ switch (requestHttp.getRequestType()) {
+ case APACHE_HTTP:
+ return new ApacheApiSignaturePostRequestExecutor(requestHttp);
+ case JODD_HTTP:
+ return new JoddApiSignaturePostRequestExecutor(requestHttp);
+ case OK_HTTP:
+ return new OkHttpApiSignaturePostRequestExecutor(requestHttp);
+ default:
+ throw new IllegalArgumentException("非法请求参数");
+ }
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/executor/JoddApiSignaturePostRequestExecutor.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/executor/JoddApiSignaturePostRequestExecutor.java
new file mode 100644
index 000000000..b7568bc21
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/executor/JoddApiSignaturePostRequestExecutor.java
@@ -0,0 +1,59 @@
+package cn.binarywang.wx.miniapp.executor;
+
+import cn.binarywang.wx.miniapp.bean.WxMaApiResponse;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+import jodd.http.HttpConnectionProvider;
+import jodd.http.HttpRequest;
+import jodd.http.HttpResponse;
+import jodd.http.ProxyInfo;
+import me.chanjar.weixin.common.enums.WxType;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JoddApiSignaturePostRequestExecutor
+ extends ApiSignaturePostRequestExecutor {
+ private static final Logger logger =
+ LoggerFactory.getLogger(JoddApiSignaturePostRequestExecutor.class);
+
+ public JoddApiSignaturePostRequestExecutor(RequestHttp, ?> requestHttp) {
+ super(requestHttp);
+ }
+
+ @Override
+ public WxMaApiResponse execute(
+ String uri, Map headers, String postEntity, WxType wxType)
+ throws WxErrorException, IOException {
+ // logger.debug(
+ // "JoddApiSignaturePostRequestExecutor.execute uri:{}, headers:{}, postData:{}",
+ // uri,
+ // headers,
+ // postEntity);
+ HttpConnectionProvider provider = requestHttp.getRequestHttpClient();
+ ProxyInfo proxyInfo = requestHttp.getRequestHttpProxy();
+
+ HttpRequest request = HttpRequest.post(uri);
+ if (proxyInfo != null) {
+ provider.useProxy(proxyInfo);
+ }
+ if (headers != null) {
+ headers.forEach(request::header);
+ }
+ request.withConnectionProvider(provider);
+ if (postEntity != null) {
+ request.contentType("application/json", "utf-8");
+ request.bodyText(postEntity);
+ }
+ HttpResponse response = request.send();
+ response.charset(StandardCharsets.UTF_8.name());
+ Map respHeaders = new HashMap<>();
+ for (String n : response.headerNames()) {
+ respHeaders.putIfAbsent(n, response.header(n));
+ }
+ return this.handleResponse(wxType, response.bodyText(), respHeaders);
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/executor/OkHttpApiSignaturePostRequestExecutor.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/executor/OkHttpApiSignaturePostRequestExecutor.java
new file mode 100644
index 000000000..10c75a26b
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/executor/OkHttpApiSignaturePostRequestExecutor.java
@@ -0,0 +1,51 @@
+package cn.binarywang.wx.miniapp.executor;
+
+import cn.binarywang.wx.miniapp.bean.WxMaApiResponse;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import me.chanjar.weixin.common.enums.WxType;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo;
+import okhttp3.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OkHttpApiSignaturePostRequestExecutor
+ extends ApiSignaturePostRequestExecutor {
+ private static final Logger logger =
+ LoggerFactory.getLogger(OkHttpApiSignaturePostRequestExecutor.class);
+
+ public OkHttpApiSignaturePostRequestExecutor(RequestHttp, ?> requestHttp) {
+ super(requestHttp);
+ }
+
+ @Override
+ public WxMaApiResponse execute(
+ String uri, Map headers, String postEntity, WxType wxType)
+ throws WxErrorException, IOException {
+ // logger.debug(
+ // "OkHttpApiSignaturePostRequestExecutor.execute uri:{}, headers:{}, postData:{}",
+ // uri,
+ // headers,
+ // postEntity);
+ RequestBody body =
+ RequestBody.Companion.create(
+ postEntity, MediaType.parse("application/json; charset=utf-8"));
+ Request.Builder builder = new Request.Builder();
+ if (headers != null) {
+ headers.forEach(builder::addHeader);
+ }
+ Request request = builder.url(uri).post(body).build();
+ Response response = requestHttp.getRequestHttpClient().newCall(request).execute();
+ Map respHeaders = new HashMap<>();
+ Headers rHeaders = response.headers();
+ for (String n : rHeaders.names()) {
+ respHeaders.put(n, rHeaders.get(n));
+ }
+ return this.handleResponse(
+ wxType, Objects.requireNonNull(response.body()).string(), respHeaders);
+ }
+}
diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaIntracityServiceImpleTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaIntracityServiceImpleTest.java
new file mode 100644
index 000000000..51ad846e9
--- /dev/null
+++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaIntracityServiceImpleTest.java
@@ -0,0 +1,234 @@
+package cn.binarywang.wx.miniapp.api.impl;
+
+import static org.testng.AssertJUnit.*;
+
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.intractiy.*;
+import cn.binarywang.wx.miniapp.bean.openapi.WxMiniGetApiQuotaResult;
+import cn.binarywang.wx.miniapp.constant.WxMaApiUrlConstants;
+import cn.binarywang.wx.miniapp.test.ApiTestModule;
+import cn.binarywang.wx.miniapp.test.TestConfig;
+import com.google.inject.Inject;
+import java.util.ArrayList;
+import java.util.List;
+import me.chanjar.weixin.common.error.WxErrorException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+@Test
+@Guice(modules = ApiTestModule.class)
+public class WxMaIntracityServiceImpleTest {
+ private static final Logger logger = LoggerFactory.getLogger(WxMaIntracityServiceImpleTest.class);
+
+ @Inject private WxMaService wxService;
+
+ @Test
+ public void testApiSignature() throws Exception {
+ WxMiniGetApiQuotaResult result =
+ wxService
+ .getWxMaOpenApiService()
+ .getApiQuota(
+ WxMaApiUrlConstants.Intracity.APPLY_URL.substring(
+ "https://api.weixin.qq.com".length()));
+ logger.info("apply 额度剩余 :{}", result.getQuota());
+ }
+
+ @Test
+ public void testApply() throws Exception {
+ logger.debug("testApply");
+ try {
+ wxService.getIntracityService().apply();
+ } catch (WxErrorException wxEx) {
+ if (wxEx.getError().getErrorCode() == 45009) {
+ // 调用分钟频率受限
+ } else {
+ throw wxEx;
+ }
+ }
+ }
+
+ @Test
+ public void testStoreRelatedApis() throws Exception {
+ WxMaStore store = new WxMaStore();
+ store.setStoreName("南京东路店");
+ store.setOutStoreId("njdl-001");
+ WxMaStore.AddressInfo addr = new WxMaStore.AddressInfo();
+ addr.setProvince("上海市");
+ addr.setCity("上海市");
+ addr.setArea("黄浦区");
+ addr.setStreet("");
+ addr.setHouse("南京东路690号");
+ addr.setLat(31.235318);
+ addr.setLng(121.477284);
+ addr.setPhone("021-23456789");
+ store.setAddressInfo(addr);
+ String wxStoreId;
+ List result =
+ wxService.getIntracityService().queryStoreByOutStoreId(store.getOutStoreId());
+ if (result.isEmpty()) {
+ wxStoreId = wxService.getIntracityService().createStore(store);
+ logger.debug("create store result:{}", wxStoreId);
+ } else {
+ wxStoreId = result.get(0).getWxStoreId();
+ }
+ store.setWxStoreId(wxStoreId);
+ addr.setPhone("021-23450000");
+ store.setStoreName(null);
+ wxService.getIntracityService().updateStore(store);
+ List stores = wxService.getIntracityService().listAllStores();
+ logger.info("listAllStores 查询到 {} 个门店 {}", stores.size(), stores);
+ if (stores.size() > 0) {
+ WxMaStore s =
+ wxService.getIntracityService().queryStoreByWxStoreId(stores.get(0).getWxStoreId());
+ assertNotNull(s);
+ List list =
+ wxService.getIntracityService().queryStoreByOutStoreId(stores.get(0).getOutStoreId());
+ logger.info("queryStoreByOutStoreId 查询到 {} 个门店 {}", list.size(), list);
+ }
+ }
+
+ @Test
+ public void testStoreChargeRelated() throws Exception {
+ List stores = wxService.getIntracityService().listAllStores();
+ if (stores.isEmpty()) {
+ logger.warn("没有门店,无法测试");
+ return;
+ }
+ WxMaStore store = stores.get(0);
+
+ WxMaGetPayModeResponse resp = wxService.getIntracityService().getPayMode();
+ logger.debug("查询付费主体 {}", resp);
+ PayMode currentPayMode = resp.getPayMode();
+ // 只能用当前付费模式充值;否则微信接口会返回 错误代码:934025, 错误信息:pay_mode not match
+ WxMaStoreChargeRequest request = new WxMaStoreChargeRequest();
+ request.setPayMode(currentPayMode);
+ request.setWxStoreId(store.getWxStoreId());
+ request.setServiceTransId("DADA");
+ request.setAmount(5000);
+ String payUrl = wxService.getIntracityService().storeCharge(request);
+ logger.debug("充值URL:{}", payUrl);
+
+ // 查询余额
+ WxMaStoreBalance balance =
+ wxService.getIntracityService().balanceQuery(store.getWxStoreId(), null, PayMode.STORE);
+ logger.debug("余额 {}", balance);
+
+ // 退款
+ WxMaStoreRefundRequest rr = new WxMaStoreRefundRequest();
+ rr.setPayMode(PayMode.STORE);
+ rr.setWxStoreId(store.getWxStoreId());
+ rr.setServiceTransId("DADA");
+ int refundAmount = wxService.getIntracityService().storeRefund(rr);
+ logger.debug("退款:{}", refundAmount);
+
+ // 查询流水
+ WxMaQueryFlowRequest qfr = new WxMaQueryFlowRequest();
+ qfr.setWxStoreId(store.getWxStoreId());
+ WxMaStoreFlowResponse flowResponse = wxService.getIntracityService().queryFlow(qfr);
+ logger.debug("查询流水 {}", flowResponse);
+ }
+
+ @Test
+ public void testPayMode() throws Exception {
+ WxMaGetPayModeResponse resp = wxService.getIntracityService().getPayMode();
+ logger.debug("查询付费主体 {}", resp);
+ PayMode newMode = resp.getPayMode() == PayMode.APP ? PayMode.STORE : PayMode.APP;
+ logger.debug("set pay mode to {}", newMode);
+ wxService.getIntracityService().setPayMode(newMode);
+ WxMaGetPayModeResponse resp2 = wxService.getIntracityService().getPayMode();
+ logger.debug("查询付费主体 {}", resp2);
+ }
+
+ @Test
+ public void testGetCity() throws Exception {
+ List list = wxService.getIntracityService().getCity(null);
+ logger.debug("支持的城市 {}", list);
+ List list2 = wxService.getIntracityService().getCity("SFTC");
+ logger.debug("SFTC支持的城市有{}个", list2.get(0).getCityList().size());
+ }
+
+ @Test
+ public void testOrderRelatived() throws Exception {
+ List stores = wxService.getIntracityService().listAllStores();
+ if (stores.isEmpty()) {
+ logger.warn("没有门店,无法测试");
+ return;
+ }
+ String wxStoreId = stores.get(0).getWxStoreId();
+ {
+ WxMaPreAddOrderRequest request = new WxMaPreAddOrderRequest();
+ request.setWxStoreId(wxStoreId);
+ request.setUseSandbox(1);
+ request.setUserName("顺丰同城");
+ request.setUserPhone("13800000138");
+ request.setUserAddress("北京市海淀区学清嘉创大厦A座15层");
+ request.setUserLat(40.01496);
+ request.setUserLng(116.353093);
+ WxMaPreAddOrderRequest.Cargo cargo = new WxMaPreAddOrderRequest.Cargo();
+ cargo.setCargoName("蛋糕");
+ cargo.setCargoType(13);
+ cargo.setCargoNum(1);
+ cargo.setCargoPrice(10000);
+ cargo.setCargoWeight(1000);
+ request.setCargo(cargo);
+ WxMaAddOrderResponse response = wxService.getIntracityService().preAddOrder(request);
+ logger.debug("查询运费返回 {}, 预估运费{}元", response, response.getFee() / 100.0);
+ }
+ String wxOrderId = null;
+ {
+ TestConfig config = (TestConfig) this.wxService.getWxMaConfig();
+ WxMaAddOrderRequest request = new WxMaAddOrderRequest();
+ request.setWxStoreId(wxStoreId);
+ request.setStoreOrderId("store-order-" + System.currentTimeMillis());
+ request.setOrderSeq("0001");
+ request.setUserOpenid(config.getOpenid());
+ request.setUseSandbox(1);
+ request.setUserName("顺丰同城");
+ request.setUserPhone("13800000138");
+ request.setUserAddress("北京市海淀区学清嘉创大厦A座15层");
+ request.setUserLat(40.01496);
+ request.setUserLng(116.353093);
+ request.setOrderDetailPath("/pages/user-center/order/detail/detail?id=xxx");
+ WxMaAddOrderRequest.Cargo cargo = new WxMaAddOrderRequest.Cargo();
+ cargo.setCargoName("蛋糕");
+ cargo.setCargoType(13);
+ cargo.setCargoNum(1);
+ cargo.setCargoPrice(10000);
+ cargo.setCargoWeight(1000);
+ WxMaAddOrderRequest.ItemDetail detail = new WxMaAddOrderRequest.ItemDetail();
+ detail.setItemName("蛋糕A");
+ detail.setItemPicUrl("https://www.somehost.com/aaa.jpg");
+ detail.setCount(1);
+ List itemList = new ArrayList<>();
+ itemList.add(detail);
+ cargo.setItemList(itemList);
+ request.setCargo(cargo);
+ WxMaAddOrderResponse response = wxService.getIntracityService().addOrder(request);
+ wxOrderId = response.getWxOrderId();
+ logger.debug("创建订单返回 {}, wxOrderId:{}", response, wxOrderId);
+ }
+ WxMaOrder order = wxService.getIntracityService().queryOrderByWxOrderId(wxOrderId);
+ logger.debug("查询订单返回 {}, storeOrderId:{} ", order, order.getStoreOrderId());
+ WxMaOrder order2 =
+ wxService
+ .getIntracityService()
+ .queryOrderByStoreOrderId(wxStoreId, order.getStoreOrderId());
+ logger.debug("查询订单返回 {}, ", order);
+ assertEquals(order2.getWxOrderId(), wxOrderId);
+
+ WxMaCancelOrderResponse cancelOrderResp =
+ wxService.getIntracityService().cancelOrderByWxOrderId(wxOrderId, 1, "不再需要");
+ logger.debug("取消订单返回 {}, 扣费:{} ", cancelOrderResp, cancelOrderResp.getDeductfee());
+
+ try {
+ wxService
+ .getIntracityService()
+ .cancelOrderByStoreOrderId(wxStoreId, order.getStoreOrderId(), 1, "不再需要");
+ fail("重复取消未抛异常,疑似第一次取消未成功");
+ } catch (WxErrorException wxErrorException) {
+ // 订单已经被取消了,重复取消会报错,这里才正常
+ }
+ }
+}
diff --git a/weixin-java-miniapp/src/test/resources/test-config-sample.xml b/weixin-java-miniapp/src/test/resources/test-config-sample.xml
index 7812fc746..5a3272c0f 100644
--- a/weixin-java-miniapp/src/test/resources/test-config-sample.xml
+++ b/weixin-java-miniapp/src/test/resources/test-config-sample.xml
@@ -9,4 +9,9 @@
可以不填写
某个用户的openId
模版消息的模版ID
+ API签名AES密钥【没有开启API签名不要这条】
+ API签名AES密钥的序号【没有开启API签名不要这条】
+ API签名RSA私钥的【没有开启API签名不要这条】
+ API签名RSA私钥的序【没有开启API签名不要这条】
+
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java
index 60304604d..52f8f828c 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java
@@ -1,13 +1,12 @@
package me.chanjar.weixin.open.api;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
+import java.util.concurrent.locks.Lock;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken;
import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken;
-import java.util.concurrent.locks.Lock;
-
/**
* The interface Wx open config storage.
*
@@ -99,9 +98,7 @@ public interface WxOpenConfigStorage {
*/
boolean isComponentAccessTokenExpired();
- /**
- * Expire component access token.
- */
+ /** Expire component access token. */
void expireComponentAccessToken();
/**
@@ -141,6 +138,7 @@ public interface WxOpenConfigStorage {
/**
* http 请求重试间隔
+ *
*
* {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setRetrySleepMillis(int)}
* {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setRetrySleepMillis(int)}
@@ -150,6 +148,7 @@ public interface WxOpenConfigStorage {
/**
* http 请求最大重试次数
+ *
*
* {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setMaxRetryTimes(int)}
* {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setMaxRetryTimes(int)}
@@ -199,7 +198,7 @@ public interface WxOpenConfigStorage {
* 应该是线程安全的
*
* @param componentAccessToken 新的accessToken值
- * @param expiresInSeconds 过期时间,以秒为单位
+ * @param expiresInSeconds 过期时间,以秒为单位
*/
void updateComponentAccessToken(String componentAccessToken, int expiresInSeconds);
@@ -221,7 +220,7 @@ public interface WxOpenConfigStorage {
/**
* Sets authorizer refresh token.
*
- * @param appId the app id
+ * @param appId the app id
* @param authorizerRefreshToken the authorizer refresh token
*/
void setAuthorizerRefreshToken(String appId, String authorizerRefreshToken);
@@ -229,7 +228,7 @@ public interface WxOpenConfigStorage {
/**
* setAuthorizerRefreshToken(String appId, String authorizerRefreshToken) 方法重载方法
*
- * @param appId the app id
+ * @param appId the app id
* @param authorizerRefreshToken the authorizer refresh token
*/
void updateAuthorizerRefreshToken(String appId, String authorizerRefreshToken);
@@ -260,7 +259,7 @@ public interface WxOpenConfigStorage {
/**
* 应该是线程安全的
*
- * @param appId the app id
+ * @param appId the app id
* @param authorizerAccessToken 要更新的WxAccessToken对象
*/
void updateAuthorizerAccessToken(String appId, WxOpenAuthorizerAccessToken authorizerAccessToken);
@@ -268,11 +267,12 @@ public interface WxOpenConfigStorage {
/**
* 应该是线程安全的
*
- * @param appId the app id
+ * @param appId the app id
* @param authorizerAccessToken 新的accessToken值
- * @param expiresInSeconds 过期时间,以秒为单位
+ * @param expiresInSeconds 过期时间,以秒为单位
*/
- void updateAuthorizerAccessToken(String appId, String authorizerAccessToken, int expiresInSeconds);
+ void updateAuthorizerAccessToken(
+ String appId, String authorizerAccessToken, int expiresInSeconds);
/**
* Gets jsapi ticket.
@@ -300,8 +300,8 @@ public interface WxOpenConfigStorage {
/**
* 应该是线程安全的
*
- * @param appId the app id
- * @param jsapiTicket 新的jsapi ticket值
+ * @param appId the app id
+ * @param jsapiTicket 新的jsapi ticket值
* @param expiresInSeconds 过期时间,以秒为单位
*/
void updateJsapiTicket(String appId, String jsapiTicket, int expiresInSeconds);
@@ -314,7 +314,6 @@ public interface WxOpenConfigStorage {
*/
String getCardApiTicket(String appId);
-
/**
* Is card api ticket expired boolean.
*
@@ -333,8 +332,8 @@ public interface WxOpenConfigStorage {
/**
* 应该是线程安全的
*
- * @param appId the app id
- * @param cardApiTicket 新的cardApi ticket值
+ * @param appId the app id
+ * @param cardApiTicket 新的cardApi ticket值
* @param expiresInSeconds 过期时间,以秒为单位
*/
void updateCardApiTicket(String appId, String cardApiTicket, int expiresInSeconds);
@@ -342,10 +341,34 @@ public interface WxOpenConfigStorage {
/**
* 设置第三方平台基础信息
*
- * @param componentAppId 第三方平台 appid
+ * @param componentAppId 第三方平台 appid
* @param componentAppSecret 第三方平台 appsecret
- * @param componentToken 消息校验Token
- * @param componentAesKey 消息加解密Key
+ * @param componentToken 消息校验Token
+ * @param componentAesKey 消息加解密Key
*/
- void setWxOpenInfo(String componentAppId, String componentAppSecret, String componentToken, String componentAesKey);
+ void setWxOpenInfo(
+ String componentAppId,
+ String componentAppSecret,
+ String componentToken,
+ String componentAesKey);
+
+ /** 第三方平台设置API签名 RSA 私钥 */
+ String getComponentApiSignatureRsaPrivateKey();
+
+ void setComponentApiSignatureRsaPrivateKey(String apiSignatureRsaPrivateKey);
+
+ /** 第三方平台设置API签名 AES KEY */
+ String getComponentApiSignatureAesKey();
+
+ void setComponentApiSignatureAesKey(String apiSignatureAesKey);
+
+ /** 第三方平台设置API签名 RSA 私钥 序号 */
+ String getComponentApiSignatureRsaPrivateKeySn();
+
+ void setComponentApiSignatureRsaPrivateKeySn(String apiSignatureRsaPrivateKeySn);
+
+ /** 第三方平台设置API签名 AES key 序号 */
+ String getComponentApiSignatureAesKeySn();
+
+ void setComponentApiSignatureAesKeySn(String apiSignatureAesKeySn);
}
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java
index 43a351100..a103315b5 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java
@@ -1,7 +1,11 @@
package me.chanjar.weixin.open.api.impl;
-
import cn.binarywang.wx.miniapp.config.WxMaConfig;
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
@@ -16,12 +20,6 @@ import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken;
import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken;
import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder;
-import java.io.File;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
/**
* 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化
*
@@ -37,26 +35,36 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
private String componentAccessToken;
private long componentExpiresTime;
+ private String componentApiSignatureRsaPrivateKey;
+ private String componentApiSignatureAesKey;
+ private String componentApiSignatureRsaPrivateKeySn;
+ private String componentApiSignatureAesKeySn;
+
private String httpProxyHost;
private int httpProxyPort;
private String httpProxyUsername;
private String httpProxyPassword;
+
/**
* http 请求重试间隔
+ *
*
* {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setRetrySleepMillis(int)}
* {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setRetrySleepMillis(int)}
*
*/
private int retrySleepMillis = 1000;
+
/**
* http 请求最大重试次数
+ *
*
* {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setMaxRetryTimes(int)}
* {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setMaxRetryTimes(int)}
*
*/
private int maxRetryTimes = 5;
+
private ApacheHttpClientBuilder apacheHttpClientBuilder;
private Map authorizerRefreshTokens = new ConcurrentHashMap<>();
@@ -77,7 +85,8 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
@Override
public void updateComponentAccessToken(WxOpenComponentAccessToken componentAccessToken) {
- updateComponentAccessToken(componentAccessToken.getComponentAccessToken(), componentAccessToken.getExpiresIn());
+ updateComponentAccessToken(
+ componentAccessToken.getComponentAccessToken(), componentAccessToken.getExpiresIn());
}
private Lock accessTokenLockInstance;
@@ -126,8 +135,11 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
}
@Override
- public void setWxOpenInfo(String componentAppId, String componentAppSecret, String componentToken,
- String componentAesKey) {
+ public void setWxOpenInfo(
+ String componentAppId,
+ String componentAppSecret,
+ String componentToken,
+ String componentAesKey) {
setComponentAppId(componentAppId);
setComponentAppSecret(componentAppSecret);
setComponentToken(componentToken);
@@ -141,7 +153,8 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
private String getTokenString(Map map, String key) {
Token token = map.get(key);
- if (token == null || (token.expiresTime != null && System.currentTimeMillis() > token.expiresTime)) {
+ if (token == null
+ || (token.expiresTime != null && System.currentTimeMillis() > token.expiresTime)) {
return null;
}
return token.token;
@@ -154,7 +167,8 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
}
}
- private void updateToken(Map map, String key, String tokenString, Integer expiresInSeconds) {
+ private void updateToken(
+ Map map, String key, String tokenString, Integer expiresInSeconds) {
Token token = map.get(key);
if (token == null) {
token = new Token();
@@ -186,7 +200,6 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
return getTokenString(authorizerAccessTokens, appId);
}
-
@Override
public boolean isAuthorizerAccessTokenExpired(String appId) {
return getTokenString(authorizerAccessTokens, appId) == null;
@@ -198,13 +211,17 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
}
@Override
- public void updateAuthorizerAccessToken(String appId, WxOpenAuthorizerAccessToken authorizerAccessToken) {
- updateAuthorizerAccessToken(appId, authorizerAccessToken.getAuthorizerAccessToken(),
- authorizerAccessToken.getExpiresIn());
+ public void updateAuthorizerAccessToken(
+ String appId, WxOpenAuthorizerAccessToken authorizerAccessToken) {
+ updateAuthorizerAccessToken(
+ appId,
+ authorizerAccessToken.getAuthorizerAccessToken(),
+ authorizerAccessToken.getExpiresIn());
}
@Override
- public void updateAuthorizerAccessToken(String appId, String authorizerAccessToken, int expiresInSeconds) {
+ public void updateAuthorizerAccessToken(
+ String appId, String authorizerAccessToken, int expiresInSeconds) {
updateToken(authorizerAccessTokens, appId, authorizerAccessToken, expiresInSeconds);
}
@@ -261,21 +278,18 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
private WxMpHostConfig hostConfig;
private String apiHostUrl;
private String accessTokenUrl;
- /**
- * 是否使用稳定版获取accessToken接口
- */
+
+ /** 是否使用稳定版获取accessToken接口 */
@Getter(value = AccessLevel.NONE)
@Setter(value = AccessLevel.NONE)
private boolean useStableAccessToken;
- /**
- * 小程序原始ID
- */
+ /** 小程序原始ID */
private volatile String originalId;
- /**
- * 云环境ID
- */
+
+ /** 云环境ID */
private volatile String cloudEnv;
+
private final Lock accessTokenLock;
private final Lock jsapiTicketLock;
private final Lock cardApiTicketLock;
@@ -326,15 +340,18 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
@Override
public String getTicket(TicketType type) {
switch (type) {
- case JSAPI: {
- return wxOpenConfigStorage.getJsapiTicket(appId);
- }
- case WX_CARD: {
- return wxOpenConfigStorage.getCardApiTicket(appId);
- }
- default: {
- // do nothing
- }
+ case JSAPI:
+ {
+ return wxOpenConfigStorage.getJsapiTicket(appId);
+ }
+ case WX_CARD:
+ {
+ return wxOpenConfigStorage.getCardApiTicket(appId);
+ }
+ default:
+ {
+ // do nothing
+ }
}
return null;
}
@@ -342,15 +359,18 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
@Override
public Lock getTicketLock(TicketType type) {
switch (type) {
- case JSAPI: {
- return this.jsapiTicketLock;
- }
- case WX_CARD: {
- return this.cardApiTicketLock;
- }
- default: {
- // do nothing
- }
+ case JSAPI:
+ {
+ return this.jsapiTicketLock;
+ }
+ case WX_CARD:
+ {
+ return this.cardApiTicketLock;
+ }
+ default:
+ {
+ // do nothing
+ }
}
return null;
}
@@ -358,15 +378,18 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
@Override
public boolean isTicketExpired(TicketType type) {
switch (type) {
- case JSAPI: {
- return wxOpenConfigStorage.isJsapiTicketExpired(appId);
- }
- case WX_CARD: {
- return wxOpenConfigStorage.isCardApiTicketExpired(appId);
- }
- default: {
- // do nothing
- }
+ case JSAPI:
+ {
+ return wxOpenConfigStorage.isJsapiTicketExpired(appId);
+ }
+ case WX_CARD:
+ {
+ return wxOpenConfigStorage.isCardApiTicketExpired(appId);
+ }
+ default:
+ {
+ // do nothing
+ }
}
return false;
@@ -375,36 +398,41 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
@Override
public void expireTicket(TicketType type) {
switch (type) {
- case JSAPI: {
- wxOpenConfigStorage.expireJsapiTicket(appId);
- break;
- }
- case WX_CARD: {
- wxOpenConfigStorage.expireCardApiTicket(appId);
- break;
- }
- default: {
- // do nothing
- }
+ case JSAPI:
+ {
+ wxOpenConfigStorage.expireJsapiTicket(appId);
+ break;
+ }
+ case WX_CARD:
+ {
+ wxOpenConfigStorage.expireCardApiTicket(appId);
+ break;
+ }
+ default:
+ {
+ // do nothing
+ }
}
}
@Override
public void updateTicket(TicketType type, String ticket, int expiresInSeconds) {
switch (type) {
- case JSAPI: {
- wxOpenConfigStorage.updateJsapiTicket(appId, ticket, expiresInSeconds);
- break;
- }
- case WX_CARD: {
- wxOpenConfigStorage.updateCardApiTicket(appId, ticket, expiresInSeconds);
- break;
- }
- default: {
- // do nothing
- }
+ case JSAPI:
+ {
+ wxOpenConfigStorage.updateJsapiTicket(appId, ticket, expiresInSeconds);
+ break;
+ }
+ case WX_CARD:
+ {
+ wxOpenConfigStorage.updateCardApiTicket(appId, ticket, expiresInSeconds);
+ break;
+ }
+ default:
+ {
+ // do nothing
+ }
}
-
}
@Override
@@ -510,12 +538,35 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
return 0;
}
-
@Override
public String getAesKey() {
return wxOpenConfigStorage.getComponentAesKey();
}
+ @Override
+ public String getApiSignatureRsaPrivateKey() {
+ return wxOpenConfigStorage.getComponentApiSignatureRsaPrivateKey();
+ }
+
+ @Override
+ public String getApiSignatureAesKey() {
+ return wxOpenConfigStorage.getComponentApiSignatureAesKey();
+ }
+
+ public String getApiSignatureRsaPrivateKeySn() {
+ return wxOpenConfigStorage.getComponentApiSignatureRsaPrivateKeySn();
+ }
+
+ @Override
+ public String getApiSignatureAesKeySn() {
+ return wxOpenConfigStorage.getComponentApiSignatureAesKeySn();
+ }
+
+ @Override
+ public String getWechatMpAppid() {
+ return wxOpenConfigStorage.getComponentAppId();
+ }
+
@Override
public String getMsgDataFormat() {
return null;