引入 multi-tenant library 并完成初步测试
diff --git a/payapi-sdk/build.gradle b/payapi-sdk/build.gradle
index ecd7869..53c76f1 100644
--- a/payapi-sdk/build.gradle
+++ b/payapi-sdk/build.gradle
@@ -24,8 +24,20 @@
     enabled = false
 }
 
+repositories {
+    maven {
+        url "http://ykt-nx.supwisdom.com/repository/ecard-repo/"
+        credentials {
+            username "${nxUser}"
+            password "${nxPassword}"
+        }
+    }
+}
+
 dependencies {
     implementation project(":payapi-common")
+    implementation "com.supwisdom:multi-tenant-core:${multiTenantLibVersion}"
+    compile "com.supwisdom:multi-tenant-jwt-client:${multiTenantLibVersion}"
 
     implementation "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
     implementation "org.springframework.cloud:spring-cloud-starter-openfeign"
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/ApiLoginHelper.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/ApiLoginHelper.java
index 378bf1b..9c10a7e 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/ApiLoginHelper.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/ApiLoginHelper.java
@@ -4,8 +4,10 @@
 import com.supwisdom.dlpay.api.bean.ApiLoginResponse;
 import com.supwisdom.dlpay.api.util.HMACUtil;
 import com.supwisdom.dlpay.paysdk.proxy.ApiLoginProxy;
-import com.supwisdom.dlpay.paysdk.utils.JwtContext;
 
+/**
+ * @deprecated 1.1
+ */
 public class ApiLoginHelper {
   private ApiLoginProxy apiLoginProxy;
 
@@ -37,7 +39,6 @@
     if (login.getRetcode() != 0) {
       throw new RuntimeException("登录错误: " + loginInit.getRetcode() + ", " + loginInit.getException());
     }
-    JwtContext.setJwt(login.getJwt());
   }
 
   public void refresh() {
@@ -45,6 +46,5 @@
     if (response.getRetcode() != 0) {
       throw new RuntimeException("刷新JWT错误: " + response.getRetcode() + ", " + response.getException());
     }
-    JwtContext.setJwt(response.getJwt());
   }
 }
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/MultiTenantAutoConfig.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/MultiTenantAutoConfig.java
deleted file mode 100644
index f849cea..0000000
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/MultiTenantAutoConfig.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.supwisdom.dlpay.paysdk;
-
-import com.supwisdom.dlpay.paysdk.tenant.DefaultMultiTenantProviderFactory;
-import com.supwisdom.dlpay.paysdk.tenant.MultiTenantProviderFactory;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-public class MultiTenantAutoConfig {
-  @Bean
-  @ConditionalOnMissingBean(MultiTenantProviderFactory.class)
-  public MultiTenantProviderFactory defaultFactory() {
-    return new DefaultMultiTenantProviderFactory();
-  }
-}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/PayAPIRequestInterceptor.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/PayAPIRequestInterceptor.java
index 0a11f39..604d9ff 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/PayAPIRequestInterceptor.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/PayAPIRequestInterceptor.java
@@ -1,40 +1,40 @@
 package com.supwisdom.dlpay.paysdk;
 
-import com.supwisdom.dlpay.paysdk.tenant.MultiTenantProviderFactory;
 import com.supwisdom.dlpay.paysdk.utils.Constants;
-import com.supwisdom.dlpay.paysdk.utils.JwtContext;
+import com.supwisdom.mutlitenant.client.JwtTokenClientManager;
+import com.supwisdom.mutlitenant.client.JwtTokenMetadata;
+import com.supwisdom.mutlitenant.client.config.JwtTenantAuthentication;
 import feign.RequestInterceptor;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.stereotype.Component;
 
+import java.util.Optional;
+
 @Component
 public class PayAPIRequestInterceptor {
 
+  private final JwtTokenClientManager manager;
+
+  public PayAPIRequestInterceptor(JwtTokenClientManager manager) {
+    this.manager = manager;
+  }
+
   @Value("${payapi.tenantid:}")
   private String tenantid;
 
-  private final MultiTenantProviderFactory tenantProviderFactory;
-
-  public PayAPIRequestInterceptor(MultiTenantProviderFactory tenantProviderFactory) {
-    this.tenantProviderFactory = tenantProviderFactory;
-  }
 
   @Bean
   public RequestInterceptor headerInterceptor() {
     return requestTemplate -> {
-      // 小示例,没什么卵用
-      String tenant;
-      if (tenantid != null || "".equals(tenantid)) {
-        tenant = tenantProviderFactory.getProvider().getCurrentTenant();
-      } else {
-        tenant = tenantid;
-      }
-      requestTemplate.header(Constants.HEADER_TENANT_ID, tenant);
-      String jwt = JwtContext.getJwt();
-      if (jwt != null) {
-        requestTemplate.header(Constants.JWT_HEADER, "Bearer " + jwt);
-      }
+      Optional<JwtTenantAuthentication> authentication = manager.currentContextTenantAuthentication();
+      requestTemplate.header(Constants.HEADER_TENANT_ID, tenantid);
+      authentication.ifPresent(jwtTenantAuthentication ->
+          requestTemplate.header(Constants.HEADER_TENANT_ID, jwtTenantAuthentication.getTenantId()));
+
+      Optional<JwtTokenMetadata> metadata = manager.currentContextJwtTokenMetadata();
+      metadata.ifPresent(jwtTokenMetadata -> requestTemplate.header(jwtTokenMetadata.getHttpHeader(),
+          jwtTokenMetadata.getSchema() + " " + jwtTokenMetadata.getToken()));
     };
   }
 }
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/PayAPISDKConfigure.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/PayAPISDKConfigure.java
new file mode 100644
index 0000000..a4d6790
--- /dev/null
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/PayAPISDKConfigure.java
@@ -0,0 +1,24 @@
+package com.supwisdom.dlpay.paysdk;
+
+import com.supwisdom.dlpay.paysdk.impl.PaySDKJwtTokenCallback;
+import com.supwisdom.dlpay.paysdk.proxy.ApiLoginProxy;
+import com.supwisdom.mutlitenant.client.JwtTokenClientCallback;
+import com.supwisdom.mutlitenant.client.annotations.EnableTenantJwtClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.DependsOn;
+import org.springframework.stereotype.Component;
+
+@Component
+@EnableTenantJwtClient
+public class PayAPISDKConfigure {
+  @Bean
+  public JwtTokenClientCallback jwtTokenClientCallback(ApiLoginProxy loginProxy) {
+    return new PaySDKJwtTokenCallback(loginProxy);
+  }
+
+  @Bean
+  @DependsOn("jwtTokenClientCallback")
+  public PayApiJwtClientConfigure jwtClientConfigure(JwtTokenClientCallback callback) {
+    return new PayApiJwtClientConfigure(callback);
+  }
+}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/PayApiJwtClientConfigure.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/PayApiJwtClientConfigure.java
new file mode 100644
index 0000000..125fb10
--- /dev/null
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/PayApiJwtClientConfigure.java
@@ -0,0 +1,18 @@
+package com.supwisdom.dlpay.paysdk;
+
+import com.supwisdom.mutlitenant.client.JwtClientConfigure;
+import com.supwisdom.mutlitenant.client.JwtClientConfigureAdapter;
+import com.supwisdom.mutlitenant.client.JwtTokenClientCallback;
+
+public class PayApiJwtClientConfigure implements JwtClientConfigureAdapter {
+  private final JwtTokenClientCallback callback;
+
+  public PayApiJwtClientConfigure(JwtTokenClientCallback callback) {
+    this.callback = callback;
+  }
+
+  @Override
+  public void configure(JwtClientConfigure configure) {
+    configure.registerCallback(callback);
+  }
+}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/impl/PaySDKJwtTokenCallback.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/impl/PaySDKJwtTokenCallback.java
new file mode 100644
index 0000000..8719384
--- /dev/null
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/impl/PaySDKJwtTokenCallback.java
@@ -0,0 +1,61 @@
+package com.supwisdom.dlpay.paysdk.impl;
+
+import com.supwisdom.dlpay.api.bean.ApiLoginInitResponse;
+import com.supwisdom.dlpay.api.bean.ApiLoginResponse;
+import com.supwisdom.dlpay.api.util.HMACUtil;
+import com.supwisdom.dlpay.paysdk.proxy.ApiLoginProxy;
+import com.supwisdom.dlpay.paysdk.utils.Constants;
+import com.supwisdom.mutlitenant.client.JwtTokenClientCallback;
+import com.supwisdom.mutlitenant.client.JwtTokenMetadata;
+import com.supwisdom.mutlitenant.client.config.JwtTenantAuthentication;
+import org.springframework.util.StringUtils;
+
+import java.time.Instant;
+import java.util.Optional;
+
+public class PaySDKJwtTokenCallback implements JwtTokenClientCallback {
+  private final ApiLoginProxy apiLoginProxy;
+
+  public PaySDKJwtTokenCallback(ApiLoginProxy apiLoginProxy) {
+    this.apiLoginProxy = apiLoginProxy;
+
+  }
+
+  private Optional<JwtTokenMetadata> getTokenResponse(ApiLoginResponse response) {
+    if (response.getRetcode() != 0) {
+      throw new RuntimeException("登录错误: " + response.getRetcode() + ", " + response.getException());
+    }
+    Instant expiration = Instant.parse(response.getExpiredAt());
+    return Optional.of(new JwtTokenMetadata(response.getJwt(),
+        Constants.JWT_HEADER, Constants.JWT_SCHEMA, expiration.getEpochSecond()));
+  }
+
+  @Override
+  public Optional<JwtTokenMetadata> execute(JwtTenantAuthentication authentication) {
+    ApiLoginInitResponse loginInit;
+    boolean withClientId = (authentication.getClientId() != null &&
+        !StringUtils.isEmpty(authentication.getClientId()));
+    if (withClientId) {
+      loginInit = apiLoginProxy.loginInitWithClientId(authentication.getAppId(), authentication.getClientId());
+    } else {
+      loginInit = apiLoginProxy.loginInit(authentication.getAppId());
+    }
+    if (loginInit.getRetcode() != 0) {
+      throw new RuntimeException("登录初始化错误: " + loginInit.getRetcode() + ", " + loginInit.getException());
+    }
+    String token = HMACUtil.sha256HMAC(loginInit.getToken(), authentication.getSecret());
+    ApiLoginResponse login;
+    if (withClientId) {
+      login = apiLoginProxy.loginWithClientId(authentication.getAppId(), token, authentication.getClientId());
+    } else {
+      login = apiLoginProxy.login(authentication.getAppId(), token);
+    }
+    return getTokenResponse(login);
+  }
+
+  @Override
+  public Optional<JwtTokenMetadata> refresh(JwtTokenMetadata old) {
+    ApiLoginResponse response = apiLoginProxy.refresh();
+    return getTokenResponse(response);
+  }
+}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ApiLoginProxy.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ApiLoginProxy.java
index f564a00..c8b8761 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ApiLoginProxy.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ApiLoginProxy.java
@@ -2,6 +2,7 @@
 
 import com.supwisdom.dlpay.api.bean.ApiLoginInitResponse;
 import com.supwisdom.dlpay.api.bean.ApiLoginResponse;
+import com.supwisdom.mutlitenant.client.annotations.JwtMethod;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -25,5 +26,6 @@
                                      @PathVariable(value = "clientid") String clientid);
 
   @RequestMapping(value = "/api/auth/refresh", method = RequestMethod.GET)
+  @JwtMethod
   ApiLoginResponse refresh();
 }
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/CitizenCardPayProxy.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/CitizenCardPayProxy.java
index d68a238..ee873d9 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/CitizenCardPayProxy.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/CitizenCardPayProxy.java
@@ -3,6 +3,7 @@
 import com.supwisdom.dlpay.api.bean.CitizenCardPayfinishParam;
 import com.supwisdom.dlpay.api.bean.CitizenCardPayinitParam;
 import com.supwisdom.dlpay.api.bean.CitizenPayResponse;
+import com.supwisdom.mutlitenant.client.annotations.JwtMethod;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -13,8 +14,10 @@
 @FeignClient(value = "citizenCardPay", url = "${payapi.url}")
 public interface CitizenCardPayProxy {
   @RequestMapping(value = "/api/consume/citizencard/payinit", method = RequestMethod.GET)
+  @JwtMethod
   CitizenPayResponse citizencardPayinit(@RequestBody CitizenCardPayinitParam param);
 
   @RequestMapping(value = "/api/consume/citizencard/payfinish", method = RequestMethod.GET)
+  @JwtMethod
   CitizenPayResponse citizencardPayFinish(@RequestBody CitizenCardPayfinishParam param);
 }
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ConsumePropxy.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ConsumePropxy.java
index 62584f7..dc287f3 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ConsumePropxy.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ConsumePropxy.java
@@ -1,6 +1,7 @@
 package com.supwisdom.dlpay.paysdk.proxy;
 
 import com.supwisdom.dlpay.api.bean.*;
+import com.supwisdom.mutlitenant.client.annotations.JwtMethod;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -11,17 +12,22 @@
 public interface ConsumePropxy {
 
     @PostMapping("/qrcode/init")
+    @JwtMethod
     QrcodePayResponse qrcodePayInit(@RequestBody QrcodePayParam param);
 
     @PostMapping("/qrcode/confirm")
+    @JwtMethod
     QrcodePayResponse  qrcodePayConfirm(@RequestBody QrcodePayParam param);
 
     @PostMapping("/thirdpay/init")
+    @JwtMethod
     ThirdPayResponse thirdpayInit(@RequestBody ThirdPayinitParam param);
 
     @PostMapping("/thirdpay/finish")
+    @JwtMethod
     ThirdPayResponse thirdpayFinish(@RequestBody ThirdPayfinishParam param);
 
     @PostMapping("/qrcodequery")
+    @JwtMethod
     DoorQrcodeResponse qrcodequery(@RequestBody DoorQRCodeParam param);
 }
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ShopProxy.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ShopProxy.java
index 4562fa2..87f20e9 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ShopProxy.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ShopProxy.java
@@ -4,6 +4,7 @@
 import com.supwisdom.dlpay.api.bean.OpenShopParam;
 import com.supwisdom.dlpay.api.bean.QueryShopParam;
 import com.supwisdom.dlpay.api.bean.ShopResponse;
+import com.supwisdom.mutlitenant.client.annotations.JwtMethod;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -14,11 +15,14 @@
 @RequestMapping("/api/shop")
 public interface ShopProxy {
   @PostMapping("/open")
+  @JwtMethod
   ShopResponse openAccount(@RequestBody OpenShopParam param);
 
   @GetMapping("/query")
+  @JwtMethod
   ShopResponse queryShop(@RequestBody QueryShopParam param);
 
   @PostMapping("/downloadshopbill")
+  @JwtMethod
   String downloadShopBill(@RequestBody DownloadShopBillParam param);
 }
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/TransactionProxy.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/TransactionProxy.java
index 712fcd3..087936e 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/TransactionProxy.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/TransactionProxy.java
@@ -1,6 +1,7 @@
 package com.supwisdom.dlpay.paysdk.proxy;
 
 import com.supwisdom.dlpay.api.bean.*;
+import com.supwisdom.mutlitenant.client.annotations.JwtMethod;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -8,17 +9,22 @@
 @FeignClient(name = "payTransactionProxy", url = "${payapi.url}")
 public interface TransactionProxy {
   @PostMapping("/api/consume/paycancel")
+  @JwtMethod
   PayReverseResponse payCancel(@RequestBody ConsumePayCancelParam param);
 
   @PostMapping("/api/consume/payrefund")
+  @JwtMethod
   PayReverseResponse payRefund(@RequestBody ConsumePayRefundParam param);
 
   @PostMapping("/api/consume/queryresult")
+  @JwtMethod
   QueryTransDtlResponse queryDtlResult(@RequestBody QueryDtlResultParam param);
 
   @PostMapping("/api/deposit/merchant/init")
+  @JwtMethod
   MerchantDepositResponse depositInit(@RequestBody MerchantDepositParam param);
 
   @PostMapping("/api/deposit/merchant/confirm")
+  @JwtMethod
   MerchantDepositResponse depositConfirm(@RequestBody MerchantDepositParam param);
 }
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/UserProxy.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/UserProxy.java
index 7a17aec..7ba2336 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/UserProxy.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/UserProxy.java
@@ -1,41 +1,53 @@
 package com.supwisdom.dlpay.paysdk.proxy;
 
 import com.supwisdom.dlpay.api.bean.*;
+import com.supwisdom.mutlitenant.client.annotations.JwtMethod;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.*;
 
 @FeignClient(value = "userProxy", url = "${payapi.url}")
 public interface UserProxy {
   @PostMapping("/api/user/open")
+  @JwtMethod
   UserResponse openAccount(@RequestBody OpenUserParam param);
 
   @PostMapping("/api/user/query")
+  @JwtMethod
   UserResponse queryAccount(@RequestBody QueryUserParam param);
 
   @PostMapping("/api/user/modify")
+  @JwtMethod
   UserResponse modifyAccount(@RequestBody ModifyUserParam param);
 
   @PostMapping("/api/user/querybycardno")
+  @JwtMethod
   UserInforResponse querybycardno(@RequestBody QueryUserParam param);
 
   @PostMapping("/api/user/querycards")
+  @JwtMethod
   CardsResponse querycards(@RequestBody QueryCardsParam param);
 
   @PostMapping("/api/user/testmsg")
+  @JwtMethod
   ApiResponse testmsg();
 
   @PostMapping("/api/user/biz_init")
+  @JwtMethod
   CardBizResponse bizInit(@RequestBody CardBizParam param);
 
   @PostMapping("/api/user/biz_confirm")
+  @JwtMethod
   CardBizResponse bizConfirm(@RequestBody CardBizParam param);
 
   @PostMapping("/api/user/biz_refund_init")
+  @JwtMethod
   CardBizResponse bizRefundInit(@RequestBody CardBizRefundParam param);
 
   @PostMapping("/api/user/biz_refund")
+  @JwtMethod
   CardBizResponse bizRefund(String refno);
 
   @RequestMapping(value = "/api/user/biz_query", method = RequestMethod.GET)
+  @JwtMethod
   CardBizResponse bizQuery(@RequestParam("refno") String refno);
 }
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/YktPayProxy.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/YktPayProxy.java
index 46d967c..fa44fc8 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/YktPayProxy.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/YktPayProxy.java
@@ -2,6 +2,7 @@
 
 import com.supwisdom.dlpay.api.bean.CitizenCardPayfinishParam;
 import com.supwisdom.dlpay.api.bean.YktCardPayinitParam;
+import com.supwisdom.mutlitenant.client.annotations.JwtMethod;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -12,8 +13,10 @@
 @FeignClient(name = "yktPayProxy", url = "${payapi.url}")
 public interface YktPayProxy {
   @PostMapping("/api/consume/ykt/payinit")
+  @JwtMethod
   ResponseEntity<Map<String, String>> yktPayInit(@RequestBody YktCardPayinitParam param);
 
   @PostMapping("/api/consume/ykt/payfinish")
+  @JwtMethod
   ResponseEntity<Map<String, String>> yktPayFinish(@RequestBody CitizenCardPayfinishParam param);
 }
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/tenant/DefaultMultiTenantProvider.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/tenant/DefaultMultiTenantProvider.java
deleted file mode 100644
index 95dd221..0000000
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/tenant/DefaultMultiTenantProvider.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.supwisdom.dlpay.paysdk.tenant;
-
-public class DefaultMultiTenantProvider implements MultiTenantProvider {
-  @Override
-  public String getCurrentTenant() {
-    return "{tenantid}";
-  }
-}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/tenant/DefaultMultiTenantProviderFactory.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/tenant/DefaultMultiTenantProviderFactory.java
deleted file mode 100644
index 0b42fa3..0000000
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/tenant/DefaultMultiTenantProviderFactory.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.supwisdom.dlpay.paysdk.tenant;
-
-public class DefaultMultiTenantProviderFactory implements MultiTenantProviderFactory {
-  private MultiTenantProvider provider = new DefaultMultiTenantProvider();
-
-  public MultiTenantProvider getProvider() {
-    return provider;
-  }
-}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/tenant/MultiTenantProvider.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/tenant/MultiTenantProvider.java
deleted file mode 100644
index 5db786c..0000000
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/tenant/MultiTenantProvider.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.supwisdom.dlpay.paysdk.tenant;
-
-public interface MultiTenantProvider {
-  String getCurrentTenant();
-}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/tenant/MultiTenantProviderFactory.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/tenant/MultiTenantProviderFactory.java
deleted file mode 100644
index bc137c7..0000000
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/tenant/MultiTenantProviderFactory.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.supwisdom.dlpay.paysdk.tenant;
-
-public interface MultiTenantProviderFactory {
-  MultiTenantProvider getProvider();
-}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/utils/Constants.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/utils/Constants.java
index f3dae03..1384897 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/utils/Constants.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/utils/Constants.java
@@ -3,4 +3,5 @@
 public class Constants {
   public static final String HEADER_TENANT_ID = "X-TENANT-ID";
   public static final String JWT_HEADER = "Authorization";
+  public static final String JWT_SCHEMA = "Bearer";
 }
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/utils/JwtContext.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/utils/JwtContext.java
deleted file mode 100644
index 0bd07ef..0000000
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/utils/JwtContext.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.supwisdom.dlpay.paysdk.utils;
-
-public class JwtContext {
-  private static String jwt;
-
-  public static String getJwt() {
-    synchronized (JwtContext.class) {
-      return jwt;
-    }
-  }
-
-  public static void setJwt(String j) {
-    synchronized (JwtContext.class) {
-      jwt = j;
-    }
-  }
-}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/utils/Utils.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/utils/Utils.java
deleted file mode 100644
index 27b15a0..0000000
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/utils/Utils.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.supwisdom.dlpay.paysdk.utils;
-
-public class Utils {
-
-}
diff --git a/payapi-sdk/src/main/resources/META-INF/spring.factories b/payapi-sdk/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..91aa77c
--- /dev/null
+++ b/payapi-sdk/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  com.supwisdom.dlpay.paysdk.PayAPISDKConfigure
\ No newline at end of file
diff --git a/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/APITestConfig.java b/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/APITestConfig.java
new file mode 100644
index 0000000..f8d2605
--- /dev/null
+++ b/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/APITestConfig.java
@@ -0,0 +1,12 @@
+package com.supwisdom.dlpay.paysdktest;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class APITestConfig {
+  @Bean
+  public TestJwtClientConfigure testJwtClientConfigure() {
+    return new TestJwtClientConfigure();
+  }
+}
diff --git a/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/CitizenCardPayProxyTest.java b/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/CitizenCardPayProxyTest.java
index 231a684..7d47710 100644
--- a/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/CitizenCardPayProxyTest.java
+++ b/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/CitizenCardPayProxyTest.java
@@ -5,6 +5,8 @@
 import com.supwisdom.dlpay.api.util.DateUtil;
 import com.supwisdom.dlpay.paysdk.ApiLoginHelper;
 import com.supwisdom.dlpay.paysdk.proxy.*;
+import com.supwisdom.mutlitenant.client.annotations.EnableTenantJwtClient;
+import com.supwisdom.mutlitenant.client.config.JwtTenantAuthentication;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -31,8 +33,9 @@
     classes = CitizenCardPayProxyTest.class)
 @ImportAutoConfiguration({RibbonAutoConfiguration.class,
     FeignRibbonClientAutoConfiguration.class, FeignAutoConfiguration.class,
-    HttpMessageConvertersAutoConfiguration.class})
+    HttpMessageConvertersAutoConfiguration.class, APITestConfig.class})
 @EnableFeignClients(basePackages = "com.supwisdom.dlpay.paysdk")
+@EnableTenantJwtClient
 @ComponentScan(basePackages = {"com.supwisdom.dlpay.paysdk"})
 public class CitizenCardPayProxyTest {
   private final static String appid = "700001";
@@ -40,6 +43,9 @@
 
   private final static String operid = "1001";
 
+  public final static JwtTenantAuthentication authentication = new JwtTenantAuthentication(appid, secret,
+      "{tenantid}");
+
   @Autowired
   private ApiLoginProxy apiLoginProxy;
 
@@ -58,9 +64,6 @@
 
   @org.junit.Test
   public void citizencardPayinit() {
-    ApiLoginHelper helper = new ApiLoginHelper(apiLoginProxy);
-    helper.login(appid, secret);
-
     ApiVersionResponse version = apiCommonProxy.apiVersion();
 
     assertThat("get version error " + version.getException(),
@@ -83,8 +86,6 @@
   @Test
   public void openShopAccount() {
 
-    ApiLoginHelper helper = new ApiLoginHelper(apiLoginProxy);
-    helper.login(appid, secret);
     ApiVersionResponse version = apiCommonProxy.apiVersion();
 
     assertThat("get version error " + version.getException(),
@@ -104,8 +105,6 @@
   @Test
   public void openUserAccount() {
 
-    ApiLoginHelper helper = new ApiLoginHelper(apiLoginProxy);
-    helper.login(appid, secret);
     ApiVersionResponse version = apiCommonProxy.apiVersion();
 
     assertThat("get version error " + version.getException(),
@@ -125,8 +124,7 @@
 
   @Test
   public void qrcodeInit() {
-    ApiLoginHelper helper = new ApiLoginHelper(apiLoginProxy);
-    helper.login(appid, secret);
+
     ApiVersionResponse version = apiCommonProxy.apiVersion();
 
     assertThat("get version error " + version.getException(),
@@ -149,8 +147,6 @@
 
   @Test
   public void qrcodePay() {
-    ApiLoginHelper helper = new ApiLoginHelper(apiLoginProxy);
-    helper.login(appid, secret);
     ApiVersionResponse version = apiCommonProxy.apiVersion();
 
     assertThat("get version error " + version.getException(),
@@ -180,8 +176,6 @@
 
   @Test
   public void qrcodeQuery() {
-    ApiLoginHelper helper = new ApiLoginHelper(apiLoginProxy);
-    helper.login(appid, secret);
     DoorQRCodeParam param = new DoorQRCodeParam();
     param.setQrcode("6M4I1KGUO_UOVJVYCW52FQ");
 
@@ -204,8 +198,6 @@
 
   @Test
   public void testmsg() {
-    ApiLoginHelper helper = new ApiLoginHelper(apiLoginProxy);
-    helper.login(appid, secret);
     ApiResponse response = userProxy.testmsg();
     assertThat("test msg " + response.getRetmsg() + response.getException(),
         response.getRetcode(), equalTo(0));
@@ -213,8 +205,7 @@
 
   @Test
   public void queryCards() {
-    ApiLoginHelper helper = new ApiLoginHelper(apiLoginProxy);
-    helper.login(appid, secret);
+
     QueryCardsParam param = new QueryCardsParam();
     param.setStarttime("20190724100001");
     param.setEndtime("20190826100001");
@@ -231,8 +222,6 @@
 
   @Test
   public void testPublishCard() {
-    ApiLoginHelper helper = new ApiLoginHelper(apiLoginProxy);
-    helper.login(appid, secret);
 
     CardBizParam param = new CardBizParam();
     param.setTransdate(DateUtil.getNow("yyyyMMdd"));
diff --git a/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/MultiTenantProxyTest.java b/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/MultiTenantProxyTest.java
deleted file mode 100644
index 45b1b4c..0000000
--- a/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/MultiTenantProxyTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.supwisdom.dlpay.paysdktest;
-
-import com.supwisdom.dlpay.paysdk.ApiLoginHelper;
-import com.supwisdom.dlpay.paysdk.proxy.ApiLoginProxy;
-import com.supwisdom.dlpay.paysdk.tenant.MultiTenantProvider;
-import com.supwisdom.dlpay.paysdk.tenant.MultiTenantProviderFactory;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
-import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
-import org.springframework.cloud.openfeign.EnableFeignClients;
-import org.springframework.cloud.openfeign.FeignAutoConfiguration;
-import org.springframework.cloud.openfeign.ribbon.FeignRibbonClientAutoConfiguration;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Primary;
-import org.springframework.test.context.junit4.SpringRunner;
-
-@RunWith(SpringRunner.class)
-//@SpringBootTest(properties = {
-//    "payapi.url=http://localhost:8080/payapi"},
-//    classes = MultiTenantProxyTest.class)
-@ImportAutoConfiguration({RibbonAutoConfiguration.class,
-    FeignRibbonClientAutoConfiguration.class, FeignAutoConfiguration.class,
-    HttpMessageConvertersAutoConfiguration.class})
-@EnableFeignClients(basePackages = "com.supwisdom.dlpay.paysdk")
-@ComponentScan(basePackages = {"com.supwisdom.dlpay.paysdk"})
-public class MultiTenantProxyTest {
-
-  @Autowired
-  private ApiLoginProxy apiLoginProxy;
-
-  private final static String appid = "700001";
-  private final static String secret = "d6dd7f0d4551419d8d11736d0f28df0d";
-
-
-  @TestConfiguration
-  static class MultiTenantTestBean {
-    @Bean
-    @Primary
-    public MultiTenantProviderFactory newProviderFactory() {
-      return () -> (MultiTenantProvider) () -> "122020";
-    }
-  }
-
-
-  @Test
-  public void testMultiTenant() {
-    ApiLoginHelper helper = new ApiLoginHelper(apiLoginProxy);
-    helper.login(appid, secret);
-  }
-}
diff --git a/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/TestJwtClientConfigure.java b/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/TestJwtClientConfigure.java
new file mode 100644
index 0000000..15c2c2b
--- /dev/null
+++ b/payapi-sdk/src/test/java/com/supwisdom/dlpay/paysdktest/TestJwtClientConfigure.java
@@ -0,0 +1,11 @@
+package com.supwisdom.dlpay.paysdktest;
+
+import com.supwisdom.mutlitenant.client.JwtClientConfigure;
+import com.supwisdom.mutlitenant.client.JwtClientConfigureAdapter;
+
+public class TestJwtClientConfigure implements JwtClientConfigureAdapter {
+  @Override
+  public void configure(JwtClientConfigure configure) {
+    configure.withAuthenication(CitizenCardPayProxyTest.authentication);
+  }
+}