refactor: 优化重构 payapi-sdk
diff --git a/payapi-sdk/build.gradle b/payapi-sdk/build.gradle
index af9e76f..3523c69 100644
--- a/payapi-sdk/build.gradle
+++ b/payapi-sdk/build.gradle
@@ -57,10 +57,15 @@
     implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:2.1.2.RELEASE'
 
     implementation 'javax.servlet:javax.servlet-api:4.0.1'
+    compileOnly 'org.projectlombok:lombok:1.18.8'
+    annotationProcessor 'org.projectlombok:lombok:1.18.8'
 
     testImplementation 'org.springframework:spring-test'
     testImplementation 'org.springframework.boot:spring-boot-test'
     testImplementation 'junit:junit:4.12'
+    testAnnotationProcessor 'org.projectlombok:lombok:1.18.8'
+    testCompileOnly 'org.projectlombok:lombok:1.18.8'
+    testImplementation 'org.hamcrest:hamcrest:2.1'
     testImplementation project(':common')
 
 }
\ No newline at end of file
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
new file mode 100644
index 0000000..d095603
--- /dev/null
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/ApiLoginHelper.java
@@ -0,0 +1,42 @@
+package com.supwisdom.dlpay.paysdk;
+
+import com.supwisdom.dlpay.paysdk.bean.ApiLoginInitResponse;
+import com.supwisdom.dlpay.paysdk.bean.ApiLoginResponse;
+import com.supwisdom.dlpay.paysdk.proxy.ApiLoginProxy;
+import com.supwisdom.dlpay.paysdk.utils.JwtContext;
+import com.supwisdom.dlpay.paysdk.utils.Utils;
+
+public class ApiLoginHelper {
+  private ApiLoginProxy apiLoginProxy;
+
+  public ApiLoginHelper(ApiLoginProxy apiLoginProxy) {
+    this.apiLoginProxy = apiLoginProxy;
+  }
+
+  public void login(String appid, String secret) {
+    loginWithClientId(appid, null, secret);
+  }
+
+  public void loginWithClientId(String appid, String clientId, String secret) {
+    ApiLoginInitResponse loginInit;
+    if (clientId != null) {
+      loginInit = apiLoginProxy.loginInitWithClientId(appid, clientId);
+    } else {
+      loginInit = apiLoginProxy.loginInit(appid);
+    }
+    if (loginInit.getRetcode() != 0) {
+      throw new RuntimeException("登录初始化错误: " + loginInit.getRetcode() + ", " + loginInit.getException());
+    }
+    String token = Utils.sha256HMAC(loginInit.getToken(), secret);
+    ApiLoginResponse login;
+    if (clientId != null) {
+      login = apiLoginProxy.loginWithClientId(appid, token, clientId);
+    } else {
+      login = apiLoginProxy.login(appid, token);
+    }
+    if (login.getRetcode() != 0) {
+      throw new RuntimeException("登录错误: " + loginInit.getRetcode() + ", " + loginInit.getException());
+    }
+    JwtContext.setJwt(login.getJwt());
+  }
+}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/ApiLoginProxy.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/ApiLoginProxy.java
deleted file mode 100644
index efb2afd..0000000
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/ApiLoginProxy.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.supwisdom.dlpay.paysdk;
-
-import org.springframework.cloud.openfeign.FeignClient;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-
-import javax.servlet.http.HttpServletRequest;
-import java.util.Map;
-
-@FeignClient(value = "apiLoginProxy", url = "${payapi.url}")
-public interface ApiLoginProxy {
-  @RequestMapping(value = "/api/auth/gettoken", method = RequestMethod.GET)
-  ResponseEntity<Map<String, String>> loginInit(@RequestParam("appid") String appid);
-
-  @RequestMapping(value = "/api/auth/gettoken/{clientid}", method = RequestMethod.GET)
-  ResponseEntity<Map<String, String>> loginInitWithClientId(@RequestParam("appid") String appid,
-                                       @PathVariable(value = "clientid") String clientid);
-
-  @RequestMapping(value = "/api/auth/authentication", method = RequestMethod.GET)
-  ResponseEntity<Map<String, String>> login(@RequestParam("appid") String appid, @RequestParam("secret") String secret);
-
-  @RequestMapping(value = "/api/auth/authentication/{clientid}", method = RequestMethod.GET)
-  ResponseEntity<Map<String, String>> loginWithClientId(@RequestParam("appid") String appid, @RequestParam("secret") String secret,
-                                   @PathVariable(value = "clientid") String clientid);
-
-  @RequestMapping(value = "/api/auth/refresh", method = RequestMethod.GET)
-  ResponseEntity<Map<String, String>> refresh(HttpServletRequest request);
-}
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 305c665..1002d52 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,6 +1,7 @@
 package com.supwisdom.dlpay.paysdk;
 
 import com.supwisdom.dlpay.paysdk.utils.Constants;
+import com.supwisdom.dlpay.paysdk.utils.JwtContext;
 import feign.RequestInterceptor;
 import org.springframework.context.annotation.Bean;
 import org.springframework.stereotype.Component;
@@ -12,6 +13,10 @@
     return requestTemplate -> {
       // 小示例,没什么卵用
       requestTemplate.header(Constants.HEADER_TENANT_ID, "{tenantid}");
+      String jwt = JwtContext.getJwt();
+      if (jwt != null) {
+        requestTemplate.header(Constants.JWT_HEADER, "Bearer " + jwt);
+      }
     };
   }
 }
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/bean/ApiLoginInitResponse.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/bean/ApiLoginInitResponse.java
new file mode 100644
index 0000000..405d4ae
--- /dev/null
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/bean/ApiLoginInitResponse.java
@@ -0,0 +1,12 @@
+package com.supwisdom.dlpay.paysdk.bean;
+
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class ApiLoginInitResponse extends ApiResponse {
+  private String timestamp;
+  private String token;
+}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/bean/ApiLoginResponse.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/bean/ApiLoginResponse.java
new file mode 100644
index 0000000..787fe90
--- /dev/null
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/bean/ApiLoginResponse.java
@@ -0,0 +1,13 @@
+package com.supwisdom.dlpay.paysdk.bean;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class ApiLoginResponse extends ApiResponse {
+  private String jwt;
+  private String appid;
+  private String expiredAt;
+
+}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/bean/ApiResponse.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/bean/ApiResponse.java
new file mode 100644
index 0000000..4b18413
--- /dev/null
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/bean/ApiResponse.java
@@ -0,0 +1,13 @@
+package com.supwisdom.dlpay.paysdk.bean;
+
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class ApiResponse {
+  private Integer retcode;
+  private String retmsg;
+  private String exception;
+}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/bean/CitizenPayInitResponse.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/bean/CitizenPayInitResponse.java
new file mode 100644
index 0000000..cf28b8b
--- /dev/null
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/bean/CitizenPayInitResponse.java
@@ -0,0 +1,12 @@
+package com.supwisdom.dlpay.paysdk.bean;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CitizenPayInitResponse extends ApiResponse {
+  private String refno;
+  private String billno;
+  private Double amount;
+}
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
new file mode 100644
index 0000000..f9e5a67
--- /dev/null
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/ApiLoginProxy.java
@@ -0,0 +1,31 @@
+package com.supwisdom.dlpay.paysdk.proxy;
+
+import com.supwisdom.dlpay.paysdk.bean.ApiLoginInitResponse;
+import com.supwisdom.dlpay.paysdk.bean.ApiLoginResponse;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.servlet.http.HttpServletRequest;
+
+@FeignClient(value = "apiLoginProxy", url = "${payapi.url}")
+public interface ApiLoginProxy {
+  @RequestMapping(value = "/api/auth/gettoken", method = RequestMethod.GET)
+  ApiLoginInitResponse loginInit(@RequestParam("appid") String appid);
+
+  @RequestMapping(value = "/api/auth/gettoken/{clientid}", method = RequestMethod.GET)
+  ApiLoginInitResponse loginInitWithClientId(@RequestParam("appid") String appid,
+                                                            @PathVariable(value = "clientid") String clientid);
+
+  @RequestMapping(value = "/api/auth/authentication", method = RequestMethod.GET)
+  ApiLoginResponse login(@RequestParam("appid") String appid, @RequestParam("secret") String secret);
+
+  @RequestMapping(value = "/api/auth/authentication/{clientid}", method = RequestMethod.GET)
+  ApiLoginResponse loginWithClientId(@RequestParam("appid") String appid, @RequestParam("secret") String secret,
+                                                        @PathVariable(value = "clientid") String clientid);
+
+  @RequestMapping(value = "/api/auth/refresh", method = RequestMethod.GET)
+  ApiLoginResponse refresh(HttpServletRequest request);
+}
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/CitizenCardPayProxy.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/CitizenCardPayProxy.java
similarity index 67%
rename from payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/CitizenCardPayProxy.java
rename to payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/CitizenCardPayProxy.java
index c5e38b1..d2e758f 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/CitizenCardPayProxy.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/CitizenCardPayProxy.java
@@ -1,20 +1,18 @@
-package com.supwisdom.dlpay.paysdk;
+package com.supwisdom.dlpay.paysdk.proxy;
 
 import com.supwisdom.dlpay.api.bean.CitizenCardPayfinishParam;
 import com.supwisdom.dlpay.api.bean.CitizenCardPayinitParam;
+import com.supwisdom.dlpay.paysdk.bean.CitizenPayInitResponse;
 import org.springframework.cloud.openfeign.FeignClient;
-import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 
-import java.util.Map;
-
 @FeignClient(value = "citizenCardPay", url = "${payapi.url}")
 public interface CitizenCardPayProxy {
   @RequestMapping(value = "/api/consume/citizencard/payinit", method = RequestMethod.GET)
-  ResponseEntity<Map<String, String>> citizencardPayinit(@RequestBody CitizenCardPayinitParam param);
+  CitizenPayInitResponse citizencardPayinit(@RequestBody CitizenCardPayinitParam param);
 
   @RequestMapping(value = "/api/consume/citizencard/payfinish", method = RequestMethod.GET)
-  ResponseEntity<Map<String, String>> citizencardPayFinish(@RequestBody CitizenCardPayfinishParam param);
+  CitizenPayInitResponse citizencardPayFinish(@RequestBody CitizenCardPayfinishParam param);
 }
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/PayReverseProxy.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/PayReverseProxy.java
similarity index 94%
rename from payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/PayReverseProxy.java
rename to payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/PayReverseProxy.java
index fc2ad65..827e685 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/PayReverseProxy.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/PayReverseProxy.java
@@ -1,4 +1,4 @@
-package com.supwisdom.dlpay.paysdk;
+package com.supwisdom.dlpay.paysdk.proxy;
 
 import com.supwisdom.dlpay.api.bean.ConsumePayCancelParam;
 import com.supwisdom.dlpay.api.bean.ConsumePayRefundParam;
diff --git a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/YktPayProxy.java b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/YktPayProxy.java
similarity index 94%
rename from payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/YktPayProxy.java
rename to payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/YktPayProxy.java
index 238b008..46d967c 100644
--- a/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/YktPayProxy.java
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/proxy/YktPayProxy.java
@@ -1,4 +1,4 @@
-package com.supwisdom.dlpay.paysdk;
+package com.supwisdom.dlpay.paysdk.proxy;
 
 import com.supwisdom.dlpay.api.bean.CitizenCardPayfinishParam;
 import com.supwisdom.dlpay.api.bean.YktCardPayinitParam;
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 ba565ee..f3dae03 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
@@ -2,4 +2,5 @@
 
 public class Constants {
   public static final String HEADER_TENANT_ID = "X-TENANT-ID";
+  public static final String JWT_HEADER = "Authorization";
 }
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
new file mode 100644
index 0000000..0bd07ef
--- /dev/null
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/utils/JwtContext.java
@@ -0,0 +1,17 @@
+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
new file mode 100644
index 0000000..791850d
--- /dev/null
+++ b/payapi-sdk/src/main/java/com/supwisdom/dlpay/paysdk/utils/Utils.java
@@ -0,0 +1,29 @@
+package com.supwisdom.dlpay.paysdk.utils;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+public class Utils {
+  public static String sha256HMAC(String message, String secret) {
+    String hash = "";
+    try {
+      Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
+      SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
+      sha256_HMAC.init(secret_key);
+      byte[] bytes = sha256_HMAC.doFinal(message.getBytes());
+      hash = byteArrayToHexString(bytes);
+      System.out.println(hash);
+    } catch (Exception e) {
+      System.out.println("Error HmacSHA256 ===========" + e.getMessage());
+    }
+    return hash;
+  }
+
+  private static String byteArrayToHexString(byte[] bytes) {
+    StringBuilder builder = new StringBuilder();
+    for (byte b : bytes) {
+      builder.append(String.format("%02x", ((int) b) & 0xFF));
+    }
+    return builder.toString();
+  }
+}
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 76407f5..4838929 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
@@ -1,8 +1,11 @@
 package com.supwisdom.dlpay.paysdktest;
 
 
-import com.supwisdom.dlpay.paysdk.ApiLoginProxy;
-import com.supwisdom.dlpay.paysdk.CitizenCardPayProxy;
+import com.supwisdom.dlpay.api.bean.CitizenCardPayinitParam;
+import com.supwisdom.dlpay.paysdk.ApiLoginHelper;
+import com.supwisdom.dlpay.paysdk.proxy.ApiLoginProxy;
+import com.supwisdom.dlpay.paysdk.proxy.CitizenCardPayProxy;
+import com.supwisdom.dlpay.paysdk.bean.CitizenPayInitResponse;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
@@ -13,9 +16,11 @@
 import org.springframework.cloud.openfeign.FeignAutoConfiguration;
 import org.springframework.cloud.openfeign.ribbon.FeignRibbonClientAutoConfiguration;
 import org.springframework.context.annotation.ComponentScan;
-import org.springframework.http.ResponseEntity;
 import org.springframework.test.context.junit4.SpringRunner;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+
 
 @RunWith(SpringRunner.class)
 @SpringBootTest(properties = {
@@ -28,8 +33,7 @@
 @ComponentScan(basePackages = {"com.supwisdom.dlpay.paysdk"})
 public class CitizenCardPayProxyTest {
   private final static String appid = "700001";
-
-  private final static String tenantId = "{tenant_id}";
+  private final static String secret = "5f788ce433ec44f299351cdf7f137e81";
 
   @Autowired
   private ApiLoginProxy apiLoginProxy;
@@ -39,8 +43,18 @@
 
   @org.junit.Test
   public void citizencardPayinit() {
-    ResponseEntity loginInit = apiLoginProxy.loginInit(appid);
-    System.out.println("Data " + loginInit.getBody());
+    ApiLoginHelper helper = new ApiLoginHelper(apiLoginProxy);
+    helper.login(appid, secret);
+
+    CitizenCardPayinitParam initParam = new CitizenCardPayinitParam();
+    initParam.setBillno("20190708172756000001");
+    initParam.setCardNo("1231231213");
+    initParam.setAmount(100);
+    initParam.setTransdate("20190708");
+    initParam.setTranstime("172713");
+    CitizenPayInitResponse payInit = citizenCardPayProxy.citizencardPayinit(initParam);
+    assertThat("pay initialized " + payInit.getRetmsg() + payInit.getException(),
+        payInit.getRetcode(), equalTo(0));
   }
 
   public static void main(String[] args) {