1
0
فهرست منبع

添加cuspay支付单推送海关模块

zhh 3 سال پیش
والد
کامیت
d77a707095
100فایلهای تغییر یافته به همراه11794 افزوده شده و 0 حذف شده
  1. 64 0
      kmall-admin/pom.xml
  2. 189 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/aop/AspectWebLog.java
  3. 63 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/AbstractCusDeclareBiz.java
  4. 15 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/CuspayBiz.java
  5. 60 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/AliCusDeclareApi.java
  6. 425 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/AliCusDeclareBiz.java
  7. 337 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/AliCusDeclareQueryBiz.java
  8. 44 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/config/AlipayConfig.java
  9. 66 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/sign/MD5.java
  10. 117 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/AlipayCore.java
  11. 123 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/AlipayNotify.java
  12. 219 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/AlipaySubmit.java
  13. 71 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/UtilDate.java
  14. 191 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/httpClient/HttpProtocolHandler.java
  15. 152 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/httpClient/HttpRequest.java
  16. 72 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/httpClient/HttpResponse.java
  17. 27 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/httpClient/HttpResultType.java
  18. 150 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/merch/MerchantNoticeBiz.java
  19. 581 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/wx/WxCusDeclareBiz.java
  20. 383 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/wx/WxCusDeclareQueryBiz.java
  21. 116 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/common/MerchNotiBuilder.java
  22. 40 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/common/ali/AliContants.java
  23. 228 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/common/ali/AliDict.java
  24. 40 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/common/wx/WxContants.java
  25. 237 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/common/wx/WxDict.java
  26. 110 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/ali/AliCusDeclareBizDto.java
  27. 13 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/ali/AliCusDeclareQueryBizDto.java
  28. 53 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/ali/AliCusDeclareRequestDto.java
  29. 75 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/ali/AliQueryResponseMsg.java
  30. 153 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/ali/AliQuerySuccessResponseMsgDto.java
  31. 147 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/ali/AliResponseMsg.java
  32. 147 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/wx/WxQueryResponseMsg.java
  33. 162 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/wx/WxQuerySuccessResponseMsgDto.java
  34. 210 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/wx/WxResponseMsg.java
  35. 596 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/entity/ali/AliCbPayDoc.java
  36. 285 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/entity/ali/AliPayError.java
  37. 442 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/entity/wx/WxCbPayDoc.java
  38. 222 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/entity/wx/WxPayError.java
  39. 53 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/ali/AliCbPayDocService.java
  40. 17 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/ali/AliPayErrorService.java
  41. 129 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/ali/impl/AliCbPayDocServiceImpl.java
  42. 28 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/ali/impl/AliPayErrorServiceImpl.java
  43. 57 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/wx/WxCbPayDocService.java
  44. 17 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/wx/WxPayErrorService.java
  45. 125 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/wx/impl/WxCbPayDocServiceImpl.java
  46. 27 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/wx/impl/WxPayErrorServiceImpl.java
  47. 168 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/common/contant/MerchNoticeDict.java
  48. 21 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/common/contant/TablePrimaryKeyPrefix.java
  49. 147 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/common/core/db/IdWorker.java
  50. 56 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/common/core/db/IdWorkerAide.java
  51. 82 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/common/date/DateTimeDeserializer.java
  52. 34 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/common/date/DateTimeSerializer.java
  53. 46 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/common/msg/RequestMessage.java
  54. 150 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/common/msg/Result.java
  55. 36 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/common/msg/ResultCodeEnum.java
  56. 35 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/config/AspectWebConfiguration.java
  57. 38 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/config/DistributedSystemProperties.java
  58. 81 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/config/db/primary/PrimaryDataSourceConfiguration.java
  59. 41 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/config/db/primary/PrimaryMapperConfiguration.java
  60. 55 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/config/servlet/WebMvcConfiguration.java
  61. 116 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/config/spring/HttpResponseConfig.java
  62. 27 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/config/spring/SpringConfiguration.java
  63. 112 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/entity/merch/MerchCusCfg.java
  64. 303 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/entity/merch/MerchNoti.java
  65. 132 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/entity/merch/MerchPayCfg.java
  66. 29 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/manager/snow/SnowflakeConfiguration.java
  67. 145 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/manager/snow/SnowflakeIdWorker.java
  68. 33 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/manager/snow/SnowflakeUtil.java
  69. 15 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/service/MerchCusService.java
  70. 26 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/service/MerchNotiService.java
  71. 31 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/service/MerchPaymentService.java
  72. 26 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/service/impl/MerchCusServiceImpl.java
  73. 50 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/service/impl/MerchNotiServiceImpl.java
  74. 64 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/service/impl/MerchPaymentServiceImpl.java
  75. 57 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/support/msg/resp/MessageException.java
  76. 246 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/support/msg/resp/ResponseMessage.java
  77. 86 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/support/msg/resp/ResponseMessageData.java
  78. 45 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/support/msg/resp/ResponseStatus.java
  79. 279 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/support/sign/Base64.java
  80. 31 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/support/sign/MD5Util.java
  81. 143 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/support/sign/RSA.java
  82. 23 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/task/AliPayCuspayTask.java
  83. 33 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/task/CuspayTask.java
  84. 152 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/util/Contants.java
  85. 227 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/util/MapBeanUtils.java
  86. 140 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/util/OkHttpUtils.java
  87. 85 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/util/ReaderXmlForDOM4J.java
  88. 114 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/util/SerializeUtils.java
  89. 28 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/util/SpringContextSupport.java
  90. 44 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/util/SysContants.java
  91. 72 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/util/Validator.java
  92. 236 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/util/XmlUtils.java
  93. 23 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/util/date/DateConstant.java
  94. 69 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/util/jackson/JacksonStringUnicodeSerializer.java
  95. 337 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/util/jackson/JacksonUtil.java
  96. 54 0
      kmall-admin/src/main/java/com/kmall/admin/cuspay/web/controller/merch/MerchPaymentController.java
  97. 26 0
      kmall-admin/src/main/java/com/kmall/admin/dao/cuspay/ali/AliCbPayDocMapper.java
  98. 19 0
      kmall-admin/src/main/java/com/kmall/admin/dao/cuspay/ali/AliPayErrorMapper.java
  99. 20 0
      kmall-admin/src/main/java/com/kmall/admin/dao/cuspay/merch/MerchCusCfgMapper.java
  100. 28 0
      kmall-admin/src/main/java/com/kmall/admin/dao/cuspay/merch/MerchNotiMapper.java

+ 64 - 0
kmall-admin/pom.xml

@@ -13,6 +13,10 @@
     <packaging>war</packaging>
     <description>管理后台</description>
 
+    <properties>
+        <jackson-version>2.8.0</jackson-version>
+    </properties>
+
 
     <dependencies>
 
@@ -159,6 +163,66 @@
             <version>1.18.4</version>
         </dependency>
 
+        <!--    jackson相关依赖    -->
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>${jackson-version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.fasterxml.jackson.dataformat</groupId>
+                    <artifactId>jackson-dataformat-xml</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>${jackson-version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.fasterxml.jackson.dataformat</groupId>
+                    <artifactId>jackson-dataformat-xml</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <version>${jackson-version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.fasterxml.jackson.dataformat</groupId>
+                    <artifactId>jackson-dataformat-xml</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-jsr310</artifactId>
+            <version>${jackson-version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.fasterxml.jackson.dataformat</groupId>
+                    <artifactId>jackson-dataformat-xml</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <!--    guava依赖    -->
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>23.3-jre</version>
+        </dependency>
+
+        <!--    dom4j依赖    -->
+        <dependency>
+            <groupId>dom4j</groupId>
+            <artifactId>dom4j</artifactId>
+            <version>1.6.1</version>
+        </dependency>
+
 
     </dependencies>
 

+ 189 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/aop/AspectWebLog.java

@@ -0,0 +1,189 @@
+package com.kmall.admin.cuspay.aop;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.lang.annotation.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * 日志AOP
+ * 通过<code>JoinPoint</code>可以获得通知的签名信息,如目标方法名、目标方法参数信息等
+ * 通过RequestContextHolder来获取<code>HttpServletRequest</code>请求信息,<code>Session</code>Session信息
+ * @author Scott Chen
+ * @since 1.0
+ * 2015-05-13
+ */
+@Component
+@Aspect
+public class AspectWebLog {
+    private static final Logger logger = LoggerFactory.getLogger(AspectWebLog.class);
+
+    @Autowired
+    ObjectMapper objectMapper;
+
+    @Pointcut("execution(* com.kmall.admin.cuspay..*.*(..)) && @annotation(org.springframework.web.bind.annotation.RequestMapping) && !execution(* com.kmall.admin.cuspay..aop..*.*(..))")
+    public void controllerPointcut(){}
+
+    /**
+     * 前置通知
+     * 执行方法之前执行前置通知方法
+     * @param jp:JoinPoint
+     * @return
+     */
+    @Before(value="controllerPointcut()")
+    public void beforeAdvice(JoinPoint jp) {
+        // 目标方法的参数信息
+        Object[] args = jp.getArgs();
+
+        // AOP代理类的信息
+        Object objThis = jp.getThis();
+        // 代理的目标对象
+        Object objTarget = jp.getTarget();
+        // 通知的方法签名
+        Signature signature = jp.getSignature();
+
+        // AOP代理类类型
+        Class proxyClzz = signature.getDeclaringType();
+        // AOP代理类名
+        String className = signature.getDeclaringTypeName();
+        // 代理方法名
+        String methodName = signature.getName();
+
+        // 获取RequestAttributes
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        // 从获取RequestAttributes中获取HttpServletRequest的信息
+        HttpServletRequest request = attributes.getRequest();
+
+        //method
+        logger.debug("--- 请求Method: {}", request.getMethod());
+        //类方法
+        logger.debug("--- 调用class: 【{}】, method: 【{}】", className, methodName);
+
+        try {
+
+            String str = null;
+
+            if (args.length > 0) {
+                if (args[0] instanceof Collection || args[0] instanceof Map) {
+                    str = objectMapper.writeValueAsString(args[0]);
+                } else {
+                    for(int i=0;i<args.length;i++) {
+                        str += objectMapper.writeValueAsString(args[i]);
+                        if (i < args.length - 1) {
+                            str += ", ";
+                        }
+                    }
+                }
+            }
+            logger.debug("【" + className + "#" + methodName + "】发起请求, 请求参数: {}", str);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 环绕通知
+     * 主体方法返回后将执行的通知方法
+     * @param pjp:ProceedingJoinPoint
+     * @return
+     */
+    @Around(value="controllerPointcut()")
+    public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
+        String className = pjp.getSignature().getDeclaringTypeName();
+        String methodName = pjp.getSignature().getName();
+
+        long bftime = System.currentTimeMillis();
+
+        // 继续执行被拦截的方法
+        Object retVal = pjp.proceed();
+        double time = (System.currentTimeMillis() - bftime) / 1000.0D;
+        logger.info("【" + className + "#" + methodName + "】执行时间: {}秒", Double.valueOf(time));
+        return retVal;
+    }
+
+    /**
+     * 后置通知
+     * 执行方法之后执行后置通知方法
+     * @param jp:JoinPoint
+     * @return
+     */
+    @After(value="controllerPointcut()")
+    public void afterAdvice(JoinPoint jp) {
+
+        Object[] args = jp.getArgs();
+        String className = jp.getSignature().getDeclaringTypeName();
+        String methodName = jp.getSignature().getName();
+
+        try {
+
+            String str = null;
+
+            if (args.length > 0) {
+                if (args[0] instanceof Collection || args[0] instanceof Map) {
+                    str = objectMapper.writeValueAsString(args[0]);
+                } else {
+                    for(int i=0;i<args.length;i++) {
+                        str += objectMapper.writeValueAsString(args[i]);
+                        if (i < args.length - 1) {
+                            str += ", ";
+                        }
+                    }
+                }
+            }
+            logger.info("【" + className + "#" + methodName + "】执行结束, 请求参数: {}", str);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    /**
+     * 返回通知
+     * 方法执行成功后,调用返回通知,如果方法在运行过程中抛出异常,则不会调用
+     * @param jp:JoinPoint
+     * @param retValue:String 主体方法传递到通知方法的返回值
+     * @return
+     */
+    @AfterReturning(value="controllerPointcut()", returning = "retValue")
+    public void afterReturningAdvice(JoinPoint jp, Object retValue) {
+        String className = jp.getSignature().getDeclaringTypeName();
+        String methodName = jp.getSignature().getName();
+
+        if (retValue == null) {
+            logger.info("【" + className + "#" + methodName + "】执行结束, 返回数据: {}");
+            return;
+        }
+        try {
+            String str = objectMapper.writeValueAsString(retValue);
+            logger.info("【" + className + "#" + methodName + "】执行结束, 返回数据:{}", str);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 异常通知
+     * 方法在运行过程中,如果抛出异常,则执行异常通知
+     * @param jp:JoinPoint
+     * @return
+     */
+    @AfterThrowing(value="controllerPointcut()", throwing = "ex")
+    public void afterThrowingAdvice(JoinPoint jp, Exception ex) {
+        String className = jp.getSignature().getDeclaringTypeName();
+        String methodName = jp.getSignature().getName();
+        logger.info("【" + className + "#" + methodName + "】发生异常结束: {}", ex);
+    }
+
+}

+ 63 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/AbstractCusDeclareBiz.java

@@ -0,0 +1,63 @@
+package com.kmall.admin.cuspay.biz;
+
+import com.kmall.admin.cuspay.biz.CuspayBiz;
+import com.kmall.admin.cuspay.entity.merch.MerchPayCfg;
+import com.kmall.admin.cuspay.service.MerchPaymentService;
+import com.google.common.collect.Maps;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 加载缓存
+ * @author zx
+ * @version 1.0
+ * 2018-05-23 10:00
+ */
+@Component
+public abstract class AbstractCusDeclareBiz implements CuspayBiz {
+
+    @Autowired
+    private MerchPaymentService paymentService;
+
+    //商户支付信息缓存
+    private Map<String, MerchPayCfg> payCaches = Maps.newHashMap();
+
+    //重新加载缓存
+    @PostConstruct
+    private void reloadPayCaches() {
+        if (this.paymentService == null) {
+            throw new NullPointerException("paymentService is null");
+        }
+        List<MerchPayCfg> list = this.paymentService.loadMerchPayCfg();
+        if (list != null && !list.isEmpty()) {
+            list.forEach(cfg ->{
+                payCaches.put(cfg.getAppid(), cfg);
+            });
+        }
+    }
+
+    //获取商户支付数据
+    protected MerchPayCfg getMerchPayCfgCache(String sn) {
+        MerchPayCfg merchPayCfg = payCaches.get(sn);
+        if(merchPayCfg == null) {
+            reloadPayCaches();
+            return payCaches.get(sn);
+        }
+        return merchPayCfg;
+    }
+
+
+    public MerchPaymentService getPaymentService() {
+        return paymentService;
+    }
+
+    public void setPaymentService(MerchPaymentService paymentService) {
+        this.paymentService = paymentService;
+    }
+
+}
+

+ 15 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/CuspayBiz.java

@@ -0,0 +1,15 @@
+package com.kmall.admin.cuspay.biz;
+
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * @author hyq
+ * @version 1.0
+ * 2018-05-23 09:32
+ */
+@Component
+public interface CuspayBiz {
+    void biz(Map<String, Object> params);
+}

+ 60 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/AliCusDeclareApi.java

@@ -0,0 +1,60 @@
+package com.kmall.admin.cuspay.biz.ali;
+
+import com.kmall.admin.cuspay.biz.ali.support.config.AlipayConfig;
+import com.kmall.admin.cuspay.biz.ali.support.util.AlipaySubmit;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * 阿里支付凭证海关申报
+ * @author zx
+ * @version 1.0
+ * 2018-05-23 09:55
+ */
+public class AliCusDeclareApi {
+    private static final Logger logger = LoggerFactory.getLogger(AliCusDeclareApi.class);
+
+    /**
+     * 发起推送支付凭证请求
+     * @param declParas
+     * @return
+     */
+    public String declare(Map<String, String> declParas) {
+        declParas.put("service", "alipay.acquire.customs");
+        declParas.put("partner", AlipayConfig.partner);
+        declParas.put("_input_charset", AlipayConfig.input_charset);
+        declParas.put("out_request_no", declParas.get("out_request_no"));
+        declParas.put("trade_no", declParas.get("trade_no"));
+        declParas.put("merchant_customs_code", declParas.get("merchant_customs_code"));
+        declParas.put("merchant_customs_name", declParas.get("merchant_customs_name"));
+        declParas.put("amount", declParas.get("amount"));
+        declParas.put("customs_place", declParas.get("customs_place"));
+
+        //建立请求
+        String sHtmlText = null;
+        try {
+            AlipaySubmit.buildRequest("", "", declParas);
+        } catch (Exception e) {
+            logger.error("推支付宝海关支付凭证时异常, {}", e.getMessage());
+            e.printStackTrace();
+            throw new RuntimeException("推支付宝海关支付凭证时异常");
+        }
+
+        return sHtmlText;
+    }
+
+    /**
+     * 发起支付凭证推送查询
+     * @param declParas
+     * @return
+     */
+    public String declareQuery(Map<String, String> declParas) {
+        // TODO ...
+
+        return null;
+    }
+
+}

+ 425 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/AliCusDeclareBiz.java

@@ -0,0 +1,425 @@
+package com.kmall.admin.cuspay.biz.ali;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.google.common.base.Strings;
+import com.google.common.collect.Maps;
+import com.kmall.admin.cuspay.biz.AbstractCusDeclareBiz;
+import com.kmall.admin.cuspay.biz.CuspayBiz;
+import com.kmall.admin.cuspay.ccnet2cuspay.common.ali.AliContants;
+import com.kmall.admin.cuspay.ccnet2cuspay.common.ali.AliDict;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.ali.AliCbPayDoc;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.ali.AliPayError;
+import com.kmall.admin.cuspay.common.contant.MerchNoticeDict;
+import com.kmall.admin.cuspay.common.core.db.IdWorkerAide;
+import com.kmall.admin.cuspay.entity.merch.MerchNoti;
+import com.kmall.admin.cuspay.entity.merch.MerchPayCfg;
+import com.kmall.admin.cuspay.manager.snow.SnowflakeUtil;
+import com.kmall.admin.cuspay.service.MerchNotiService;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseMessage;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseStatus;
+import com.kmall.admin.cuspay.util.*;
+import com.kmall.admin.cuspay.ccnet2cuspay.common.MerchNotiBuilder;
+import com.kmall.admin.cuspay.ccnet2cuspay.service.ali.AliCbPayDocService;
+import com.kmall.admin.cuspay.ccnet2cuspay.service.ali.AliPayErrorService;
+import com.google.common.collect.Lists;
+import com.kmall.admin.cuspay.util.jackson.JacksonUtil;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.util.StringUtils;
+import com.kmall.admin.cuspay.biz.ali.support.sign.MD5;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * 阿里支付凭证海关申报
+ *
+ * @author zx
+ * @version 1.0
+ * 2018-05-23 09:55
+ * @author zhuhh
+ * @version 1.1
+ * @date 2021-12-1 10:15:18
+ */
+@Component
+@PropertySource(value = {"classpath:conf/cuspay/cuspay-ali.properties"})
+public class AliCusDeclareBiz extends AbstractCusDeclareBiz implements CuspayBiz {
+    private static final Logger logger = LoggerFactory.getLogger(AliCusDeclareBiz.class);
+
+    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+    @Autowired
+    private Environment environment;
+
+    private Integer limit;
+
+    private Integer count;
+
+    private String declareURL;
+
+    @Autowired
+    private AliCbPayDocService aliCbPayDocService;
+
+    @Autowired
+    private AliPayErrorService aliPayErrorService;
+
+    @Autowired
+    private MerchNotiService merchNotiService;
+
+    /**
+     * 海关报关接口
+     */
+    @Override
+    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
+    public void biz(Map<String, Object> params) {
+        limit = Integer.parseInt(environment.getProperty("db.ali.declare.limit"));
+        count = Integer.parseInt(environment.getProperty("db.ali.declare.count"));
+        declareURL = environment.getProperty("ali.payment.declare.url");
+
+        String platSn = environment.getProperty("merchant.plat-sn");
+        String platName = environment.getProperty("merchant.plat-name");
+        String customsCode = environment.getProperty("merchant.customs-code");
+        String customsName = environment.getProperty("merchant.customs-name");
+        String partner = environment.getProperty("cus.play.alipay.partner");
+        String customs = environment.getProperty("cus.play.alipay.customs");
+
+        // 记录异常数据
+        List<AliPayError> errors = Lists.newArrayList();
+        // 待通知的用户
+        List<MerchNoti> merchNotis = Lists.newArrayList();
+        // 支付宝跨境支付单证
+        AliCbPayDoc aliCbPayDoc = new AliCbPayDoc();
+
+        try {
+            // *********设置支付单报关参数*********
+            // 报关金额
+            aliCbPayDoc.setAmount(params.get("amount").toString());
+            // 支付宝制定的海关编号(大小写皆可)
+            aliCbPayDoc.setCustomsPlace(customs);
+            // 商户海关备案编号
+            aliCbPayDoc.setMerchantCustomsCode(customsCode);
+            // 商户海关备案名称
+            aliCbPayDoc.setMerchantCustomsName(customsName);
+            // 商户生成的用于唯一标识一次报关操作的业务编号
+            aliCbPayDoc.setOutRequestNo(Contants.WX + SnowflakeUtil.getSnowNextId());
+            // 合作者身份ID
+            aliCbPayDoc.setPartner(partner);
+            // 该交易在支付宝系统中的交易流水号
+            aliCbPayDoc.setTradeNo(params.get("tradeNo").toString());
+            // *********设置支付单报关参数*********
+
+            // *********设置商户通知表参数*********
+            // 接入平台内部编号
+            aliCbPayDoc.setMerchErpOrderSn(SysContants.alipay_pay_doc + SnowflakeUtil.getSnowNextId());
+            // 商户编号
+            aliCbPayDoc.setMerchSn(params.get("merchSn").toString());
+            // 商户名称
+            aliCbPayDoc.setMerchName(params.get("merchName").toString());
+            // 平台编号
+            aliCbPayDoc.setPlatSn(platSn);
+            // 平台中文名
+            aliCbPayDoc.setPlatName(platName);
+            // 第三方商户代码
+            aliCbPayDoc.setThirdPartyMerchCode(params.get("thirdPartyMerchCode").toString());
+            // 第三方商户名称
+            aliCbPayDoc.setThirdPartyMerchName(params.get("thirdPartyMerchName").toString());
+            // 内部编号
+            aliCbPayDoc.setAliPaySn("alicb" + IdWorkerAide.nextId());
+            // *********设置商户通知表参数*********
+        } catch (Exception e) {
+            logger.error("支付宝支付单设置参数失败:" + e.getMessage());
+            return;
+        }
+
+        // 先将支付单信息写入数据库,后面直接更新状态即可
+        logger.info("支付宝支付单信息写入数据库开始");
+        try {
+            addAliCbPayDoc(aliCbPayDoc);
+        } catch (Exception e) {
+            logger.error("支付宝支付单信息写入数据库失败");
+            logger.error(e.getMessage());
+            // 手动回滚事务
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            return;
+        }
+        logger.info("支付宝支付单信息写入数据库结束");
+
+        // merch_pay_cfg 表的数据是手动配置
+        // 获取商户信息 从缓存中去  缓存不存在 从数据库重取
+        MerchPayCfg merchPayCfg = getMerchPayCfgCache(aliCbPayDoc.getPartner());
+
+        MerchNotiBuilder builder = new MerchNotiBuilder();
+
+        //设置支付信息
+        builder.aliCbPay(aliCbPayDoc);
+        //设置通知次数
+        builder.notiCount(count);
+
+        if (merchPayCfg == null) {
+            logger.error("partner为【" + aliCbPayDoc.getPartner() + "】的商户支付配置信息不存在");
+            aliCbPayDoc.setResultCode("FAIL");
+            aliCbPayDoc.setDetailErrorCode("partner为【" + aliCbPayDoc.getPartner() + "】的商户支付配置信息不存在");
+            aliCbPayDocService.updateAliCbPay(aliCbPayDoc);
+        }
+
+        if (merchPayCfg.getMerchWxApiKey() == null) {
+            logger.error("appid为【" + aliCbPayDoc.getPartner() + "】的商户支付信息api密钥为空");
+            aliCbPayDoc.setResultCode(AliContants.ERROR_NO_INFOMATION);
+            aliCbPayDoc.setDetailErrorCode("appid为【" + aliCbPayDoc.getPartner() + "】的商户支付信息api密钥为空");
+            aliCbPayDocService.updateAliCbPay(aliCbPayDoc);
+        }
+        //设置商户配置信息
+        builder.merchPay(merchPayCfg);
+
+        // 组装海关支付报关参数
+        String paramter = assemblyDeclareXml(aliCbPayDoc);
+        logger.info("支付宝支付报关开始,请求数据为:" + declareURL + paramter);
+        Document doc = null;
+        String isSuccess = "F";
+        Map<String, Object> stringObjectMap = null;
+
+        try {
+            // todo, 请求海关接口
+            // String result = OkHttpUtils.get(declareURL + paramter);
+            String result = "";
+            doc = DocumentHelper.parseText(result);
+            logger.info("alipay response message result :" + result);
+            stringObjectMap = XmlUtils.Dom2Map(doc);
+            logger.info("解析数据:");
+            logger.info("alipay response message to json:" + JSONObject.wrap(stringObjectMap).toString());
+            if (stringObjectMap == null) {
+                throw new IOException("http请求[" + declareURL + "]响应结果为空");
+            }
+        } catch (IOException e) {
+            logger.error("数据请求异常,支付单请求数据为xml{}", paramter, e);
+            AliPayError aliPayError = createAliPayError(aliCbPayDoc);
+            errors.add(aliPayError);
+        } catch (DocumentException e) {
+            logger.error("数据请求异常,支付单请求数据为xml{}", paramter, e);
+            AliPayError aliPayError = createAliPayError(aliCbPayDoc);
+            errors.add(aliPayError);
+        }
+
+        MerchNoti merchNoti = new MerchNoti();
+        try {
+            if (stringObjectMap != null) {
+                isSuccess = stringObjectMap.get("is_success").toString();
+                if ("F".equals(isSuccess)) {
+                    logger.info("支付宝报关请求失败,请检查数据是否正确或网络是否正常!");
+                    logger.info("错误码:" + stringObjectMap.get("error").toString());
+                } else {
+                    logger.info("支付宝报关请求成功");
+                    Map response = (HashMap) ((HashMap) stringObjectMap.get("response")).get("alipay");
+                    Map request = (HashMap) stringObjectMap.get("request");
+                    aliCbPayDoc.setResultCode(response.get("result_code").toString());
+                    aliCbPayDoc.setTradeNo(request.get("trade_no").toString());
+                    aliCbPayDoc.setMerchantCustomsCode(request.get("merchant_customs_code").toString());
+                    aliCbPayDoc.setAmount(request.get("amount").toString());
+                    aliCbPayDoc.setMerchantCustomsName(request.get("merchant_customs_name").toString());
+                    aliCbPayDoc.setCustomsPlace(request.get("customs_place").toString());
+                    aliCbPayDoc.setOutRequestNo(request.get("out_request_no").toString());
+                    aliCbPayDoc.setPartner(request.get("partner").toString());
+                    aliCbPayDoc.setIdentityCheck((request.get("identity_check") == null) ? "T" : request.get("identity_check").toString());
+                    aliCbPayDoc.setAlipayDeclareNo((request.get("alipay_declare_no") == null) ? null : request.get("alipay_declare_no").toString());
+                    aliCbPayDoc.setTotalAmount((request.get("total_amount") == null) ? null : request.get("total_amount").toString());
+                    aliCbPayDoc.setVerDept((request.get("ver_dept") == null) ? null : request.get("ver_dept").toString());
+                    aliCbPayDoc.setPayCode((request.get("pay_code") == null) ? null : request.get("pay_code").toString());
+                    aliCbPayDoc.setPayTransactionId((request.get("pay_transaction_id") == null) ? null : request.get("pay_transaction_id").toString());
+                    if (aliCbPayDoc.getResultCode().equals("FAIL")) {
+                        aliCbPayDoc.setDetailErrorCode(response.get("detail_error_code").toString());
+                        aliCbPayDoc.setDetailErrorDes(response.get("detail_error_des").toString());
+                        logger.info("支付宝报关业务处理失败!!");
+                        logger.info("错误码:" + aliCbPayDoc.getDetailErrorCode());
+                        logger.info("错误详细信息:" + aliCbPayDoc.getDetailErrorDes());
+                        aliCbPayDoc.setDocStatus(AliDict.PaymentDocStatus.i_03.getItem());
+                        merchNoti = builder.code(aliCbPayDoc.getResultCode()).msg(AliDict.ResponseMsgState.FAIL.getItemName()).cusDeclStatus(AliDict.MerchNoticeStatus.i_13.getItem()).build();
+                    } else if (aliCbPayDoc.getResultCode().equals("SUCCESS")) {
+                        logger.info("支付宝报关业务处理成功!!");
+                        aliCbPayDoc.setAlipayDeclareNo(response.get("alipay_declare_no").toString());
+                        aliCbPayDoc.setDocStatus(AliDict.PaymentDocStatus.i_12.getItem());
+                        merchNoti = builder.code(aliCbPayDoc.getResultCode()).msg(aliCbPayDoc.getDetailErrorDes()).cusDeclStatus(AliDict.MerchNoticeStatus.i_12.getItem()).build();
+                    }
+                    if (!StringUtils.isEmpty(aliCbPayDoc.getIdentityCheck())) {
+                        if (aliCbPayDoc.getIdentityCheck().equals("T")) {
+                            merchNoti = builder.certCheckResult(MerchNoticeDict.BuyerPayerCheckStatus.i_1.getItem()).build();
+                        } else if (aliCbPayDoc.getIdentityCheck().equals("F")) {
+                            merchNoti = builder.certCheckResult(MerchNoticeDict.BuyerPayerCheckStatus.i_2.getItem()).build();
+                        } else {
+                            merchNoti = builder.certCheckResult(MerchNoticeDict.BuyerPayerCheckStatus.i_0.getItem()).build();
+                        }
+                    }
+                }
+            }
+            if ("F".equals(isSuccess) || "FAIL".equals(aliCbPayDoc.getResultCode())) {
+                aliCbPayDoc.setDocStatus(AliDict.PaymentDocStatus.i_03.getItem());
+                merchNoti = builder.code("-3").msg(aliCbPayDoc.getDetailErrorCode()).cusDeclStatus(AliDict.MerchNoticeStatus.i_13.getItem()).build();
+            }
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            aliCbPayDoc.setModerSn("1");
+            aliCbPayDoc.setModTime(sdf.format(new Date()));
+            this.aliCbPayDocService.updateAliCbPay(aliCbPayDoc);
+        } catch (Exception e) {
+            logger.error("更新支付单证入库信息状态异常", e);
+            AliPayError aliPayError = createAliPayError(aliCbPayDoc);
+            errors.add(aliPayError);
+        }
+        merchNoti = builder.aliCbPay(aliCbPayDoc).build();
+        merchNoti = builder.code(aliCbPayDoc.getResultCode()).cusDeclStatus(AliDict.MerchNoticeStatus.i_12.getItem()).build();
+        merchNotis.add(merchNoti);
+
+        // 持久化商户通知数据
+        try {
+            int result = merchNotiService.insertBatch(merchNotis);
+            if (result <= 0) {
+                logger.error("持久化" + result + "条商户通知数据失败data:" + merchNotis);
+                throw new Exception("持久化" + result + "条商户通知数据失败data:" + merchNotis);
+            }
+        } catch (Exception e) {
+            logger.error("持久化商户通知数据异常", e);
+            // 手动回滚事务
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            return;
+        }
+        // 存储异常记录
+        try {
+            if (errors != null && !errors.isEmpty()) {
+
+                int errResult = aliPayErrorService.insertAliPayErrorBatch(errors);
+                if (errResult == 0) {
+                    logger.error("持久化支付申报异常信息数据失败data:" + errors);
+                    throw new Exception("持久化支付申报异常信息数据失败data:" + errors);
+                }
+            }
+        } catch (Exception e) {
+            logger.error("持久化支付申报异常信息数据失败data:" + errors, e);
+            // 手动回滚事务
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            return;
+        }
+        logger.info("支付宝支付报关结束");
+    }
+
+    /**
+     * 记录异常的支付单证信息
+     *
+     * @param wxCbPayDoc
+     * @return
+     */
+    private AliPayError createAliPayError(AliCbPayDoc wxCbPayDoc) {
+        AliPayError wxPayError = new AliPayError();
+        wxPayError.setAliErrorSn("alier" + IdWorkerAide.nextId());
+        wxPayError.setAliPaySn(wxCbPayDoc.getAliPaySn());
+        wxPayError.setMerchSn(wxCbPayDoc.getMerchSn());
+        wxPayError.setMerchName(wxCbPayDoc.getMerchName());
+        wxPayError.setPartner(wxCbPayDoc.getPartner());
+        wxPayError.setMerchSn(wxCbPayDoc.getMerchSn());
+        wxPayError.setTradeNo2(wxCbPayDoc.getTradeNo());
+        wxPayError.setCustomsPlace(wxCbPayDoc.getCustomsPlace());
+        wxPayError.setErrCode(wxCbPayDoc.getDetailErrorCode());
+        wxPayError.setErrMsg(wxCbPayDoc.getDetailErrorDes());
+        wxPayError.setCreateTime(this.sdf.format(new Date()));
+        return wxPayError;
+    }
+
+    /**
+     * 组装报关所需要的报关数据
+     *
+     * @param aliCbPayDoc 支付宝支付数据
+     * @return
+     */
+    protected static String assemblyDeclareXml(AliCbPayDoc aliCbPayDoc) {
+        Map<String, String> paramMap = new HashMap<>();
+        paramMap.put("amount", aliCbPayDoc.getAmount());
+        paramMap.put("customs_place", aliCbPayDoc.getCustomsPlace());
+        paramMap.put("_input_charset", "utf-8");
+        paramMap.put("merchant_customs_code", aliCbPayDoc.getMerchantCustomsCode());
+        paramMap.put("merchant_customs_name", aliCbPayDoc.getMerchantCustomsName());
+        paramMap.put("out_request_no", aliCbPayDoc.getOutRequestNo());
+        paramMap.put("partner", aliCbPayDoc.getPartner());
+        paramMap.put("service", "alipay.acquire.customs");
+        paramMap.put("trade_no", aliCbPayDoc.getTradeNo());
+        List<String> keys = new ArrayList<>(paramMap.keySet());
+        Collections.sort(keys);
+        String prestr = "";
+        for (int i = 0; i < keys.size(); i++) {
+            String key = keys.get(i);
+            String value = paramMap.get(key);
+            if (i == keys.size() - 1) {
+                prestr = prestr + key + "=" + value;
+            } else {
+                prestr = prestr + key + "=" + value + "&";
+            }
+        }
+        String sign = MD5.sign(prestr, "6zo20oar6qufb6x41ipli3yma9ju107h", "UTF-8");
+        prestr = prestr + "&sign_type=MD5";
+        prestr = prestr + "&sign=" + sign;
+        prestr = "?" + prestr;
+        return prestr;
+    }
+
+    /**
+     * 支付单信息写入数据库
+     *
+     * @author zhuhh
+     * @param aliCbPayDoc
+     * @return
+     */
+    protected void addAliCbPayDoc(AliCbPayDoc aliCbPayDoc) {
+        logger.info("支付宝支付单信息写入数据库接口请求开始");
+        if (aliCbPayDoc == null) {
+            throw new RuntimeException("支付宝支付单信息写入数据库失败:支付宝支付单业务数据为空!");
+        }
+        logger.info("支付宝支付单信息写入数据库接口请求数据:【{}】", JacksonUtil.toJson(aliCbPayDoc));
+
+        //数据校验
+        Map<String, Object> validate = MapBeanUtils.fromObject(aliCbPayDoc);
+        Map<String, Object> beVerified = Maps.newHashMap();
+
+        beVerified.put("partner", "合作者身份 ID");
+        beVerified.put("outRequestNo", "报关流水号");
+        beVerified.put("tradeNo", "支付宝交易号");
+        beVerified.put("merchantCustomsCode", "商户海关备案号");
+        beVerified.put("amount", "报关金额");
+        beVerified.put("customsPlace", "海关编号");
+        beVerified.put("merchantCustomsName", "商户海关备案名称");
+
+        ResponseMessage rst = Validator.isEmpty(beVerified, validate);
+        if (ResponseStatus.ERROR.getItem().equals(rst.getCode())) {
+            throw new RuntimeException("支付宝支付单信息写入数据库失败:支付宝支付单业务数据校验失败!");
+        }
+
+        // 根据OutRequestNo查询,查询为空说明是新数据,查询不为空说明是重推数据
+        AliCbPayDoc aliCbPayDoc1 = aliCbPayDocService.selectByOutRequestNo(aliCbPayDoc.getOutRequestNo());
+        ResponseMessage responseMessage;
+        if (aliCbPayDoc1 != null) {
+            // 更新
+            responseMessage = this.aliCbPayDocService.heavyPush(aliCbPayDoc1);
+        } else {
+            // 新增
+            responseMessage = aliCbPayDocService.addAliCbPayDoc(aliCbPayDoc);
+        }
+
+        // 判断返回结果
+        if (ResponseStatus.SUCCESS.getItem().equals(responseMessage.getCode())) {
+            logger.info(responseMessage.getMsg());
+        } else if (ResponseStatus.ERROR.getItem().equals(responseMessage.getCode())) {
+            logger.error(responseMessage.getMsg());
+            throw new RuntimeException(responseMessage.getMsg());
+        }
+
+    }
+
+
+}

+ 337 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/AliCusDeclareQueryBiz.java

@@ -0,0 +1,337 @@
+package com.kmall.admin.cuspay.biz.ali;
+
+import com.kmall.admin.cuspay.biz.AbstractCusDeclareBiz;
+import com.kmall.admin.cuspay.biz.CuspayBiz;
+import com.kmall.admin.cuspay.ccnet2cuspay.common.ali.AliDict;
+import com.kmall.admin.cuspay.ccnet2cuspay.dto.ali.AliQuerySuccessResponseMsgDto;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.ali.AliCbPayDoc;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.ali.AliPayError;
+import com.kmall.admin.cuspay.ccnet2cuspay.service.ali.AliCbPayDocService;
+import com.kmall.admin.cuspay.ccnet2cuspay.service.ali.AliPayErrorService;
+import com.kmall.admin.cuspay.common.contant.MerchNoticeDict;
+import com.kmall.admin.cuspay.common.contant.TablePrimaryKeyPrefix;
+import com.kmall.admin.cuspay.common.core.db.IdWorkerAide;
+import com.kmall.admin.cuspay.entity.merch.MerchNoti;
+import com.kmall.admin.cuspay.entity.merch.MerchPayCfg;
+import com.kmall.admin.cuspay.service.MerchNotiService;
+import com.kmall.admin.cuspay.util.OkHttpUtils;
+import com.kmall.admin.cuspay.util.ReaderXmlForDOM4J;
+import com.kmall.admin.cuspay.util.XmlUtils;
+import com.kmall.admin.cuspay.ccnet2cuspay.common.MerchNotiBuilder;
+import com.kmall.admin.cuspay.ccnet2cuspay.common.wx.WxContants;
+import com.kmall.admin.cuspay.ccnet2cuspay.common.wx.WxDict;
+import com.kmall.admin.cuspay.ccnet2cuspay.dto.wx.WxQueryResponseMsg;
+import com.kmall.admin.cuspay.ccnet2cuspay.dto.wx.WxQuerySuccessResponseMsgDto;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.wx.WxCbPayDoc;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.wx.WxPayError;
+import com.kmall.admin.cuspay.ccnet2cuspay.service.wx.WxCbPayDocService;
+import com.kmall.admin.cuspay.ccnet2cuspay.service.wx.WxPayErrorService;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import okhttp3.MediaType;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.stereotype.Component;
+import com.kmall.admin.cuspay.biz.ali.support.sign.MD5;
+
+import javax.xml.bind.JAXB;
+import java.io.IOException;
+import java.io.StringReader;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * 阿里支付凭证推单信息查询
+ * @author hyq
+ * @version 1.0
+ * 2018-05-23 17:46
+ */
+@Component
+@PropertySource(value = {"classpath:conf/cuspay/cuspay-ali.properties"})
+public class AliCusDeclareQueryBiz extends AbstractCusDeclareBiz implements CuspayBiz {
+    private static final Logger logger = LoggerFactory.getLogger(AliCusDeclareQueryBiz.class);
+
+//    @Value("${db.ali.declare.limit}")
+    private Integer limit = 20;
+
+//    @Value("${db.ali.declare.count}")
+    private Integer count = 2;
+
+//    @Value("${ali.payment.query.url}")
+    private String queryURL = "https://mapi.alipay.com/gateway.do?";
+
+    @Autowired
+    private AliCbPayDocService aliCbPayDocService;
+
+    @Autowired
+    private AliPayErrorService aliPayErrorService;
+
+    @Autowired
+    private MerchNotiService merchNotiService;
+
+    /**
+     * 微信订单信息查询
+     */
+    public void biz(Map<String, Object> params) {
+        // -------- TODO ALL ----
+
+        limit = (limit != null && limit > 0) ? limit : 20;
+        count = (count != null && count > 0) ? count : 10;
+
+        //查出等待处理、业务处理中的支付单证信息
+        List<AliCbPayDoc> aliCbPayDocs = null;
+        try {
+            aliCbPayDocs = aliCbPayDocService.selectPayDocByDocStatus(limit);
+            if (aliCbPayDocs == null || aliCbPayDocs.isEmpty()) {
+                logger.info("未查到等待处理、业务处理中支付宝推海关的支付数据");
+                return;
+            }
+        } catch (Exception e) {
+            logger.error("查询等待处理、业务处理中微信推海关的支付数据异常", e);
+            return;
+        }
+
+        //记录异常数据
+        List<AliPayError> errorList = Lists.newArrayList();
+
+        aliCbPayDocs.forEach(aliCbPayDoc -> {
+            AliQuerySuccessResponseMsgDto querySuccessResponseDto = new AliQuerySuccessResponseMsgDto();
+            //获取商户信息 从缓存中去  缓存不存在 从数据库重取
+            MerchPayCfg merchPayCfg = getMerchPayCfgCache(aliCbPayDoc.getPartner());
+
+            MerchNotiBuilder builder = new MerchNotiBuilder();
+
+            //设置支付信息
+            builder.aliCbPay(aliCbPayDoc);
+            //设置通知次数
+            builder.notiCount(count);
+
+            if (merchPayCfg == null) {
+                aliCbPayDoc.setResultCode("FAIL");
+                aliCbPayDoc.setDetailErrorDes("appid为【" + aliCbPayDoc.getPartner() + "】的商户支付配置信息不存在");
+                this.aliCbPayDocService.updateAliCbPay(aliCbPayDoc);
+                logger.error("appid为【" + aliCbPayDoc.getPartner() + "】的商户支付配置信息不存在 ");
+                return;
+            }
+
+            if (merchPayCfg.getMerchWxApiKey() == null) {
+                aliCbPayDoc.setResultCode("-1");
+                aliCbPayDoc.setDetailErrorDes("appid为【" + aliCbPayDoc.getPartner() + "】的商户支付信息api密钥为空");
+                this.aliCbPayDocService.updateAliCbPay(aliCbPayDoc);
+                logger.error("appid为【"+aliCbPayDoc.getAppid()+"】的商户支付信息api密钥为空 ");
+                return;
+            }
+            //设置商户配置信息
+            builder.merchPay(merchPayCfg);
+
+            String paramter = assemblyDeclareQueryXml(aliCbPayDoc, merchPayCfg.getMerchWxApiKey());
+
+            String result = "";
+            Map<String, Object> stringObjectMap = null;
+            try {
+                logger.info("支付宝支付查询报关请求开始:" + this.queryURL + paramter);
+                result = OkHttpUtils.get(this.queryURL + paramter);
+                logger.info("支付宝查询报关返回结果:" + result);
+                stringObjectMap = XmlUtils.Dom2Map(DocumentHelper.parseText(result));
+                logger.info("解析数据:" + JSONObject.wrap(stringObjectMap).toString());
+                if (stringObjectMap == null || stringObjectMap.size() == 0) {
+                    throw new IOException("http请求[" + this.queryURL + "]响应结果为空");
+                }
+            } catch (IOException | DocumentException e) {
+                logger.error("数据异常:", e);
+                AliPayError wxPayError = createAliPayError(aliCbPayDoc, querySuccessResponseDto);
+                errorList.add(wxPayError);
+                return;
+            }
+            MerchNoti merchNoti = new MerchNoti();
+            String allSubOrderId = "";
+            String allSubOrderNo = "";
+            try {
+                String isSuccess = stringObjectMap.get("is_success").toString();
+                if ("F".equals(isSuccess)) {
+                    logger.info("支付宝查询报关请求失败,error : " + stringObjectMap.get("error").toString());
+                    aliCbPayDoc.setDetailErrorCode(stringObjectMap.get("error").toString());
+                    aliCbPayDoc.setResultCode(stringObjectMap.get("error").toString());
+                    aliCbPayDoc.setDocStatus(AliDict.PaymentDocStatus.i_03.getItem());
+                    merchNoti = builder.code("-3").msg(stringObjectMap.get("error").toString()).cusDeclStatus(AliDict.MerchNoticeStatus.i_13.getItem()).build();
+                    this.aliCbPayDocService.updateAliCbPay(aliCbPayDoc);
+                    MerchNoti noti = new MerchNoti();
+                    noti.setCode(aliCbPayDoc.getResultCode());
+                    noti.setAllPayNo(aliCbPayDoc.getAlipayDeclareNo());
+                    noti.setCusDeclStatus(merchNoti.getCusDeclStatus());
+                    noti.setAllSubOrderNo(allSubOrderNo);
+                    updateMerchNoti(noti, allSubOrderId, merchNoti);
+                } else if ("T".equals(isSuccess)) {
+                    logger.info("支付宝查询报关请求成功");
+                    Map request = (HashMap)stringObjectMap.get("request");
+                    Map alipay = (HashMap)((HashMap)stringObjectMap.get("response")).get("alipay");
+                    aliCbPayDoc.setResultCode(alipay.get("result_code").toString());
+                    aliCbPayDoc.setOutRequestNo(request.get("out_request_nos").toString());
+                    aliCbPayDoc.setPartner(request.get("partner").toString());
+                    if ("FAIL".equals(aliCbPayDoc.getResultCode())) {
+                        logger.info("支付宝查询报关业务处理失败");
+                        aliCbPayDoc.setDetailErrorCode(alipay.get("detail_error_code").toString());
+                        aliCbPayDoc.setDetailErrorDes(alipay.get("detail_error_des").toString());
+                        aliCbPayDoc.setDocStatus(AliDict.PaymentDocStatus.i_13.getItem());
+                        merchNoti = builder.code(aliCbPayDoc.getDetailErrorCode()).msg(aliCbPayDoc.getDetailErrorDes()).cusDeclStatus(AliDict.MerchNoticeStatus.i_13.getItem()).certCheckResult(MerchNoticeDict.BuyerPayerCheckStatus.i_0.getItem()).build();
+                        this.aliCbPayDocService.updateAliCbPay(aliCbPayDoc);
+                        MerchNoti noti = new MerchNoti();
+                        noti.setCode(aliCbPayDoc.getDetailErrorCode());
+                        noti.setAllPayNo(aliCbPayDoc.getAlipayDeclareNo());
+                        noti.setCusDeclStatus(merchNoti.getCusDeclStatus());
+                        noti.setAllSubOrderNo(allSubOrderNo);
+                        updateMerchNoti(noti, allSubOrderId, merchNoti);
+                    } else if ("SUCCESS".equals(aliCbPayDoc.getResultCode())) {
+                        logger.info("支付宝查询报关业务处理成功");
+                        String notFound = (alipay.get("not_found") == null) ? null : alipay.get("not_found").toString();
+                        if (notFound == null || notFound.isEmpty()) {
+                            Map customsDeclare = (HashMap)((HashMap)alipay.get("records")).get("customs_declare");
+                            String status = (customsDeclare.get("status") == null) ? null : customsDeclare.get("status").toString().toUpperCase();
+                            String customsCode = (customsDeclare.get("customs_code") == null) ? null : customsDeclare.get("customs_code").toString().toUpperCase();
+                            String customsInfo = (customsDeclare.get("customs_info") == null) ? null : customsDeclare.get("customs_info").toString();
+                            String customsReturnTime = (customsDeclare.get("customs_return_time") == null) ? null : customsDeclare.get("customs_return_time").toString();
+                            String outRequestNo = (customsDeclare.get("out_request_no") == null) ? null : customsDeclare.get("out_request_no").toString();
+                            String alipayDeclareNo = (customsDeclare.get("alipay_declare_no") == null) ? null : customsDeclare.get("alipay_declare_no").toString();
+                            String tradeNo = (customsDeclare.get("trade_no") == null) ? null : customsDeclare.get("trade_no").toString();
+                            String customsPlace = (customsDeclare.get("customs_place") == null) ? null : customsDeclare.get("customs_place").toString();
+                            String merchantCustomsCode = (customsDeclare.get("merchant_customs_code") == null) ? null : customsDeclare.get("merchant_customs_code").toString();
+                            String merchantCustomsName = (customsDeclare.get("merchant_customs_name") == null) ? null : customsDeclare.get("merchant_customs_name").toString();
+                            String amount = (customsDeclare.get("amount") == null) ? null : customsDeclare.get("amount").toString();
+                            if (status == null || status.isEmpty() || AliDict.ResponseMsgState.SUCC.getItem().equals(status)) {
+                                aliCbPayDoc.setDocStatus(AliDict.PaymentDocStatus.i_12.getItem());
+                                merchNoti = builder.code(customsCode).msg(customsInfo).cusDeclStatus(AliDict.MerchNoticeStatus.i_12.getItem()).build();
+                            } else if (AliDict.ResponseMsgState.FAIL.getItem().equals(status)) {
+                                aliCbPayDoc.setDocStatus(AliDict.PaymentDocStatus.i_03.getItem());
+                                merchNoti = builder.code(customsCode).msg(customsInfo).cusDeclStatus(AliDict.MerchNoticeStatus.i_13.getItem()).build();
+                            } else if (AliDict.ResponseMsgState.EXCEPT.getItem().equals(status)) {
+                                aliCbPayDoc.setDocStatus(AliDict.PaymentDocStatus.i_03.getItem());
+                                merchNoti = builder.code(customsCode).msg(customsInfo).cusDeclStatus(AliDict.MerchNoticeStatus.i_13.getItem()).build();
+                            }
+                            this.aliCbPayDocService.updateAliCbPay(aliCbPayDoc);
+                            merchNoti = builder.certCheckResult(MerchNoticeDict.BuyerPayerCheckStatus.i_1.getItem()).build();
+                            MerchNoti noti = new MerchNoti();
+                            noti.setNotiSn(builder.build().getNotiSn());
+                            merchNoti.setNotiSn(builder.build().getNotiSn());
+                            noti.setCode(aliCbPayDoc.getDetailErrorCode());
+                            noti.setAllPayNo(aliCbPayDoc.getAlipayDeclareNo());
+                            noti.setCusDeclStatus(merchNoti.getCusDeclStatus());
+                            noti.setAllSubOrderNo(allSubOrderNo);
+                            updateMerchNoti(noti, allSubOrderId, merchNoti);
+                        } else {
+                            logger.info("未查询到报关请求号 :" + notFound);
+                            aliCbPayDoc.setDocStatus(AliDict.PaymentDocStatus.i_03.getItem());
+                            this.aliCbPayDocService.updateAliCbPay(aliCbPayDoc);
+                            merchNoti = builder.code(AliDict.ResponseMsgState.FAIL.getItem()).msg("未查询到报关请求号").cusDeclStatus(AliDict.MerchNoticeStatus.i_13.getItem()).certCheckResult(MerchNoticeDict.BuyerPayerCheckStatus.i_0.getItem()).build();
+                                                                                                  MerchNoti noti = new MerchNoti();
+                            noti.setNotiSn(builder.build().getNotiSn());
+                            merchNoti.setNotiSn(builder.build().getNotiSn());
+                            noti.setCode(aliCbPayDoc.getDetailErrorCode());
+                            noti.setAllPayNo(aliCbPayDoc.getAlipayDeclareNo());
+                            noti.setCusDeclStatus(merchNoti.getCusDeclStatus());
+                            noti.setAllSubOrderNo(allSubOrderNo);
+                            updateMerchNoti(noti, allSubOrderId, merchNoti);
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                logger.error("更新支付单证入库信息状态异常", e);
+                AliPayError aliPayError = createAliPayError(aliCbPayDoc, querySuccessResponseDto);
+                errorList.add(aliPayError);
+                return;
+            }
+        });
+        //存储异常记录
+        try {
+            if (errorList != null && !errorList.isEmpty()) {
+                int errResult = aliPayErrorService.insertAliPayErrorBatch(errorList);
+                if (errResult == 0) {
+                    logger.error("持久化支付申报异常数据失败data:" + errorList);
+                    throw new Exception("持久化支付申报异常数据失败data:" + errorList);
+                }
+            }
+        } catch (Exception e) {
+            logger.error("持久化支付申报异常数据失败data:" + errorList, e);
+            throw new RuntimeException("持久化支付申报异常数据失败data:",e);
+        }
+
+    }
+    private void updateMerchNoti(MerchNoti noti,String allSubOrderId,MerchNoti merchNoti){
+        // -------- TODO ALL ----
+
+        List<MerchNoti> merchNotiList = merchNotiService.getMerchNotiByCodeAndOrderNo(noti);
+        if(merchNotiList != null && merchNotiList.size()>0){
+            MerchNoti merchNoti1 = merchNotiList.get(0);
+            merchNoti1.setTstm(new Date());
+            merchNoti1.setAllSubOrderId(allSubOrderId);
+            merchNotiService.update(merchNoti1);
+        }else{
+            merchNoti.setNotiSn(TablePrimaryKeyPrefix.merch_pay_noti_type + IdWorkerAide.nextId());
+            merchNotiService.insert(merchNoti);
+        }
+    }
+
+    /**
+     * 记录异常的支付单证信息
+     * @param aliCbPayDoc
+     * @return
+     */
+    private AliPayError createAliPayError(AliCbPayDoc aliCbPayDoc, AliQuerySuccessResponseMsgDto querySuccessDto) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        AliPayError wxPayError = new AliPayError();
+        wxPayError.setAliErrorSn("alier" + IdWorkerAide.nextId());
+        wxPayError.setAliPaySn(aliCbPayDoc.getAliPaySn());
+        wxPayError.setMerchSn(aliCbPayDoc.getMerchSn());
+        wxPayError.setMerchName(aliCbPayDoc.getMerchName());
+        wxPayError.setPartner(aliCbPayDoc.getPartner());
+        wxPayError.setMerchSn(aliCbPayDoc.getMerchSn());
+        wxPayError.setTradeNo2(aliCbPayDoc.getTradeNo());
+        wxPayError.setCustomsPlace(aliCbPayDoc.getCustomsPlace());
+        wxPayError.setErrCode(aliCbPayDoc.getDetailErrorCode());
+        wxPayError.setErrMsg(aliCbPayDoc.getDetailErrorDes());
+        wxPayError.setCreateTime(sdf.format(new Date()));
+        return wxPayError;
+    }
+
+    /**
+     * 组装支付宝查询订单所需要的参数数据
+     * @param aliCbPayDoc 微信支付数据
+     * @param key2 Api密钥
+     * @return
+     */
+    protected static String assemblyDeclareQueryXml(AliCbPayDoc aliCbPayDoc, String key2) {
+        Map<String, String> paramMap = new HashMap<>();
+        paramMap.put("_input_charset", "UTF-8");
+        paramMap.put("out_request_nos", aliCbPayDoc.getOutRequestNo());
+        paramMap.put("service", "alipay.overseas.acquire.customs.query");
+        paramMap.put("partner", aliCbPayDoc.getPartner());
+        List<String> keys = new ArrayList<>(paramMap.keySet());
+        Collections.sort(keys);
+        String prestr = "";
+        for (int i = 0; i < keys.size(); i++) {
+            String key = keys.get(i);
+            String value = paramMap.get(key);
+            if (i == keys.size() - 1) {
+                prestr = prestr + key + "=" + value;
+            } else {
+                prestr = prestr + key + "=" + value + "&";
+            }
+        }
+        String sign = MD5.sign(prestr, "6zo20oar6qufb6x41ipli3yma9ju107h", "UTF-8");
+        prestr = prestr + "&sign_type=MD5";
+        prestr = prestr + "&sign=" + sign;
+        prestr = "?" + prestr;
+        return prestr;
+    }
+
+    public static void main(String[] args) {}
+}

+ 44 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/config/AlipayConfig.java

@@ -0,0 +1,44 @@
+package com.kmall.admin.cuspay.biz.ali.support.config;
+
+/* *
+ *类名:AlipayConfig
+ *功能:基础配置类
+ *详细:设置帐户有关信息及返回路径
+ *版本:3.3
+ *日期:2012-08-10
+ *说明:
+ *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
+ *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
+	
+ *提示:如何获取安全校验码和合作身份者ID
+ *1.用您的签约支付宝账号登录支付宝网站(www.alipay.com)
+ *2.点击“商家服务”(https://b.alipay.com/order/myOrder.htm)
+ *3.点击“查询合作者身份(PID)”、“查询安全校验码(Key)”
+
+ *安全校验码查看时,输入支付密码后,页面呈灰色的现象,怎么办?
+ *解决方法:
+ *1、检查浏览器配置,不让浏览器做弹框屏蔽设置
+ *2、更换浏览器或电脑,重新登录查询。
+ */
+
+public class AlipayConfig {
+	
+	//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
+	// 合作身份者ID,以2088开头由16位纯数字组成的字符串
+	public static String partner = "2088821582509154";
+	// 商户的私钥
+	public static String key = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC1DOjdI/nVtDq3NRU8mZ08uTzDWcGYFCV1c+pH8q0MjdA518xsQv5ecuyf1jNwMJ7YcartUeanLHF/mys4hbTCyeOXwC9rX9Dd6xGSC6K/jCMiKu4ZDIRWpA93a35Lu9qRZKkD7h+cWuCMfu6s+qM8ikDN1MU2y7846AKL39XtDEpOzHKuctvxysXfz2MkI4rsKLyy8TmkG+q5hAU1C+Rs+nDp3D2C5dC9Aku7hRCW68rQo3yzuvn0EZ37BxIQO4pTCSbyI0N0C7gv5yjr+jFRnguXcNO/Qf0Vyfu9EUDPabQHwckoqD3ZAysS38oqvC3N1NlLI/+FEks4uR1cZAubAgMBAAECggEBAJjbwW+UBEdt13T/GGMFvz+ZlbfJfC4ONGIp78+3EGvc/8UWcb2mAmVz2lxI2T0Lj9Fmhs2/rGHQoDMAq0kZejhLhCCHXoHlb88tvLP1pv7aLn+Wh1gWvVT5RyWoWAVRIYRH3Hs4/O9hutxj/teE9XUTtQsTbT6KX3SITj4SSefMYREqMGro2qwL8yBj3d/wspi4iFQM8IbQdXWUlCbq9Y+hS3pDKxZn7MRqL2gcASbPvI9JRl2m5eqWRVG/2SdYvyFIuzas7l0ytuR/86bxw/rsmTNPZfcW7Y/MN9/+PGLJY0lDKD4QLnp/vG7hjXEgVqFuys7rCCWX0fgJiBNO22ECgYEA2dXkwG9U3COC3Bh/snJ9yRNeUkeZo8W3EfdRgKJqmid8dBR1hvV8dDgOTVsk5I7J4uktBruUN1i1FJwxU9mDuoWE1wbEnirdqyGVi4v9bLgmckTF5pr6y/q5PzVMcNgf64iu28PHv8cWdiltnBG622mFcJG/9KaaMlRaVFY/19UCgYEA1MUsdYDT6RgcDoMoGCoc2mX7Bv/2M6M0p5PURl/2o8Z4EdcqZO57ieCL5UVlXdHUkfuui9lVELv8zZXP7+OKiI/fV9yG37gtPH3c1pVj9wuAWhY0S0ENMIT4PELSiturGWA7GRBM5p6CDxA1N+ANcdg6ZzLgk6p8D0T1NI+q/a8CgYAK6YcbCLi0imbcxbFn7ApXD0xTTNjqdlYUZVJE4l36uO2oFvpIN3XzkHdO8rjnZivA3TNvOehT2XLAxI5ICAZsSpH7/4/L6JPQJc+K/QlF7/elE8LiKXNU0ouDGhVpNbprnx47ThRsi/mZE7w07EJzCVcw62w1Qj9JNCaOQP/TvQKBgQCtLnwcfCp/3JbhnRGicYygm0cykF51805lY+bxDST0cxPB+a9RDefR9soHaG+0aJkr5X5R6CjcARcowtrIOB3HP8ubeSzypbd0OEHrCxedumfTa6VO53jz2Bcw/XbffSML+Y7AvMrLH5Ne7WNTwnNPCZ+n5fpzVt25k/g9uv6DkwKBgQCbJFdWeLM3Ve7ci38bh53Elp+BLSQjViRvj59xb8Ymm3H1UbwyLPQQ48lJXAVDo1AZe1MXEr40mbqGrKnjaTv3T2r4Vj7UT4y3O0attE6t3gWv8AXR6nidj60RQhynnv4oFEBDUWuIIjez4xSMH9og8ZYHBWOis1isQ8vu4fVRtQ==";
+
+	//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
+	
+
+	// 调试用,创建TXT日志文件夹路径
+	public static String log_path = "D:\\";
+
+	// 字符编码格式 目前支持 gbk 或 utf-8
+	public static String input_charset = "utf-8";
+	
+	// 签名方式 不需修改
+	public static String sign_type = "MD5";
+
+}

+ 66 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/sign/MD5.java

@@ -0,0 +1,66 @@
+package com.kmall.admin.cuspay.biz.ali.support.sign;
+
+import org.apache.commons.codec.digest.DigestUtils;
+
+import java.io.UnsupportedEncodingException;
+import java.security.SignatureException;
+
+/** 
+* 功能:支付宝MD5签名处理核心文件,不需要修改
+* 版本:3.3
+* 修改日期:2012-08-17
+* 说明:
+* 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
+* 该代码仅供学习和研究支付宝接口使用,只是提供一个
+* */
+public class MD5 {
+
+    /**
+     * 签名字符串
+     * @param text 需要签名的字符串
+     * @param key 密钥
+     * @param input_charset 编码格式
+     * @return 签名结果
+     */
+    public static String sign(String text, String key, String input_charset) {
+    	text = text + key;
+        return DigestUtils.md5Hex(getContentBytes(text, input_charset));
+    }
+    
+    /**
+     * 签名字符串
+     * @param text 需要签名的字符串
+     * @param sign 签名结果
+     * @param key 密钥
+     * @param input_charset 编码格式
+     * @return 签名结果
+     */
+    public static boolean verify(String text, String sign, String key, String input_charset) {
+    	text = text + key;
+    	String mysign = DigestUtils.md5Hex(getContentBytes(text, input_charset));
+    	if(mysign.equals(sign)) {
+    		return true;
+    	}else {
+    		return false;
+    	}
+    }
+
+    /**
+     * @param content
+     * @param charset
+     * @return
+     * @throws SignatureException
+     * @throws UnsupportedEncodingException 
+     */
+    private static byte[] getContentBytes(String content, String charset) {
+        if (charset == null || "".equals(charset)) {
+            return content.getBytes();
+        }
+        try {
+            return content.getBytes(charset);
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
+        }
+    }
+
+}

+ 117 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/AlipayCore.java

@@ -0,0 +1,117 @@
+package com.kmall.admin.cuspay.biz.ali.support.util;
+
+import com.kmall.admin.cuspay.biz.ali.support.config.AlipayConfig;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.httpclient.methods.multipart.FilePartSource;
+import org.apache.commons.httpclient.methods.multipart.PartSource;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.*;
+
+/* *
+ *类名:AlipayFunction
+ *功能:支付宝接口公用函数类
+ *详细:该类是请求、通知返回两个文件所调用的公用函数核心处理文件,不需要修改
+ *版本:3.3
+ *日期:2012-08-14
+ *说明:
+ *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
+ *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
+ */
+
+public class AlipayCore {
+
+    /** 
+     * 除去数组中的空值和签名参数
+     * @param sArray 签名参数组
+     * @return 去掉空值与签名参数后的新签名参数组
+     */
+    public static Map<String, String> paraFilter(Map<String, String> sArray) {
+
+        Map<String, String> result = new HashMap<String, String>();
+
+        if (sArray == null || sArray.size() <= 0) {
+            return result;
+        }
+
+        for (String key : sArray.keySet()) {
+            String value = sArray.get(key);
+            if (value == null || value.equals("") || key.equalsIgnoreCase("sign")
+                || key.equalsIgnoreCase("sign_type")) {
+                continue;
+            }
+            result.put(key, value);
+        }
+
+        return result;
+    }
+
+    /** 
+     * 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串
+     * @param params 需要排序并参与字符拼接的参数组
+     * @return 拼接后字符串
+     */
+    public static String createLinkString(Map<String, String> params) {
+
+        List<String> keys = new ArrayList<String>(params.keySet());
+        Collections.sort(keys);
+
+        String prestr = "";
+
+        for (int i = 0; i < keys.size(); i++) {
+            String key = keys.get(i);
+            String value = params.get(key);
+
+            if (i == keys.size() - 1) {//拼接时,不包括最后一个&字符
+                prestr = prestr + key + "=" + value;
+            } else {
+                prestr = prestr + key + "=" + value + "&";
+            }
+        }
+
+        return prestr;
+    }
+
+    /** 
+     * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
+     * @param sWord 要写入日志里的文本内容
+     */
+    public static void logResult(String sWord) {
+        FileWriter writer = null;
+        try {
+            writer = new FileWriter(AlipayConfig.log_path + "alipay_log_" + System.currentTimeMillis() + ".txt");
+            writer.write(sWord);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (writer != null) {
+                try {
+                    writer.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /** 
+     * 生成文件摘要
+     * @param strFilePath 文件路径
+     * @param file_digest_type 摘要算法
+     * @return 文件摘要结果
+     */
+    public static String getAbstract(String strFilePath, String file_digest_type) throws IOException {
+        FilePartSource filePartSource = new FilePartSource(new File(strFilePath));
+    	if(file_digest_type.equals("MD5")){
+    		return DigestUtils.md5Hex(filePartSource.createInputStream());
+    	}
+    	else if(file_digest_type.equals("SHA")) {
+    		return DigestUtils.sha256Hex(filePartSource.createInputStream());
+    	}
+    	else {
+    		return "";
+    	}
+    }
+}

+ 123 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/AlipayNotify.java

@@ -0,0 +1,123 @@
+package com.kmall.admin.cuspay.biz.ali.support.util;
+
+import com.kmall.admin.cuspay.biz.ali.support.config.AlipayConfig;
+import com.kmall.admin.cuspay.support.sign.MD5Util;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Map;
+
+/* *
+ *类名:AlipayNotify
+ *功能:支付宝通知处理类
+ *详细:处理支付宝各接口通知返回
+ *版本:3.3
+ *日期:2012-08-17
+ *说明:
+ *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
+ *该代码仅供学习和研究支付宝接口使用,只是提供一个参考
+
+ *************************注意*************************
+ *调试通知返回时,可查看或改写log日志的写入TXT里的数据,来检查通知返回是否正常
+ */
+public class AlipayNotify {
+
+    /**
+     * 支付宝消息验证地址
+     */
+    private static final String HTTPS_VERIFY_URL = "https://mapi.alipay.com/gateway.do?service=notify_verify&";
+
+    /**
+     * 验证消息是否是支付宝发出的合法消息
+     * @param params 通知返回来的参数数组
+     * @return 验证结果
+     */
+    public static boolean verify(Map<String, String> params) {
+
+        //判断responsetTxt是否为true,isSign是否为true
+        //responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
+        //isSign不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
+    	String responseTxt = "false";
+		if(params.get("notify_id") != null) {
+			String notify_id = params.get("notify_id");
+			responseTxt = verifyResponse(notify_id);
+		}
+	    String sign = "";
+	    if(params.get("sign") != null) {sign = params.get("sign");}
+	    boolean isSign = getSignVeryfy(params, sign);
+
+        //写日志记录(若要调试,请取消下面两行注释)
+        //String sWord = "responseTxt=" + responseTxt + "\n isSign=" + isSign + "\n 返回回来的参数:" + AlipayCore.createLinkString(params);
+	    //AlipayCore.logResult(sWord);
+
+        if (isSign && responseTxt.equals("true")) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 根据反馈回来的信息,生成签名结果
+     * @param Params 通知返回来的参数数组
+     * @param sign 比对的签名结果
+     * @return 生成的签名结果
+     */
+	private static boolean getSignVeryfy(Map<String, String> Params, String sign) {
+    	//过滤空值、sign与sign_type参数
+    	Map<String, String> sParaNew = AlipayCore.paraFilter(Params);
+        //获取待签名字符串
+        String preSignStr = AlipayCore.createLinkString(sParaNew);
+        //获得签名验证结果
+        boolean isSign = false;
+        if(AlipayConfig.sign_type.equals("MD5Util") ) {
+        	isSign = MD5Util.verify(preSignStr, sign, AlipayConfig.key, AlipayConfig.input_charset);
+        }
+        return isSign;
+    }
+
+    /**
+    * 获取远程服务器ATN结果,验证返回URL
+    * @param notify_id 通知校验ID
+    * @return 服务器ATN结果
+    * 验证结果集:
+    * invalid命令参数不对 出现这个错误,请检测返回处理中partner和key是否为空 
+    * true 返回正确信息
+    * false 请检查防火墙或者是服务器阻止端口问题以及验证时间是否超过一分钟
+    */
+    private static String verifyResponse(String notify_id) {
+        //获取远程服务器ATN结果,验证是否是支付宝服务器发来的请求
+
+        String partner = AlipayConfig.partner;
+        String veryfy_url = HTTPS_VERIFY_URL + "partner=" + partner + "&notify_id=" + notify_id;
+
+        return checkUrl(veryfy_url);
+    }
+
+    /**
+    * 获取远程服务器ATN结果
+    * @param urlvalue 指定URL路径地址
+    * @return 服务器ATN结果
+    * 验证结果集:
+    * invalid命令参数不对 出现这个错误,请检测返回处理中partner和key是否为空 
+    * true 返回正确信息
+    * false 请检查防火墙或者是服务器阻止端口问题以及验证时间是否超过一分钟
+    */
+    private static String checkUrl(String urlvalue) {
+        String inputLine = "";
+
+        try {
+            URL url = new URL(urlvalue);
+            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+            BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
+            inputLine = in.readLine().toString();
+        } catch (Exception e) {
+            e.printStackTrace();
+            inputLine = "";
+        }
+
+        return inputLine;
+    }
+}

+ 219 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/AlipaySubmit.java

@@ -0,0 +1,219 @@
+package com.kmall.admin.cuspay.biz.ali.support.util;
+
+import com.kmall.admin.cuspay.biz.ali.support.config.AlipayConfig;
+import com.kmall.admin.cuspay.biz.ali.support.sign.MD5;
+import com.kmall.admin.cuspay.biz.ali.support.util.httpClient.HttpProtocolHandler;
+import com.kmall.admin.cuspay.biz.ali.support.util.httpClient.HttpRequest;
+import com.kmall.admin.cuspay.biz.ali.support.util.httpClient.HttpResponse;
+import com.kmall.admin.cuspay.biz.ali.support.util.httpClient.HttpResultType;
+import org.apache.commons.httpclient.NameValuePair;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Node;
+import org.dom4j.io.SAXReader;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/* *
+ *类名:AlipaySubmit
+ *功能:支付宝各接口请求提交类
+ *详细:构造支付宝各接口表单HTML文本,获取远程HTTP数据
+ *版本:3.3
+ *日期:2012-08-13
+ *说明:
+ *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
+ *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
+ */
+
+public class AlipaySubmit {
+    
+    /**
+     * 支付宝提供给商户的服务接入网关URL(新)
+     */
+    private static final String ALIPAY_GATEWAY_NEW = "https://mapi.alipay.com/gateway.do?";
+	
+    /**
+     * 生成签名结果
+     * @param sPara 要签名的数组
+     * @return 签名结果字符串
+     */
+	public static String buildRequestMysign(Map<String, String> sPara) {
+    	String prestr = AlipayCore.createLinkString(sPara); //把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
+        String mysign = "";
+        if(AlipayConfig.sign_type.equals("MD5Util") ) {
+        	mysign = MD5.sign(prestr, AlipayConfig.key, AlipayConfig.input_charset);
+        }
+        return mysign;
+    }
+	
+    /**
+     * 生成要请求给支付宝的参数数组
+     * @param sParaTemp 请求前的参数数组
+     * @return 要请求的参数数组
+     */
+    private static Map<String, String> buildRequestPara(Map<String, String> sParaTemp) {
+        //除去数组中的空值和签名参数
+        Map<String, String> sPara = AlipayCore.paraFilter(sParaTemp);
+        //生成签名结果
+        String mysign = buildRequestMysign(sPara);
+
+        //签名结果与签名方式加入请求提交参数组中
+        sPara.put("sign", mysign);
+        sPara.put("sign_type", AlipayConfig.sign_type);
+
+        return sPara;
+    }
+
+    /**
+     * 建立请求,以表单HTML形式构造(默认)
+     * @param sParaTemp 请求参数数组
+     * @param strMethod 提交方式。两个值可选:post、get
+     * @param strButtonName 确认按钮显示文字
+     * @return 提交表单HTML文本
+     */
+    public static String buildRequest(Map<String, String> sParaTemp, String strMethod, String strButtonName) {
+        //待请求参数数组
+        Map<String, String> sPara = buildRequestPara(sParaTemp);
+        List<String> keys = new ArrayList<String>(sPara.keySet());
+
+        StringBuffer sbHtml = new StringBuffer();
+
+        sbHtml.append("<form id=\"alipaysubmit\" name=\"alipaysubmit\" action=\"" + ALIPAY_GATEWAY_NEW
+                      + "_input_charset=" + AlipayConfig.input_charset + "\" method=\"" + strMethod
+                      + "\">");
+
+        for (int i = 0; i < keys.size(); i++) {
+            String name = (String) keys.get(i);
+            String value = (String) sPara.get(name);
+
+            sbHtml.append("<input type=\"hidden\" name=\"" + name + "\" value=\"" + value + "\"/>");
+        }
+
+        //submit按钮控件请不要含有name属性
+        sbHtml.append("<input type=\"submit\" value=\"" + strButtonName + "\" style=\"display:none;\"></form>");
+        sbHtml.append("<script>document.forms['alipaysubmit'].submit();</script>");
+
+        return sbHtml.toString();
+    }
+    
+    /**
+     * 建立请求,以表单HTML形式构造,带文件上传功能
+     * @param sParaTemp 请求参数数组
+     * @param strMethod 提交方式。两个值可选:post、get
+     * @param strButtonName 确认按钮显示文字
+     * @param strParaFileName 文件上传的参数名
+     * @return 提交表单HTML文本
+     */
+    public static String buildRequest(Map<String, String> sParaTemp, String strMethod, String strButtonName, String strParaFileName) {
+        //待请求参数数组
+        Map<String, String> sPara = buildRequestPara(sParaTemp);
+        List<String> keys = new ArrayList<String>(sPara.keySet());
+
+        StringBuffer sbHtml = new StringBuffer();
+
+        sbHtml.append("<form id=\"alipaysubmit\" name=\"alipaysubmit\"  enctype=\"multipart/form-data\" action=\"" + ALIPAY_GATEWAY_NEW
+                      + "_input_charset=" + AlipayConfig.input_charset + "\" method=\"" + strMethod
+                      + "\">");
+
+        for (int i = 0; i < keys.size(); i++) {
+            String name = keys.get(i);
+            String value = sPara.get(name);
+
+            sbHtml.append("<input type=\"hidden\" name=\"" + name + "\" value=\"" + value + "\"/>");
+        }
+        
+        sbHtml.append("<input type=\"file\" name=\"" + strParaFileName + "\" />");
+
+        //submit按钮控件请不要含有name属性
+        sbHtml.append("<input type=\"submit\" value=\"" + strButtonName + "\" style=\"display:none;\"></form>");
+
+        return sbHtml.toString();
+    }
+    
+    /**
+     * 建立请求,以模拟远程HTTP的POST请求方式构造并获取支付宝的处理结果
+     * 如果接口中没有上传文件参数,那么strParaFileName与strFilePath设置为空值
+     * 如:buildRequest("", "",sParaTemp)
+     * @param strParaFileName 文件类型的参数名
+     * @param strFilePath 文件路径
+     * @param sParaTemp 请求参数数组
+     * @return 支付宝处理结果
+     * @throws Exception
+     */
+    public static String buildRequest(String strParaFileName, String strFilePath,Map<String, String> sParaTemp) throws Exception {
+        //待请求参数数组
+        Map<String, String> sPara = buildRequestPara(sParaTemp);
+
+        HttpProtocolHandler httpProtocolHandler = HttpProtocolHandler.getInstance();
+
+        HttpRequest request = new HttpRequest(HttpResultType.BYTES);
+        //设置编码集
+        request.setCharset(AlipayConfig.input_charset);
+
+        request.setParameters(generatNameValuePair(sPara));
+        request.setUrl(ALIPAY_GATEWAY_NEW+"_input_charset="+AlipayConfig.input_charset);
+
+        HttpResponse response = httpProtocolHandler.execute(request,strParaFileName,strFilePath);
+        if (response == null) {
+            return null;
+        }
+        
+        String strResult = response.getStringResult();
+
+        return strResult;
+    }
+
+    /**
+     * MAP类型数组转换成NameValuePair类型
+     * @param properties  MAP类型数组
+     * @return NameValuePair类型数组
+     */
+    private static NameValuePair[] generatNameValuePair(Map<String, String> properties) {
+        NameValuePair[] nameValuePair = new NameValuePair[properties.size()];
+        int i = 0;
+        for (Map.Entry<String, String> entry : properties.entrySet()) {
+            nameValuePair[i++] = new NameValuePair(entry.getKey(), entry.getValue());
+        }
+
+        return nameValuePair;
+    }
+    
+    /**
+     * 用于防钓鱼,调用接口query_timestamp来获取时间戳的处理函数
+     * 注意:远程解析XML出错,与服务器是否支持SSL等配置有关
+     * @return 时间戳字符串
+     * @throws IOException
+     * @throws DocumentException
+     * @throws MalformedURLException
+     */
+	public static String query_timestamp() throws MalformedURLException,
+            DocumentException, IOException {
+
+        //构造访问query_timestamp接口的URL串
+        String strUrl = ALIPAY_GATEWAY_NEW + "service=query_timestamp&partner=" + AlipayConfig.partner + "&_input_charset" +AlipayConfig.input_charset;
+        StringBuffer result = new StringBuffer();
+
+        SAXReader reader = new SAXReader();
+        Document doc = reader.read(new URL(strUrl).openStream());
+
+        List<Node> nodeList = doc.selectNodes("//alipay/*");
+
+        for (Node node : nodeList) {
+            // 截取部分不需要解析的信息
+            if (node.getName().equals("is_success") && node.getText().equals("T")) {
+                // 判断是否有成功标示
+                List<Node> nodeList1 = doc.selectNodes("//response/timestamp/*");
+                for (Node node1 : nodeList1) {
+                    result.append(node1.getText());
+                }
+            }
+        }
+
+        return result.toString();
+    }
+}

+ 71 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/UtilDate.java

@@ -0,0 +1,71 @@
+
+package com.kmall.admin.cuspay.biz.ali.support.util;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Random;
+
+/* *
+ *类名:UtilDate
+ *功能:自定义订单类
+ *详细:工具类,可以用作获取系统日期、订单编号等
+ *版本:3.3
+ *日期:2012-08-17
+ *说明:
+ *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
+ *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
+ */
+public class UtilDate {
+	
+    /** 年月日时分秒(无下划线) yyyyMMddHHmmss */
+    public static final String dtLong                  = "yyyyMMddHHmmss";
+    
+    /** 完整时间 yyyy-MM-dd HH:mm:ss */
+    public static final String simple                  = "yyyy-MM-dd HH:mm:ss";
+    
+    /** 年月日(无下划线) yyyyMMdd */
+    public static final String dtShort                 = "yyyyMMdd";
+	
+    
+    /**
+     * 返回系统当前时间(精确到毫秒),作为一个唯一的订单编号
+     * @return
+     *      以yyyyMMddHHmmss为格式的当前系统时间
+     */
+	public  static String getOrderNum(){
+		Date date=new Date();
+		DateFormat df=new SimpleDateFormat(dtLong);
+		return df.format(date);
+	}
+	
+	/**
+	 * 获取系统当前日期(精确到毫秒),格式:yyyy-MM-dd HH:mm:ss
+	 * @return
+	 */
+	public  static String getDateFormatter(){
+		Date date=new Date();
+		DateFormat df=new SimpleDateFormat(simple);
+		return df.format(date);
+	}
+	
+	/**
+	 * 获取系统当期年月日(精确到天),格式:yyyyMMdd
+	 * @return
+	 */
+	public static String getDate(){
+		Date date=new Date();
+		DateFormat df=new SimpleDateFormat(dtShort);
+		return df.format(date);
+	}
+	
+	/**
+	 * 产生随机的三位数
+	 * @return
+	 */
+	public static String getThree(){
+		Random rad=new Random();
+		return rad.nextInt(1000)+"";
+	}
+	
+}

+ 191 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/httpClient/HttpProtocolHandler.java

@@ -0,0 +1,191 @@
+package com.kmall.admin.cuspay.biz.ali.support.util.httpClient;
+
+import org.apache.commons.httpclient.*;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.multipart.*;
+import org.apache.commons.httpclient.params.HttpMethodParams;
+import org.apache.commons.httpclient.util.IdleConnectionTimeoutThread;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+
+/* *
+ *类名:HttpProtocolHandler
+ *功能:HttpClient方式访问
+ *详细:获取远程HTTP数据
+ *版本:3.3
+ *日期:2012-08-17
+ *说明:
+ *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
+ *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
+ */
+
+public class HttpProtocolHandler {
+
+    private static String              DEFAULT_CHARSET                     = "GBK";
+
+    /** 连接超时时间,由bean factory设置,缺省为8秒钟 */
+    private int                        defaultConnectionTimeout            = 8000;
+
+    /** 回应超时时间, 由bean factory设置,缺省为30秒钟 */
+    private int                        defaultSoTimeout                    = 30000;
+
+    /** 闲置连接超时时间, 由bean factory设置,缺省为60秒钟 */
+    private int                        defaultIdleConnTimeout              = 60000;
+
+    private int                        defaultMaxConnPerHost               = 30;
+
+    private int                        defaultMaxTotalConn                 = 80;
+
+    /** 默认等待HttpConnectionManager返回连接超时(只有在达到最大连接数时起作用):1秒*/
+    private static final long          defaultHttpConnectionManagerTimeout = 3 * 1000;
+
+    /**
+     * HTTP连接管理器,该连接管理器必须是线程安全的.
+     */
+    private HttpConnectionManager      connectionManager;
+
+    private static HttpProtocolHandler httpProtocolHandler                 = new HttpProtocolHandler();
+
+    /**
+     * 工厂方法
+     * 
+     * @return
+     */
+    public static HttpProtocolHandler getInstance() {
+        return httpProtocolHandler;
+    }
+
+    /**
+     * 私有的构造方法
+     */
+    private HttpProtocolHandler() {
+        // 创建一个线程安全的HTTP连接池
+        connectionManager = new MultiThreadedHttpConnectionManager();
+        connectionManager.getParams().setDefaultMaxConnectionsPerHost(defaultMaxConnPerHost);
+        connectionManager.getParams().setMaxTotalConnections(defaultMaxTotalConn);
+
+        IdleConnectionTimeoutThread ict = new IdleConnectionTimeoutThread();
+        ict.addConnectionManager(connectionManager);
+        ict.setConnectionTimeout(defaultIdleConnTimeout);
+
+        ict.start();
+    }
+
+    /**
+     * 执行Http请求
+     * 
+     * @param request 请求数据
+     * @param strParaFileName 文件类型的参数名
+     * @param strFilePath 文件路径
+     * @return 
+     * @throws HttpException, IOException 
+     */
+    public HttpResponse execute(HttpRequest request, String strParaFileName, String strFilePath) throws HttpException, IOException {
+        HttpClient httpclient = new HttpClient(connectionManager);
+
+        // 设置连接超时
+        int connectionTimeout = defaultConnectionTimeout;
+        if (request.getConnectionTimeout() > 0) {
+            connectionTimeout = request.getConnectionTimeout();
+        }
+        httpclient.getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout);
+
+        // 设置回应超时
+        int soTimeout = defaultSoTimeout;
+        if (request.getTimeout() > 0) {
+            soTimeout = request.getTimeout();
+        }
+        httpclient.getHttpConnectionManager().getParams().setSoTimeout(soTimeout);
+
+        // 设置等待ConnectionManager释放connection的时间
+        httpclient.getParams().setConnectionManagerTimeout(defaultHttpConnectionManagerTimeout);
+
+        String charset = request.getCharset();
+        charset = charset == null ? DEFAULT_CHARSET : charset;
+        HttpMethod method = null;
+
+        //get模式且不带上传文件
+        if (request.getMethod().equals(HttpRequest.METHOD_GET)) {
+            method = new GetMethod(request.getUrl());
+            method.getParams().setCredentialCharset(charset);
+
+            // parseNotifyConfig会保证使用GET方法时,request一定使用QueryString
+            method.setQueryString(request.getQueryString());
+        } else if(strParaFileName.equals("") && strFilePath.equals("")) {
+        	//post模式且不带上传文件
+            method = new PostMethod(request.getUrl());
+            ((PostMethod) method).addParameters(request.getParameters());
+            method.addRequestHeader("Content-Type", "application/x-www-form-urlencoded; text/html; charset=" + charset);
+        }
+        else {
+        	//post模式且带上传文件
+            method = new PostMethod(request.getUrl());
+            List<Part> parts = new ArrayList<Part>();
+            for (int i = 0; i < request.getParameters().length; i++) {
+            	parts.add(new StringPart(request.getParameters()[i].getName(), request.getParameters()[i].getValue(), charset));
+            }
+            //增加文件参数,strParaFileName是参数名,使用本地文件
+            parts.add(new FilePart(strParaFileName, new FilePartSource(new File(strFilePath))));
+            
+            // 设置请求体
+            ((PostMethod) method).setRequestEntity(new MultipartRequestEntity(parts.toArray(new Part[0]), new HttpMethodParams()));
+        }
+
+        // 设置Http Header中的User-Agent属性
+        method.addRequestHeader("User-Agent", "Mozilla/4.0");
+        HttpResponse response = new HttpResponse();
+
+        try {
+            httpclient.executeMethod(method);
+            if (request.getResultType().equals(HttpResultType.STRING)) {
+                response.setStringResult(method.getResponseBodyAsString());
+            } else if (request.getResultType().equals(HttpResultType.BYTES)) {
+                response.setByteResult(method.getResponseBody());
+            }
+            response.setResponseHeaders(method.getResponseHeaders());
+        } catch (UnknownHostException ex) {
+
+            return null;
+        } catch (IOException ex) {
+
+            return null;
+        } catch (Exception ex) {
+
+            return null;
+        } finally {
+            method.releaseConnection();
+        }
+        return response;
+    }
+
+    /**
+     * 将NameValuePairs数组转变为字符串
+     * 
+     * @param nameValues
+     * @return
+     */
+    protected String toString(NameValuePair[] nameValues) {
+        if (nameValues == null || nameValues.length == 0) {
+            return "null";
+        }
+
+        StringBuffer buffer = new StringBuffer();
+
+        for (int i = 0; i < nameValues.length; i++) {
+            NameValuePair nameValue = nameValues[i];
+
+            if (i == 0) {
+                buffer.append(nameValue.getName() + "=" + nameValue.getValue());
+            } else {
+                buffer.append("&" + nameValue.getName() + "=" + nameValue.getValue());
+            }
+        }
+
+        return buffer.toString();
+    }
+}

+ 152 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/httpClient/HttpRequest.java

@@ -0,0 +1,152 @@
+package com.kmall.admin.cuspay.biz.ali.support.util.httpClient;
+
+import org.apache.commons.httpclient.NameValuePair;
+
+/* *
+ *类名:HttpRequest
+ *功能:Http请求对象的封装
+ *详细:封装Http请求
+ *版本:3.3
+ *日期:2011-08-17
+ *说明:
+ *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
+ *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
+ */
+
+public class HttpRequest {
+
+    /** HTTP GET method */
+    public static final String METHOD_GET        = "GET";
+
+    /** HTTP POST method */
+    public static final String METHOD_POST       = "POST";
+
+    /**
+     * 待请求的url
+     */
+    private String             url               = null;
+
+    /**
+     * 默认的请求方式
+     */
+    private String             method            = METHOD_POST;
+
+    private int                timeout           = 0;
+
+    private int                connectionTimeout = 0;
+
+    /**
+     * Post方式请求时组装好的参数值对
+     */
+    private NameValuePair[]    parameters        = null;
+
+    /**
+     * Get方式请求时对应的参数
+     */
+    private String             queryString       = null;
+
+    /**
+     * 默认的请求编码方式
+     */
+    private String             charset           = "GBK";
+
+    /**
+     * 请求发起方的ip地址
+     */
+    private String             clientIp;
+
+    /**
+     * 请求返回的方式
+     */
+    private HttpResultType     resultType        = HttpResultType.BYTES;
+
+    public HttpRequest(HttpResultType resultType) {
+        super();
+        this.resultType = resultType;
+    }
+
+    /**
+     * @return Returns the clientIp.
+     */
+    public String getClientIp() {
+        return clientIp;
+    }
+
+    /**
+     * @param clientIp The clientIp to set.
+     */
+    public void setClientIp(String clientIp) {
+        this.clientIp = clientIp;
+    }
+
+    public NameValuePair[] getParameters() {
+        return parameters;
+    }
+
+    public void setParameters(NameValuePair[] parameters) {
+        this.parameters = parameters;
+    }
+
+    public String getQueryString() {
+        return queryString;
+    }
+
+    public void setQueryString(String queryString) {
+        this.queryString = queryString;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getMethod() {
+        return method;
+    }
+
+    public void setMethod(String method) {
+        this.method = method;
+    }
+
+    public int getConnectionTimeout() {
+        return connectionTimeout;
+    }
+
+    public void setConnectionTimeout(int connectionTimeout) {
+        this.connectionTimeout = connectionTimeout;
+    }
+
+    public int getTimeout() {
+        return timeout;
+    }
+
+    public void setTimeout(int timeout) {
+        this.timeout = timeout;
+    }
+
+    /**
+     * @return Returns the charset.
+     */
+    public String getCharset() {
+        return charset;
+    }
+
+    /**
+     * @param charset The charset to set.
+     */
+    public void setCharset(String charset) {
+        this.charset = charset;
+    }
+
+    public HttpResultType getResultType() {
+        return resultType;
+    }
+
+    public void setResultType(HttpResultType resultType) {
+        this.resultType = resultType;
+    }
+
+}

+ 72 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/httpClient/HttpResponse.java

@@ -0,0 +1,72 @@
+package com.kmall.admin.cuspay.biz.ali.support.util.httpClient;
+
+import com.kmall.admin.cuspay.biz.ali.support.config.AlipayConfig;
+import org.apache.commons.httpclient.Header;
+
+import java.io.UnsupportedEncodingException;
+
+/* *
+ *类名:HttpResponse
+ *功能:Http返回对象的封装
+ *详细:封装Http返回信息
+ *版本:3.3
+ *日期:2011-08-17
+ *说明:
+ *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
+ *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
+ */
+
+public class HttpResponse {
+
+    /**
+     * 返回中的Header信息
+     */
+    private Header[] responseHeaders;
+
+    /**
+     * String类型的result
+     */
+    private String   stringResult;
+
+    /**
+     * btye类型的result
+     */
+    private byte[]   byteResult;
+
+    public Header[] getResponseHeaders() {
+        return responseHeaders;
+    }
+
+    public void setResponseHeaders(Header[] responseHeaders) {
+        this.responseHeaders = responseHeaders;
+    }
+
+    public byte[] getByteResult() {
+        if (byteResult != null) {
+            return byteResult;
+        }
+        if (stringResult != null) {
+            return stringResult.getBytes();
+        }
+        return null;
+    }
+
+    public void setByteResult(byte[] byteResult) {
+        this.byteResult = byteResult;
+    }
+
+    public String getStringResult() throws UnsupportedEncodingException {
+        if (stringResult != null) {
+            return stringResult;
+        }
+        if (byteResult != null) {
+            return new String(byteResult, AlipayConfig.input_charset);
+        }
+        return null;
+    }
+
+    public void setStringResult(String stringResult) {
+        this.stringResult = stringResult;
+    }
+
+}

+ 27 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/ali/support/util/httpClient/HttpResultType.java

@@ -0,0 +1,27 @@
+/*
+ * Alipay.com Inc.
+ * Copyright (c) 2004-2005 All Rights Reserved.
+ */
+package com.kmall.admin.cuspay.biz.ali.support.util.httpClient;
+
+/* *
+ *类名:HttpResultType
+ *功能:表示Http返回的结果字符方式
+ *详细:表示Http返回的结果字符方式
+ *版本:3.3
+ *日期:2012-08-17
+ *说明:
+ *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
+ *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
+ */
+public enum HttpResultType {
+    /**
+     * 字符串方式
+     */
+    STRING,
+
+    /**
+     * 字节数组方式
+     */
+    BYTES
+}

+ 150 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/merch/MerchantNoticeBiz.java

@@ -0,0 +1,150 @@
+package com.kmall.admin.cuspay.biz.merch;
+
+import com.kmall.admin.cuspay.biz.CuspayBiz;
+import com.kmall.admin.cuspay.common.contant.MerchNoticeDict;
+import com.kmall.admin.dao.cuspay.merch.MerchNotiMapper;
+import com.kmall.admin.cuspay.entity.merch.MerchNoti;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseMessage;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseStatus;
+import com.kmall.admin.cuspay.util.OkHttpUtils;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.gson.Gson;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 商户通知请求回执
+ * @author hyq
+ * @version 1.0
+ * 2018-05-23 09:12
+ * @author zhuhh
+ * @version 1.1
+ * @date 2021-12-3 15:02:15
+ *
+ */
+@Component
+@PropertySource(value = {"classpath:conf/cuspay/cuspay-merch-notice.properties"})
+public class MerchantNoticeBiz implements CuspayBiz{
+    private static final Logger logger = LoggerFactory.getLogger(MerchantNoticeBiz.class);
+
+    @Autowired
+    private Environment environment;
+
+    private Integer limit;
+
+    @Autowired
+    private MerchNotiMapper merchNotiMapper;
+
+    @Override
+    public void biz(Map<String, Object> params) {
+        limit = Integer.parseInt(environment.getProperty("db.merch.notice.limit"));
+
+        limit = (limit != null && limit > 0) ? limit : 20;
+        List<MerchNoti> notis = merchNotiMapper.selectMerchNotis(limit);
+
+        if (notis == null || notis.isEmpty()) {
+            logger.info("未查到商户通知数据");
+            return;
+        }
+
+        //记录通知状态
+        List<MerchNoti> noticeList = Lists.newArrayList();
+
+        notis.forEach(noti->{
+
+            if (noti.getNotifyUrl() == null) {
+                logger.error("商户通知回调接口为空");
+                noti.setNotiStatue(MerchNoticeDict.NoticeStatus.i_3.getItem()); //发送失败
+                noti.setIsStoped(MerchNoticeDict.IsStopStatus.i_1.getItem());
+                noticeList.add(noti);
+                return;
+            }
+
+            if (noti.getNotiCount() == null || noti.getNotiCount() <= 0) {
+                logger.error("通知商户次数为空");
+                noti.setNotiStatue(MerchNoticeDict.NoticeStatus.i_3.getItem()); //发送失败
+                noti.setIsStoped(MerchNoticeDict.IsStopStatus.i_1.getItem());
+                noticeList.add(noti);
+                return;
+            }
+
+            //组装需要请求的参数
+            String jsonStr = createJsonByNoti(noti);
+            logger.info("商户通知回调参数Parameters:"+ jsonStr);
+
+            int counter = 0;
+
+            while (counter < noti.getNotiCount()) {
+                ++counter;
+
+                Request request = OkHttpUtils.buildRequest(noti.getNotifyUrl(),
+                        RequestBody.create(OkHttpUtils.JSON, jsonStr));
+                String result = null;
+                try{
+                    result = OkHttpUtils.post(request);
+                    noti.setNotiStatue(MerchNoticeDict.NoticeStatus.i_2.getItem()); //通知发送成功
+                    noti.setIsStoped(MerchNoticeDict.IsStopStatus.i_1.getItem());//停止通知
+                    break;
+                }catch (IOException e) {
+                    logger.error("商户回调通知异常", e);
+                    noti.setNotiStatue(MerchNoticeDict.NoticeStatus.i_3.getItem()); //发送失败
+                    noti.setIsStoped(MerchNoticeDict.IsStopStatus.i_1.getItem());
+                }
+            }
+            noticeList.add(noti);
+        });
+
+        try {
+            int result = merchNotiMapper.updateBatch(noticeList);
+            if (result < 0) {
+                logger.error("更新商户通知数据失败" + noticeList);
+            }
+        } catch (Exception e) {
+            logger.error("更新商户通知数据失败", e);
+            throw new RuntimeException("更新商户通知数据失败",e);
+        }
+    }
+
+    private String createJsonByNoti(MerchNoti noti) {
+        Map<String, String> request = Maps.newHashMap();
+        request.put("merchErpOrderSn",noti.getMerchErpOrderSn());
+        request.put("merchSn", noti.getMerchSn());
+        request.put("allPaySn",noti.getAllPaySn());
+        request.put("allPayNo",noti.getAllPayNo());
+        request.put("allMerchId",noti.getAllMerchId());
+        request.put("allSubOrderNo",noti.getAllSubOrderNo());
+        request.put("buyerPayerCheck",noti.getBuyerPayerCheck());
+        request.put("payChnlFlag",noti.getPayChnlFlag());
+        request.put("code",noti.getCode());
+        request.put("msg",noti.getMsg());
+        request.put("cusDeclStatus", noti.getCusDeclStatus());
+        request.put("thirdPartyMerchCode",noti.getThirdPartyMerchCode());
+        request.put("thirdPartyMerchName",noti.getThirdPartyMerchName());
+        request.put("platNo", noti.getPlatSn());
+        request.put("platName", noti.getPlatName());
+        request.put("merchOrderSn",noti.getAllSubOrderId());
+
+        ResponseMessage responseMessage = new ResponseMessage.Builder()
+                .setCode(ResponseStatus.SUCCESS.getItem())
+                .setData(request).build();
+        return new Gson().toJson(responseMessage);
+    }
+
+    public void bizsTest() {
+        logger.info("测试定时执行11");
+        logger.info("测试定时执行11");
+    }
+
+}

+ 581 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/wx/WxCusDeclareBiz.java

@@ -0,0 +1,581 @@
+package com.kmall.admin.cuspay.biz.wx;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.google.common.base.Strings;
+import com.kmall.admin.cuspay.biz.AbstractCusDeclareBiz;
+import com.kmall.admin.cuspay.biz.CuspayBiz;
+import com.kmall.admin.cuspay.common.contant.MerchNoticeDict;
+import com.kmall.admin.cuspay.common.contant.TablePrimaryKeyPrefix;
+import com.kmall.admin.cuspay.common.core.db.IdWorkerAide;
+import com.kmall.admin.cuspay.entity.merch.MerchNoti;
+import com.kmall.admin.cuspay.entity.merch.MerchPayCfg;
+import com.kmall.admin.cuspay.manager.snow.SnowflakeUtil;
+import com.kmall.admin.cuspay.service.MerchNotiService;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseMessage;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseStatus;
+import com.kmall.admin.cuspay.util.*;
+import com.kmall.admin.cuspay.ccnet2cuspay.common.MerchNotiBuilder;
+import com.kmall.admin.cuspay.ccnet2cuspay.common.wx.WxContants;
+import com.kmall.admin.cuspay.ccnet2cuspay.common.wx.WxDict;
+import com.kmall.admin.cuspay.ccnet2cuspay.dto.wx.WxQueryResponseMsg;
+import com.kmall.admin.cuspay.ccnet2cuspay.dto.wx.WxResponseMsg;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.wx.WxCbPayDoc;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.wx.WxPayError;
+import com.kmall.admin.cuspay.ccnet2cuspay.service.wx.WxCbPayDocService;
+import com.kmall.admin.cuspay.ccnet2cuspay.service.wx.WxPayErrorService;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.kmall.admin.cuspay.util.jackson.JacksonUtil;
+import okhttp3.MediaType;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.bind.JAXB;
+import java.io.IOException;
+import java.io.StringReader;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * 微信海关申报
+ *
+ * @author zx
+ * @version 1.0
+ * 2018-05-23 09:55
+ * @author zhuhh
+ * @version 1.1
+ * @date 2021年12月1日10:00:46
+ */
+@Component
+@PropertySource(value = {"classpath:conf/cuspay/cuspay-wx.properties"})
+public class WxCusDeclareBiz extends AbstractCusDeclareBiz implements CuspayBiz {
+    private static final Logger logger = LoggerFactory.getLogger(WxCusDeclareBiz.class);
+
+    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+    @Autowired
+    private Environment environment;
+
+    private Integer limit;
+
+    private Integer count;
+
+    private String declareURL;
+
+    @Autowired
+    private WxCbPayDocService wxCbPayDocService;
+
+    @Autowired
+    private WxPayErrorService wxPayErrorService;
+
+    @Autowired
+    private MerchNotiService merchNotiService;
+
+    /**
+     * 海关报关接口
+     */
+    @Override
+    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
+    public void biz(Map<String, Object> params) {
+        // 读取配置文件参数
+        limit = Integer.parseInt(environment.getProperty("db.wx.declare.limit"));
+        count = Integer.parseInt(environment.getProperty("db.wx.declare.count"));
+        declareURL = environment.getProperty("wx.payment.declare.url");
+
+        String appid = environment.getProperty("cus.play.wx.app-id");
+        String mchid = environment.getProperty("cus.play.wx.mch-id");
+        String customs = environment.getProperty("cus.play.wx.customs");
+        String platSn = environment.getProperty("merchant.plat-sn");
+        String platName = environment.getProperty("merchant.plat-name");
+        String customsCode = environment.getProperty("merchant.customs-code");
+
+        // 记录异常数据
+        List<WxPayError> errors = Lists.newArrayList();
+        // 待通知的用户
+        List<MerchNoti> merchNotis = Lists.newArrayList();
+        // 微信跨境支付单证
+        WxCbPayDoc wxCbPayDoc = new WxCbPayDoc();
+
+        try {
+            // *********设置支付单报关参数*********
+            // appid
+            wxCbPayDoc.setAppid(appid);
+            // 微信支付商户号
+            wxCbPayDoc.setMchId(mchid);
+            // 商户订单号,商户系统内部订单号
+            wxCbPayDoc.setOutTradeNo(params.get("outTradeNo").toString());
+            // 微信支付订单号
+            wxCbPayDoc.setTransactionId(params.get("transactionId").toString());
+            // 报送海关
+            wxCbPayDoc.setCustoms(customs);
+            // 商户海关备案号
+            wxCbPayDoc.setMchCustomsNo(customsCode);
+            // 如有拆单必传
+            // 商户子订单号
+            if (!StringUtils.isEmpty(params.get("subOrderNo"))) {
+                wxCbPayDoc.setSubOrderNo(params.get("subOrderNo").toString());
+            }
+            // 币种,暂时只支持CNY
+            if (!StringUtils.isEmpty(params.get("feeType"))) {
+                wxCbPayDoc.setFeeType(params.get("feeType").toString());
+            }
+            // 子订单金额,以分为单位
+            if (!StringUtils.isEmpty(params.get("orderFee"))) {
+                wxCbPayDoc.setOrderFee(Integer.parseInt(params.get("orderFee").toString()));
+            }
+            // 物流费用,以分为单位
+            if (!StringUtils.isEmpty(params.get("transportFee"))) {
+                wxCbPayDoc.setTransportFee(Integer.parseInt(params.get("transportFee").toString()));
+            }
+            // 商品费用,以分为单位
+            if (!StringUtils.isEmpty(params.get("productFee"))) {
+                wxCbPayDoc.setProductFee(Integer.parseInt(params.get("productFee").toString()));
+            }
+            // *********设置支付单报关参数*********
+
+            // *********设置商户通知表参数*********
+            // 接入平台内部编号
+            wxCbPayDoc.setMerchErpOrderSn(SysContants.wx_pay_doc + SnowflakeUtil.getSnowNextId());
+            // 商户编号
+            wxCbPayDoc.setMerchSn(params.get("merchSn").toString());
+            // 商户名称
+            wxCbPayDoc.setMerchName(params.get("merchName").toString());
+            // 平台编号
+            wxCbPayDoc.setPlatSn(platSn);
+            // 平台中文名
+            wxCbPayDoc.setPlatName(platName);
+            // 第三方商户代码
+            wxCbPayDoc.setThirdPartyMerchCode(params.get("thirdPartyMerchCode").toString());
+            // 第三方商户名称
+            wxCbPayDoc.setThirdPartyMerchName(params.get("thirdPartyMerchName").toString());
+            // 微信子订单号
+            if (!StringUtils.isEmpty(params.get("subOrderId"))) {
+                wxCbPayDoc.setSubOrderId(params.get("subOrderId").toString());
+            }
+            // *********设置商户通知表参数*********
+        } catch (Exception e) {
+            logger.error("微信支付单设置参数失败:" + e.getMessage());
+            return;
+        }
+
+        // 先将支付单信息写入数据库,后面直接更新状态即可
+        logger.info("微信支付单信息写入数据库开始");
+        try {
+            addWxCbPayDoc(wxCbPayDoc);
+        } catch (Exception e) {
+            logger.error("微信支付单信息写入数据库失败");
+            logger.error(e.getMessage());
+            // 手动回滚事务
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            return;
+        }
+        logger.info("微信支付单信息写入数据库结束");
+
+        // merch_pay_cfg 表由手动配置数据
+        //获取商户信息,先从缓存中获取,缓存不存在再从数据库重取
+        MerchPayCfg merchPayCfg = getMerchPayCfgCache(wxCbPayDoc.getAppid());
+
+        MerchNotiBuilder builder = new MerchNotiBuilder();
+
+        // 设置支付信息
+        builder.wxCbPay(wxCbPayDoc);
+        // 设置通知次数
+        builder.notiCount(count);
+
+        if (merchPayCfg == null) {
+            logger.error("appid为【" + wxCbPayDoc.getAppid() + "】的商户支付配置信息不存在");
+            wxCbPayDoc.setReturnCode("FAIL");
+            wxCbPayDoc.setReturnMsg("appid为【" + wxCbPayDoc.getAppid() + "】的商户支付配置信息不存在");
+            wxCbPayDocService.updateWxCbPay(wxCbPayDoc);
+
+            return;
+        }
+
+        if (merchPayCfg.getMerchWxApiKey() == null) {
+            logger.error("appid为【" + wxCbPayDoc.getAppid() + "】的商户支付信息api密钥为空");
+            wxCbPayDoc.setReturnCode(WxContants.ERROR_NO_INFOMATION);
+            wxCbPayDoc.setReturnMsg("appid为【" + wxCbPayDoc.getAppid() + "】的商户支付信息api密钥为空");
+            wxCbPayDocService.updateWxCbPay(wxCbPayDoc);
+
+            return;
+        }
+        //设置商户配置信息
+        builder.merchPay(merchPayCfg);
+
+        //组装xml 格式数据
+        String xml = XmlUtils.map2Xml(assemblyDeclareXml(wxCbPayDoc, merchPayCfg.getMerchWxApiKey()));
+        logger.info("微信支付报关请求数xml据为:" + xml);
+
+        //通过http post请求 发送xml数据
+        Request request = OkHttpUtils.buildRequest(declareURL,
+                RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml));
+
+        WxResponseMsg wxResponseMsgDto = null;
+        try {
+            // todo, 请求海关接口
+            // String result = OkHttpUtils.post(request);
+            String result = "";
+            StringReader reader = new StringReader(result);
+            wxResponseMsgDto = JAXB.unmarshal(reader, WxResponseMsg.class);
+            logger.info("result:" + result + "wx response message pojo:" + wxResponseMsgDto);
+            if (wxResponseMsgDto == null) {
+                throw new IOException("http请求[" + declareURL + "]响应结果为空");
+            }
+        } catch (IOException e) {
+            logger.error("数据请求异常,支付单请求数据为xml{}", xml, e);
+            WxPayError wxPayError = createWxPayError(wxCbPayDoc);
+            errors.add(wxPayError);
+        }
+
+        MerchNoti merchNoti = new MerchNoti();
+        try {
+            wxCbPayDoc.setResultCode(wxResponseMsgDto.getResultCode());
+            wxCbPayDoc.setReturnCode(wxResponseMsgDto.getReturnCode());
+            wxCbPayDoc.setReturnMsg(wxResponseMsgDto.getReturnMsg());
+            //返回这状态码为成功 业务结果成功
+            if (WxContants.SUCCESS.equals(wxResponseMsgDto.getReturnCode())) {
+                if (WxContants.SUCCESS.equals(wxResponseMsgDto.getResultCode())) {
+                    wxCbPayDoc.setSubOrderNo(wxResponseMsgDto.getSubOrderNo());
+                    wxCbPayDoc.setSubOrderId(wxResponseMsgDto.getSubOrderId());
+
+                    //订购人与支付人校验结果
+                    if (!StringUtils.isEmpty(wxResponseMsgDto.getCertCheckResult())) {
+                        if ("UNCHECKED".equals(wxResponseMsgDto.getCertCheckResult())) { //未知
+                            builder.certCheckResult(MerchNoticeDict.BuyerPayerCheckStatus.i_0.getItem());
+                            wxCbPayDoc.setBuyerPayerCheck(MerchNoticeDict.BuyerPayerCheckStatus.i_0.getItem());
+                        }
+                        if ("SAME".equals(wxResponseMsgDto.getCertCheckResult())) {//一致
+                            builder.certCheckResult(MerchNoticeDict.BuyerPayerCheckStatus.i_1.getItem());
+                            wxCbPayDoc.setBuyerPayerCheck(MerchNoticeDict.BuyerPayerCheckStatus.i_1.getItem());
+                        }
+                        if ("DIFFERENT".equals(wxResponseMsgDto.getCertCheckResult())) {//不一致
+                            builder.certCheckResult(MerchNoticeDict.BuyerPayerCheckStatus.i_2.getItem());
+                            wxCbPayDoc.setBuyerPayerCheck(MerchNoticeDict.BuyerPayerCheckStatus.i_2.getItem());
+                        }
+                    }
+                    //返回状态未申报
+                    if (WxDict.ResponseMsgState.UNDECLARED.getItem().equals(wxResponseMsgDto.getState())) {
+                        wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_10.getItem());
+                        merchNoti = builder.code(wxResponseMsgDto.getErrCode())
+                                .msg(WxDict.ResponseMsgState.UNDECLARED.getItemName())
+                                .cusDeclStatus(WxDict.MerchNoticeStatus.i_10.getItem())
+                                .build();
+                    } else if (WxDict.ResponseMsgState.PROCESSING.getItem().equals(wxResponseMsgDto.getState())) {//申报中
+                        wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_11.getItem());
+                        merchNoti = builder.code(wxResponseMsgDto.getErrCode())
+                                .msg(WxDict.ResponseMsgState.PROCESSING.getItemName())
+                                .cusDeclStatus(WxDict.MerchNoticeStatus.i_11.getItem())
+                                .build();
+                    } else if (WxDict.ResponseMsgState.SUBMITTED.getItem().equals(wxResponseMsgDto.getState())) {//申报已提交
+                        wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_10.getItem());
+                        merchNoti = builder.code(wxResponseMsgDto.getErrCode())
+                                .msg(WxDict.ResponseMsgState.SUBMITTED.getItemName())
+                                .cusDeclStatus(WxDict.MerchNoticeStatus.i_11.getItem())
+                                .build();
+
+                    } else if (WxDict.ResponseMsgState.SUCCESS.getItem().equals(wxResponseMsgDto.getState())) {//申报成功
+                        wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_12.getItem());
+                        merchNoti = builder.code(wxResponseMsgDto.getErrCode())
+                                .msg(wxResponseMsgDto.getErrCodeDes())
+                                .cusDeclStatus(WxDict.MerchNoticeStatus.i_12.getItem())
+                                .build();
+                    } else if (WxDict.ResponseMsgState.FAIL.getItem().equals(wxResponseMsgDto.getState())) {//申报失败
+                        wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_03.getItem());
+                        merchNoti = builder.code(wxResponseMsgDto.getErrCode())
+                                .msg(WxDict.ResponseMsgState.FAIL.getItemName())
+                                .cusDeclStatus(WxDict.MerchNoticeStatus.i_13.getItem())
+                                .build();
+                    } else if (WxDict.ResponseMsgState.EXCEPT.getItem().equals(wxResponseMsgDto.getState())) {//海关接口异常
+                        wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_03.getItem());
+                        merchNoti = builder.code(wxResponseMsgDto.getErrCode())
+                                .msg(WxDict.ResponseMsgState.EXCEPT.getItemName())
+                                .cusDeclStatus(WxDict.MerchNoticeStatus.i_13.getItem())
+                                .build();
+                    }
+                } else {
+                    //返回状态码为成功 业务结果失败
+                    wxCbPayDoc.setErrCode(wxResponseMsgDto.getErrCode());
+                    wxCbPayDoc.setErrCodeDes(wxResponseMsgDto.getErrCodeDes());
+                    wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_13.getItem());
+                    wxCbPayDoc.setBuyerPayerCheck(MerchNoticeDict.BuyerPayerCheckStatus.i_3.getItem());
+                    //[35324042]您的证件号码校验异常请联系财付通客服处理的情况,修改商户通知数据为“身份校验不一致”,“申报成功”
+                    if ("35324042".equalsIgnoreCase(wxResponseMsgDto.getErrCode())) {
+                        builder.certCheckResult(MerchNoticeDict.BuyerPayerCheckStatus.i_2.getItem());
+                        merchNoti = builder.code(wxResponseMsgDto.getErrCode())
+                                .msg(wxResponseMsgDto.getErrCodeDes())
+                                .cusDeclStatus(WxDict.MerchNoticeStatus.i_12.getItem())
+                                .build();
+                    } else {
+                        builder.certCheckResult(MerchNoticeDict.BuyerPayerCheckStatus.i_3.getItem());
+                        merchNoti = builder.code(wxResponseMsgDto.getErrCode())
+                                .msg(wxResponseMsgDto.getErrCodeDes())
+                                .cusDeclStatus(WxDict.MerchNoticeStatus.i_13.getItem())
+                                .build();
+                    }
+                }
+            }
+            ///返回状态码为失败
+            if (WxContants.RETURN_CODE_FAIL.equals(wxResponseMsgDto.getReturnCode()) ||
+                    WxContants.FAIL.equals(wxResponseMsgDto.getReturnCode())) {
+                wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_03.getItem());
+
+                //通知商户
+                merchNoti = builder.code(WxContants.ERROR_FAIL)
+                        .msg(wxResponseMsgDto.getReturnMsg())
+                        .cusDeclStatus(WxDict.MerchNoticeStatus.i_13.getItem())
+                        .build();
+            }
+            wxCbPayDocService.updateWxCbPay(wxCbPayDoc);
+        } catch (Exception e) {
+            logger.error("更新支付单证写入数据库信息状态异常", e);
+            // 手动回滚事务
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            return;
+        }
+        merchNotis.add(merchNoti);
+
+
+        //持久化商户通知数据
+        try {
+            int result = merchNotiService.insertBatch(merchNotis);
+            if (result == 0) {
+                logger.error("持久化" + result + "条商户通知数据失败data:" + merchNotis);
+                throw new Exception("持久化" + result + "条商户通知数据失败data:" + merchNotis);
+            }
+        } catch (Exception e) {
+            logger.error("持久化商户通知数据异常", e);
+            // 手动回滚事务
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            return;
+        }
+        //存储异常记录
+        try {
+            if (errors != null && !errors.isEmpty()) {
+                int errResult = wxPayErrorService.insertWxPayErrorBatch(errors);
+                if (errResult == 0) {
+                    logger.error("持久化支付申报异常信息数据失败data:" + errors);
+                    throw new Exception("持久化支付申报异常信息数据失败data:" + errors);
+                }
+            }
+        } catch (Exception e) {
+            logger.error("持久化支付申报异常信息数据失败data:" + errors, e);
+            // 手动回滚事务
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            return;
+        }
+    }
+
+    /**
+     * 记录异常的支付单证信息
+     *
+     * @param wxCbPayDoc
+     * @return
+     */
+    private WxPayError createWxPayError(WxCbPayDoc wxCbPayDoc) {
+        WxPayError wxPayError = new WxPayError();
+        wxPayError.setErrorSn(TablePrimaryKeyPrefix.wx_pay_error_type + IdWorkerAide.nextId());
+        wxPayError.setWxPaySn(wxCbPayDoc.getTransactionId());
+        wxPayError.setMerchSn(wxCbPayDoc.getMerchSn());
+        wxPayError.setMerchName(wxCbPayDoc.getMerchName());
+        wxPayError.setAppid(wxCbPayDoc.getAppid());
+        wxPayError.setMchId(wxCbPayDoc.getMchId());
+        wxPayError.setOutTradeNo(wxCbPayDoc.getOutTradeNo());
+        wxPayError.setTransactionId(wxCbPayDoc.getTransactionId());
+        wxPayError.setSubOrderNo(wxCbPayDoc.getSubOrderNo());
+        wxPayError.setCustoms(wxCbPayDoc.getCustoms());
+        wxPayError.setErrCode(wxCbPayDoc.getErrCode());
+        wxPayError.setErrMsg(wxCbPayDoc.getReturnMsg());
+        wxPayError.getCreateTime(sdf.format(new Date()));
+        return wxPayError;
+    }
+
+
+    /**
+     * 组装报关所需要的报关数据
+     *
+     * @param wxCbPayDoc 微信支付数据
+     * @param key        微信Api密钥
+     * @return
+     */
+    protected Map<String, String> assemblyDeclareXml(WxCbPayDoc wxCbPayDoc, String key) {
+        // 报关请求参数文档:https://pay.weixin.qq.com/wiki/doc/api/external/declarecustom.php?chapter=18_1
+        //1.选择报关数据,排序
+        SortedMap<String, String> sorted = Maps.newTreeMap();
+        sorted.put("appid", wxCbPayDoc.getAppid());
+        sorted.put("mch_id", wxCbPayDoc.getMchId());
+        sorted.put("out_trade_no", wxCbPayDoc.getOutTradeNo());
+        sorted.put("transaction_id", wxCbPayDoc.getTransactionId());
+        sorted.put("customs", wxCbPayDoc.getCustoms());
+        sorted.put("mch_customs_no", wxCbPayDoc.getMchCustomsNo());
+        // 关税,以分为单位,非必填项,不会提交给海关。少数海关特殊要求上传该字段时需要
+        // sorted.put("duty", String.valueOf(wxCbPayDoc.getDuty()));
+        // 报关信息,不传,默认是新增。ADD 新增报关申请;MODIFY 修改
+        // sorted.put("action_type", "ADD");
+
+        // 以下为拆单必传参数
+        if (wxCbPayDoc.getSubOrderNo() != null && !wxCbPayDoc.getSubOrderNo().isEmpty()) {
+            sorted.put("sub_order_no", wxCbPayDoc.getSubOrderNo());
+        }
+        if (wxCbPayDoc.getFeeType() != null && !wxCbPayDoc.getFeeType().isEmpty()) {
+            sorted.put("fee_type", wxCbPayDoc.getFeeType());
+        }
+        if (wxCbPayDoc.getOrderFee() != null) {
+            sorted.put("order_fee", String.valueOf(wxCbPayDoc.getOrderFee()));
+        }
+        if (wxCbPayDoc.getTransportFee() != null) {
+            sorted.put("transport_fee", String.valueOf(wxCbPayDoc.getTransportFee()));
+        }
+        if (wxCbPayDoc.getProductFee() != null) {
+            sorted.put("product_fee", String.valueOf(wxCbPayDoc.getProductFee()));
+        }
+
+        // 用户实名信息将以微信侧的为准,推送给海关。以下字段上传后,如与微信侧的信息不一致,会反馈给商户,便于商户收集正确的信息用于订单推送,不影响报关结果。
+        if (wxCbPayDoc.getCertType() != null && !wxCbPayDoc.getCertType().isEmpty()) {
+            sorted.put("cert_type", wxCbPayDoc.getCertType());
+        }
+        if (wxCbPayDoc.getCertId() != null && !wxCbPayDoc.getCertId().isEmpty()) {
+            sorted.put("cert_id", wxCbPayDoc.getCertId());
+        }
+        if (wxCbPayDoc.getName() != null && !wxCbPayDoc.getName().isEmpty()) {
+            sorted.put("name", wxCbPayDoc.getName());
+        }
+
+        //2.生成签名
+        StringBuilder sb = new StringBuilder();
+        for (Map.Entry<String, String> entry : sorted.entrySet()) {
+            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
+        }
+        sb.append("key").append("=").append(key);
+        //签名MD5 加密
+        String sign = DigestUtils.md5Hex(sb.toString()).toUpperCase();
+
+        sorted.put("sign", sign);
+        return sorted;
+    }
+
+    /**
+     * 支付单信息写入数据库
+     *
+     * @author zhuhh
+     * @param wxCbPayDoc
+     * @return
+     */
+    protected void addWxCbPayDoc(WxCbPayDoc wxCbPayDoc) {
+        logger.info("微信支付单信息写入数据库接口请求开始");
+        if (wxCbPayDoc == null) {
+            throw new RuntimeException("微信支付单信息写入数据库失败:微信支付单业务数据为空!");
+        }
+        logger.info("微信支付单信息写入数据库接口请求数据:【{}】", JacksonUtil.toJson(wxCbPayDoc));
+
+        //数据校验
+        Map<String, Object> validate = MapBeanUtils.fromObject(wxCbPayDoc);
+        Map<String, Object> beVerified = Maps.newHashMap();
+
+        beVerified.put("merchSn", "商户编号");
+        beVerified.put("merchName", "商户名称");
+        beVerified.put("appid", "微信公众号ID");
+        beVerified.put("mchId","微信支付商户号");
+        beVerified.put("outTradeNo", "商户订单号");
+        beVerified.put("transactionId","微信支付订单号");
+        beVerified.put("customs","报送海关");
+        beVerified.put("mchCustomsNo","商户海关备案号");
+        beVerified.put("merchErpOrderSn","商户erp订单编号");
+
+        ResponseMessage rst = Validator.isEmpty(beVerified, validate);
+        if (ResponseStatus.ERROR.getItem().equals(rst.getCode())) {
+            throw new RuntimeException("微信支付单信息写入数据库失败:微信支付单业务数据校验失败!");
+        }
+
+        // 身份证如不为空则校验身份证格式是否正确
+        if(StringUtils.hasText(wxCbPayDoc.getCertId()) && !Validator.isCardNo(wxCbPayDoc.getCertId())){
+            throw new RuntimeException("身份证格式不正确,请填写正确的号码!");
+        }
+
+        ResponseMessage  responseMessage = wxCbPayDocService.addWxCbPayDoc(wxCbPayDoc);
+
+        // 判断返回结果
+        if (ResponseStatus.SUCCESS.getItem().equals(responseMessage.getCode())) {
+            logger.info(responseMessage.getMsg());
+        } else if (ResponseStatus.ERROR.getItem().equals(responseMessage.getCode())) {
+            logger.error(responseMessage.getMsg());
+            throw new RuntimeException(responseMessage.getMsg());
+        }
+
+    }
+
+    public static void main(String[] args) {
+
+        String queryURL = "https://api.mch.weixin.qq.com/cgi-bin/mch/customs/customdeclarequery";
+        WxCbPayDoc wxCbPayDoc = new WxCbPayDoc();
+        wxCbPayDoc.setAppid("125453");
+        wxCbPayDoc.setMchId("1501125641");
+        wxCbPayDoc.setOutTradeNo("701415011050");
+        wxCbPayDoc.setTransactionId("4200000114201805234418784392");
+        wxCbPayDoc.setCustoms("SHENZHEN");
+        wxCbPayDoc.setMchCustomsNo("4403160Z3Y");//中网科技(深圳)有限公司
+
+
+        SortedMap<String, String> sorted = Maps.newTreeMap();
+        sorted.put("appid", wxCbPayDoc.getAppid());
+        sorted.put("mch_id", wxCbPayDoc.getMchId());
+        sorted.put("out_trade_no", wxCbPayDoc.getOutTradeNo());
+        sorted.put("transaction_id", wxCbPayDoc.getTransactionId());
+        sorted.put("customs", wxCbPayDoc.getCustoms());
+//        sorted.put("mch_customs_no", wxCbPayDoc.getMchCustomsNo());
+        //sorted.put("action_type", "MODIFY ");
+//        sorted.put("cert_type", "IDCARD");
+//        sorted.put("cert_id", "440301198012261939");
+//        sorted.put("name", "司晓峰");
+
+
+        //2.生成签名
+        StringBuilder sb = new StringBuilder();
+        for (Map.Entry<String, String> entry : sorted.entrySet()) {
+            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
+        }
+        sb.append("key").append("=").append("Zx1245uytDLliom12345622222222222");
+        //签名MD5 加密
+        String sign = DigestUtils.md5Hex(sb.toString()).toUpperCase();
+
+        sorted.put("sign", sign);
+
+        String xml = XmlUtils.map2Xml(sorted);
+
+        System.out.println("xml:" + xml);
+
+        //通过http post请求 发送xml数据
+        Request request = OkHttpUtils.buildRequest(queryURL,
+                RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml));
+        String result = null;
+        try {
+            result = OkHttpUtils.post(request);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+
+        System.out.println(result);
+        System.out.println(ReaderXmlForDOM4J.parse(result, 1));
+
+        StringReader reader = new StringReader(result);
+        WxQueryResponseMsg wxResponseMsg = JAXB.unmarshal(reader, WxQueryResponseMsg.class);
+
+        System.out.println(wxResponseMsg);
+
+    }
+
+}

+ 383 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/biz/wx/WxCusDeclareQueryBiz.java

@@ -0,0 +1,383 @@
+package com.kmall.admin.cuspay.biz.wx;
+
+import com.kmall.admin.cuspay.biz.AbstractCusDeclareBiz;
+import com.kmall.admin.cuspay.biz.CuspayBiz;
+import com.kmall.admin.cuspay.common.contant.MerchNoticeDict;
+import com.kmall.admin.cuspay.common.contant.TablePrimaryKeyPrefix;
+import com.kmall.admin.cuspay.common.core.db.IdWorkerAide;
+import com.kmall.admin.cuspay.entity.merch.MerchNoti;
+import com.kmall.admin.cuspay.entity.merch.MerchPayCfg;
+import com.kmall.admin.cuspay.service.MerchNotiService;
+import com.kmall.admin.cuspay.util.OkHttpUtils;
+import com.kmall.admin.cuspay.util.ReaderXmlForDOM4J;
+import com.kmall.admin.cuspay.util.XmlUtils;
+import com.kmall.admin.cuspay.ccnet2cuspay.common.MerchNotiBuilder;
+import com.kmall.admin.cuspay.ccnet2cuspay.common.wx.WxContants;
+import com.kmall.admin.cuspay.ccnet2cuspay.common.wx.WxDict;
+import com.kmall.admin.cuspay.ccnet2cuspay.dto.wx.WxQueryResponseMsg;
+import com.kmall.admin.cuspay.ccnet2cuspay.dto.wx.WxQuerySuccessResponseMsgDto;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.wx.WxCbPayDoc;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.wx.WxPayError;
+import com.kmall.admin.cuspay.ccnet2cuspay.service.wx.WxCbPayDocService;
+import com.kmall.admin.cuspay.ccnet2cuspay.service.wx.WxPayErrorService;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import okhttp3.MediaType;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+
+import javax.xml.bind.JAXB;
+import java.io.IOException;
+import java.io.StringReader;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+
+/**
+ * 微信订单信息查询
+ * @author hyq
+ * @version 1.0
+ * 2018-05-23 17:46
+ */
+@Component
+@PropertySource(value = {"classpath:conf/cuspay/cuspay-wx.properties"})
+public class WxCusDeclareQueryBiz extends AbstractCusDeclareBiz implements CuspayBiz {
+    private static final Logger logger = LoggerFactory.getLogger(WxCusDeclareQueryBiz.class);
+
+    @Autowired
+    private Environment environment;
+
+    private Integer limit;
+
+    private Integer count;
+
+    private String queryURL;
+
+    @Autowired
+    private WxCbPayDocService wxCbPayDocService;
+
+    @Autowired
+    private WxPayErrorService wxPayErrorService;
+
+    @Autowired
+    private MerchNotiService merchNotiService;
+
+    /**
+     * 微信订单信息查询
+     */
+    @Override
+    public void biz(Map<String, Object> params) {
+
+        limit = Integer.parseInt(environment.getProperty("db.wx.declare.limit"));
+        count = Integer.parseInt(environment.getProperty("db.wx.declare.count"));
+        queryURL = environment.getProperty("wx.payment.query.url");
+
+        limit = (limit != null && limit > 0) ? limit : 20;
+        count = (count != null && count > 0) ? count : 10;
+
+        //查出等待处理、业务处理中的支付单证信息
+        List<WxCbPayDoc> wxCbPayDocs = null;
+        try {
+            wxCbPayDocs = wxCbPayDocService.selectPayDocByDocStatus(limit);
+            if (wxCbPayDocs == null || wxCbPayDocs.isEmpty()) {
+                logger.info("未查到等待处理、业务处理中微信推海关的支付数据");
+                return;
+            }
+        } catch (Exception e) {
+            logger.error("查询等待处理、业务处理中微信推海关的支付数据异常", e);
+            return;
+        }
+
+        //请求微信查询接口
+
+        //记录异常数据
+        List<WxPayError> errorList = Lists.newArrayList();
+
+        wxCbPayDocs.forEach(wxCbPayDoc -> {
+            WxQuerySuccessResponseMsgDto querySuccessResponseDto = new WxQuerySuccessResponseMsgDto();
+            //获取商户信息 从缓存中去  缓存不存在 从数据库重取
+            MerchPayCfg merchPayCfg = getMerchPayCfgCache(wxCbPayDoc.getAppid());
+
+            MerchNotiBuilder builder = new MerchNotiBuilder();
+
+            //设置支付信息
+            builder.wxCbPay(wxCbPayDoc);
+            //设置通知次数
+            builder.notiCount(count);
+
+            if (merchPayCfg == null) {
+                wxCbPayDoc.setReturnCode("FAIL");
+                wxCbPayDoc.setReturnMsg("appid为【"+wxCbPayDoc.getAppid()+"】的商户支付配置信息不存在");
+                wxCbPayDocService.updateWxCbPay(wxCbPayDoc);
+                logger.error("appid为【"+wxCbPayDoc.getAppid()+"】的商户支付配置信息不存在 ");
+                return;
+            }
+
+            if (merchPayCfg.getMerchWxApiKey() == null) {
+                wxCbPayDoc.setReturnCode(WxContants.ERROR_NO_INFOMATION);
+                wxCbPayDoc.setReturnMsg("appid为【"+wxCbPayDoc.getAppid()+"】的商户支付信息api密钥为空");
+                wxCbPayDocService.updateWxCbPay(wxCbPayDoc);
+                logger.error("appid为【"+wxCbPayDoc.getAppid()+"】的商户支付信息api密钥为空 ");
+                return;
+            }
+            //设置商户配置信息
+            builder.merchPay(merchPayCfg);
+
+            //组装xml 格式数据
+            String xml = XmlUtils.map2Xml(assemblyDeclareQueryXml(wxCbPayDoc, merchPayCfg.getMerchWxApiKey()));
+            logger.info("微信查询订单请求数xml据为:"+xml);
+
+            //通过http post请求 发送xml数据
+            Request request = OkHttpUtils.buildRequest(queryURL,
+                    RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml));
+
+            WxQueryResponseMsg wxQueryResponseMsg = null;
+            String result = "";
+            try {
+                result = OkHttpUtils.post(request);
+                StringReader reader = new StringReader(result);
+                wxQueryResponseMsg = JAXB.unmarshal(reader, WxQueryResponseMsg.class);
+                logger.info("请求微信查询订单接口返回result:"+result + ";xml:"+wxQueryResponseMsg);
+                if (wxQueryResponseMsg == null) {
+                    throw new IOException("http请求["+queryURL+"]响应结果为空" );
+                }
+            } catch (IOException e) {
+                logger.error("数据请求异常,查询订单请求数据为xml{}", xml, e);
+                WxPayError wxPayError = createWxPayError(wxCbPayDoc, querySuccessResponseDto);
+                errorList.add(wxPayError);
+            }
+            MerchNoti merchNoti = new MerchNoti();
+            String allSubOrderId = "";
+            String allSubOrderNo = "";
+            try {
+                //返回状态码为成功
+                if(WxContants.SUCCESS.equals(wxQueryResponseMsg.getReturnCode())){
+
+                    wxCbPayDoc.setResultCode(wxQueryResponseMsg.getResultCode());
+                    wxCbPayDoc.setReturnCode(wxQueryResponseMsg.getReturnCode());
+                    wxCbPayDoc.setReturnMsg(wxQueryResponseMsg.getReturnMsg());
+                    wxCbPayDoc.setErrCode(wxQueryResponseMsg.getErrCode());
+                    wxCbPayDoc.setErrCodeDes(wxQueryResponseMsg.getErrCodeDes());
+                    //业务状态码为成功
+                    if(WxContants.SUCCESS.equals(wxQueryResponseMsg.getResultCode())){
+                        wxCbPayDoc.setTransactionId(wxQueryResponseMsg.getTransactionId());
+
+                        //订购人与支付人校验结果
+                        if (wxCbPayDoc.getBuyerPayerCheck() != null) {
+                            if (MerchNoticeDict.BuyerPayerCheckStatus.i_0.getItem().equals(wxCbPayDoc.getBuyerPayerCheck())) { //未知
+                                builder.certCheckResult(MerchNoticeDict.BuyerPayerCheckStatus.i_0.getItem());
+                            }
+                            if (MerchNoticeDict.BuyerPayerCheckStatus.i_1.getItem().equals(wxCbPayDoc.getBuyerPayerCheck())) {//一致
+                                builder.certCheckResult(MerchNoticeDict.BuyerPayerCheckStatus.i_1.getItem());
+                            }
+                            if (MerchNoticeDict.BuyerPayerCheckStatus.i_2.getItem().equals(wxCbPayDoc.getBuyerPayerCheck())) {//不一致
+                                builder.certCheckResult(MerchNoticeDict.BuyerPayerCheckStatus.i_2.getItem());
+                            }
+                            if(MerchNoticeDict.BuyerPayerCheckStatus.i_3.getItem().equals(wxCbPayDoc.getBuyerPayerCheck())){//校验异常
+                                builder.certCheckResult(MerchNoticeDict.BuyerPayerCheckStatus.i_3.getItem());
+                                wxCbPayDoc.setBuyerPayerCheck(MerchNoticeDict.BuyerPayerCheckStatus.i_3.getItem());
+                            }
+                        }
+
+                        int msgCount = wxQueryResponseMsg.getCount();
+                        for (int i = 0; i < msgCount; i++){
+                            //解析xml获取WxQuerySuccessResponseMsgDto
+                            querySuccessResponseDto = ReaderXmlForDOM4J.parse(result, i);
+                            wxCbPayDoc.setSubOrderNo(querySuccessResponseDto.getSubOrderNo());
+                            wxCbPayDoc.setSubOrderId(querySuccessResponseDto.getSubOrderId());
+                            wxCbPayDoc.setMchCustomsNo(querySuccessResponseDto.getMchCustomsNo());
+                            wxCbPayDoc.setCustoms(querySuccessResponseDto.getCustoms());
+                            wxCbPayDoc.setFeeType(querySuccessResponseDto.getFeeType());
+                            wxCbPayDoc.setOrderFee(querySuccessResponseDto.getOrderFee());
+                            wxCbPayDoc.setDuty(querySuccessResponseDto.getDuty());
+                            wxCbPayDoc.setTransportFee(querySuccessResponseDto.getTransportFee());
+                            wxCbPayDoc.setProductFee(querySuccessResponseDto.getProductFee());
+                            allSubOrderId = querySuccessResponseDto.getSubOrderId();
+                            allSubOrderNo = querySuccessResponseDto.getSubOrderNo();
+
+                            String state = querySuccessResponseDto.getState();
+
+                            if (WxDict.ResponseMsgState.UNDECLARED.getItem().equals(state)) {//返回状态未申报
+                                wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_10.getItem());
+                                merchNoti = builder.code(wxQueryResponseMsg.getErrCode())
+                                        .msg(WxDict.ResponseMsgState.UNDECLARED.getItemName())
+                                        .cusDeclStatus(WxDict.MerchNoticeStatus.i_10.getItem())
+                                        .build();
+                            }else if (WxDict.ResponseMsgState.PROCESSING.getItem().equals(state)) {// 申报中
+                                wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_11.getItem());
+                                merchNoti = builder.code(wxQueryResponseMsg.getErrCode())
+                                        .msg(WxDict.ResponseMsgState.PROCESSING.getItemName())
+                                        .cusDeclStatus(WxDict.MerchNoticeStatus.i_11.getItem())
+                                        .build();
+                            }else if(WxDict.ResponseMsgState.SUBMITTED.getItem().equals(state)) {//申报已提交
+                                wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_10.getItem());
+                                merchNoti = builder.code(wxQueryResponseMsg.getErrCode())
+                                        .msg(WxDict.ResponseMsgState.SUBMITTED.getItemName())
+                                        .cusDeclStatus(WxDict.MerchNoticeStatus.i_11.getItem())
+                                        .build();
+
+                            }else if (WxDict.ResponseMsgState.SUCCESS.getItem().equals(state)) {//申报成功
+                                wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_12.getItem());
+                                merchNoti = builder.code(wxQueryResponseMsg.getErrCode())
+                                        .msg(wxQueryResponseMsg.getErrCodeDes())
+                                        .cusDeclStatus(WxDict.MerchNoticeStatus.i_12.getItem())
+                                        .build();
+                            }else if (WxDict.ResponseMsgState.FAIL.getItem().equals(state)) {//申报失败
+                                wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_03.getItem());
+                                merchNoti = builder.code(wxQueryResponseMsg.getErrCode())
+                                        .msg(WxDict.ResponseMsgState.FAIL.getItemName())
+                                        .cusDeclStatus(WxDict.MerchNoticeStatus.i_13.getItem())
+                                        .build();
+                            }else if (WxDict.ResponseMsgState.EXCEPT.getItem().equals(state)) {//海关接口异常
+                                wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_03.getItem());
+                                merchNoti = builder.code(wxQueryResponseMsg.getErrCode())
+                                        .msg(WxDict.ResponseMsgState.EXCEPT.getItemName())
+                                        .cusDeclStatus(WxDict.MerchNoticeStatus.i_13.getItem())
+                                        .build();
+                            }
+                            wxCbPayDocService.updateWxCbPay(wxCbPayDoc);
+
+                            MerchNoti noti = new MerchNoti();
+                            noti.setCode(wxQueryResponseMsg.getErrCode());
+                            noti.setAllPayNo(wxQueryResponseMsg.getTransactionId());
+                            noti.setCusDeclStatus(merchNoti.getCusDeclStatus());
+                            noti.setAllSubOrderNo(allSubOrderNo);
+                            updateMerchNoti(noti,allSubOrderId,merchNoti);//更新商户通知
+                        }
+                    }else{//业务状态码失败
+                        wxCbPayDoc.setErrCode(wxQueryResponseMsg.getErrCode());
+                        wxCbPayDoc.setErrCodeDes(wxQueryResponseMsg.getErrCodeDes());
+                        wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_13.getItem());
+
+                        merchNoti = builder.code(wxQueryResponseMsg.getErrCode())
+                                .msg(wxQueryResponseMsg.getErrCodeDes())
+                                .cusDeclStatus(WxDict.MerchNoticeStatus.i_13.getItem())
+                                .build();
+                        wxCbPayDocService.updateWxCbPay(wxCbPayDoc);
+
+                        MerchNoti noti = new MerchNoti();
+                        noti.setCode(wxQueryResponseMsg.getErrCode());
+                        noti.setAllPayNo(wxQueryResponseMsg.getTransactionId());
+                        noti.setCusDeclStatus(merchNoti.getCusDeclStatus());
+                        noti.setAllSubOrderNo(allSubOrderNo);
+                        updateMerchNoti(noti,allSubOrderId,merchNoti);//更新商户通知
+                    }
+                }
+                ///返回状态码为失败
+                if (WxContants.RETURN_CODE_FAIL.equals(wxQueryResponseMsg.getReturnCode()) ||
+                        WxContants.FAIL.equals(wxQueryResponseMsg.getReturnCode())) {
+                    wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_03.getItem());
+                    //通知商户
+                    merchNoti = builder.code(WxContants.ERROR_FAIL)
+                            .msg(wxQueryResponseMsg.getReturnMsg())
+                            .cusDeclStatus(WxDict.MerchNoticeStatus.i_13.getItem())
+                            .build();
+                    wxCbPayDocService.updateWxCbPay(wxCbPayDoc);
+
+                    MerchNoti noti = new MerchNoti();
+                    noti.setCode(wxQueryResponseMsg.getErrCode());
+                    noti.setAllPayNo(wxQueryResponseMsg.getTransactionId());
+                    noti.setCusDeclStatus(merchNoti.getCusDeclStatus());
+                    noti.setAllSubOrderNo(allSubOrderNo);
+                    updateMerchNoti(noti,allSubOrderId,merchNoti);//更新商户通知
+                }
+            } catch (Exception e) {
+                logger.error("更新支付单证入库信息状态异常", e);
+                return;
+            }
+        });
+        //存储异常记录
+        try {
+            if (errorList != null && !errorList.isEmpty()) {
+                int errResult = wxPayErrorService.insertWxPayErrorBatch(errorList);
+                if (errResult == 0) {
+                    logger.error("持久化支付申报异常数据失败data:" + errorList);
+                    throw new Exception("持久化支付申报异常数据失败data:" + errorList);
+                }
+            }
+        } catch (Exception e) {
+            logger.error("持久化支付申报异常数据失败data:" + errorList, e);
+            throw new RuntimeException("持久化支付申报异常数据失败data:",e);
+        }
+
+    }
+    private void updateMerchNoti(MerchNoti noti,String allSubOrderId,MerchNoti merchNoti){
+        List<MerchNoti> merchNotiList = merchNotiService.getMerchNotiByCodeAndOrderNo(noti);
+        if(merchNotiList != null && merchNotiList.size()>0){
+            MerchNoti merchNoti1 = merchNotiList.get(0);
+            merchNoti1.setTstm(new Date());
+            merchNoti1.setAllSubOrderId(allSubOrderId);
+            merchNotiService.update(merchNoti1);
+        }else{
+            merchNoti.setNotiSn(TablePrimaryKeyPrefix.merch_pay_noti_type + IdWorkerAide.nextId());
+            merchNotiService.insert(merchNoti);
+        }
+    }
+    /**
+     * 记录异常的支付单证信息
+     * @param wxCbPayDoc
+     * @return
+     */
+    private WxPayError createWxPayError(WxCbPayDoc wxCbPayDoc, WxQuerySuccessResponseMsgDto querySuccessDto) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        WxPayError wxPayError = new WxPayError();
+        wxPayError.setErrorSn(TablePrimaryKeyPrefix.wx_pay_error_type + IdWorkerAide.nextId());
+        wxPayError.setWxPaySn(wxCbPayDoc.getTransactionId());
+        wxPayError.setMerchSn(wxCbPayDoc.getMerchSn());
+        wxPayError.setMerchName(wxCbPayDoc.getMerchName());
+        wxPayError.setAppid(wxCbPayDoc.getAppid());
+        wxPayError.setMchId(wxCbPayDoc.getMchId());
+        wxPayError.setOutTradeNo(wxCbPayDoc.getOutTradeNo());
+        wxPayError.setTransactionId(wxCbPayDoc.getTransactionId());
+        wxPayError.setSubOrderNo(querySuccessDto.getSubOrderNo());
+        wxPayError.setCustoms(querySuccessDto.getCustoms());
+        wxPayError.setErrCode(wxCbPayDoc.getErrCode());
+        wxPayError.setErrMsg(wxCbPayDoc.getReturnMsg());
+        wxPayError.getCreateTime(sdf.format(new Date()));
+        return  wxPayError;
+    }
+
+    /**
+     * 组装微信查询订单所需要的参数数据
+     * @param wxCbPayDoc 微信支付数据
+     * @param key 微信Api密钥
+     * @return
+     */
+    protected Map<String, String> assemblyDeclareQueryXml(WxCbPayDoc wxCbPayDoc, String key) {
+        //1.选择报关数据,排序
+        SortedMap<String, String> sorted = Maps.newTreeMap();
+        sorted.put("sign_type", "MD5");
+        sorted.put("appid", wxCbPayDoc.getAppid());
+        sorted.put("mch_id", wxCbPayDoc.getMchId());
+        sorted.put("out_trade_no", wxCbPayDoc.getOutTradeNo());
+        sorted.put("transaction_id", wxCbPayDoc.getTransactionId());
+        if(org.apache.commons.lang3.StringUtils.isNotEmpty(wxCbPayDoc.getSubOrderNo())) {
+            sorted.put("sub_order_no", wxCbPayDoc.getSubOrderNo());
+        }
+        sorted.put("customs", wxCbPayDoc.getCustoms());
+
+        //2.生成签名
+        StringBuilder sb = new StringBuilder();
+        for (Map.Entry<String,String> entry : sorted.entrySet()) {
+            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
+        }
+        sb.append("key").append("=").append(key);
+        //签名MD5 加密
+        String sign = DigestUtils.md5Hex(sb.toString()).toUpperCase();
+
+        sorted.put("sign", sign);
+        return sorted;
+    }
+
+
+}

+ 116 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/common/MerchNotiBuilder.java

@@ -0,0 +1,116 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.common;
+
+import com.kmall.admin.cuspay.ccnet2cuspay.common.wx.WxDict;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.ali.AliCbPayDoc;
+import com.kmall.admin.cuspay.common.contant.TablePrimaryKeyPrefix;
+import com.kmall.admin.cuspay.common.core.db.IdWorkerAide;
+import com.kmall.admin.cuspay.entity.merch.MerchNoti;
+import com.kmall.admin.cuspay.entity.merch.MerchPayCfg;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.wx.WxCbPayDoc;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * @author zx
+ * @version 1.0
+ * 2018-05-19 09:02
+ */
+public class MerchNotiBuilder {
+
+    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+    /**
+     * 默认通知次数
+     */
+    private final int defaultCount = 1;
+
+    private MerchNoti merchNoti;
+
+    public MerchNoti getMerchNoti() {
+        return this.merchNoti;
+    }
+
+    public void setMerchNoti(MerchNoti merchNoti) {
+        this.merchNoti = merchNoti;
+    }
+
+    public MerchNotiBuilder() {
+        this.merchNoti = new MerchNoti();
+        this.merchNoti.setNotiSn(TablePrimaryKeyPrefix.merch_pay_noti_type + IdWorkerAide.nextId());
+        this.merchNoti.setNotiCount(defaultCount);
+        this.merchNoti.setIsStoped(WxDict.IsStopStatus.i_0.getItem());
+        this.merchNoti.setNotiStatue(WxDict.NoticeStatus.i_0.getItem());
+    }
+
+    public MerchNotiBuilder wxCbPay(WxCbPayDoc wxCbPay) {
+        this.merchNoti.setMerchErpOrderSn(wxCbPay.getMerchErpOrderSn());
+        this.merchNoti.setMerchSn(wxCbPay.getMerchSn());
+        this.merchNoti.setMerchName(wxCbPay.getMerchName());
+        this.merchNoti.setPlatSn(wxCbPay.getPlatSn());
+        this.merchNoti.setPlatName(wxCbPay.getPlatName());
+        this.merchNoti.setThirdPartyMerchCode(wxCbPay.getThirdPartyMerchCode());
+        this.merchNoti.setThirdPartyMerchName(wxCbPay.getThirdPartyMerchName());
+        this.merchNoti.setAllMerchId(wxCbPay.getMchId());
+        this.merchNoti.setAllOrderNo(wxCbPay.getOutTradeNo());
+        this.merchNoti.setAllPayNo(wxCbPay.getTransactionId());
+        this.merchNoti.setAllSubOrderNo(wxCbPay.getSubOrderNo());
+        this.merchNoti.setAllSubOrderId(wxCbPay.getSubOrderId());
+        this.merchNoti.setCreaterSn("1");
+        this.merchNoti.setCreateTime(sdf.format(new Date()));
+        return this;
+    }
+
+    public MerchNotiBuilder aliCbPay(AliCbPayDoc aliCbPay) {
+        this.merchNoti.setMerchErpOrderSn(aliCbPay.getMerchErpOrderSn());
+        this.merchNoti.setMerchSn(aliCbPay.getMerchSn());
+        this.merchNoti.setMerchName(aliCbPay.getMerchName());
+        this.merchNoti.setPlatSn(aliCbPay.getPlatSn());
+        this.merchNoti.setPlatName(aliCbPay.getPlatName());
+        this.merchNoti.setThirdPartyMerchCode(aliCbPay.getThirdPartyMerchCode());
+        this.merchNoti.setThirdPartyMerchName(aliCbPay.getThirdPartyMerchName());
+        this.merchNoti.setAllMerchId(aliCbPay.getMerchSn());
+        this.merchNoti.setAllOrderNo(aliCbPay.getTradeNo());
+        this.merchNoti.setAllPayNo(aliCbPay.getAliPaySn());
+        this.merchNoti.setCreaterSn("1");
+        this.merchNoti.setCreateTime(this.sdf.format(new Date()));
+        return this;
+    }
+
+    public MerchNotiBuilder merchPay(MerchPayCfg merchPay) {
+        this.merchNoti.setPayChnlFlag(merchPay.getPayChnlFlag());
+        this.merchNoti.setNotifyUrl(merchPay.getNotifyUrl());
+        return this;
+    }
+
+    public MerchNotiBuilder code(String code) {
+        this.merchNoti.setCode(code);
+        return this;
+    }
+
+    public MerchNotiBuilder msg(String msg) {
+        this.merchNoti.setMsg(msg);
+        return this;
+    }
+
+    public MerchNotiBuilder cusDeclStatus(String cusDeclStatus) {
+        this.merchNoti.setCusDeclStatus(cusDeclStatus);
+        return this;
+    }
+
+    public MerchNotiBuilder notiCount(Integer count) {
+        int notiCount = (count != null && count > 0) ? count : defaultCount;
+        this.merchNoti.setNotiCount(notiCount);
+        return this;
+    }
+
+    public MerchNotiBuilder certCheckResult(String result) {
+        this.merchNoti.setBuyerPayerCheck(result);
+        return  this;
+    }
+
+    public MerchNoti build() {
+        return this.merchNoti;
+    }
+
+}

+ 40 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/common/ali/AliContants.java

@@ -0,0 +1,40 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.common.ali;
+
+/**
+ * @author zx
+ * @version 1.0
+ * 2018-05-19 08:45
+ */
+public abstract class AliContants {
+
+    public final static String FAIL = "FAIL";
+
+    public final static String RETURN_CODE_FAIL = "RETURN_CODE_FAIL";
+
+    public final static String SUCCESS = "SUCCESS";
+
+    /**
+     * 商户支付配置信息不存在
+     */
+    public final static String ERROR_NO_INFOMATION = "-1";
+
+    /**
+     * 没有商户支付配置信息API密钥不存在
+     */
+    public final static String ERROR_NO_API_KEY = "-2";
+
+    /**
+     *海关校验失败
+     */
+    public final static String ERROR_FAIL = "-3";
+
+    /**
+     *海关接口异常
+     */
+    public final static String  ERROR_EXCEPT = "-4";
+
+    /**
+     *未申报
+     */
+    public final static String  ERROR_UN_DECLARE = "-5";
+}

+ 228 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/common/ali/AliDict.java

@@ -0,0 +1,228 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.common.ali;
+
+public abstract class AliDict {
+    public enum PaymentDocStatus {
+        i_00("00", "待申报"),
+        i_01("01", "申报中"),
+        i_03("03", "申报失败"),
+        i_10("10", "等待处理"),
+        i_11("11", "业务处理中"),
+        i_12("12", "业务成功"),
+        i_13("13", "业务处理失败");
+
+        private String item;
+
+        private String itemName;
+
+        PaymentDocStatus(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return this.item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return this.itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    public enum ResponseMsgState {
+        WS("WS", "未申报"),
+        SENDING("SENDING", "申报已提交"),
+        PROCESSING("PROCESSING", "申报中"),
+        SUCCESS("SUCCESS", "申报成功"),
+        SUCC("SUCC", "海关返回受理成功"),
+        FAIL("FAIL", "申报失败"),
+        EXCEPT("EXCEPT", "海关接口异常");
+
+        private String item;
+
+        private String itemName;
+
+        ResponseMsgState(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return this.item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return this.itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    public enum Whether {
+        Yes("Y", "是"),
+        No("N", "否");
+
+        private String item;
+
+        private String itemName;
+
+        Whether(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return this.item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return this.itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    public enum BuyerPayerCheckStatus {
+        i_0("0", "未知"),
+        i_1("1", "一致"),
+        i_2("2", "不一致");
+
+        private String item;
+
+        private String itemName;
+
+        BuyerPayerCheckStatus(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return this.item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return this.itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    public enum IsStopStatus {
+        i_0("0", "否"),
+        i_1("1", "是");
+
+        private String item;
+
+        private String itemName;
+
+        IsStopStatus(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return this.item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return this.itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    public enum NoticeStatus {
+        i_0("0", "初始"),
+        i_1("1", "通知已发送"),
+        i_2("2", "通知发送成功"),
+        i_3("3", "通知发送失败");
+
+        private String item;
+
+        private String itemName;
+
+        NoticeStatus(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return this.item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return this.itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    public enum MerchNoticeStatus {
+        i_10("10", "等待海关处理"),
+        i_11("11", "海关申报中"),
+        i_12("12", "海关申报成功"),
+        i_13("13", "海关申报失败");
+
+        private String item;
+
+        private String itemName;
+
+        MerchNoticeStatus(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return this.item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return this.itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+}

+ 40 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/common/wx/WxContants.java

@@ -0,0 +1,40 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.common.wx;
+
+/**
+ * @author zx
+ * @version 1.0
+ * 2018-05-19 08:45
+ */
+public abstract class WxContants {
+
+    public final static String FAIL = "FAIL";
+
+    public final static String RETURN_CODE_FAIL = "RETURN_CODE_FAIL";
+
+    public final static String SUCCESS = "SUCCESS";
+
+    /**
+     * 商户支付配置信息不存在
+     */
+    public final static String ERROR_NO_INFOMATION = "-1";
+
+    /**
+     * 没有商户支付配置信息API密钥不存在
+     */
+    public final static String ERROR_NO_API_KEY = "-2";
+
+    /**
+     *海关校验失败
+     */
+    public final static String ERROR_FAIL = "-3";
+
+    /**
+     *海关接口异常
+     */
+    public final static String  ERROR_EXCEPT = "-4";
+
+    /**
+     *未申报
+     */
+    public final static String  ERROR_UN_DECLARE = "-5";
+}

+ 237 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/common/wx/WxDict.java

@@ -0,0 +1,237 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.common.wx;
+
+/**
+ * @author zx
+ * @version 1.0
+ * 2018-05-15 13:56
+ */
+public abstract class WxDict {
+
+    /**
+     * 微信支付单证状态
+     */
+    public enum PaymentDocStatus {
+        i_00("00","待申报"),
+        i_01("01", "申报中"),
+        i_03("03", "申报失败"),
+        i_10("10", "等待处理"),
+        i_11("11","业务处理中"),
+        i_12("12","业务成功"),
+        i_13("13", "业务处理失败");
+
+
+
+        private String item;
+        private String itemName;
+
+        PaymentDocStatus(String item, String itemName){
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    public enum  ResponseMsgState{
+        UNDECLARED("UNDECLARED", "未申报"),
+        SUBMITTED("SUBMITTED","申报已提交"),
+        PROCESSING("PROCESSING","申报中"),
+        SUCCESS("SUCCESS","申报成功"),
+        FAIL("FAIL","申报失败"),
+        EXCEPT("EXCEPT","海关接口异常");
+
+        private String item;
+        private String itemName;
+
+        ResponseMsgState(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    public enum Whether {
+        Yes("Y", "是"),
+        No("N","否");
+
+        private String item;
+        private String itemName;
+
+        Whether(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    public enum BuyerPayerCheckStatus {
+        i_0("0", "未知"),
+        i_1("1", "一致"),
+        i_2("2", "不一致");
+
+        private String item;
+        private String itemName;
+
+        BuyerPayerCheckStatus(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    /**
+     * 是否停止通知
+     */
+    public enum IsStopStatus {
+        i_0("0", "否"),
+        i_1("1", "是");
+
+        private String item;
+        private String itemName;
+
+        IsStopStatus(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    /**
+     * 通知状态
+     */
+    public enum NoticeStatus {
+        i_0("0", "初始"),
+        i_1("1", "通知已发送"),
+        i_2("2", "通知发送成功"),
+        i_3("3", "通知发送失败");
+
+        private String item;
+        private String itemName;
+
+        NoticeStatus(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    public enum MerchNoticeStatus {
+        i_10("10", "等待海关处理"),
+        i_11("11", "海关申报中"),
+        i_12("12", "海关申报成功"),
+        i_13("13", "海关申报失败");
+
+        private String item;
+        private String itemName;
+
+        MerchNoticeStatus(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+}

+ 110 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/ali/AliCusDeclareBizDto.java

@@ -0,0 +1,110 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.dto.ali;
+
+public class AliCusDeclareBizDto extends AliCusDeclareRequestDto {
+    private String out_request_no;
+
+    private String trade_no;
+
+    private String merchant_customs_code;
+
+    private String amount;
+
+    private String customs_place;
+
+    private String merchant_customs_name;
+
+    private String is_split;
+
+    private String sub_out_biz_no;
+
+    private String buyer_name;
+
+    private String buyer_id_no;
+
+
+    public String getOut_request_no() {
+        return this.out_request_no;
+    }
+
+    public void setOut_request_no(String out_request_no) {
+        this.out_request_no = out_request_no;
+    }
+
+    public String getTrade_no() {
+        return this.trade_no;
+    }
+
+    public void setTrade_no(String trade_no) {
+        this.trade_no = trade_no;
+    }
+
+    public String getMerchant_customs_code() {
+        return this.merchant_customs_code;
+    }
+
+    public void setMerchant_customs_code(String merchant_customs_code) {
+        this.merchant_customs_code = merchant_customs_code;
+    }
+
+    public String getAmount() {
+        return this.amount;
+    }
+
+    public void setAmount(String amount) {
+        this.amount = amount;
+    }
+
+    public String getCustoms_place() {
+        return this.customs_place;
+    }
+
+    public void setCustoms_place(String customs_place) {
+        this.customs_place = customs_place;
+    }
+
+    public String getMerchant_customs_name() {
+        return this.merchant_customs_name;
+    }
+
+    public void setMerchant_customs_name(String merchant_customs_name) {
+        this.merchant_customs_name = merchant_customs_name;
+    }
+
+    public String getIs_split() {
+        return this.is_split;
+    }
+
+    public void setIs_split(String is_split) {
+        this.is_split = is_split;
+    }
+
+    public String getSub_out_biz_no() {
+        return this.sub_out_biz_no;
+    }
+
+    public void setSub_out_biz_no(String sub_out_biz_no) {
+        this.sub_out_biz_no = sub_out_biz_no;
+    }
+
+    public String getBuyer_name() {
+        return this.buyer_name;
+    }
+
+    public void setBuyer_name(String buyer_name) {
+        this.buyer_name = buyer_name;
+    }
+
+    public String getBuyer_id_no() {
+        return this.buyer_id_no;
+    }
+
+    public void setBuyer_id_no(String buyer_id_no) {
+        this.buyer_id_no = buyer_id_no;
+    }
+}
+
+
+/* Location:              E:\shipeng.liu\cuspay_cw\classes\!\com.kmall.admin\cuspay\ccnet2cuspay\dto\ali\AliCusDeclareBizDto.class
+ * Java compiler version: 8 (52.0)
+ * JD-Core Version:       1.1.3
+ */

+ 13 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/ali/AliCusDeclareQueryBizDto.java

@@ -0,0 +1,13 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.dto.ali;
+
+public class AliCusDeclareQueryBizDto extends AliCusDeclareRequestDto {
+    private String out_request_nos;
+
+    public String getOut_request_nos() {
+        return this.out_request_nos;
+    }
+
+    public void setOut_request_nos(String out_request_nos) {
+        this.out_request_nos = out_request_nos;
+    }
+}

+ 53 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/ali/AliCusDeclareRequestDto.java

@@ -0,0 +1,53 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.dto.ali;
+
+public class AliCusDeclareRequestDto {
+    private String service;
+
+    private String partner;
+
+    private String _input_charset = "UTF-8";
+
+    private String sign_type = "MD5";
+
+    private String sign;
+
+    public String getService() {
+        return this.service;
+    }
+
+    public void setService(String service) {
+        this.service = service;
+    }
+
+    public String getPartner() {
+        return this.partner;
+    }
+
+    public void setPartner(String partner) {
+        this.partner = partner;
+    }
+
+    public String get_input_charset() {
+        return this._input_charset;
+    }
+
+    public void set_input_charset(String _input_charset) {
+        this._input_charset = _input_charset;
+    }
+
+    public String getSign_type() {
+        return this.sign_type;
+    }
+
+    public void setSign_type(String sign_type) {
+        this.sign_type = sign_type;
+    }
+
+    public String getSign() {
+        return this.sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+}

+ 75 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/ali/AliQueryResponseMsg.java

@@ -0,0 +1,75 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.dto.ali;
+
+import java.util.List;
+
+public class AliQueryResponseMsg {
+    private String isSuccess;
+
+    private String error;
+
+    private String resultCode;
+
+    private String notFound;
+
+    private String detailErrorCode;
+
+    private String detailErrorDes;
+
+    private List<AliQuerySuccessResponseMsgDto> customsDeclare;
+
+    public String getIsSuccess() {
+        return this.isSuccess;
+    }
+
+    public void setIsSuccess(String isSuccess) {
+        this.isSuccess = isSuccess;
+    }
+
+    public String getError() {
+        return this.error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+
+    public String getResultCode() {
+        return this.resultCode;
+    }
+
+    public void setResultCode(String resultCode) {
+        this.resultCode = resultCode;
+    }
+
+    public String getNotFound() {
+        return this.notFound;
+    }
+
+    public void setNotFound(String notFound) {
+        this.notFound = notFound;
+    }
+
+    public String getDetailErrorCode() {
+        return this.detailErrorCode;
+    }
+
+    public void setDetailErrorCode(String detailErrorCode) {
+        this.detailErrorCode = detailErrorCode;
+    }
+
+    public String getDetailErrorDes() {
+        return this.detailErrorDes;
+    }
+
+    public void setDetailErrorDes(String detailErrorDes) {
+        this.detailErrorDes = detailErrorDes;
+    }
+
+    public List<AliQuerySuccessResponseMsgDto> getCustomsDeclare() {
+        return this.customsDeclare;
+    }
+
+    public void setCustomsDeclare(List<AliQuerySuccessResponseMsgDto> customsDeclare) {
+        this.customsDeclare = customsDeclare;
+    }
+}

+ 153 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/ali/AliQuerySuccessResponseMsgDto.java

@@ -0,0 +1,153 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.dto.ali;
+
+public class AliQuerySuccessResponseMsgDto {
+    private String outRequestNo;
+
+    private String alipayDeclareNo;
+
+    private String tradeNo;
+
+    private String customsPlace;
+
+    private String merchantCustomsCode;
+
+    private String merchantCustomsName;
+
+    private String amount;
+
+    private String status;
+
+    private String memo;
+
+    private String lastModifiedTime;
+
+    private String customsCode;
+
+    private String customsInfo;
+
+    private String customsReturnTime;
+
+    private String isSplit;
+
+    private String subOutBizNo;
+
+    public String getOutRequestNo() {
+        return this.outRequestNo;
+    }
+
+    public void setOutRequestNo(String outRequestNo) {
+        this.outRequestNo = outRequestNo;
+    }
+
+    public String getAlipayDeclareNo() {
+        return this.alipayDeclareNo;
+    }
+
+    public void setAlipayDeclareNo(String alipayDeclareNo) {
+        this.alipayDeclareNo = alipayDeclareNo;
+    }
+
+    public String getTradeNo() {
+        return this.tradeNo;
+    }
+
+    public void setTradeNo(String tradeNo) {
+        this.tradeNo = tradeNo;
+    }
+
+    public String getCustomsPlace() {
+        return this.customsPlace;
+    }
+
+    public void setCustomsPlace(String customsPlace) {
+        this.customsPlace = customsPlace;
+    }
+
+    public String getMerchantCustomsCode() {
+        return this.merchantCustomsCode;
+    }
+
+    public void setMerchantCustomsCode(String merchantCustomsCode) {
+        this.merchantCustomsCode = merchantCustomsCode;
+    }
+
+    public String getMerchantCustomsName() {
+        return this.merchantCustomsName;
+    }
+
+    public void setMerchantCustomsName(String merchantCustomsName) {
+        this.merchantCustomsName = merchantCustomsName;
+    }
+
+    public String getAmount() {
+        return this.amount;
+    }
+
+    public void setAmount(String amount) {
+        this.amount = amount;
+    }
+
+    public String getStatus() {
+        return this.status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getMemo() {
+        return this.memo;
+    }
+
+    public void setMemo(String memo) {
+        this.memo = memo;
+    }
+
+    public String getLastModifiedTime() {
+        return this.lastModifiedTime;
+    }
+
+    public void setLastModifiedTime(String lastModifiedTime) {
+        this.lastModifiedTime = lastModifiedTime;
+    }
+
+    public String getCustomsCode() {
+        return this.customsCode;
+    }
+
+    public void setCustomsCode(String customsCode) {
+        this.customsCode = customsCode;
+    }
+
+    public String getCustomsInfo() {
+        return this.customsInfo;
+    }
+
+    public void setCustomsInfo(String customsInfo) {
+        this.customsInfo = customsInfo;
+    }
+
+    public String getCustomsReturnTime() {
+        return this.customsReturnTime;
+    }
+
+    public void setCustomsReturnTime(String customsReturnTime) {
+        this.customsReturnTime = customsReturnTime;
+    }
+
+    public String getIsSplit() {
+        return this.isSplit;
+    }
+
+    public void setIsSplit(String isSplit) {
+        this.isSplit = isSplit;
+    }
+
+    public String getSubOutBizNo() {
+        return this.subOutBizNo;
+    }
+
+    public void setSubOutBizNo(String subOutBizNo) {
+        this.subOutBizNo = subOutBizNo;
+    }
+}

+ 147 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/ali/AliResponseMsg.java

@@ -0,0 +1,147 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.dto.ali;
+
+import javax.xml.bind.annotation.XmlElement;
+
+public class AliResponseMsg {
+    private String isSuccess;
+
+    private String signType;
+
+    private String sign;
+
+    private String error;
+
+    private String resultCode;
+
+    private String tradeNo;
+
+    private String alipayDeclareNo;
+
+    private String detailErrorCode;
+
+    private String detailErrorDes;
+
+    private String identityCheck;
+
+    private String verDept;
+
+    private String payCode;
+
+    private String totalAmount;
+
+    private String payTransactionId;
+
+    public String getIsSuccess() {
+        return this.isSuccess;
+    }
+
+    public void setIsSuccess(String isSuccess) {
+        this.isSuccess = isSuccess;
+    }
+
+    public String getSignType() {
+        return this.signType;
+    }
+
+    public void setSignType(String signType) {
+        this.signType = signType;
+    }
+
+    public String getSign() {
+        return this.sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+
+    public String getError() {
+        return this.error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+
+    @XmlElement(name = "result_code")
+    public String getResultCode() {
+        return this.resultCode;
+    }
+
+    public void setResultCode(String resultCode) {
+        this.resultCode = resultCode;
+    }
+
+    @XmlElement(name = "trade_no")
+    public String getTradeNo() {
+        return this.tradeNo;
+    }
+
+    public void setTradeNo(String tradeNo) {
+        this.tradeNo = tradeNo;
+    }
+
+    public String getAlipayDeclareNo() {
+        return this.alipayDeclareNo;
+    }
+
+    public void setAlipayDeclareNo(String alipayDeclareNo) {
+        this.alipayDeclareNo = alipayDeclareNo;
+    }
+
+    public String getDetailErrorCode() {
+        return this.detailErrorCode;
+    }
+
+    public void setDetailErrorCode(String detailErrorCode) {
+        this.detailErrorCode = detailErrorCode;
+    }
+
+    public String getDetailErrorDes() {
+        return this.detailErrorDes;
+    }
+
+    public void setDetailErrorDes(String detailErrorDes) {
+        this.detailErrorDes = detailErrorDes;
+    }
+
+    public String getIdentityCheck() {
+        return this.identityCheck;
+    }
+
+    public void setIdentityCheck(String identityCheck) {
+        this.identityCheck = identityCheck;
+    }
+
+    public String getVerDept() {
+        return this.verDept;
+    }
+
+    public void setVerDept(String verDept) {
+        this.verDept = verDept;
+    }
+
+    public String getPayCode() {
+        return this.payCode;
+    }
+
+    public void setPayCode(String payCode) {
+        this.payCode = payCode;
+    }
+
+    public String getTotalAmount() {
+        return this.totalAmount;
+    }
+
+    public void setTotalAmount(String totalAmount) {
+        this.totalAmount = totalAmount;
+    }
+
+    public String getPayTransactionId() {
+        return this.payTransactionId;
+    }
+
+    public void setPayTransactionId(String payTransactionId) {
+        this.payTransactionId = payTransactionId;
+    }
+}

+ 147 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/wx/WxQueryResponseMsg.java

@@ -0,0 +1,147 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.dto.wx;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * 微信查询订单响应数据实体类
+ */
+@XmlRootElement(name = "xml")
+public class WxQueryResponseMsg {
+	//返回状态码
+	private String returnCode;
+	//返回信息
+	private String returnMsg;
+	//签名类型
+	private String signType;
+	//签名
+	private String sign;
+	//公众号ID
+	private String appid;
+	//商户号
+	private String mchId;
+	//业务结果
+	private String resultCode;
+	//错误代码
+	private String errCode;
+	//错误代码描述
+	private String errCodeDes;
+	//微信支付订单号
+	private String transactionId;
+	//笔数
+	private int count;
+
+	@Override
+	public String toString() {
+		return "WxResponseMsg{" +
+				"returnCode='" + returnCode + '\'' +
+				", returnMsg='" + returnMsg + '\'' +
+				", signType='" + signType + '\'' +
+				", sign='" + sign + '\'' +
+				", appid='" + appid + '\'' +
+				", mchId='" + mchId + '\'' +
+				", resultCode='" + resultCode + '\'' +
+				", errCode='" + errCode + '\'' +
+				", errCodeDes='" + errCodeDes + '\'' +
+				", transactionId='" + transactionId + '\'' ;
+	}
+
+	@XmlElement(name = "return_code")
+	public String getReturnCode() {
+		return returnCode;
+	}
+
+	public void setReturnCode(String returnCode) {
+		this.returnCode = returnCode;
+	}
+
+	@XmlElement(name = "return_msg")
+	public String getReturnMsg() {
+		return returnMsg;
+	}
+
+	public void setReturnMsg(String returnMsg) {
+		this.returnMsg = returnMsg;
+	}
+
+	@XmlElement(name = "sign_type")
+	public String getSignType() {
+		return signType;
+	}
+
+	public void setSignType(String signType) {
+		this.signType = signType;
+	}
+
+	@XmlElement(name = "sign")
+	public String getSign() {
+		return sign;
+	}
+
+	public void setSign(String sign) {
+		this.sign = sign;
+	}
+
+	@XmlElement(name = "appid")
+	public String getAppid() {
+		return appid;
+	}
+
+	public void setAppid(String appid) {
+		this.appid = appid;
+	}
+
+	@XmlElement(name = "mch_id")
+	public String getMchId() {
+		return mchId;
+	}
+
+	public void setMchId(String mchId) {
+		this.mchId = mchId;
+	}
+
+	@XmlElement(name = "result_code")
+	public String getResultCode() {
+		return resultCode;
+	}
+
+	public void setResultCode(String resultCode) {
+		this.resultCode = resultCode;
+	}
+
+	@XmlElement(name = "err_code")
+	public String getErrCode() {
+		return errCode;
+	}
+
+	public void setErrCode(String errCode) {
+		this.errCode = errCode;
+	}
+
+	@XmlElement(name = "err_code_des")
+	public String getErrCodeDes() {
+		return errCodeDes;
+	}
+
+	public void setErrCodeDes(String errCodeDes) {
+		this.errCodeDes = errCodeDes;
+	}
+
+	@XmlElement(name = "transaction_id")
+	public String getTransactionId() {
+		return transactionId;
+	}
+
+	public void setTransactionId(String transactionId) {
+		this.transactionId = transactionId;
+	}
+
+	@XmlElement(name = "count")
+	public int getCount() {
+		return count;
+	}
+
+	public void setCount(int count) {
+		this.count = count;
+	}
+}

+ 162 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/wx/WxQuerySuccessResponseMsgDto.java

@@ -0,0 +1,162 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.dto.wx;
+
+/**
+ * 微信查询订单响应成功后数据实体类
+ * @author huangyq
+ * @version 1.0
+ * 2018-05-24 16:55
+ */
+public class WxQuerySuccessResponseMsgDto {
+    //商户子订单号
+    private String subOrderNo;
+    //微信子订单号
+    private String subOrderId;
+    //商户海关备案号
+    private String mchCustomsNo;
+    //海关
+    private String customs;
+    //币种
+    private String feeType;
+    //应付金额
+    private int orderFee;
+    //关税
+    private int duty;
+    //物流费
+    private int transportFee;
+    //商品价格
+    private int productFee;
+    //状态码
+    private String state;
+    //申报结果说明
+    private String explanation;
+    //最后更新时间
+    private String modifyTime;
+    //订购人和支付人 校验结果
+    private String certCheckResult;
+
+    @Override
+    public String toString() {
+        return "WxResponseMsg{" +
+                "  state='" + state + '\'' +
+                ", subOrderNo='" + subOrderNo + '\'' +
+                ", subOrderId='" + subOrderId + '\'' +
+
+                ", mchCustomsNo='" + mchCustomsNo + '\'' +
+                ", customs='" + customs + '\'' +
+                ", feeType='" + feeType + '\'' +
+                ", orderFee='" + orderFee + '\'' +
+                ", duty='" + duty + '\'' +
+                ", transportFee='" + transportFee + '\'' +
+                ", productFee='" + productFee + '\'' +
+                ", explanation='" + explanation + '\'' +
+
+                ", modifyTime='" + modifyTime + '\'' +
+                ", certCheckResult='" + certCheckResult + '\'' +
+                '}';
+    }
+
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public String getSubOrderNo() {
+        return subOrderNo;
+    }
+
+    public void setSubOrderNo(String subOrderNo) {
+        this.subOrderNo = subOrderNo;
+    }
+
+    public String getSubOrderId() {
+        return subOrderId;
+    }
+
+    public void setSubOrderId(String subOrderId) {
+        this.subOrderId = subOrderId;
+    }
+
+    public String getModifyTime() {
+        return modifyTime;
+    }
+
+    public void setModifyTime(String modifyTime) {
+        this.modifyTime = modifyTime;
+    }
+
+    public String getCertCheckResult() {
+        return certCheckResult;
+    }
+
+    public void setCertCheckResult(String certCheckResult) {
+        this.certCheckResult = certCheckResult;
+    }
+
+    public String getMchCustomsNo() {
+        return mchCustomsNo;
+    }
+
+    public void setMchCustomsNo(String mchCustomsNo) {
+        this.mchCustomsNo = mchCustomsNo;
+    }
+
+    public String getCustoms() {
+        return customs;
+    }
+
+    public void setCustoms(String customs) {
+        this.customs = customs;
+    }
+
+    public String getFeeType() {
+        return feeType;
+    }
+
+    public void setFeeType(String feeType) {
+        this.feeType = feeType;
+    }
+
+    public int getOrderFee() {
+        return orderFee;
+    }
+
+    public void setOrderFee(int orderFee) {
+        this.orderFee = orderFee;
+    }
+
+    public int getDuty() {
+        return duty;
+    }
+
+    public void setDuty(int duty) {
+        this.duty = duty;
+    }
+
+    public int getTransportFee() {
+        return transportFee;
+    }
+
+    public void setTransportFee(int transportFee) {
+        this.transportFee = transportFee;
+    }
+
+    public int getProductFee() {
+        return productFee;
+    }
+
+    public void setProductFee(int productFee) {
+        this.productFee = productFee;
+    }
+
+    public String getExplanation() {
+        return explanation;
+    }
+
+    public void setExplanation(String explanation) {
+        this.explanation = explanation;
+    }
+}

+ 210 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/dto/wx/WxResponseMsg.java

@@ -0,0 +1,210 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.dto.wx;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * 微信支付报关响应数据实体类
+ */
+@XmlRootElement(name = "xml")
+public class WxResponseMsg {
+	//返回状态码
+	private String returnCode;
+	//返回信息
+	private String returnMsg;
+	//签名类型
+	private String signType;
+	//签名
+	private String sign;
+	//公众号ID
+	private String appid;
+	//商户号
+	private String mchId;
+	//业务结果
+	private String resultCode;
+	//错误代码
+	private String errCode;
+	//错误代码描述
+	private String errCodeDes;
+	//状态码
+	private String state;
+	//微信支付订单号
+	private String transactionId;
+	//商户订单号
+	private String outTradeNo;
+	//商户子订单号
+	private String subOrderNo;
+	//微信子订单号
+	private String subOrderId;
+	//最后更新时间
+	private String modifyTime;
+	//订购人和支付人 校验结果
+	private String certCheckResult;
+
+	@Override
+	public String toString() {
+		return "WxResponseMsg{" +
+				"returnCode='" + returnCode + '\'' +
+				", returnMsg='" + returnMsg + '\'' +
+				", signType='" + signType + '\'' +
+				", sign='" + sign + '\'' +
+				", appid='" + appid + '\'' +
+				", mchId='" + mchId + '\'' +
+				", resultCode='" + resultCode + '\'' +
+				", errCode='" + errCode + '\'' +
+				", errCodeDes='" + errCodeDes + '\'' +
+				", state='" + state + '\'' +
+				", transactionId='" + transactionId + '\'' +
+				", outTradeNo='" + outTradeNo + '\'' +
+				", subOrderNo='" + subOrderNo + '\'' +
+				", subOrderId='" + subOrderId + '\'' +
+				", modifyTime='" + modifyTime + '\'' +
+				", certCheckResult='" + certCheckResult + '\'' +
+				'}';
+	}
+
+	@XmlElement(name = "return_code")
+	public String getReturnCode() {
+		return returnCode;
+	}
+
+	public void setReturnCode(String returnCode) {
+		this.returnCode = returnCode;
+	}
+	
+	@XmlElement(name = "return_msg")
+	public String getReturnMsg() {
+		return returnMsg;
+	}
+
+	public void setReturnMsg(String returnMsg) {
+		this.returnMsg = returnMsg;
+	}
+
+	@XmlElement(name = "sign_type")
+	public String getSignType() {
+		return signType;
+	}
+
+	public void setSignType(String signType) {
+		this.signType = signType;
+	}
+
+	@XmlElement(name = "sign")
+	public String getSign() {
+		return sign;
+	}
+
+	public void setSign(String sign) {
+		this.sign = sign;
+	}
+
+	@XmlElement(name = "appid")
+	public String getAppid() {
+		return appid;
+	}
+
+	public void setAppid(String appid) {
+		this.appid = appid;
+	}
+
+	@XmlElement(name = "mch_id")
+	public String getMchId() {
+		return mchId;
+	}
+
+	public void setMchId(String mchId) {
+		this.mchId = mchId;
+	}
+
+	@XmlElement(name = "result_code")
+	public String getResultCode() {
+		return resultCode;
+	}
+
+	public void setResultCode(String resultCode) {
+		this.resultCode = resultCode;
+	}
+
+	@XmlElement(name = "err_code")
+	public String getErrCode() {
+		return errCode;
+	}
+
+	public void setErrCode(String errCode) {
+		this.errCode = errCode;
+	}
+
+	@XmlElement(name = "err_code_des")
+	public String getErrCodeDes() {
+		return errCodeDes;
+	}
+
+	public void setErrCodeDes(String errCodeDes) {
+		this.errCodeDes = errCodeDes;
+	}
+
+	@XmlElement(name = "state")
+	public String getState() {
+		return state;
+	}
+
+	public void setState(String state) {
+		this.state = state;
+	}
+
+	@XmlElement(name = "transaction_id")
+	public String getTransactionId() {
+		return transactionId;
+	}
+
+	public void setTransactionId(String transactionId) {
+		this.transactionId = transactionId;
+	}
+
+	@XmlElement(name = "out_trade_no")
+	public String getOutTradeNo() {
+		return outTradeNo;
+	}
+
+	public void setOutTradeNo(String outTradeNo) {
+		this.outTradeNo = outTradeNo;
+	}
+
+	@XmlElement(name = "sub_order_no")
+	public String getSubOrderNo() {
+		return subOrderNo;
+	}
+
+	public void setSubOrderNo(String subOrderNo) {
+		this.subOrderNo = subOrderNo;
+	}
+
+	@XmlElement(name = "sub_order_id")
+	public String getSubOrderId() {
+		return subOrderId;
+	}
+
+	public void setSubOrderId(String subOrderId) {
+		this.subOrderId = subOrderId;
+	}
+
+	@XmlElement(name = "modify_time")
+	public String getModifyTime() {
+		return modifyTime;
+	}
+
+	public void setModifyTime(String modifyTime) {
+		this.modifyTime = modifyTime;
+	}
+
+	@XmlElement(name = "cert_check_result")
+	public String getCertCheckResult() {
+		return certCheckResult;
+	}
+
+	public void setCertCheckResult(String certCheckResult) {
+		this.certCheckResult = certCheckResult;
+	}
+	
+}

+ 596 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/entity/ali/AliCbPayDoc.java

@@ -0,0 +1,596 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.entity.ali;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class AliCbPayDoc implements Serializable {
+    /**
+     * 内部编号
+     */
+    private String aliPaySn;
+
+    private String appid;
+
+    /**
+     * 商户编号,e码头分配
+     */
+    private String merchSn;
+
+    /**
+     * 商户名称
+     */
+    private String merchName;
+
+    /**
+     * 接入平台内部编号
+     */
+    private String merchErpOrderSn;
+
+    /**
+     * 平台编号,e码头分配
+     */
+    private String platSn;
+
+    /**
+     * 平台中文名
+     */
+    private String platName;
+
+    /**
+     * 第三方商户代码
+     */
+    private String thirdPartyMerchCode;
+
+    /**
+     * 第三方商户名称
+     */
+    private String thirdPartyMerchName;
+
+    /**
+     * 商户生成的购物订单编号
+     */
+    private String merchOrderSn;
+
+    /**
+     * 单证状态,00:待申报,01:申报中,03:申报失败,10:等待处理,11:业务处理中,12:业务成功,13:业务失败
+     */
+    private String docStatus;
+
+    /**
+     * 
+             合作者身份ID
+     */
+    private String partner;
+
+    /**
+     * 商户生成的用于唯一标识一次报关操作的业务编号。不可空。
+     */
+    private String outRequestNo;
+
+    /**
+     * 该交易在支付宝系统中的交易流水号。不可空。
+     */
+    private String tradeNo;
+
+    /**
+     * 商户海关备案编号。不可空。
+     */
+    private String merchantCustomsCode;
+
+    /**
+     * 商户海关备案名称。不可空。
+     */
+    private String merchantCustomsName;
+
+    /**
+     * 报关金额。不可空。人民币“元”,小数点后2位。交易累计的报关金额不得大于交易总金额
+     */
+    private String amount;
+
+    /**
+     * 支付宝制定的海关编号。不可空。参见“海关编号”,大小写均支持。
+     */
+    private String customsPlace;
+
+    /**
+     * 是否拆单。可空。商户控制本单是否拆单报关。
+ 
+             仅当该参数传值为T或者t时,才会触发拆单(报关海关必须支持拆单)。
+     */
+    private String isSplit;
+
+    /**
+     * 子订单号。可空。商户子订单号。拆单时由商户传入,且拆单时必须传入,否则会报INVALID_PARAMETER错误码。
+     */
+    private String subOutBizNo;
+
+    /**
+     * 订购人姓名。即订购人留在商户处的姓名信息。可空。
+     */
+    private String buyerName;
+
+    /**
+     * 订购人身份证号。即订购人留在商户处的身份证信息。可空。
+     */
+    private String buyerIdNo;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 结果响应码。SUCCESS:成功,FAIL:失败
+     */
+    private String resultCode;
+
+    /**
+     * 支付宝报关流水号。可空。
+     */
+    private String alipayDeclareNo;
+
+    /**
+     * 返回订付人一致校验,T:一致,F:不一致。可空。
+     */
+    private String identityCheck;
+
+    /**
+     * 核验机构标志,1-银联,2-网联,3-其他。银行卡支付返回清算组织标志,花呗、余额等支付时,统一返回3。
+     */
+    private String verDept;
+
+    /**
+     * 支付企业的海关注册登记编号
+     */
+    private String payCode;
+
+    /**
+     * 交易唯一编号。当ver_dept为3时,pay_transaction_id等于trade_no;
+ 
+             当ver_dept非3时,返回支付时实际清算流水号。
+     */
+    private String payTransactionId;
+
+    /**
+     * 实际交易总金额(单位:分)
+     */
+    private String totalAmount;
+
+    /**
+     * 返回响应码进行原因说明。当result_code响应码为SUCCESS时,不返回该参数。可空
+     */
+    private String detailErrorCode;
+
+    /**
+     * 详细错误。当result_code响应码为SUCCESS时,不返回该参数。可空。
+     */
+    private String detailErrorDes;
+
+    /**
+     * 申报开始时间
+     */
+    private String begDeclareTime;
+
+    /**
+     * 申报结束时间
+     */
+    private String endDeclareTime;
+
+    private String column29;
+
+    /**
+     * 创建人编号
+     */
+    private String createrSn;
+
+    /**
+     * 创建时间,yyyy-MM-dd HH:mm:ss
+     */
+    private String createTime;
+
+    /**
+     * 修改人编号
+     */
+    private String moderSn;
+
+    /**
+     * 修改时间,yyyy-MM-dd HH:mm:ss
+     */
+    private String modTime;
+
+    /**
+     * 时间戳
+     */
+    private Date tstm;
+
+    /**
+     * 扩展字段1
+     */
+    private String exField;
+
+    /**
+     * 扩展字段2
+     */
+    private String exField2;
+
+    /**
+     * 扩展字段3
+     */
+    private String exField3;
+
+    /**
+     * 扩展字段4
+     */
+    private String exField4;
+
+    /**
+     * 扩展字段5
+     */
+    private String exField5;
+
+    private static final long serialVersionUID = 1L;
+
+    public AliCbPayDoc() {
+        super();
+    }
+
+    public String getAliPaySn() {
+        return aliPaySn;
+    }
+
+    public void setAliPaySn(String aliPaySn) {
+        this.aliPaySn = aliPaySn == null ? null : aliPaySn.trim();
+    }
+
+    public String getMerchSn() {
+        return merchSn;
+    }
+
+    public void setMerchSn(String merchSn) {
+        this.merchSn = merchSn == null ? null : merchSn.trim();
+    }
+
+    public String getMerchName() {
+        return merchName;
+    }
+
+    public void setMerchName(String merchName) {
+        this.merchName = merchName == null ? null : merchName.trim();
+    }
+
+    public String getMerchErpOrderSn() {
+        return merchErpOrderSn;
+    }
+
+    public void setMerchErpOrderSn(String merchErpOrderSn) {
+        this.merchErpOrderSn = merchErpOrderSn == null ? null : merchErpOrderSn.trim();
+    }
+
+    public String getPlatSn() {
+        return platSn;
+    }
+
+    public void setPlatSn(String platSn) {
+        this.platSn = platSn == null ? null : platSn.trim();
+    }
+
+    public String getPlatName() {
+        return platName;
+    }
+
+    public void setPlatName(String platName) {
+        this.platName = platName == null ? null : platName.trim();
+    }
+
+    public String getThirdPartyMerchCode() {
+        return thirdPartyMerchCode;
+    }
+
+    public void setThirdPartyMerchCode(String thirdPartyMerchCode) {
+        this.thirdPartyMerchCode = thirdPartyMerchCode == null ? null : thirdPartyMerchCode.trim();
+    }
+
+    public String getThirdPartyMerchName() {
+        return thirdPartyMerchName;
+    }
+
+    public void setThirdPartyMerchName(String thirdPartyMerchName) {
+        this.thirdPartyMerchName = thirdPartyMerchName == null ? null : thirdPartyMerchName.trim();
+    }
+
+    public String getMerchOrderSn() {
+        return merchOrderSn;
+    }
+
+    public void setMerchOrderSn(String merchOrderSn) {
+        this.merchOrderSn = merchOrderSn == null ? null : merchOrderSn.trim();
+    }
+
+    public String getDocStatus() {
+        return docStatus;
+    }
+
+    public void setDocStatus(String docStatus) {
+        this.docStatus = docStatus == null ? null : docStatus.trim();
+    }
+
+    public String getPartner() {
+        return partner;
+    }
+
+    public void setPartner(String partner) {
+        this.partner = partner == null ? null : partner.trim();
+    }
+
+    public String getOutRequestNo() {
+        return outRequestNo;
+    }
+
+    public void setOutRequestNo(String outRequestNo) {
+        this.outRequestNo = outRequestNo == null ? null : outRequestNo.trim();
+    }
+
+    public String getTradeNo() {
+        return tradeNo;
+    }
+
+    public void setTradeNo(String tradeNo) {
+        this.tradeNo = tradeNo == null ? null : tradeNo.trim();
+    }
+
+    public String getMerchantCustomsCode() {
+        return merchantCustomsCode;
+    }
+
+    public void setMerchantCustomsCode(String merchantCustomsCode) {
+        this.merchantCustomsCode = merchantCustomsCode == null ? null : merchantCustomsCode.trim();
+    }
+
+    public String getMerchantCustomsName() {
+        return merchantCustomsName;
+    }
+
+    public void setMerchantCustomsName(String merchantCustomsName) {
+        this.merchantCustomsName = merchantCustomsName == null ? null : merchantCustomsName.trim();
+    }
+
+    public String getAmount() {
+        return amount;
+    }
+
+    public void setAmount(String amount) {
+        this.amount = amount == null ? null : amount.trim();
+    }
+
+    public String getCustomsPlace() {
+        return customsPlace;
+    }
+
+    public void setCustomsPlace(String customsPlace) {
+        this.customsPlace = customsPlace == null ? null : customsPlace.trim();
+    }
+
+    public String getIsSplit() {
+        return isSplit;
+    }
+
+    public void setIsSplit(String isSplit) {
+        this.isSplit = isSplit == null ? null : isSplit.trim();
+    }
+
+    public String getSubOutBizNo() {
+        return subOutBizNo;
+    }
+
+    public void setSubOutBizNo(String subOutBizNo) {
+        this.subOutBizNo = subOutBizNo == null ? null : subOutBizNo.trim();
+    }
+
+    public String getBuyerName() {
+        return buyerName;
+    }
+
+    public void setBuyerName(String buyerName) {
+        this.buyerName = buyerName == null ? null : buyerName.trim();
+    }
+
+    public String getBuyerIdNo() {
+        return buyerIdNo;
+    }
+
+    public void setBuyerIdNo(String buyerIdNo) {
+        this.buyerIdNo = buyerIdNo == null ? null : buyerIdNo.trim();
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark == null ? null : remark.trim();
+    }
+
+    public String getResultCode() {
+        return resultCode;
+    }
+
+    public void setResultCode(String resultCode) {
+        this.resultCode = resultCode == null ? null : resultCode.trim();
+    }
+
+    public String getAlipayDeclareNo() {
+        return alipayDeclareNo;
+    }
+
+    public void setAlipayDeclareNo(String alipayDeclareNo) {
+        this.alipayDeclareNo = alipayDeclareNo == null ? null : alipayDeclareNo.trim();
+    }
+
+    public String getIdentityCheck() {
+        return identityCheck;
+    }
+
+    public void setIdentityCheck(String identityCheck) {
+        this.identityCheck = identityCheck == null ? null : identityCheck.trim();
+    }
+
+    public String getVerDept() {
+        return verDept;
+    }
+
+    public void setVerDept(String verDept) {
+        this.verDept = verDept == null ? null : verDept.trim();
+    }
+
+    public String getPayCode() {
+        return payCode;
+    }
+
+    public void setPayCode(String payCode) {
+        this.payCode = payCode == null ? null : payCode.trim();
+    }
+
+    public String getPayTransactionId() {
+        return payTransactionId;
+    }
+
+    public void setPayTransactionId(String payTransactionId) {
+        this.payTransactionId = payTransactionId == null ? null : payTransactionId.trim();
+    }
+
+    public String getTotalAmount() {
+        return totalAmount;
+    }
+
+    public void setTotalAmount(String totalAmount) {
+        this.totalAmount = totalAmount == null ? null : totalAmount.trim();
+    }
+
+    public String getDetailErrorCode() {
+        return detailErrorCode;
+    }
+
+    public void setDetailErrorCode(String detailErrorCode) {
+        this.detailErrorCode = detailErrorCode == null ? null : detailErrorCode.trim();
+    }
+
+    public String getDetailErrorDes() {
+        return detailErrorDes;
+    }
+
+    public void setDetailErrorDes(String detailErrorDes) {
+        this.detailErrorDes = detailErrorDes == null ? null : detailErrorDes.trim();
+    }
+
+    public String getBegDeclareTime() {
+        return begDeclareTime;
+    }
+
+    public void setBegDeclareTime(String begDeclareTime) {
+        this.begDeclareTime = begDeclareTime == null ? null : begDeclareTime.trim();
+    }
+
+    public String getEndDeclareTime() {
+        return endDeclareTime;
+    }
+
+    public void setEndDeclareTime(String endDeclareTime) {
+        this.endDeclareTime = endDeclareTime == null ? null : endDeclareTime.trim();
+    }
+
+    public String getColumn29() {
+        return column29;
+    }
+
+    public void setColumn29(String column29) {
+        this.column29 = column29 == null ? null : column29.trim();
+    }
+
+    public String getCreaterSn() {
+        return createrSn;
+    }
+
+    public void setCreaterSn(String createrSn) {
+        this.createrSn = createrSn == null ? null : createrSn.trim();
+    }
+
+    public String getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(String createTime) {
+        this.createTime = createTime == null ? null : createTime.trim();
+    }
+
+    public String getModerSn() {
+        return moderSn;
+    }
+
+    public void setModerSn(String moderSn) {
+        this.moderSn = moderSn == null ? null : moderSn.trim();
+    }
+
+    public String getModTime() {
+        return modTime;
+    }
+
+    public void setModTime(String modTime) {
+        this.modTime = modTime == null ? null : modTime.trim();
+    }
+
+    public Date getTstm() {
+        return tstm;
+    }
+
+    public void setTstm(Date tstm) {
+        this.tstm = tstm;
+    }
+
+    public String getExField() {
+        return exField;
+    }
+
+    public void setExField(String exField) {
+        this.exField = exField == null ? null : exField.trim();
+    }
+
+    public String getExField2() {
+        return exField2;
+    }
+
+    public void setExField2(String exField2) {
+        this.exField2 = exField2 == null ? null : exField2.trim();
+    }
+
+    public String getExField3() {
+        return exField3;
+    }
+
+    public void setExField3(String exField3) {
+        this.exField3 = exField3 == null ? null : exField3.trim();
+    }
+
+    public String getExField4() {
+        return exField4;
+    }
+
+    public void setExField4(String exField4) {
+        this.exField4 = exField4 == null ? null : exField4.trim();
+    }
+
+    public String getExField5() {
+        return exField5;
+    }
+
+    public void setExField5(String exField5) {
+        this.exField5 = exField5 == null ? null : exField5.trim();
+    }
+
+    public String getAppid() {
+        return appid;
+    }
+
+    public void setAppid(String appid) {
+        this.appid = appid;
+    }
+}

+ 285 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/entity/ali/AliPayError.java

@@ -0,0 +1,285 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.entity.ali;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class AliPayError implements Serializable {
+    /**
+     * 异常单编号
+     */
+    private String aliErrorSn;
+
+    /**
+     * 推支付宝内部编号
+     */
+    private String aliPaySn;
+
+    /**
+     * 商户编号,e码头分配
+     */
+    private String merchSn;
+
+    /**
+     * 商户名称
+     */
+    private String merchName;
+
+    /**
+     * 平台编号,e码头分配
+     */
+    private String platSn;
+
+    /**
+     * 平台中文名
+     */
+    private String platName;
+
+    /**
+     * 第三方商户代码
+     */
+    private String thirdPartyMerchCode;
+
+    /**
+     * 第三方商户名称
+     */
+    private String thirdPartyMerchName;
+
+    /**
+     * 商户生成的购物订单编号
+     */
+    private String merchOrderSn;
+
+    /**
+     * 商户生成的用于唯一标识一次报关操作的业务编号。不可空。
+     */
+    private String outRequestNo;
+
+    /**
+     * 合作者身份ID
+     */
+    private String partner;
+
+    /**
+     * 该交易在支付宝系统中的交易流水号。不可空。
+     */
+    private String tradeNo2;
+
+    /**
+     * 子订单号。可空。商户子订单号。拆单时由商户传入,且拆单时必须传入,否则会报INVALID_PARAMETER错误码。
+     */
+    private String subOutBizNo;
+
+    /**
+     * 支付宝制定的海关编号。不可空。参见“海关编号”,大小写均支持。
+     */
+    private String customsPlace;
+
+    /**
+     * 异常代码
+     */
+    private String errCode;
+
+    /**
+     * 异常消息
+     */
+    private String errMsg;
+
+    /**
+     * 创建人编号
+     */
+    private String createrSn;
+
+    /**
+     * 创建时间,yyyy-MM-dd HH:mm:ss
+     */
+    private String createTime;
+
+    /**
+     * 修改人编号
+     */
+    private String moderSn;
+
+    /**
+     * 修改时间,yyyy-MM-dd HH:mm:ss
+     */
+    private String modTime;
+
+    /**
+     * 时间戳
+     */
+    private Date tstm;
+
+    private static final long serialVersionUID = 1L;
+
+    public AliPayError() {
+        super();
+    }
+
+    public String getAliErrorSn() {
+        return aliErrorSn;
+    }
+
+    public void setAliErrorSn(String aliErrorSn) {
+        this.aliErrorSn = aliErrorSn == null ? null : aliErrorSn.trim();
+    }
+
+    public String getAliPaySn() {
+        return aliPaySn;
+    }
+
+    public void setAliPaySn(String aliPaySn) {
+        this.aliPaySn = aliPaySn == null ? null : aliPaySn.trim();
+    }
+
+    public String getMerchSn() {
+        return merchSn;
+    }
+
+    public void setMerchSn(String merchSn) {
+        this.merchSn = merchSn == null ? null : merchSn.trim();
+    }
+
+    public String getMerchName() {
+        return merchName;
+    }
+
+    public void setMerchName(String merchName) {
+        this.merchName = merchName == null ? null : merchName.trim();
+    }
+
+    public String getPlatSn() {
+        return platSn;
+    }
+
+    public void setPlatSn(String platSn) {
+        this.platSn = platSn == null ? null : platSn.trim();
+    }
+
+    public String getPlatName() {
+        return platName;
+    }
+
+    public void setPlatName(String platName) {
+        this.platName = platName == null ? null : platName.trim();
+    }
+
+    public String getThirdPartyMerchCode() {
+        return thirdPartyMerchCode;
+    }
+
+    public void setThirdPartyMerchCode(String thirdPartyMerchCode) {
+        this.thirdPartyMerchCode = thirdPartyMerchCode == null ? null : thirdPartyMerchCode.trim();
+    }
+
+    public String getThirdPartyMerchName() {
+        return thirdPartyMerchName;
+    }
+
+    public void setThirdPartyMerchName(String thirdPartyMerchName) {
+        this.thirdPartyMerchName = thirdPartyMerchName == null ? null : thirdPartyMerchName.trim();
+    }
+
+    public String getMerchOrderSn() {
+        return merchOrderSn;
+    }
+
+    public void setMerchOrderSn(String merchOrderSn) {
+        this.merchOrderSn = merchOrderSn == null ? null : merchOrderSn.trim();
+    }
+
+    public String getOutRequestNo() {
+        return outRequestNo;
+    }
+
+    public void setOutRequestNo(String outRequestNo) {
+        this.outRequestNo = outRequestNo == null ? null : outRequestNo.trim();
+    }
+
+    public String getPartner() {
+        return partner;
+    }
+
+    public void setPartner(String partner) {
+        this.partner = partner == null ? null : partner.trim();
+    }
+
+    public String getTradeNo2() {
+        return tradeNo2;
+    }
+
+    public void setTradeNo2(String tradeNo2) {
+        this.tradeNo2 = tradeNo2 == null ? null : tradeNo2.trim();
+    }
+
+    public String getSubOutBizNo() {
+        return subOutBizNo;
+    }
+
+    public void setSubOutBizNo(String subOutBizNo) {
+        this.subOutBizNo = subOutBizNo == null ? null : subOutBizNo.trim();
+    }
+
+    public String getCustomsPlace() {
+        return customsPlace;
+    }
+
+    public void setCustomsPlace(String customsPlace) {
+        this.customsPlace = customsPlace == null ? null : customsPlace.trim();
+    }
+
+    public String getErrCode() {
+        return errCode;
+    }
+
+    public void setErrCode(String errCode) {
+        this.errCode = errCode == null ? null : errCode.trim();
+    }
+
+    public String getErrMsg() {
+        return errMsg;
+    }
+
+    public void setErrMsg(String errMsg) {
+        this.errMsg = errMsg == null ? null : errMsg.trim();
+    }
+
+    public String getCreaterSn() {
+        return createrSn;
+    }
+
+    public void setCreaterSn(String createrSn) {
+        this.createrSn = createrSn == null ? null : createrSn.trim();
+    }
+
+    public String getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(String createTime) {
+        this.createTime = createTime == null ? null : createTime.trim();
+    }
+
+    public String getModerSn() {
+        return moderSn;
+    }
+
+    public void setModerSn(String moderSn) {
+        this.moderSn = moderSn == null ? null : moderSn.trim();
+    }
+
+    public String getModTime() {
+        return modTime;
+    }
+
+    public void setModTime(String modTime) {
+        this.modTime = modTime == null ? null : modTime.trim();
+    }
+
+    public Date getTstm() {
+        return tstm;
+    }
+
+    public void setTstm(Date tstm) {
+        this.tstm = tstm;
+    }
+}

+ 442 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/entity/wx/WxCbPayDoc.java

@@ -0,0 +1,442 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.entity.wx;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class WxCbPayDoc implements Serializable {
+    private String wxPaySn;
+
+    private String merchSn;
+
+    private String merchName;
+
+    private String platSn;
+
+    private String platName;
+
+    private String thirdPartyMerchCode;
+
+    private String thirdPartyMerchName;
+
+    private String appid;
+
+    private String mchId;
+
+    private String outTradeNo;
+
+    private String transactionId;
+
+    private String customs;
+
+    private String mchCustomsNo;
+
+    private Integer duty;
+
+    private String actionType;
+
+    private String subOrderNo;
+
+    private String feeType;
+
+    private Integer orderFee;
+
+    private Integer transportFee;
+
+    private Integer productFee;
+
+    private String certType;
+
+    private String certId;
+
+    private String name;
+
+    private String docStatus;
+
+    private String remark;
+
+    private String returnCode;
+
+    private String returnMsg;
+
+    private String resultCode;
+
+    private String errCode;
+
+    private String errCodeDes;
+
+    private String createrSn;
+
+    private String createTime;
+
+    private String moderSn;
+
+    private String modTime;
+
+    private Date tstm;
+
+    private String exField;
+
+    private String exField2;
+
+    private String exField3;
+
+    private String exField4;
+
+    private String exField5;
+
+    private String merchErpOrderSn;
+
+    private String buyerPayerCheck;
+
+    private String subOrderId;
+
+    private static final long serialVersionUID = 1L;
+
+    public WxCbPayDoc() {
+        super();
+    }
+
+    public String getSubOrderId() {
+        return subOrderId;
+    }
+
+    public void setSubOrderId(String subOrderId) {
+        this.subOrderId = subOrderId;
+    }
+
+    public String getBuyerPayerCheck() {
+        return buyerPayerCheck;
+    }
+
+    public void setBuyerPayerCheck(String buyerPayerCheck) {
+        this.buyerPayerCheck = buyerPayerCheck == null ? null : buyerPayerCheck.trim();
+    }
+
+    public String getMerchErpOrderSn() {
+        return merchErpOrderSn;
+    }
+
+    public void setMerchErpOrderSn(String merchErpOrderSn) {
+        this.merchErpOrderSn = merchErpOrderSn == null ? null : merchErpOrderSn.trim();
+    }
+
+    public String getWxPaySn() {
+        return wxPaySn;
+    }
+
+    public void setWxPaySn(String wxPaySn) {
+        this.wxPaySn = wxPaySn == null ? null : wxPaySn.trim();
+    }
+
+    public String getMerchSn() {
+        return merchSn;
+    }
+
+    public void setMerchSn(String merchSn) {
+        this.merchSn = merchSn == null ? null : merchSn.trim();
+    }
+
+    public String getMerchName() {
+        return merchName;
+    }
+
+    public void setMerchName(String merchName) {
+        this.merchName = merchName == null ? null : merchName.trim();
+    }
+
+    public String getPlatSn() {
+        return platSn;
+    }
+
+    public void setPlatSn(String platSn) {
+        this.platSn = platSn == null ? null : platSn.trim();
+    }
+
+    public String getPlatName() {
+        return platName;
+    }
+
+    public void setPlatName(String platName) {
+        this.platName = platName == null ? null : platName.trim();
+    }
+
+    public String getThirdPartyMerchCode() {
+        return thirdPartyMerchCode;
+    }
+
+    public void setThirdPartyMerchCode(String thirdPartyMerchCode) {
+        this.thirdPartyMerchCode = thirdPartyMerchCode == null ? null : thirdPartyMerchCode.trim();
+    }
+
+    public String getThirdPartyMerchName() {
+        return thirdPartyMerchName;
+    }
+
+    public void setThirdPartyMerchName(String thirdPartyMerchName) {
+        this.thirdPartyMerchName = thirdPartyMerchName == null ? null : thirdPartyMerchName.trim();
+    }
+
+    public String getAppid() {
+        return appid;
+    }
+
+    public void setAppid(String appid) {
+        this.appid = appid == null ? null : appid.trim();
+    }
+
+    public String getMchId() {
+        return mchId;
+    }
+
+    public void setMchId(String mchId) {
+        this.mchId = mchId == null ? null : mchId.trim();
+    }
+
+    public String getOutTradeNo() {
+        return outTradeNo;
+    }
+
+    public void setOutTradeNo(String outTradeNo) {
+        this.outTradeNo = outTradeNo == null ? null : outTradeNo.trim();
+    }
+
+    public String getTransactionId() {
+        return transactionId;
+    }
+
+    public void setTransactionId(String transactionId) {
+        this.transactionId = transactionId == null ? null : transactionId.trim();
+    }
+
+    public String getCustoms() {
+        return customs;
+    }
+
+    public void setCustoms(String customs) {
+        this.customs = customs == null ? null : customs.trim();
+    }
+
+    public String getMchCustomsNo() {
+        return mchCustomsNo;
+    }
+
+    public void setMchCustomsNo(String mchCustomsNo) {
+        this.mchCustomsNo = mchCustomsNo == null ? null : mchCustomsNo.trim();
+    }
+
+    public Integer getDuty() {
+        return duty;
+    }
+
+    public void setDuty(Integer duty) {
+        this.duty = duty;
+    }
+
+    public String getActionType() {
+        return actionType;
+    }
+
+    public void setActionType(String actionType) {
+        this.actionType = actionType == null ? null : actionType.trim();
+    }
+
+    public String getSubOrderNo() {
+        return subOrderNo;
+    }
+
+    public void setSubOrderNo(String subOrderNo) {
+        this.subOrderNo = subOrderNo == null ? null : subOrderNo.trim();
+    }
+
+    public String getFeeType() {
+        return feeType;
+    }
+
+    public void setFeeType(String feeType) {
+        this.feeType = feeType == null ? null : feeType.trim();
+    }
+
+    public Integer getOrderFee() {
+        return orderFee;
+    }
+
+    public void setOrderFee(Integer orderFee) {
+        this.orderFee = orderFee;
+    }
+
+    public Integer getTransportFee() {
+        return transportFee;
+    }
+
+    public void setTransportFee(Integer transportFee) {
+        this.transportFee = transportFee;
+    }
+
+    public Integer getProductFee() {
+        return productFee;
+    }
+
+    public void setProductFee(Integer productFee) {
+        this.productFee = productFee;
+    }
+
+    public String getCertType() {
+        return certType;
+    }
+
+    public void setCertType(String certType) {
+        this.certType = certType == null ? null : certType.trim();
+    }
+
+    public String getCertId() {
+        return certId;
+    }
+
+    public void setCertId(String certId) {
+        this.certId = certId == null ? null : certId.trim();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name == null ? null : name.trim();
+    }
+
+    public String getDocStatus() {
+        return docStatus;
+    }
+
+    public void setDocStatus(String docStatus) {
+        this.docStatus = docStatus == null ? null : docStatus.trim();
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark == null ? null : remark.trim();
+    }
+
+    public String getReturnCode() {
+        return returnCode;
+    }
+
+    public void setReturnCode(String returnCode) {
+        this.returnCode = returnCode == null ? null : returnCode.trim();
+    }
+
+    public String getReturnMsg() {
+        return returnMsg;
+    }
+
+    public void setReturnMsg(String returnMsg) {
+        this.returnMsg = returnMsg == null ? null : returnMsg.trim();
+    }
+
+    public String getResultCode() {
+        return resultCode;
+    }
+
+    public void setResultCode(String resultCode) {
+        this.resultCode = resultCode == null ? null : resultCode.trim();
+    }
+
+    public String getErrCode() {
+        return errCode;
+    }
+
+    public void setErrCode(String errCode) {
+        this.errCode = errCode == null ? null : errCode.trim();
+    }
+
+    public String getErrCodeDes() {
+        return errCodeDes;
+    }
+
+    public void setErrCodeDes(String errCodeDes) {
+        this.errCodeDes = errCodeDes == null ? null : errCodeDes.trim();
+    }
+
+    public String getCreaterSn() {
+        return createrSn;
+    }
+
+    public void setCreaterSn(String createrSn) {
+        this.createrSn = createrSn == null ? null : createrSn.trim();
+    }
+
+    public String getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(String createTime) {
+        this.createTime = createTime == null ? null : createTime.trim();
+    }
+
+    public String getModerSn() {
+        return moderSn;
+    }
+
+    public void setModerSn(String moderSn) {
+        this.moderSn = moderSn == null ? null : moderSn.trim();
+    }
+
+    public String getModTime() {
+        return modTime;
+    }
+
+    public void setModTime(String modTime) {
+        this.modTime = modTime == null ? null : modTime.trim();
+    }
+
+    public Date getTstm() {
+        return tstm;
+    }
+
+    public void setTstm(Date tstm) {
+        this.tstm = tstm;
+    }
+
+    public String getExField() {
+        return exField;
+    }
+
+    public void setExField(String exField) {
+        this.exField = exField == null ? null : exField.trim();
+    }
+
+    public String getExField2() {
+        return exField2;
+    }
+
+    public void setExField2(String exField2) {
+        this.exField2 = exField2 == null ? null : exField2.trim();
+    }
+
+    public String getExField3() {
+        return exField3;
+    }
+
+    public void setExField3(String exField3) {
+        this.exField3 = exField3 == null ? null : exField3.trim();
+    }
+
+    public String getExField4() {
+        return exField4;
+    }
+
+    public void setExField4(String exField4) {
+        this.exField4 = exField4 == null ? null : exField4.trim();
+    }
+
+    public String getExField5() {
+        return exField5;
+    }
+
+    public void setExField5(String exField5) {
+        this.exField5 = exField5 == null ? null : exField5.trim();
+    }
+}

+ 222 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/entity/wx/WxPayError.java

@@ -0,0 +1,222 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.entity.wx;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class WxPayError implements Serializable {
+    private String errorSn;
+
+    private String wxPaySn;
+
+    private String merchSn;
+
+    private String merchName;
+
+    private String platSn;
+
+    private String platName;
+
+    private String thirdPartyMerchCode;
+
+    private String thirdPartyMerchName;
+
+    private String appid;
+
+    private String mchId;
+
+    private String outTradeNo;
+
+    private String transactionId;
+
+    private String subOrderNo;
+
+    private String customs;
+
+    private String errCode;
+
+    private String errMsg;
+
+    private String createrSn;
+
+    private String createTime;
+
+    private String moderSn;
+
+    private String modTime;
+
+    private Date tstm;
+
+    private static final long serialVersionUID = 1L;
+
+    public WxPayError() {
+        super();
+    }
+
+    public String getErrorSn() {
+        return errorSn;
+    }
+
+    public void setErrorSn(String errorSn) {
+        this.errorSn = errorSn == null ? null : errorSn.trim();
+    }
+
+    public String getWxPaySn() {
+        return wxPaySn;
+    }
+
+    public void setWxPaySn(String wxPaySn) {
+        this.wxPaySn = wxPaySn == null ? null : wxPaySn.trim();
+    }
+
+    public String getMerchSn() {
+        return merchSn;
+    }
+
+    public void setMerchSn(String merchSn) {
+        this.merchSn = merchSn == null ? null : merchSn.trim();
+    }
+
+    public String getMerchName() {
+        return merchName;
+    }
+
+    public void setMerchName(String merchName) {
+        this.merchName = merchName == null ? null : merchName.trim();
+    }
+
+    public String getPlatSn() {
+        return platSn;
+    }
+
+    public void setPlatSn(String platSn) {
+        this.platSn = platSn == null ? null : platSn.trim();
+    }
+
+    public String getPlatName() {
+        return platName;
+    }
+
+    public void setPlatName(String platName) {
+        this.platName = platName == null ? null : platName.trim();
+    }
+
+    public String getThirdPartyMerchCode() {
+        return thirdPartyMerchCode;
+    }
+
+    public void setThirdPartyMerchCode(String thirdPartyMerchCode) {
+        this.thirdPartyMerchCode = thirdPartyMerchCode == null ? null : thirdPartyMerchCode.trim();
+    }
+
+    public String getThirdPartyMerchName() {
+        return thirdPartyMerchName;
+    }
+
+    public void setThirdPartyMerchName(String thirdPartyMerchName) {
+        this.thirdPartyMerchName = thirdPartyMerchName == null ? null : thirdPartyMerchName.trim();
+    }
+
+    public String getAppid() {
+        return appid;
+    }
+
+    public void setAppid(String appid) {
+        this.appid = appid == null ? null : appid.trim();
+    }
+
+    public String getMchId() {
+        return mchId;
+    }
+
+    public void setMchId(String mchId) {
+        this.mchId = mchId == null ? null : mchId.trim();
+    }
+
+    public String getOutTradeNo() {
+        return outTradeNo;
+    }
+
+    public void setOutTradeNo(String outTradeNo) {
+        this.outTradeNo = outTradeNo == null ? null : outTradeNo.trim();
+    }
+
+    public String getTransactionId() {
+        return transactionId;
+    }
+
+    public void setTransactionId(String transactionId) {
+        this.transactionId = transactionId == null ? null : transactionId.trim();
+    }
+
+    public String getSubOrderNo() {
+        return subOrderNo;
+    }
+
+    public void setSubOrderNo(String subOrderNo) {
+        this.subOrderNo = subOrderNo == null ? null : subOrderNo.trim();
+    }
+
+    public String getCustoms() {
+        return customs;
+    }
+
+    public void setCustoms(String customs) {
+        this.customs = customs == null ? null : customs.trim();
+    }
+
+    public String getErrCode() {
+        return errCode;
+    }
+
+    public void setErrCode(String errCode) {
+        this.errCode = errCode == null ? null : errCode.trim();
+    }
+
+    public String getErrMsg() {
+        return errMsg;
+    }
+
+    public void setErrMsg(String errMsg) {
+        this.errMsg = errMsg == null ? null : errMsg.trim();
+    }
+
+    public String getCreaterSn() {
+        return createrSn;
+    }
+
+    public void setCreaterSn(String createrSn) {
+        this.createrSn = createrSn == null ? null : createrSn.trim();
+    }
+
+    public String getCreateTime(String format) {
+        return createTime;
+    }
+
+    public void setCreateTime(String createTime) {
+        this.createTime = createTime == null ? null : createTime.trim();
+    }
+
+    public String getModerSn() {
+        return moderSn;
+    }
+
+    public void setModerSn(String moderSn) {
+        this.moderSn = moderSn == null ? null : moderSn.trim();
+    }
+
+    public String getModTime() {
+        return modTime;
+    }
+
+    public void setModTime(String modTime) {
+        this.modTime = modTime == null ? null : modTime.trim();
+    }
+
+    public Date getTstm() {
+        return tstm;
+    }
+
+    public void setTstm(Date tstm) {
+        this.tstm = tstm;
+    }
+}

+ 53 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/ali/AliCbPayDocService.java

@@ -0,0 +1,53 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.service.ali;
+
+import com.kmall.admin.cuspay.support.msg.resp.ResponseMessage;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.ali.AliCbPayDoc;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * @author huangyq
+ * @version 1.0
+ * 2018-05-18 16:05
+ */
+public interface AliCbPayDocService {
+    /**
+     * 支付宝支付单入库
+     * @param paramAliCbPayDoc 微信支付单证
+     * @return
+     */
+    ResponseMessage addAliCbPayDoc(AliCbPayDoc paramAliCbPayDoc);
+
+    /**
+     * 查找支付宝推海关 待申报的数据
+     * @param paramInteger
+     * @return
+     */
+    List<AliCbPayDoc> selectBeDeclaredData(Integer paramInteger);
+
+    /**
+     * 更新
+     * @param paramAliCbPayDoc
+     * @return
+     */
+    int updateAliCbPay(AliCbPayDoc paramAliCbPayDoc);
+
+    /**
+     * 批量更新
+     * @param paramList
+     * @return
+     */
+    int updateBatch(List<AliCbPayDoc> paramList);
+
+    /**
+     * 查找支付宝推海关 等待处理、业务处理中的数据
+     * @param paramInteger
+     * @return
+     */
+    List<AliCbPayDoc> selectPayDocByDocStatus(Integer paramInteger);
+
+    AliCbPayDoc selectByOutRequestNo(String paramString);
+
+    ResponseMessage heavyPush(AliCbPayDoc paramAliCbPayDoc);
+}

+ 17 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/ali/AliPayErrorService.java

@@ -0,0 +1,17 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.service.ali;
+
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.ali.AliPayError;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * @author zx
+ * @version 1.0
+ * 2018-05-19 15:58
+ */
+public interface AliPayErrorService {
+
+    int insertAliPayErrorBatch(List<AliPayError> aliPayErrors);
+
+}

+ 129 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/ali/impl/AliCbPayDocServiceImpl.java

@@ -0,0 +1,129 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.service.ali.impl;
+
+
+import com.kmall.admin.cuspay.ccnet2cuspay.common.ali.AliDict;
+import com.kmall.admin.cuspay.common.contant.TablePrimaryKeyPrefix;
+import com.kmall.admin.cuspay.common.core.db.IdWorkerAide;
+import com.kmall.admin.dao.cuspay.ali.AliCbPayDocMapper;
+import com.kmall.admin.dao.cuspay.merch.MerchPayCfgMapper;
+import com.kmall.admin.cuspay.entity.merch.MerchPayCfg;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseMessage;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseStatus;
+import com.kmall.admin.cuspay.util.jackson.JacksonUtil;
+import com.kmall.admin.cuspay.ccnet2cuspay.common.wx.WxDict;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.ali.AliCbPayDoc;
+import com.kmall.admin.cuspay.ccnet2cuspay.service.ali.AliCbPayDocService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @author huangyq
+ * @version 1.0
+ * 2018-05-18 16:05
+ */
+@Service
+public class AliCbPayDocServiceImpl implements AliCbPayDocService {
+    private static final Logger logger = LoggerFactory.getLogger(AliCbPayDocServiceImpl.class);
+
+    @Autowired
+    private AliCbPayDocMapper aliCbPayDocMapper;
+
+    @Autowired
+    private MerchPayCfgMapper merchPayCfgMapper;
+
+    /**
+     * 支付单信息入库
+     * @param aliCbPayDoc 支付宝支付单证
+     * @return
+     */
+    @Override
+    public ResponseMessage addAliCbPayDoc(AliCbPayDoc aliCbPayDoc) {
+        aliCbPayDoc.setAliPaySn("alicb" + IdWorkerAide.nextId());
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        aliCbPayDoc.setCreateTime(sdf.format(new Date()));
+        //设置支付单状态 待审核
+        aliCbPayDoc.setDocStatus(AliDict.PaymentDocStatus.i_00.getItem());
+        String appid = aliCbPayDoc.getPartner();
+        try {
+            List<MerchPayCfg> merchPayCfgList = merchPayCfgMapper.getMerchPayCfgByMerchsn(appid);
+            if(merchPayCfgList.size() == 0){
+                return  new ResponseMessage.Builder().setCode(ResponseStatus.ERROR.getItem()).setMsg("支付宝交易号为" + appid + "的支付配置信息不存在")
+                        .build();
+            }
+        } catch (Exception e) {
+            logger.error("查询商户支付配置信息异常", e);
+            return  new ResponseMessage.Builder().setCode(ResponseStatus.ERROR.getItem()).setMsg("查询商户支付配置信息异常")
+                    .build();
+        }
+
+        try {
+            int result = aliCbPayDocMapper.insertSelective(aliCbPayDoc);
+            if (result > 0) {
+                HashMap<String,String> resultMap = new HashMap<>();
+                resultMap.put("docStatus", AliDict.PaymentDocStatus.i_00.getItemName());
+
+                return new ResponseMessage.Builder().setCode(ResponseStatus.SUCCESS.getItem()).setMsg("入库成功")
+                        .setData(JacksonUtil.toJson(resultMap)).build();
+            }
+        } catch (Exception e) {
+            logger.error("新增支付单入库信息异常", e);
+            return  new ResponseMessage.Builder().setCode(ResponseStatus.ERROR.getItem()).setMsg("新增支付单入库信息异常")
+                    .build();
+        }
+        return  new ResponseMessage.Builder().setCode(ResponseStatus.ERROR.getItem()).setMsg("入库失败")
+                .build();
+    }
+
+    public List<AliCbPayDoc> selectBeDeclaredData(Integer limit) {
+        return aliCbPayDocMapper.selectBeDeclaredData(limit);
+    }
+
+    public int updateAliCbPay(AliCbPayDoc aliCbPayDoc) {
+        try {
+            return aliCbPayDocMapper.updateByPrimaryKeySelective(aliCbPayDoc);
+        } catch (Exception e) {
+            logger.error("更新支付单数据失败", e);
+            throw new RuntimeException("更新支付单数据失败");
+        }
+    }
+
+    public int updateBatch(List<AliCbPayDoc> aliCbPayDocs) {
+        return  aliCbPayDocMapper.updateBatch(aliCbPayDocs);
+    }
+
+    public List<AliCbPayDoc> selectPayDocByDocStatus(Integer limit) {
+        return aliCbPayDocMapper.selectPayDocByDocStatus(limit);
+    }
+
+    @Override
+    public AliCbPayDoc selectByOutRequestNo(String outRequestNo) {
+        return aliCbPayDocMapper.selectByOutRequestNo(outRequestNo);
+    }
+
+    @Override
+    public ResponseMessage heavyPush(AliCbPayDoc aliCbPayDoc) {
+        logger.error("重推支付报关开始");
+        try {
+            aliCbPayDoc.setDocStatus(AliDict.PaymentDocStatus.i_00.getItem());
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            aliCbPayDoc.setModTime(sdf.format(new Date()));
+            int result = this.aliCbPayDocMapper.updateByPrimaryKeySelective(aliCbPayDoc);
+            if (result > 0) {
+                HashMap<String, String> resultMap = new HashMap<>();
+                resultMap.put("docStatus", AliDict.PaymentDocStatus.i_00.getItemName());
+                return (new ResponseMessage.Builder()).setCode(ResponseStatus.SUCCESS.getItem()).setMsg("更新支付单成功").setData(JacksonUtil.toJson(resultMap)).build();
+            }
+        } catch (Exception e) {
+            logger.error("更新支付单信息异常", e);
+            return (new ResponseMessage.Builder()).setCode(ResponseStatus.ERROR.getItem()).setMsg("新增支付单入库信息异常").build();
+        }
+        return (new ResponseMessage.Builder()).setCode(ResponseStatus.ERROR.getItem()).setMsg("更新支付单失败").build();
+    }
+}

+ 28 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/ali/impl/AliPayErrorServiceImpl.java

@@ -0,0 +1,28 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.service.ali.impl;
+
+import com.kmall.admin.dao.cuspay.ali.AliPayErrorMapper;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.ali.AliPayError;
+import com.kmall.admin.cuspay.ccnet2cuspay.service.ali.AliPayErrorService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author zx
+ * @version 1.0
+ * 2018-05-19 15:58
+ */
+@Service
+public class AliPayErrorServiceImpl implements AliPayErrorService {
+
+    @Autowired
+    AliPayErrorMapper aliPayErrorMapper;
+
+    @Override
+    public int insertAliPayErrorBatch(List<AliPayError> aliPayErrors) {
+        return  aliPayErrorMapper.insertAliPayErrorBatch(aliPayErrors);
+    }
+
+}

+ 57 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/wx/WxCbPayDocService.java

@@ -0,0 +1,57 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.service.wx;
+
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.wx.WxCbPayDoc;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseMessage;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * @author huangyq
+ * @version 1.0
+ * 2018-05-18 16:05
+ */
+public interface WxCbPayDocService {
+    /**
+     * 微信支付单入库
+     * @param wxCbPayDoc 微信支付单证
+     * @return
+     */
+    ResponseMessage addWxCbPayDoc(WxCbPayDoc wxCbPayDoc);
+
+    /**
+     * 查找微信推海关 待申报的数据
+     * @param limit
+     * @return
+     */
+    List<WxCbPayDoc> selectBeDeclaredData(Integer limit);
+
+    /**
+     * 更新
+     * @param wxCbPayDoc
+     * @return
+     */
+    int updateWxCbPay(WxCbPayDoc wxCbPayDoc);
+
+    /**
+     * 批量更新
+     * @param wxCbPayDocs
+     * @return
+     */
+    int updateBatch(List<WxCbPayDoc> wxCbPayDocs);
+
+    /**
+     * 查找微信推海关 等待处理、业务处理中的数据
+     * @param limit
+     * @return
+     */
+    List<WxCbPayDoc> selectPayDocByDocStatus(Integer limit);
+
+    /**
+     * 根据订单编号查询该订单是否已经有申报回执, 返回申报成功的订单编号
+     * req_20210826_001
+     * @param orderSnList   订单编号列表
+     * @return              申报成功的订单编号列表
+     */
+    ResponseMessage selectPayDocByOrderSnList(List<String> orderSnList);
+}

+ 17 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/wx/WxPayErrorService.java

@@ -0,0 +1,17 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.service.wx;
+
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.wx.WxPayError;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * @author zx
+ * @version 1.0
+ * 2018-05-19 15:58
+ */
+public interface WxPayErrorService {
+
+    int insertWxPayErrorBatch(List<WxPayError> wxPayErrors);
+
+}

+ 125 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/wx/impl/WxCbPayDocServiceImpl.java

@@ -0,0 +1,125 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.service.wx.impl;
+
+
+import com.kmall.admin.cuspay.common.contant.TablePrimaryKeyPrefix;
+import com.kmall.admin.cuspay.common.core.db.IdWorkerAide;
+import com.kmall.admin.dao.cuspay.merch.MerchPayCfgMapper;
+import com.kmall.admin.dao.cuspay.wx.WxCbPayDocMapper;
+import com.kmall.admin.cuspay.entity.merch.MerchPayCfg;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.wx.WxCbPayDoc;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseMessage;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseStatus;
+import com.kmall.admin.cuspay.util.jackson.JacksonUtil;
+import com.kmall.admin.cuspay.ccnet2cuspay.common.wx.WxDict;
+import com.kmall.admin.cuspay.ccnet2cuspay.service.wx.WxCbPayDocService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author huangyq
+ * @version 1.0
+ * 2018-05-18 16:05
+ */
+@Service
+public class WxCbPayDocServiceImpl implements WxCbPayDocService {
+    private static final Logger logger = LoggerFactory.getLogger(WxCbPayDocServiceImpl.class);
+
+    @Autowired
+    private WxCbPayDocMapper wxCbPayDocMapper;
+
+    @Autowired
+    private MerchPayCfgMapper merchPayCfgMapper;
+
+    /**
+     * 支付单信息入库
+     * @param wxCbPayDoc 微信支付单证
+     * @return
+     */
+    public ResponseMessage addWxCbPayDoc(WxCbPayDoc wxCbPayDoc) {
+        wxCbPayDoc.setWxPaySn(TablePrimaryKeyPrefix.wx_cb_pay_type + IdWorkerAide.nextId());
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        wxCbPayDoc.setCreateTime(sdf.format(new Date()));
+        //设置支付单状态 待审核
+        wxCbPayDoc.setDocStatus(WxDict.PaymentDocStatus.i_00.getItem());
+        String appid = wxCbPayDoc.getAppid();
+        try {
+            List<MerchPayCfg> merchPayCfgList = merchPayCfgMapper.getMerchPayCfgByMerchsn(appid);
+            if(merchPayCfgList.size() == 0){
+                return  new ResponseMessage.Builder().setCode(ResponseStatus.ERROR.getItem()).setMsg("appid为" + appid + "的支付配置信息不存在")
+                        .build();
+            }
+        } catch (Exception e) {
+            logger.error("查询商户支付配置信息异常", e);
+            return  new ResponseMessage.Builder().setCode(ResponseStatus.ERROR.getItem()).setMsg("查询商户支付配置信息异常")
+                    .build();
+        }
+
+        try {
+            int result = wxCbPayDocMapper.insertSelective(wxCbPayDoc);
+            if (result > 0) {
+                HashMap<String,String> resultMap = new HashMap<>();
+                resultMap.put("docStatus", WxDict.PaymentDocStatus.i_00.getItemName());
+
+                return new ResponseMessage.Builder().setCode(ResponseStatus.SUCCESS.getItem()).setMsg("入库成功")
+                        .setData(JacksonUtil.toJson(resultMap)).build();
+            }
+        } catch (Exception e) {
+            logger.error("新增支付单入库信息异常", e);
+            return  new ResponseMessage.Builder().setCode(ResponseStatus.ERROR.getItem()).setMsg("新增支付单入库信息异常")
+                    .build();
+        }
+        return  new ResponseMessage.Builder().setCode(ResponseStatus.ERROR.getItem()).setMsg("入库失败")
+                .build();
+    }
+
+    public List<WxCbPayDoc> selectBeDeclaredData(Integer limit) {
+        return wxCbPayDocMapper.selectBeDeclaredData(limit);
+    }
+
+    public int updateWxCbPay(WxCbPayDoc wxCbPayDoc) {
+        try {
+            return wxCbPayDocMapper.updateByPrimaryKeySelective(wxCbPayDoc);
+        } catch (Exception e) {
+            logger.error("更新支付单数据失败", e);
+            throw new RuntimeException("更新支付单数据失败");
+        }
+    }
+
+    public int updateBatch(List<WxCbPayDoc> wxCbPayDocs) {
+        return  wxCbPayDocMapper.updateBatch(wxCbPayDocs);
+    }
+
+    public List<WxCbPayDoc> selectPayDocByDocStatus(Integer limit) {
+        return wxCbPayDocMapper.selectPayDocByDocStatus(limit);
+    }
+
+    /**
+     * 根据订单编号查询该订单是否已经有申报回执, 返回申报成功的订单编号
+     * req_20210826_001
+     * @param orderSnList 订单编号列表
+     * @return 申报成功的订单编号列表
+     */
+    @Override
+    public ResponseMessage selectPayDocByOrderSnList(List<String> orderSnList) {
+        ResponseMessage.Builder builder = new ResponseMessage.Builder(ResponseStatus.SUCCESS.getItem(), ResponseStatus.SUCCESS.getItemName());
+        builder.setData(
+                JacksonUtil.toJson(
+                        wxCbPayDocMapper
+                                .selectPayDocByOrderSnList(orderSnList)
+                                .parallelStream()
+                                .filter(wxCbPayDoc -> WxDict.PaymentDocStatus.i_12.getItem().equals(wxCbPayDoc.getDocStatus()))
+                                .map(WxCbPayDoc::getSubOrderNo)
+                                .collect(Collectors.toList())
+                )
+        );
+        return builder.build();
+    }
+}

+ 27 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/ccnet2cuspay/service/wx/impl/WxPayErrorServiceImpl.java

@@ -0,0 +1,27 @@
+package com.kmall.admin.cuspay.ccnet2cuspay.service.wx.impl;
+
+import com.kmall.admin.dao.cuspay.wx.WxPayErrorMapper;
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.wx.WxPayError;
+import com.kmall.admin.cuspay.ccnet2cuspay.service.wx.WxPayErrorService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author zx
+ * @version 1.0
+ * 2018-05-19 15:58
+ */
+@Service
+public class WxPayErrorServiceImpl implements WxPayErrorService{
+
+    @Autowired
+    WxPayErrorMapper wxPayErrorMapper;
+
+    public int insertWxPayErrorBatch(List<WxPayError> wxPayErrors) {
+        return  wxPayErrorMapper.insertWxPayErrorBatch(wxPayErrors);
+    }
+
+}

+ 168 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/common/contant/MerchNoticeDict.java

@@ -0,0 +1,168 @@
+package com.kmall.admin.cuspay.common.contant;
+
+/**
+ * @author zx
+ * @version 1.0
+ * 2018-05-15 13:56
+ */
+public abstract class MerchNoticeDict {
+
+
+
+    public enum Whether {
+        Yes("Y", "是"),
+        No("N","否");
+
+        private String item;
+        private String itemName;
+
+        Whether(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    public enum BuyerPayerCheckStatus {
+        i_0("0", "未知"),
+        i_1("1", "一致"),
+        i_2("2", "不一致"),
+        i_3("3", "校验异常");;
+
+        private String item;
+        private String itemName;
+
+        BuyerPayerCheckStatus(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    /**
+     * 是否停止通知
+     */
+    public enum IsStopStatus {
+        i_0("0", "否"),
+        i_1("1", "是");
+
+        private String item;
+        private String itemName;
+
+        IsStopStatus(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    /**
+     * 通知状态
+     */
+    public enum NoticeStatus {
+        i_0("0", "初始"),
+        i_1("1", "通知已发送"),
+        i_2("2", "通知发送成功"),
+        i_3("3", "通知发送失败");
+
+        private String item;
+        private String itemName;
+
+        NoticeStatus(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+
+    public enum MerchNoticeStatus {
+        i_10("10", "等待海关处理"),
+        i_11("11", "海关申报中"),
+        i_12("12", "海关申报失败"),
+        i_13("13", "海关申报成功");
+
+        private String item;
+        private String itemName;
+
+        MerchNoticeStatus(String item, String itemName) {
+            this.item = item;
+            this.itemName = itemName;
+        }
+
+        public String getItem() {
+            return item;
+        }
+
+        public void setItem(String item) {
+            this.item = item;
+        }
+
+        public String getItemName() {
+            return itemName;
+        }
+
+        public void setItemName(String itemName) {
+            this.itemName = itemName;
+        }
+    }
+}

+ 21 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/common/contant/TablePrimaryKeyPrefix.java

@@ -0,0 +1,21 @@
+package com.kmall.admin.cuspay.common.contant;
+
+/**
+ * @author zx
+ * @version 1.0
+ * 2018-05-15 14:40
+ */
+public interface TablePrimaryKeyPrefix {
+    //跨境支付凭证
+    public static final String wx_cb_pay_type = "wxcb";
+    //支付单异常记录
+    public static final String wx_pay_error_type = "wxer";
+    //商户支付配置
+    public static final String merch_pay_cfg_type = "mpct";
+    //商户通知
+    public static final String merch_pay_noti_type = "noti";
+
+    public static final String ali_cb_pay_type = "alicb";
+
+    public static final String ali_pay_error_type = "alier";
+}

+ 147 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/common/core/db/IdWorker.java

@@ -0,0 +1,147 @@
+package com.kmall.admin.cuspay.common.core.db;
+
+/**
+ * Twitter_Snowflake<br>
+ * SnowFlake的结构如下(每部分用-分开):<br>
+ * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br>
+ * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br>
+ * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
+ * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>
+ * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br>
+ * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br>
+ * 加起来刚好64位,为一个Long型。<br>
+ * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
+ */
+public class IdWorker {
+	// ==============================Fields===========================================
+	/** 开始时间截 (2015-01-01) */
+	private final long twepoch = 1420041600000L;
+
+	/** 机器id所占的位数 */
+	private final long workerIdBits = 5L;
+
+	/** 数据标识id所占的位数 */
+	private final long datacenterIdBits = 5L;
+
+	/** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
+	private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+
+	/** 支持的最大数据标识id,结果是31 */
+	private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+	/** 序列在id中占的位数 */
+	private final long sequenceBits = 12L;
+
+	/** 机器ID向左移12位 */
+	private final long workerIdShift = sequenceBits;
+
+	/** 数据标识id向左移17位(12+5) */
+	private final long datacenterIdShift = sequenceBits + workerIdBits;
+
+	/** 时间截向左移22位(5+5+12) */
+	private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+	/** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
+	private final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+	/** 工作机器ID(0~31) */
+	private long workerId;
+
+	/** 数据中心ID(0~31) */
+	private long datacenterId;
+
+	/** 毫秒内序列(0~4095) */
+	private long sequence = 0L;
+
+	/** 上次生成ID的时间截 */
+	private long lastTimestamp = -1L;
+
+	//==============================Constructors=====================================
+	/**
+	 * 构造函数
+	 * @param workerId 工作ID (0~31)
+	 * @param datacenterId 数据中心ID (0~31)
+	 */
+	public IdWorker(long workerId, long datacenterId) {
+		if (workerId > maxWorkerId || workerId < 0) {
+			throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+		}
+		if (datacenterId > maxDatacenterId || datacenterId < 0) {
+			throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+		}
+		this.workerId = workerId;
+		this.datacenterId = datacenterId;
+	}
+
+	// ==============================Methods==========================================
+	/**
+	 * 获得下一个ID (该方法是线程安全的)
+	 * @return SnowflakeId
+	 */
+	public synchronized long nextId() {
+		long timestamp = timeGen();
+
+		//如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
+		if (timestamp < lastTimestamp) {
+			throw new RuntimeException(
+					String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+		}
+
+		//如果是同一时间生成的,则进行毫秒内序列
+		if (lastTimestamp == timestamp) {
+			sequence = (sequence + 1) & sequenceMask;
+			//毫秒内序列溢出
+			if (sequence == 0) {
+				//阻塞到下一个毫秒,获得新的时间戳
+				timestamp = tilNextMillis(lastTimestamp);
+			}
+		}
+		//时间戳改变,毫秒内序列重置
+		else {
+			sequence = 0L;
+		}
+
+		//上次生成ID的时间截
+		lastTimestamp = timestamp;
+
+		//移位并通过或运算拼到一起组成64位的ID
+		return ((timestamp - twepoch) << timestampLeftShift) //
+				| (datacenterId << datacenterIdShift) //
+				| (workerId << workerIdShift) //
+				| sequence;
+	}
+
+	/**
+	 * 阻塞到下一个毫秒,直到获得新的时间戳
+	 * @param lastTimestamp 上次生成ID的时间截
+	 * @return 当前时间戳
+	 */
+	protected long tilNextMillis(long lastTimestamp) {
+		long timestamp = timeGen();
+		while (timestamp <= lastTimestamp) {
+			timestamp = timeGen();
+		}
+		return timestamp;
+	}
+
+	/**
+	 * 返回以毫秒为单位的当前时间
+	 * @return 当前时间(毫秒)
+	 */
+	protected long timeGen() {
+		return System.currentTimeMillis();
+	}
+
+	//==============================Test=============================================
+	/** 测试 */
+	public static void main(String[] args) {
+        /*IdWorker idWorker = new IdWorker(0, 0);
+        for (int i = 0; i < 100; i++) {
+            long id = idWorker.nextId();
+            System.out.println(Long.toBinaryString(id));
+            System.out.println(id);
+        }*/
+
+	}
+
+}

+ 56 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/common/core/db/IdWorkerAide.java

@@ -0,0 +1,56 @@
+package com.kmall.admin.cuspay.common.core.db;
+
+import com.kmall.manager.manager.redis.JedisUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class IdWorkerAide {
+	private static final Logger logger = LoggerFactory.getLogger(IdWorkerAide.class);
+
+	private static IdWorker idWorker;
+
+	public static long nextId() {
+		if (idWorker == null) {
+			idWorker = initIdWorker();
+		}
+		return idWorker.nextId();
+	}
+
+	/**
+	 * 实例化idWorker
+	 */
+	public static IdWorker initIdWorker() {
+		String workerIdKey = "sequence-workerId";
+		// 机器id
+		Integer workerId = (Integer) JedisUtil.getObject(workerIdKey);
+		if (workerId == null) {
+			workerId = 0;
+		}
+		String datacenterIdKey = "sequence-datacenterId" + workerId;
+
+		// 数据中心id
+		Integer datacenterId = (Integer) JedisUtil.getObject(datacenterIdKey);
+
+		if (datacenterId == null) {
+			datacenterId = 0;
+		} else {
+			datacenterId++;
+		}
+
+		JedisUtil.setObject(workerIdKey, workerId, 0);
+		JedisUtil.setObject(datacenterIdKey, datacenterId, 0);
+
+		if (datacenterId > 31) {
+			datacenterId = 0;
+			workerId++;
+
+	 		// 每32 个数据中心id 换一个机器id
+			JedisUtil.setObject(workerIdKey, workerId, 0);
+			datacenterIdKey = "sequence-datacenterId" + workerId;
+			JedisUtil.setObject(datacenterIdKey, datacenterId, 0);
+		}
+
+		return new IdWorker(workerId, datacenterId);
+	}
+
+}

+ 82 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/common/date/DateTimeDeserializer.java

@@ -0,0 +1,82 @@
+package com.kmall.admin.cuspay.common.date;
+
+import com.kmall.admin.cuspay.util.date.DateConstant;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * 反序列化Date
+ * String类型反序列化为Date类型
+ * @author Scott Chen
+ * @since 1.0
+ * 2018-02-07
+ */
+public class DateTimeDeserializer extends JsonDeserializer<Date> {
+    private static final Logger logger = LoggerFactory.getLogger(DateTimeDeserializer.class);
+
+    public static final DateTimeDeserializer instance = new DateTimeDeserializer();
+
+    private static final List<String> formarts = new LinkedList();
+
+    static {
+        formarts.add(DateConstant.DATE_MONTH);
+        formarts.add(DateConstant.DATE_MONTH_DAY);
+        formarts.add(DateConstant.DATE_TIME_MINUTE);
+        formarts.add(DateConstant.DATE_TIME_SECOND);
+        formarts.add(DateConstant.DATE_TIME_SECOND_MILL);
+    }
+
+    @Override
+    public Date deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+        String source = parser.getText().trim();
+        if (source.length() == 0) {
+            return null;
+        }
+
+        String format = "";
+
+        try {
+            if (source.matches("^\\d{4}-\\d{1,2}$")) {
+                format = formarts.get(0);
+            } else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")) {
+                format = formarts.get(1);
+            } else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")) {
+                format = formarts.get(2);
+            } else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")) {
+                format = formarts.get(3);
+            } else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}\\.\\d{3}$")) {
+                format = formarts.get(4);
+            } else if (source.matches("^\\d{10}$|^\\d{13}$")) {
+                // Windows时间戳(13位),Unix时间戳(10位)
+                format = formarts.get(3);
+            } else {
+                throw new IllegalArgumentException("Invalid boolean value '" + source + "'");
+            }
+
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format, Locale.SIMPLIFIED_CHINESE);
+
+            //使用LocalDateTime作转换
+            LocalDateTime dateTime = LocalDateTime.parse(source, formatter);
+            return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
+        } catch (Exception e) {
+            logger.error("参数" + source + ", 通过【"+ this.getClass().getName() +"】转换为日期格式【" + format + "】时, 发生错误");
+            e.printStackTrace();
+            return null;
+        }
+
+    }
+
+}

+ 34 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/common/date/DateTimeSerializer.java

@@ -0,0 +1,34 @@
+package com.kmall.admin.cuspay.common.date;
+
+import com.kmall.admin.cuspay.util.date.DateConstant;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * 序列化Date
+ * Date类型序列化为String类型
+ * @author Scott Chen
+ * @since 1.0
+ * 2018-02-07
+ */
+public class DateTimeSerializer extends JsonSerializer<Date> {
+
+    @Override
+    public void serialize(Date value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
+        String format = DateConstant.DATE_TIME_SECOND;
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format, Locale.SIMPLIFIED_CHINESE);
+
+        //使用LocalDateTime作转换
+        LocalDateTime localDateTime = LocalDateTime.ofInstant(value.toInstant(), ZoneId.systemDefault());
+        gen.writeString(localDateTime.format(formatter));
+    }
+
+}

+ 46 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/common/msg/RequestMessage.java

@@ -0,0 +1,46 @@
+package com.kmall.admin.cuspay.common.msg;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author huangyq
+ * @version 1.0
+ * 2018-05-18 14:52
+ */
+public class RequestMessage implements Serializable {
+    private static final long serialVersionUID = -3044821399294307105L;
+
+    //状态码
+    private String code;
+
+    private String msg;
+    //业务数据
+    private Object data;
+
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+}

+ 150 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/common/msg/Result.java

@@ -0,0 +1,150 @@
+package com.kmall.admin.cuspay.common.msg;
+
+import com.google.common.base.Strings;
+
+
+public class Result {
+    /**
+     * 状态码, 正常0, 失败1, 未登录2, 个位数是保留状态码, 其他业务相关状态码10以上
+     */
+    private String code = ResultCodeEnum.SUCCESS.getCode();
+
+    /**
+     * 消息
+     */
+    private String msg;
+
+    /**
+     * 业务数据
+     */
+    private Object data;
+
+    private String sign;
+
+    private Result() {
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+
+    public String getMsg() {
+        return msg;
+    }
+
+
+    public Object getData() {
+        return data;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static Builder builder(String code, String msg) {
+        return new Builder(code, msg);
+    }
+
+    public static Builder builder(String code, String msg, Object data) {
+        return new Builder(code, msg, data);
+    }
+
+    public static Builder builder(String code, String msg, String sign, Object data) {
+        return new Builder(code, msg, sign, data);
+    }
+
+    //---------- 直接返回结果 ----------
+
+    public static Result success(Object object) {
+        return new Builder(ResultCodeEnum.SUCCESS.getCode(), ResultCodeEnum.SUCCESS.getMsg(), object).build();
+    }
+
+    public static Result success(String code, String msg, Object object) {
+        return new Builder(code, msg, object).build();
+    }
+
+    public static Result success(String msg) {
+        return new Builder(ResultCodeEnum.SUCCESS.getCode(), msg).build();
+    }
+
+    public static Result error(String code, String msg) {
+        return new Builder(code, msg).build();
+    }
+
+    public static Result error(String msg) {
+        return new Builder(ResultCodeEnum.FAILURE.getCode(), msg).build();
+    }
+
+    public static Result error(String code, String msg, Object object) {
+        return new Builder(code, msg, object).build();
+    }
+
+    /**
+     * 消息构建器类
+     */
+    public static class Builder {
+        private String code;
+        private String msg;
+        private Object data;
+        private String sign;
+
+        public Builder() {
+            this.code = ResultCodeEnum.SUCCESS.getCode();
+            this.msg = ResultCodeEnum.SUCCESS.getMsg();
+            this.data = null;
+        }
+
+        public Builder(String code, String msg) {
+            this.code = Strings.isNullOrEmpty(code) ? ResultCodeEnum.SUCCESS.getCode() : code;
+            this.msg = Strings.isNullOrEmpty(msg) ? ResultCodeEnum.SUCCESS.getMsg() : msg;
+        }
+
+        public Builder(String code, String msg, Object extend) {
+            this.code = Strings.isNullOrEmpty(code) ? ResultCodeEnum.SUCCESS.getCode() : code;
+            this.msg = Strings.isNullOrEmpty(msg) ? ResultCodeEnum.SUCCESS.getMsg() : msg;
+            this.data = extend;
+        }
+
+        public Builder(String code, String msg, String sign, Object extend) {
+            this.code = Strings.isNullOrEmpty(code) ? ResultCodeEnum.SUCCESS.getCode() : code;
+            this.msg = Strings.isNullOrEmpty(msg) ? ResultCodeEnum.SUCCESS.getMsg() : msg;
+            this.sign = sign;
+            this.data = extend;
+        }
+
+        public Result build() {
+            Result message = new Result();
+            message.code = this.code;
+            message.msg = this.msg;
+            message.data = this.data;
+            message.sign = this.sign;
+            return message;
+        }
+
+        public Builder setCode(String code) {
+            this.code = code;
+            return this;
+        }
+
+        public Builder setMsg(String msg) {
+            this.msg = msg;
+            return this;
+        }
+
+        public Builder setData(Object data) {
+            this.data = data;
+            return this;
+        }
+    }
+
+}

+ 36 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/common/msg/ResultCodeEnum.java

@@ -0,0 +1,36 @@
+package com.kmall.admin.cuspay.common.msg;
+
+public enum ResultCodeEnum {
+	/** 成功 */
+	SUCCESS("0", "成功"),
+	/** 失败 */
+	FAILURE("-1", "失败");
+
+	/** 状态码 */
+	private String code;
+
+	/** 信息 */
+	private String msg;
+
+	private ResultCodeEnum(String code, String msg){
+        this.code = code;
+        this.msg = msg;
+    }
+
+	public String getCode() {
+		return code;
+	}
+
+	public void setCode(String code) {
+		this.code = code;
+	}
+
+	public String getMsg() {
+		return msg;
+	}
+
+	public void setMsg(String msg) {
+		this.msg = msg;
+	}
+
+}

+ 35 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/config/AspectWebConfiguration.java

@@ -0,0 +1,35 @@
+package com.kmall.admin.cuspay.config;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.kmall.admin.cuspay.aop.AspectWebLog;
+import com.kmall.admin.cuspay.aop.AspectWebLog;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author Scott Chen
+ * @version 1.0
+ * 2017-10-23 02:27
+ */
+@Configuration
+public class AspectWebConfiguration {
+
+    /**
+     * 日志处理
+     * @return
+     */
+    @Bean
+    public static AspectWebLog webLogAspect() {
+        return new AspectWebLog();
+    }
+
+    /**
+     *
+     * @return
+     */
+    @Bean
+    public ObjectMapper objectMapper() {
+        return new ObjectMapper();
+    }
+
+}

+ 38 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/config/DistributedSystemProperties.java

@@ -0,0 +1,38 @@
+package com.kmall.admin.cuspay.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+import java.io.Serializable;
+
+/**
+ * @author Scott Chen
+ * @version 1.0
+ * 2017-11-26 16:16
+ */
+@Configuration
+//@ConfigurationProperties("ds")
+public class DistributedSystemProperties implements Serializable {
+    private static final long serialVersionUID = 2933157544322298616L;
+
+//    @Value("${workerId}")
+    private long workerId;
+//    @Value("${datacenterId}")
+    private long datacenterId;
+
+    public long getWorkerId() {
+        return workerId;
+    }
+
+    public void setWorkerId(long workerId) {
+        this.workerId = workerId;
+    }
+
+    public long getDatacenterId() {
+        return datacenterId;
+    }
+
+    public void setDatacenterId(long datacenterId) {
+        this.datacenterId = datacenterId;
+    }
+}

+ 81 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/config/db/primary/PrimaryDataSourceConfiguration.java

@@ -0,0 +1,81 @@
+package com.kmall.admin.cuspay.config.db.primary;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+
+import javax.sql.DataSource;
+
+/**
+ * 多数据源配置
+ *
+ * 数据源配置
+ *
+ * 指定mybatis-config.xml, 和要扫描的别名包
+ *
+ * @author Scott Chen
+ * @date 2017/4/22
+ */
+@Configuration
+public class PrimaryDataSourceConfiguration {
+
+    @Autowired
+    private Environment env;
+
+    /*@Bean
+    @ConfigurationProperties(prefix = "spring.datasource.primary")
+    public DataSourceProperties primaryDataSourceProperties() {
+        return new DataSourceProperties();
+    }
+
+    @Bean
+    public DataSource primaryDataSource() {
+        DataSource dataSource = primaryDataSourceProperties().initializeDataSourceBuilder().build();
+        return dataSource;
+    }*/
+
+//    @Bean
+//    @ConfigurationProperties(prefix = "spring.datasource.primary")
+//    public HikariConfig masterHikariConfig() {
+//        return new HikariConfig();
+//    }
+//
+//    @Bean(destroyMethod = "close")
+//    public HikariDataSource primaryDataSource() {
+//        HikariDataSource dataSource = new HikariDataSource(masterHikariConfig());
+//        return dataSource;
+//    }
+//
+//    @Bean
+//    public SqlSessionFactory primarySqlSessionFactory(DataSource primaryDataSource) throws Exception  {
+//        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
+//        sessionFactoryBean.setDataSource(primaryDataSource);
+//
+//        //配置mybatis-config.xml
+//        sessionFactoryBean.setConfigLocation(new PathMatchingResourcePatternResolver().getResource(env.getProperty("mybatis.primary.config-location")));
+//        //配置mapper.xml
+//        sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.primary.mapper-locations")));
+//        //配置扫描type aliases的包路径
+//        sessionFactoryBean.setTypeAliasesPackage(env.getProperty("mybatis.primary.type-aliases-package"));
+//        return sessionFactoryBean.getObject();
+//    }
+//
+//    @Bean(name = "primaryTransactionManager")
+//    public DataSourceTransactionManager primaryTransactionManager( DataSource primaryDataSource) {
+//        return new DataSourceTransactionManager(primaryDataSource);
+//    }
+//
+//    @Bean
+//    public SqlSessionTemplate primarySqlSessionTemplate(SqlSessionFactory primarySqlSessionFactory) {
+//        return new SqlSessionTemplate(primarySqlSessionFactory);
+//    }
+
+}

+ 41 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/config/db/primary/PrimaryMapperConfiguration.java

@@ -0,0 +1,41 @@
+package com.kmall.admin.cuspay.config.db.primary;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import org.mybatis.spring.mapper.MapperScannerConfigurer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+/**
+ * Mybatis Mapper接口扫描配置
+ *
+ * @author Scott Chen
+ * @date 2017/4/23
+ */
+@Configuration
+public class PrimaryMapperConfiguration {
+
+//    @Bean
+//    public MapperScannerConfigurer primaryMapperScannerConfigurer() {
+//        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
+//        //Mapper接口包
+//        mapperScannerConfigurer.setBasePackage(mapperPackage());
+//        //要使用的数据源
+//        mapperScannerConfigurer.setSqlSessionTemplateBeanName("primarySqlSessionTemplate");
+//        return mapperScannerConfigurer;
+//    }
+//
+//    /**
+//     * 添加要扫描的Mapper接口包
+//     * 以逗号分隔的字符串
+//     *
+//     * @return
+//     */
+//    protected String mapperPackage() {
+//        ImmutableList.Builder<String> builder = new ImmutableList.Builder();
+//        builder.add("com.kmall.admin.cuspay.dao.mapper");
+//        return Joiner.on(",").join(builder.build());
+//    }
+
+}

+ 55 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/config/servlet/WebMvcConfiguration.java

@@ -0,0 +1,55 @@
+// package com.kmall.admin.cuspay.config.servlet;
+//
+// import org.springframework.context.annotation.Bean;
+// import org.springframework.context.annotation.Configuration;
+// import org.springframework.web.filter.CharacterEncodingFilter;
+// import org.springframework.web.servlet.ViewResolver;
+// import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler;
+// import org.springframework.web.servlet.view.InternalResourceViewResolver;
+//
+// /**
+//  * @author Scott Chen
+//  * @version 1.0
+//  * 2017-11-21 19:06
+//  */
+// @Configuration
+// public class WebMvcConfiguration {
+//
+//     /**
+//      * 编码过滤器
+//      * 注释 spring boot 的编码过滤实现方法
+//      * @author zhuhh
+//      * @return
+//      */
+//    @Bean
+//    public FilterRegistrationBean characterEncodingFilter() {
+//        CharacterEncodingFilter filter = new CharacterEncodingFilter();
+//        filter.setEncoding("UTF-8");
+//        filter.setForceEncoding(true);
+//
+//        FilterRegistrationBean filterBean = new FilterRegistrationBean();
+//        filterBean.setFilter(filter);
+//        filterBean.addUrlPatterns("/*");
+//        return filterBean;
+//    }
+//
+//     @Bean
+//     public DefaultServletHttpRequestHandler defaultServletHttpRequestHandler() {
+//         return new DefaultServletHttpRequestHandler();
+//     }
+//
+//
+//     /**
+//      * 注册视图处理器
+//      * @return
+//      */
+//     @Bean
+//     public ViewResolver viewResolver() {
+//         InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
+//         viewResolver.setPrefix("");
+//         viewResolver.setSuffix(".html");
+//         return viewResolver;
+//     }
+//
+//
+// }

+ 116 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/config/spring/HttpResponseConfig.java

@@ -0,0 +1,116 @@
+package com.kmall.admin.cuspay.config.spring;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.format.FormatterRegistry;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.validation.MessageCodesResolver;
+import org.springframework.validation.Validator;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
+import org.springframework.web.servlet.HandlerExceptionResolver;
+import org.springframework.web.servlet.config.annotation.*;
+
+import java.util.List;
+
+/**
+ * 返回消息格式转换
+ *
+ * @author zhuhh
+ * @date 2021-12-3 10:20:21
+ */
+@Configuration
+public class HttpResponseConfig implements WebMvcConfigurer {
+
+
+    @Override
+    public void configurePathMatch(PathMatchConfigurer pathMatchConfigurer) {
+
+    }
+
+    @Override
+    public void configureContentNegotiation(ContentNegotiationConfigurer contentNegotiationConfigurer) {
+        // 因为用了jackson-dataformat相关包,返回数据格式被框架修改为 xml,需要在这里修改为 json
+        contentNegotiationConfigurer.defaultContentType(MediaType.APPLICATION_JSON_UTF8);
+    }
+
+    @Override
+    public void configureAsyncSupport(AsyncSupportConfigurer asyncSupportConfigurer) {
+
+    }
+
+    @Override
+    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer defaultServletHandlerConfigurer) {
+
+    }
+
+    @Override
+    public void addFormatters(FormatterRegistry formatterRegistry) {
+
+    }
+
+    @Override
+    public void addInterceptors(InterceptorRegistry interceptorRegistry) {
+
+    }
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry resourceHandlerRegistry) {
+
+    }
+
+    @Override
+    public void addCorsMappings(CorsRegistry corsRegistry) {
+
+    }
+
+    @Override
+    public void addViewControllers(ViewControllerRegistry viewControllerRegistry) {
+
+    }
+
+    @Override
+    public void configureViewResolvers(ViewResolverRegistry viewResolverRegistry) {
+
+    }
+
+    @Override
+    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> list) {
+
+    }
+
+    @Override
+    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> list) {
+
+    }
+
+    @Override
+    public void configureMessageConverters(List<HttpMessageConverter<?>> list) {
+
+    }
+
+    @Override
+    public void extendMessageConverters(List<HttpMessageConverter<?>> list) {
+
+    }
+
+    @Override
+    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> list) {
+
+    }
+
+    @Override
+    public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> list) {
+
+    }
+
+    @Override
+    public Validator getValidator() {
+        return null;
+    }
+
+    @Override
+    public MessageCodesResolver getMessageCodesResolver() {
+        return null;
+    }
+}

+ 27 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/config/spring/SpringConfiguration.java

@@ -0,0 +1,27 @@
+package com.kmall.admin.cuspay.config.spring;
+
+import com.kmall.admin.cuspay.util.SpringContextSupport;
+import com.kmall.admin.cuspay.util.SpringContextSupport;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author Scott Chen
+ * @version 1.0
+ * 2017-11-24 10:29
+ */
+@Configuration
+public class SpringConfiguration {
+
+    /**
+     * Spring应用上下文环境
+     * @return
+     */
+    @Bean
+    public SpringContextSupport springContextUtil() {
+        return new SpringContextSupport();
+    }
+
+
+
+}

+ 112 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/entity/merch/MerchCusCfg.java

@@ -0,0 +1,112 @@
+package com.kmall.admin.cuspay.entity.merch;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class MerchCusCfg implements Serializable {
+    private String cusCfgSn;
+
+    private String merchSn;
+
+    private String cusFlag;
+
+    private String isValid;
+
+    private String remark;
+
+    private String createrSn;
+
+    private String createTime;
+
+    private String moderSn;
+
+    private String modTime;
+
+    private Date tstm;
+
+    private static final long serialVersionUID = 1L;
+
+    public MerchCusCfg() {
+        super();
+    }
+
+    public String getCusCfgSn() {
+        return cusCfgSn;
+    }
+
+    public void setCusCfgSn(String cusCfgSn) {
+        this.cusCfgSn = cusCfgSn == null ? null : cusCfgSn.trim();
+    }
+
+    public String getMerchSn() {
+        return merchSn;
+    }
+
+    public void setMerchSn(String merchSn) {
+        this.merchSn = merchSn == null ? null : merchSn.trim();
+    }
+
+    public String getCusFlag() {
+        return cusFlag;
+    }
+
+    public void setCusFlag(String cusFlag) {
+        this.cusFlag = cusFlag == null ? null : cusFlag.trim();
+    }
+
+    public String getIsValid() {
+        return isValid;
+    }
+
+    public void setIsValid(String isValid) {
+        this.isValid = isValid == null ? null : isValid.trim();
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark == null ? null : remark.trim();
+    }
+
+    public String getCreaterSn() {
+        return createrSn;
+    }
+
+    public void setCreaterSn(String createrSn) {
+        this.createrSn = createrSn == null ? null : createrSn.trim();
+    }
+
+    public String getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(String createTime) {
+        this.createTime = createTime == null ? null : createTime.trim();
+    }
+
+    public String getModerSn() {
+        return moderSn;
+    }
+
+    public void setModerSn(String moderSn) {
+        this.moderSn = moderSn == null ? null : moderSn.trim();
+    }
+
+    public String getModTime() {
+        return modTime;
+    }
+
+    public void setModTime(String modTime) {
+        this.modTime = modTime == null ? null : modTime.trim();
+    }
+
+    public Date getTstm() {
+        return tstm;
+    }
+
+    public void setTstm(Date tstm) {
+        this.tstm = tstm;
+    }
+}

+ 303 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/entity/merch/MerchNoti.java

@@ -0,0 +1,303 @@
+package com.kmall.admin.cuspay.entity.merch;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+public class MerchNoti implements Serializable {
+    private String notiSn;
+
+    private String allPaySn;
+
+    private String merchSn;
+
+    private String merchName;
+
+    private String platSn;
+
+    private String platName;
+
+    private String thirdPartyMerchCode;
+
+    private String thirdPartyMerchName;
+
+    private String allMerchId;
+
+    private String allOrderNo;
+
+    private String allPayNo;
+
+    private String allSubOrderNo;
+
+    private String payChnlFlag;
+
+    private String buyerPayerCheck;
+
+    private Integer notiCount;
+
+    private String isStoped;
+
+    private String cusDeclStatus;
+
+    private String notiStatue;
+
+    private String code;
+
+    private String msg;
+
+    private String notifyUrl;
+
+    private String remark;
+
+    private String createrSn;
+
+    private String createTime;
+
+    private String moderSn;
+
+    private String modTime;
+
+    private Date tstm;
+
+    private String merchErpOrderSn;
+
+    private String allSubOrderId;
+
+    private static final long serialVersionUID = 1L;
+
+    public MerchNoti() {
+        super();
+    }
+
+    public String getAllSubOrderId() {
+        return allSubOrderId;
+    }
+
+    public void setAllSubOrderId(String allSubOrderId) {
+        this.allSubOrderId = allSubOrderId;
+    }
+
+    public String getNotiSn() {
+        return notiSn;
+    }
+
+    public void setNotiSn(String notiSn) {
+        this.notiSn = notiSn == null ? null : notiSn.trim();
+    }
+
+    public String getAllPaySn() {
+        return allPaySn;
+    }
+
+    public void setAllPaySn(String allPaySn) {
+        this.allPaySn = allPaySn == null ? null : allPaySn.trim();
+    }
+
+    public String getMerchSn() {
+        return merchSn;
+    }
+
+    public void setMerchSn(String merchSn) {
+        this.merchSn = merchSn == null ? null : merchSn.trim();
+    }
+
+    public String getMerchName() {
+        return merchName;
+    }
+
+    public void setMerchName(String merchName) {
+        this.merchName = merchName == null ? null : merchName.trim();
+    }
+
+    public String getPlatSn() {
+        return platSn;
+    }
+
+    public void setPlatSn(String platSn) {
+        this.platSn = platSn == null ? null : platSn.trim();
+    }
+
+    public String getPlatName() {
+        return platName;
+    }
+
+    public void setPlatName(String platName) {
+        this.platName = platName == null ? null : platName.trim();
+    }
+
+    public String getThirdPartyMerchCode() {
+        return thirdPartyMerchCode;
+    }
+
+    public void setThirdPartyMerchCode(String thirdPartyMerchCode) {
+        this.thirdPartyMerchCode = thirdPartyMerchCode == null ? null : thirdPartyMerchCode.trim();
+    }
+
+    public String getThirdPartyMerchName() {
+        return thirdPartyMerchName;
+    }
+
+    public void setThirdPartyMerchName(String thirdPartyMerchName) {
+        this.thirdPartyMerchName = thirdPartyMerchName == null ? null : thirdPartyMerchName.trim();
+    }
+
+    public String getAllMerchId() {
+        return allMerchId;
+    }
+
+    public void setAllMerchId(String allMerchId) {
+        this.allMerchId = allMerchId == null ? null : allMerchId.trim();
+    }
+
+    public String getAllOrderNo() {
+        return allOrderNo;
+    }
+
+    public void setAllOrderNo(String allOrderNo) {
+        this.allOrderNo = allOrderNo == null ? null : allOrderNo.trim();
+    }
+
+    public String getAllPayNo() {
+        return allPayNo;
+    }
+
+    public void setAllPayNo(String allPayNo) {
+        this.allPayNo = allPayNo == null ? null : allPayNo.trim();
+    }
+
+    public String getAllSubOrderNo() {
+        return allSubOrderNo;
+    }
+
+    public void setAllSubOrderNo(String allSubOrderNo) {
+        this.allSubOrderNo = allSubOrderNo == null ? null : allSubOrderNo.trim();
+    }
+
+    public String getPayChnlFlag() {
+        return payChnlFlag;
+    }
+
+    public void setPayChnlFlag(String payChnlFlag) {
+        this.payChnlFlag = payChnlFlag == null ? null : payChnlFlag.trim();
+    }
+
+    public String getBuyerPayerCheck() {
+        return buyerPayerCheck;
+    }
+
+    public void setBuyerPayerCheck(String buyerPayerCheck) {
+        this.buyerPayerCheck = buyerPayerCheck == null ? null : buyerPayerCheck.trim();
+    }
+
+    public Integer getNotiCount() {
+        return notiCount;
+    }
+
+    public void setNotiCount(Integer notiCount) {
+        this.notiCount = notiCount;
+    }
+
+    public String getIsStoped() {
+        return isStoped;
+    }
+
+    public void setIsStoped(String isStoped) {
+        this.isStoped = isStoped == null ? null : isStoped.trim();
+    }
+
+    public String getCusDeclStatus() {
+        return cusDeclStatus;
+    }
+
+    public void setCusDeclStatus(String cusDeclStatus) {
+        this.cusDeclStatus = cusDeclStatus == null ? null : cusDeclStatus.trim();
+    }
+
+    public String getNotiStatue() {
+        return notiStatue;
+    }
+
+    public void setNotiStatue(String notiStatue) {
+        this.notiStatue = notiStatue == null ? null : notiStatue.trim();
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code == null ? null : code.trim();
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg == null ? null : msg.trim();
+    }
+
+    public String getNotifyUrl() {
+        return notifyUrl;
+    }
+
+    public void setNotifyUrl(String notifyUrl) {
+        this.notifyUrl = notifyUrl == null ? null : notifyUrl.trim();
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark == null ? null : remark.trim();
+    }
+
+    public String getCreaterSn() {
+        return createrSn;
+    }
+
+    public void setCreaterSn(String createrSn) {
+        this.createrSn = createrSn == null ? null : createrSn.trim();
+    }
+
+    public String getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(String createTime) {
+        this.createTime = createTime == null ? null : createTime.trim();
+    }
+
+    public String getModerSn() {
+        return moderSn;
+    }
+
+    public void setModerSn(String moderSn) {
+        this.moderSn = moderSn == null ? null : moderSn.trim();
+    }
+
+    public String getModTime() {
+        return modTime;
+    }
+
+    public void setModTime(String modTime) {
+        this.modTime = modTime == null ? null : modTime.trim();
+    }
+
+    public String getMerchErpOrderSn() {
+        return merchErpOrderSn;
+    }
+
+    public void setMerchErpOrderSn(String merchErpOrderSn) {
+        this.merchErpOrderSn = merchErpOrderSn;
+    }
+
+    public Date getTstm() {
+        return tstm;
+    }
+
+    public void setTstm(Date tstm) {
+        this.tstm = tstm;
+    }
+}

+ 132 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/entity/merch/MerchPayCfg.java

@@ -0,0 +1,132 @@
+package com.kmall.admin.cuspay.entity.merch;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class MerchPayCfg implements Serializable {
+    private String payCfgSn;
+
+    private String appid;
+
+    private String merchWxApiKey;
+
+    private String notifyUrl;
+
+    private String payChnlFlag;
+
+    private String isValid;
+
+    private String remark;
+
+    private String createrSn;
+
+    private String createTime;
+
+    private String moderSn;
+
+    private String modTime;
+
+    private Date tstm;
+
+    private static final long serialVersionUID = 1L;
+
+    public MerchPayCfg() {
+        super();
+    }
+
+    public String getPayCfgSn() {
+        return payCfgSn;
+    }
+
+    public void setPayCfgSn(String payCfgSn) {
+        this.payCfgSn = payCfgSn == null ? null : payCfgSn.trim();
+    }
+
+    public String getAppid() {
+        return appid;
+    }
+
+    public void setAppid(String appid) {
+        this.appid = appid == null ? null : appid.trim();
+    }
+
+    public String getMerchWxApiKey() {
+        return merchWxApiKey;
+    }
+
+    public void setMerchWxApiKey(String merchWxApiKey) {
+        this.merchWxApiKey = merchWxApiKey == null ? null : merchWxApiKey.trim();
+    }
+
+    public String getNotifyUrl() {
+        return notifyUrl;
+    }
+
+    public void setNotifyUrl(String notifyUrl) {
+        this.notifyUrl = notifyUrl == null ? null : notifyUrl.trim();
+    }
+
+    public String getPayChnlFlag() {
+        return payChnlFlag;
+    }
+
+    public void setPayChnlFlag(String payChnlFlag) {
+        this.payChnlFlag = payChnlFlag == null ? null : payChnlFlag.trim();
+    }
+
+    public String getIsValid() {
+        return isValid;
+    }
+
+    public void setIsValid(String isValid) {
+        this.isValid = isValid == null ? null : isValid.trim();
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark == null ? null : remark.trim();
+    }
+
+    public String getCreaterSn() {
+        return createrSn;
+    }
+
+    public void setCreaterSn(String createrSn) {
+        this.createrSn = createrSn == null ? null : createrSn.trim();
+    }
+
+    public String getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(String createTime) {
+        this.createTime = createTime == null ? null : createTime.trim();
+    }
+
+    public String getModerSn() {
+        return moderSn;
+    }
+
+    public void setModerSn(String moderSn) {
+        this.moderSn = moderSn == null ? null : moderSn.trim();
+    }
+
+    public String getModTime() {
+        return modTime;
+    }
+
+    public void setModTime(String modTime) {
+        this.modTime = modTime == null ? null : modTime.trim();
+    }
+
+    public Date getTstm() {
+        return tstm;
+    }
+
+    public void setTstm(Date tstm) {
+        this.tstm = tstm;
+    }
+}

+ 29 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/manager/snow/SnowflakeConfiguration.java

@@ -0,0 +1,29 @@
+package com.kmall.admin.cuspay.manager.snow;
+
+import com.kmall.admin.cuspay.config.DistributedSystemProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 雪花算法生成ID
+ *
+ * @author Scott Chen
+ * @version 1.0
+ * 2017-11-26 16:06
+ */
+@Configuration
+public class SnowflakeConfiguration {
+
+    @Autowired
+    DistributedSystemProperties distributedSystemProperties;
+
+    @Bean
+    public SnowflakeIdWorker snowflakeIdWorker() {
+        return new SnowflakeIdWorker(
+                distributedSystemProperties.getWorkerId(),
+                distributedSystemProperties.getDatacenterId()
+        );
+    }
+
+}

+ 145 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/manager/snow/SnowflakeIdWorker.java

@@ -0,0 +1,145 @@
+package com.kmall.admin.cuspay.manager.snow;
+
+/**
+ * Twitter_Snowflake<br>
+ * SnowFlake的结构如下(每部分用-分开):<br>
+ * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br>
+ * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br>
+ * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
+ * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>
+ * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br>
+ * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br>
+ * 加起来刚好64位,为一个Long型。<br>
+ * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
+ */
+public class SnowflakeIdWorker {
+// ==============================Fields===========================================
+    /** 开始时间截 (2015-01-01) */
+    private final long twepoch = 1420041600000L;
+
+    /** 机器id所占的位数 */
+    private final long workerIdBits = 5L;
+
+    /** 数据标识id所占的位数 */
+    private final long datacenterIdBits = 5L;
+
+    /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
+    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+
+    /** 支持的最大数据标识id,结果是31 */
+    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+    /** 序列在id中占的位数 */
+    private final long sequenceBits = 12L;
+
+    /** 机器ID向左移12位 */
+    private final long workerIdShift = sequenceBits;
+
+    /** 数据标识id向左移17位(12+5) */
+    private final long datacenterIdShift = sequenceBits + workerIdBits;
+
+    /** 时间截向左移22位(5+5+12) */
+    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+    /** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
+    private final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+    /** 工作机器ID(0~31) */
+    private long workerId;
+
+    /** 数据中心ID(0~31) */
+    private long datacenterId;
+
+    /** 毫秒内序列(0~4095) */
+    private long sequence = 0L;
+
+    /** 上次生成ID的时间截 */
+    private long lastTimestamp = -1L;
+
+    //==============================Constructors=====================================
+    /**
+     * 构造函数
+     * @param workerId 工作ID (0~31)
+     * @param datacenterId 数据中心ID (0~31)
+     */
+    public SnowflakeIdWorker(long workerId, long datacenterId) {
+        if (workerId > maxWorkerId || workerId < 0) {
+            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+        }
+        if (datacenterId > maxDatacenterId || datacenterId < 0) {
+            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+        }
+        this.workerId = workerId;
+        this.datacenterId = datacenterId;
+    }
+
+    // ==============================Methods==========================================
+    /**
+     * 获得下一个ID (该方法是线程安全的)
+     * @return SnowflakeId
+     */
+    public synchronized long nextId() {
+        long timestamp = timeGen();
+
+        //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
+        if (timestamp < lastTimestamp) {
+            throw new RuntimeException(
+                    String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+        }
+
+        //如果是同一时间生成的,则进行毫秒内序列
+        if (lastTimestamp == timestamp) {
+            sequence = (sequence + 1) & sequenceMask;
+            //毫秒内序列溢出
+            if (sequence == 0) {
+                //阻塞到下一个毫秒,获得新的时间戳
+                timestamp = tilNextMillis(lastTimestamp);
+            }
+        }
+        //时间戳改变,毫秒内序列重置
+        else {
+            sequence = 0L;
+        }
+
+        //上次生成ID的时间截
+        lastTimestamp = timestamp;
+
+        //移位并通过或运算拼到一起组成64位的ID
+        return ((timestamp - twepoch) << timestampLeftShift) //
+                | (datacenterId << datacenterIdShift) //
+                | (workerId << workerIdShift) //
+                | sequence;
+    }
+
+    /**
+     * 阻塞到下一个毫秒,直到获得新的时间戳
+     * @param lastTimestamp 上次生成ID的时间截
+     * @return 当前时间戳
+     */
+    protected long tilNextMillis(long lastTimestamp) {
+        long timestamp = timeGen();
+        while (timestamp <= lastTimestamp) {
+            timestamp = timeGen();
+        }
+        return timestamp;
+    }
+
+    /**
+     * 返回以毫秒为单位的当前时间
+     * @return 当前时间(毫秒)
+     */
+    protected long timeGen() {
+        return System.currentTimeMillis();
+    }
+
+    //==============================Test=============================================
+    /** 测试 */
+    public static void main(String[] args) {
+        SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0);
+        for (int i = 0; i < 100; i++) {
+            long id = idWorker.nextId();
+            System.out.println(Long.toBinaryString(id));
+            System.out.println(id);
+        }
+    }
+}

+ 33 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/manager/snow/SnowflakeUtil.java

@@ -0,0 +1,33 @@
+package com.kmall.admin.cuspay.manager.snow;
+
+
+import com.kmall.admin.cuspay.util.SpringContextSupport;
+import com.kmall.admin.cuspay.util.SpringContextSupport;
+
+/**
+ * @author Scott Chen
+ * @since 1.0
+ * 2018-01-08 11:19
+ */
+public class SnowflakeUtil {
+
+    private static final ThreadLocal<SnowflakeIdWorker> snowflakeIdWorkerThreadLocal = new ThreadLocal<>();
+
+    private SnowflakeUtil() {
+        throw new RuntimeException("Illegal instance SnowflakeUtil");
+    }
+
+    private static SnowflakeIdWorker snowWorkerInstance() {
+        SnowflakeIdWorker snowflakeIdWorker = snowflakeIdWorkerThreadLocal.get();
+        if (snowflakeIdWorker == null) {
+            snowflakeIdWorker = SpringContextSupport.getBean("snowflakeIdWorker");
+            snowflakeIdWorkerThreadLocal.set(snowflakeIdWorker);
+        }
+        return snowflakeIdWorker;
+    }
+
+    public static long getSnowNextId() {
+        return snowWorkerInstance().nextId();
+    }
+
+}

+ 15 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/service/MerchCusService.java

@@ -0,0 +1,15 @@
+package com.kmall.admin.cuspay.service;
+
+import com.kmall.admin.cuspay.entity.merch.MerchCusCfg;
+
+import java.util.List;
+
+/**
+ * @author zx
+ * @version 1.0
+ * 2018-05-19 17:45
+ */
+public interface MerchCusService {
+
+    List<MerchCusCfg> findCusCfgBySn(String merchSn);
+}

+ 26 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/service/MerchNotiService.java

@@ -0,0 +1,26 @@
+package com.kmall.admin.cuspay.service;
+
+import com.kmall.admin.cuspay.entity.merch.MerchNoti;
+
+import java.util.List;
+
+/**
+ * @author zx
+ * @version 1.0
+ * 2018-05-19 15:41
+ */
+public interface MerchNotiService {
+
+    /**
+     * 批量插入
+     * @param merchNotis
+     * @return
+     */
+    int insertBatch(List<MerchNoti> merchNotis);
+
+    List<MerchNoti> getMerchNotiByCodeAndOrderNo(MerchNoti merchNoti);
+
+    MerchNoti insert(MerchNoti merchNoti);
+
+    MerchNoti update(MerchNoti merchNoti);
+}

+ 31 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/service/MerchPaymentService.java

@@ -0,0 +1,31 @@
+package com.kmall.admin.cuspay.service;
+
+
+
+import com.kmall.admin.cuspay.entity.merch.MerchPayCfg;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseMessage;
+
+import java.util.List;
+
+/**
+ * @author zx
+ *
+ *
+ * @version 1.0
+ * 2018-05-17 12:01
+ */
+public interface MerchPaymentService {
+
+    /**
+     *添加商户支付配置信息
+     * @param merchPayCfg 商户支付配置信息
+     * @return
+     */
+    ResponseMessage addMerchPayCfg(MerchPayCfg merchPayCfg);
+
+    /**
+     *获取商户支付信息
+     * @return 商户支付信息列表
+     */
+    List<MerchPayCfg> loadMerchPayCfg();
+}

+ 26 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/service/impl/MerchCusServiceImpl.java

@@ -0,0 +1,26 @@
+package com.kmall.admin.cuspay.service.impl;
+
+import com.kmall.admin.cuspay.service.MerchCusService;
+import com.kmall.admin.dao.cuspay.merch.MerchCusCfgMapper;
+import com.kmall.admin.cuspay.entity.merch.MerchCusCfg;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author zengjun
+ * @version 1.0
+ * 2018-05-19 17:46
+ */
+@Service
+public class MerchCusServiceImpl implements MerchCusService{
+
+    @Autowired
+    MerchCusCfgMapper merchCusCfgMapper;
+
+    public List<MerchCusCfg> findCusCfgBySn(String merchSn) {
+        return merchCusCfgMapper.getMerchCusCfgByMerchSn(merchSn);
+    }
+}

+ 50 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/service/impl/MerchNotiServiceImpl.java

@@ -0,0 +1,50 @@
+package com.kmall.admin.cuspay.service.impl;
+
+import com.kmall.admin.cuspay.service.MerchNotiService;
+import com.kmall.admin.dao.cuspay.merch.MerchNotiMapper;
+import com.kmall.admin.cuspay.entity.merch.MerchNoti;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 商户通知信息
+ * @author zx
+ * @version 1.0
+ * 2018-05-19 15:42
+ */
+@Service
+public class MerchNotiServiceImpl implements MerchNotiService {
+
+    @Autowired
+    MerchNotiMapper merchNotiMapper;
+
+    public int insertBatch(List<MerchNoti> merchNotis) {
+        return merchNotiMapper.insertBatch(merchNotis);
+    }
+
+
+    public List<MerchNoti> getMerchNotiByCodeAndOrderNo(MerchNoti merchNoti) {
+
+        return merchNotiMapper.getMerchNotiByCodeAndOrderNo(merchNoti);
+    }
+
+    public MerchNoti insert(MerchNoti record){
+        record.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
+        if(this.merchNotiMapper.insertSelective(record)==1) {
+            return record;
+        }
+        return null;
+    }
+
+    public MerchNoti update(MerchNoti record){
+        if(this.merchNotiMapper.updateByPrimaryKeySelective(record)==1) {
+            return record;
+        }
+        return null;
+    }
+}

+ 64 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/service/impl/MerchPaymentServiceImpl.java

@@ -0,0 +1,64 @@
+package com.kmall.admin.cuspay.service.impl;
+
+
+
+
+
+import com.kmall.admin.cuspay.service.MerchPaymentService;
+import com.kmall.admin.cuspay.common.contant.TablePrimaryKeyPrefix;
+import com.kmall.admin.cuspay.common.core.db.IdWorkerAide;
+import com.kmall.admin.dao.cuspay.merch.MerchPayCfgMapper;
+import com.kmall.admin.cuspay.entity.merch.MerchPayCfg;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseMessage;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+/**
+ * @author zx
+ * @version 1.0
+ * 2018-05-17 13:35
+ */
+@Service
+public class MerchPaymentServiceImpl implements MerchPaymentService {
+    private static final Logger logger = LoggerFactory.getLogger(MerchPaymentServiceImpl.class);
+
+    @Autowired
+    private MerchPayCfgMapper merchPayCfgMapper;
+
+    public ResponseMessage addMerchPayCfg(MerchPayCfg merchPayCfg) {
+        merchPayCfg.setPayCfgSn(TablePrimaryKeyPrefix.merch_pay_cfg_type + IdWorkerAide.nextId());
+        merchPayCfg.setIsValid("0");
+
+        try {
+            MerchPayCfg payCfg = new MerchPayCfg();
+            payCfg.setAppid(merchPayCfg.getAppid());
+            payCfg.setPayChnlFlag(merchPayCfg.getPayChnlFlag());
+            if(merchPayCfgMapper.getMerchPayCfgByMerchsnAndChnlFlag(payCfg) != null){
+                return  new ResponseMessage.Builder().setCode(ResponseStatus.ERROR.getItem()).setMsg("appid为"+merchPayCfg.getAppid()+"的支付配置信息已存在")
+                        .build();
+            }
+        } catch (Exception e) {
+            logger.error("根据商户编号和查询支付通道标识查询商户支付配置信息异常", e);
+        }
+
+
+        try {
+            int result = merchPayCfgMapper.insertSelective(merchPayCfg);
+            if (result > 0) {
+                return ResponseMessage.builder(ResponseStatus.SUCCESS.getItem(), "添加成功").build();
+            }
+        } catch (Exception e) {
+            logger.error("添加商户支付配置信息异常", e);
+        }
+        return ResponseMessage.builder(ResponseStatus.ERROR.getItem(), "添加失败").build();
+    }
+
+    public List<MerchPayCfg> loadMerchPayCfg() {
+        return merchPayCfgMapper.selectMerchPayCfg();
+    }
+
+}

+ 57 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/support/msg/resp/MessageException.java

@@ -0,0 +1,57 @@
+package com.kmall.admin.cuspay.support.msg.resp;
+
+/**
+ * 自定义异常
+ *
+ * @author Scott Chen
+ * @date 2017/3/22
+ */
+public class MessageException extends RuntimeException {
+
+    private static final long serialVersionUID = -1422580005904561463L;
+
+    private String code;
+    private String msg;
+
+    public MessageException() {
+        super();
+    }
+
+    public MessageException(String msg) {
+        super(msg);
+        this.msg = msg;
+    }
+
+    public MessageException(String code, String msg) {
+        super(msg);
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public MessageException(String code, String msg, Throwable cause) {
+        super(msg, cause);
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public MessageException(String msg, Throwable cause) {
+        super(msg, cause);
+        this.msg = msg;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+}

+ 246 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/support/msg/resp/ResponseMessage.java

@@ -0,0 +1,246 @@
+package com.kmall.admin.cuspay.support.msg.resp;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 回执消息结构
+ *
+ * @author Scott Chen
+ * @date 2017/4/20
+ */
+public class ResponseMessage {
+
+
+    /**
+     * 消息码
+     */
+    private String code;
+
+    /**
+     * 消息
+     */
+    private String msg;
+
+    /**
+     * 回执业务数据
+     */
+    private Object data;
+
+    private ResponseMessage() {
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public static boolean isSuccess(ResponseMessage message) {
+        return message.getCode() == null ? false : message.getCode().equals(ResponseStatus.SUCCESS.getItem()) ? true : false;
+    }
+
+    public static Builder builder() {
+        return new Builder();
+    }
+    public static Builder builder(String code, String msg) {
+        return new Builder(code, msg);
+    }
+    public static Builder builder(String code, String msg, ResponseMessageData responseMessageData) {
+        return new Builder(code, msg, responseMessageData);
+    }
+    public static Builder builder(String code, String msg, List list) {
+        return new Builder(code, msg, list);
+    }
+    public static <T> Builder builder(T t,  Class<T> type) {
+        return new Builder(ResponseStatus.SUCCESS.getItem(), ResponseStatus.SUCCESS.getItemName(), t, type);
+    }
+    public static <T> Builder builder(String msg, T t,  Class<T> type) {
+        return new Builder(ResponseStatus.SUCCESS.getItem(), msg, t, type);
+    }
+    public static <T> Builder builder(String code, String msg, T t,  Class<T> type) {
+        return new Builder(code, msg, t, type);
+    }
+
+
+    //---------- 直接返回结果 ----------
+    //成功
+    public static ResponseMessage success() {
+        return new Builder().build();
+    }
+    public static ResponseMessage success(String code, String msg) {
+        return new Builder(code, msg).build();
+    }
+    public static ResponseMessage success(String msg) {
+        return new Builder(ResponseStatus.SUCCESS.getItem(), msg).build();
+    }
+
+    public static ResponseMessage success(Map map) {
+        return new Builder(ResponseStatus.SUCCESS.getItem(), ResponseStatus.SUCCESS.getItemName(), map).build();
+    }
+    public static ResponseMessage success(String msg, Map map) {
+        return new Builder(ResponseStatus.SUCCESS.getItem(), msg, map).build();
+    }
+    public static ResponseMessage success(List rows) {
+        return new Builder(ResponseStatus.SUCCESS.getItem(), ResponseStatus.SUCCESS.getItemName(), rows).build();
+    }
+    public static ResponseMessage success(String msg, List rows) {
+        return new Builder(ResponseStatus.SUCCESS.getItem(), msg, rows).build();
+    }
+    public static ResponseMessage success(String code, String msg, List rows) {
+        return new Builder(code, msg, rows).build();
+    }
+    public static <T> ResponseMessage success(T t,  Class<T> type) {
+        return new Builder(ResponseStatus.SUCCESS.getItem(), ResponseStatus.SUCCESS.getItemName(), t, type).build();
+    }
+    public static <T> ResponseMessage success(String msg, T t,  Class<T> type) {
+        return new Builder(ResponseStatus.SUCCESS.getItem(), msg, t, type).build();
+    }
+    public static <T> ResponseMessage success(String code, String msg, T t,  Class<T> type) {
+        return new Builder(code, msg, t, type).build();
+    }
+
+    //错误
+    public static ResponseMessage error() {
+        return new Builder(ResponseStatus.ERROR.getItem(), ResponseStatus.ERROR.getItemName()).build();
+    }
+    public static ResponseMessage error(String code, String msg) {
+        return new Builder(code, msg).build();
+    }
+    public static ResponseMessage error(String msg) {
+        return new Builder(ResponseStatus.ERROR.getItem(), msg).build();
+    }
+    public static ResponseMessage error(Map map) {
+        return new Builder(ResponseStatus.ERROR.getItem(), ResponseStatus.ERROR.getItemName(), map).build();
+    }
+    public static ResponseMessage error(String msg, Map map) {
+        return new Builder(ResponseStatus.ERROR.getItem(), msg, map).build();
+    }
+    public static ResponseMessage error(List rows) {
+        return new Builder(ResponseStatus.ERROR.getItem(), ResponseStatus.ERROR.getItemName(), rows).build();
+    }
+    public static ResponseMessage error(String msg, List rows) {
+        return new Builder(ResponseStatus.ERROR.getItem(), msg, rows).build();
+    }
+    public static ResponseMessage error(String code, String msg, List rows) {
+        return new Builder(code, msg, rows).build();
+    }
+
+    //失败
+    public static ResponseMessage failed() {
+        return new Builder(ResponseStatus.FAILURE.getItem(), ResponseStatus.FAILURE.getItemName()).build();
+    }
+    public static ResponseMessage failed(String code, String msg) {
+        return new Builder(code, msg).build();
+    }
+    public static ResponseMessage failed(String msg) {
+        return new Builder(ResponseStatus.FAILURE.getItem(), msg).build();
+    }
+
+    public static ResponseMessage failed(Map map) {
+        return new Builder(ResponseStatus.ERROR.getItem(), ResponseStatus.ERROR.getItemName(), map).build();
+    }
+    public static ResponseMessage failed(String msg, Map map) {
+        return new Builder(ResponseStatus.ERROR.getItem(), msg, map).build();
+    }
+    public static ResponseMessage failed(List rows) {
+        return new Builder(ResponseStatus.FAILURE.getItem(), ResponseStatus.FAILURE.getItemName(), rows).build();
+    }
+    public static ResponseMessage failed(String msg, List rows) {
+        return new Builder(ResponseStatus.ERROR.getItem(), msg, rows).build();
+    }
+    public static ResponseMessage failed(String code, String msg, List rows) {
+        return new Builder(code, msg, rows).build();
+    }
+
+    /**
+     * 消息构建器类
+     */
+    public static class Builder {
+        private String code;
+        private String msg;
+        private Object data;
+
+        public Builder() {
+            this.code = ResponseStatus.SUCCESS.getItem();
+            this.msg = ResponseStatus.SUCCESS.getItemName();
+            this.data = Lists.newArrayList();
+        }
+
+        public Builder(String code, String msg) {
+            this.code = Strings.isNullOrEmpty(code) ? ResponseStatus.SUCCESS.getItem() : code;
+            this.msg = Strings.isNullOrEmpty(msg) ? ResponseStatus.SUCCESS.getItemName() : msg;
+            this.data = Lists.newArrayList();
+        }
+
+        public Builder(String code, String msg, ResponseMessageData responseMessageData) {
+            this.code = Strings.isNullOrEmpty(code) ? ResponseStatus.SUCCESS.getItem() : code;
+            this.msg = Strings.isNullOrEmpty(msg) ? ResponseStatus.SUCCESS.getItemName() : msg;
+            this.data = Lists.newArrayList();
+        }
+
+        public Builder(String code, String msg, Map map) {
+            this.code = Strings.isNullOrEmpty(code) ? ResponseStatus.SUCCESS.getItem() : code;
+            this.msg = Strings.isNullOrEmpty(msg) ? ResponseStatus.SUCCESS.getItemName() : msg;
+            this.data = Lists.newArrayList();
+        }
+
+        public Builder(String code, String msg, List rows) {
+            this.code = Strings.isNullOrEmpty(code) ? ResponseStatus.SUCCESS.getItem() : code;
+            this.msg = Strings.isNullOrEmpty(msg) ? ResponseStatus.SUCCESS.getItemName() : msg;
+            this.data = Lists.newArrayList();
+        }
+
+        public <T> Builder(T t, Class<T> type) {
+            this.code = ResponseStatus.SUCCESS.getItem();
+            this.msg = ResponseStatus.SUCCESS.getItemName();
+            this.data = Lists.newArrayList();
+        }
+
+        public <T> Builder(String msg, T t, Class<T> type) {
+            this.code = ResponseStatus.SUCCESS.getItem();
+            this.msg = Strings.isNullOrEmpty(msg) ? ResponseStatus.SUCCESS.getItemName() : msg;
+            this.data = Lists.newArrayList();
+        }
+
+        public <T> Builder(String code, String msg, T t, Class<T> type) {
+            this.code = Strings.isNullOrEmpty(code) ? ResponseStatus.SUCCESS.getItem() : code;
+            this.msg = Strings.isNullOrEmpty(msg) ? ResponseStatus.SUCCESS.getItemName() : msg;
+            this.data = Lists.newArrayList();
+        }
+
+        public Builder setCode(String code) {
+            this.code = code;
+            return this;
+        }
+
+        public Builder setMsg(String msg) {
+            this.msg = msg;
+            return this;
+        }
+
+        public Builder setData(Object data) {
+            this.data = data;
+            return this;
+        }
+
+        public ResponseMessage build() {
+            ResponseMessage message = new ResponseMessage();
+            message.code = this.code;
+            message.msg = this.msg;
+            message.data = this.data;
+            return message;
+        }
+
+    }
+}
+

+ 86 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/support/msg/resp/ResponseMessageData.java

@@ -0,0 +1,86 @@
+package com.kmall.admin.cuspay.support.msg.resp;
+
+import java.lang.reflect.ParameterizedType;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Scott Chen
+ * @date 2017/4/20
+ */
+public class ResponseMessageData {
+
+    private int total;
+    private List rows;
+
+    private ResponseMessageData() {
+    }
+
+    public int countUser() {
+        return total;
+    }
+
+    public List getRows() {
+        return rows;
+    }
+
+    public static Builder builder() {
+        return new Builder();
+    }
+    public static Builder builder(List rows) {
+        return new Builder(rows);
+    }
+    public static <T> Builder builder(T t, Class<T> type) {
+        return new Builder(t, type);
+    }
+
+
+    public static class Builder {
+        private int total = 0;
+        private List rows = new ArrayList<>();
+
+        public Builder() {
+        }
+
+        public Builder(List rows) {
+            this.total = rows ==null ? 0 : rows.size();
+            this.rows = rows ==null ? new ArrayList<>() : rows;
+        }
+
+        public <T> Builder(T t, Class<T> type) {
+            List rows = new ArrayList<>();
+            if (t == null) {
+                this.total = 0;
+            } else{
+                rows.add(t);
+                this.total = rows.size();
+            }
+            this.rows = rows;
+        }
+
+        private Class getActualTypeClass(Class entity) {
+            ParameterizedType type = (ParameterizedType) entity.getGenericSuperclass();
+            Class entityClass = (Class) type.getActualTypeArguments()[0];
+            return entityClass;
+        }
+
+        public Builder setTotal(int total) {
+            this.total = total;
+            return this;
+        }
+
+        public Builder setRows(List rows) {
+            this.rows = rows;
+            return this;
+        }
+
+        public ResponseMessageData build() {
+            ResponseMessageData data = new ResponseMessageData();
+            data.total = this.total;
+            data.rows = this.rows;
+            return data;
+        }
+
+    }
+
+}

+ 45 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/support/msg/resp/ResponseStatus.java

@@ -0,0 +1,45 @@
+package com.kmall.admin.cuspay.support.msg.resp;
+
+/**
+ * 回执状态码
+ *
+ * @author Scott Chen
+ * @date 2017/3/9
+ */
+public enum ResponseStatus {
+
+    SUCCESS("0", "成功"),
+    ERROR("-1", "错误"),
+    FAILURE("-2", "失败"),
+
+    UNAUTHORIZED("401", "非法请求"),
+
+
+    SESSION_EXPIRE("600", "会话过期");
+
+
+    public String item;
+    public String itemName;
+
+    ResponseStatus(String item, String itemName) {
+        this.item = item;
+        this.itemName = itemName;
+    }
+
+    public String getItem() {
+        return item;
+    }
+
+    public void setItem(String item) {
+        this.item = item;
+    }
+
+    public String getItemName() {
+        return itemName;
+    }
+
+    public void setItemName(String itemName) {
+        this.itemName = itemName;
+    }
+
+}

+ 279 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/support/sign/Base64.java

@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2010 The MobileSecurePay Project
+ * All right reserved.
+ * author: shiqun.shi@alipay.com
+ */
+
+package com.kmall.admin.cuspay.support.sign;
+
+public final class Base64 {
+
+    static private final int     BASELENGTH           = 128;
+    static private final int     LOOKUPLENGTH         = 64;
+    static private final int     TWENTYFOURBITGROUP   = 24;
+    static private final int     EIGHTBIT             = 8;
+    static private final int     SIXTEENBIT           = 16;
+    static private final int     FOURBYTE             = 4;
+    static private final int     SIGN                 = -128;
+    static private final char    PAD                  = '=';
+    static private final boolean fDebug               = false;
+    static final private byte[]  base64Alphabet       = new byte[BASELENGTH];
+    static final private char[]  lookUpBase64Alphabet = new char[LOOKUPLENGTH];
+
+    static {
+        for (int i = 0; i < BASELENGTH; ++i) {
+            base64Alphabet[i] = -1;
+        }
+        for (int i = 'Z'; i >= 'A'; i--) {
+            base64Alphabet[i] = (byte) (i - 'A');
+        }
+        for (int i = 'z'; i >= 'a'; i--) {
+            base64Alphabet[i] = (byte) (i - 'a' + 26);
+        }
+
+        for (int i = '9'; i >= '0'; i--) {
+            base64Alphabet[i] = (byte) (i - '0' + 52);
+        }
+
+        base64Alphabet['+'] = 62;
+        base64Alphabet['/'] = 63;
+
+        for (int i = 0; i <= 25; i++) {
+            lookUpBase64Alphabet[i] = (char) ('A' + i);
+        }
+
+        for (int i = 26, j = 0; i <= 51; i++, j++) {
+            lookUpBase64Alphabet[i] = (char) ('a' + j);
+        }
+
+        for (int i = 52, j = 0; i <= 61; i++, j++) {
+            lookUpBase64Alphabet[i] = (char) ('0' + j);
+        }
+        lookUpBase64Alphabet[62] = (char) '+';
+        lookUpBase64Alphabet[63] = (char) '/';
+
+    }
+
+    private static boolean isWhiteSpace(char octect) {
+        return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
+    }
+
+    private static boolean isPad(char octect) {
+        return (octect == PAD);
+    }
+
+    private static boolean isData(char octect) {
+        return (octect < BASELENGTH && base64Alphabet[octect] != -1);
+    }
+
+    /**
+     * Encodes hex octects into Base64
+     *
+     * @param binaryData Array containing binaryData
+     * @return Encoded Base64 array
+     */
+    public static String encode(byte[] binaryData) {
+
+        if (binaryData == null) {
+            return null;
+        }
+
+        int lengthDataBits = binaryData.length * EIGHTBIT;
+        if (lengthDataBits == 0) {
+            return "";
+        }
+
+        int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
+        int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
+        int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
+        char encodedData[] = null;
+
+        encodedData = new char[numberQuartet * 4];
+
+        byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
+
+        int encodedIndex = 0;
+        int dataIndex = 0;
+        if (fDebug) {
+            System.out.println("number of triplets = " + numberTriplets);
+        }
+
+        for (int i = 0; i < numberTriplets; i++) {
+            b1 = binaryData[dataIndex++];
+            b2 = binaryData[dataIndex++];
+            b3 = binaryData[dataIndex++];
+
+            if (fDebug) {
+                System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);
+            }
+
+            l = (byte) (b2 & 0x0f);
+            k = (byte) (b1 & 0x03);
+
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
+            byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
+
+            if (fDebug) {
+                System.out.println("val2 = " + val2);
+                System.out.println("k4   = " + (k << 4));
+                System.out.println("vak  = " + (val2 | (k << 4)));
+            }
+
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
+        }
+
+        // form integral number of 6-bit groups
+        if (fewerThan24bits == EIGHTBIT) {
+            b1 = binaryData[dataIndex];
+            k = (byte) (b1 & 0x03);
+            if (fDebug) {
+                System.out.println("b1=" + b1);
+                System.out.println("b1<<2 = " + (b1 >> 2));
+            }
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
+            encodedData[encodedIndex++] = PAD;
+            encodedData[encodedIndex++] = PAD;
+        } else if (fewerThan24bits == SIXTEENBIT) {
+            b1 = binaryData[dataIndex];
+            b2 = binaryData[dataIndex + 1];
+            l = (byte) (b2 & 0x0f);
+            k = (byte) (b1 & 0x03);
+
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
+
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
+            encodedData[encodedIndex++] = PAD;
+        }
+
+        return new String(encodedData);
+    }
+
+    /**
+     * Decodes Base64 data into octects
+     *
+     * @param encoded string containing Base64 data
+     * @return Array containind decoded data.
+     */
+    public static byte[] decode(String encoded) {
+
+        if (encoded == null) {
+            return null;
+        }
+
+        char[] base64Data = encoded.toCharArray();
+        // remove white spaces
+        int len = removeWhiteSpace(base64Data);
+
+        if (len % FOURBYTE != 0) {
+            return null;//should be divisible by four
+        }
+
+        int numberQuadruple = (len / FOURBYTE);
+
+        if (numberQuadruple == 0) {
+            return new byte[0];
+        }
+
+        byte decodedData[] = null;
+        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
+        char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
+
+        int i = 0;
+        int encodedIndex = 0;
+        int dataIndex = 0;
+        decodedData = new byte[(numberQuadruple) * 3];
+
+        for (; i < numberQuadruple - 1; i++) {
+
+            if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
+                || !isData((d3 = base64Data[dataIndex++]))
+                || !isData((d4 = base64Data[dataIndex++]))) {
+                return null;
+            }//if found "no data" just return null
+
+            b1 = base64Alphabet[d1];
+            b2 = base64Alphabet[d2];
+            b3 = base64Alphabet[d3];
+            b4 = base64Alphabet[d4];
+
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+        }
+
+        if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {
+            return null;//if found "no data" just return null
+        }
+
+        b1 = base64Alphabet[d1];
+        b2 = base64Alphabet[d2];
+
+        d3 = base64Data[dataIndex++];
+        d4 = base64Data[dataIndex++];
+        if (!isData((d3)) || !isData((d4))) {//Check if they are PAD characters
+            if (isPad(d3) && isPad(d4)) {
+                if ((b2 & 0xf) != 0)//last 4 bits should be zero
+                {
+                    return null;
+                }
+                byte[] tmp = new byte[i * 3 + 1];
+                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+                tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
+                return tmp;
+            } else if (!isPad(d3) && isPad(d4)) {
+                b3 = base64Alphabet[d3];
+                if ((b3 & 0x3) != 0)//last 2 bits should be zero
+                {
+                    return null;
+                }
+                byte[] tmp = new byte[i * 3 + 2];
+                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+                tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+                tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+                return tmp;
+            } else {
+                return null;
+            }
+        } else { //No PAD e.g 3cQl
+            b3 = base64Alphabet[d3];
+            b4 = base64Alphabet[d4];
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+
+        }
+
+        return decodedData;
+    }
+
+    /**
+     * remove WhiteSpace from MIME containing encoded Base64 data.
+     *
+     * @param data  the byte array of base64 data (with WS)
+     * @return      the new length
+     */
+    private static int removeWhiteSpace(char[] data) {
+        if (data == null) {
+            return 0;
+        }
+
+        // count characters that's not whitespace
+        int newSize = 0;
+        int len = data.length;
+        for (int i = 0; i < len; i++) {
+            if (!isWhiteSpace(data[i])) {
+                data[newSize++] = data[i];
+            }
+        }
+        return newSize;
+    }
+}

+ 31 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/support/sign/MD5Util.java

@@ -0,0 +1,31 @@
+package com.kmall.admin.cuspay.support.sign;
+
+import org.apache.commons.codec.digest.DigestUtils;
+
+import java.io.UnsupportedEncodingException;
+import java.security.SignatureException;
+
+public class MD5Util {
+    public static String sign(String text, String key, String input_charset) {
+        text = text + key;
+        return DigestUtils.md5Hex(getContentBytes(text, input_charset));
+    }
+
+    public static boolean verify(String text, String sign, String key, String input_charset) {
+        text = text + key;
+        String mysign = DigestUtils.md5Hex(getContentBytes(text, input_charset));
+        if (mysign.equals(sign))
+            return true;
+        return false;
+    }
+
+    private static byte[] getContentBytes(String content, String charset) {
+        if (charset == null || "".equals(charset))
+            return content.getBytes();
+        try {
+            return content.getBytes(charset);
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:"+ charset);
+        }
+    }
+}

+ 143 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/support/sign/RSA.java

@@ -0,0 +1,143 @@
+
+package com.kmall.admin.cuspay.support.sign;
+
+import javax.crypto.Cipher;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+public class RSA{
+	
+	public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
+	
+	/**
+	* RSA签名
+	* @param content 待签名数据
+	* @param privateKey 商户私钥
+	* @param input_charset 编码格式
+	* @return 签名值
+	*/
+	public static String sign(String content, String privateKey, String input_charset)
+	{
+        try 
+        {
+        	PKCS8EncodedKeySpec priPKCS8 	= new PKCS8EncodedKeySpec( Base64.decode(privateKey) );
+        	KeyFactory keyf 				= KeyFactory.getInstance("RSA");
+        	PrivateKey priKey 				= keyf.generatePrivate(priPKCS8);
+
+            java.security.Signature signature = java.security.Signature
+                .getInstance(SIGN_ALGORITHMS);
+
+            signature.initSign(priKey);
+            signature.update( content.getBytes(input_charset) );
+
+            byte[] signed = signature.sign();
+            
+            return Base64.encode(signed);
+        }
+        catch (Exception e)
+        {
+        	e.printStackTrace();
+        }
+        
+        return null;
+    }
+	
+	/**
+	* RSA验签名检查
+	* @param content 待签名数据
+	* @param sign 签名值
+	* @param ali_public_key 支付宝公钥
+	* @param input_charset 编码格式
+	* @return 布尔值
+	*/
+	public static boolean verify(String content, String sign, String ali_public_key, String input_charset)
+	{
+		try 
+		{
+			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+	        byte[] encodedKey = Base64.decode(ali_public_key);
+	        PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
+
+		
+			java.security.Signature signature = java.security.Signature
+			.getInstance(SIGN_ALGORITHMS);
+		
+			signature.initVerify(pubKey);
+			signature.update( content.getBytes(input_charset) );
+		
+			boolean bverify = signature.verify( Base64.decode(sign) );
+			return bverify;
+			
+		} 
+		catch (Exception e)
+		{
+			e.printStackTrace();
+		}
+		
+		return false;
+	}
+	
+	/**
+	* 解密
+	* @param content 密文
+	* @param private_key 商户私钥
+	* @param input_charset 编码格式
+	* @return 解密后的字符串
+	*/
+	public static String decrypt(String content, String private_key, String input_charset) throws Exception {
+        PrivateKey prikey = getPrivateKey(private_key);
+
+        Cipher cipher = Cipher.getInstance("RSA");
+        cipher.init(Cipher.DECRYPT_MODE, prikey);
+
+        InputStream ins = new ByteArrayInputStream(Base64.decode(content));
+        ByteArrayOutputStream writer = new ByteArrayOutputStream();
+        //rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密
+        byte[] buf = new byte[128];
+        int bufl;
+
+        while ((bufl = ins.read(buf)) != -1) {
+            byte[] block = null;
+
+            if (buf.length == bufl) {
+                block = buf;
+            } else {
+                block = new byte[bufl];
+                for (int i = 0; i < bufl; i++) {
+                    block[i] = buf[i];
+                }
+            }
+
+            writer.write(cipher.doFinal(block));
+        }
+
+        return new String(writer.toByteArray(), input_charset);
+    }
+
+	
+	/**
+	* 得到私钥
+	* @param key 密钥字符串(经过base64编码)
+	* @throws Exception
+	*/
+	public static PrivateKey getPrivateKey(String key) throws Exception {
+
+		byte[] keyBytes;
+		
+		keyBytes = Base64.decode(key);
+		
+		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
+		
+		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+		
+		PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
+		
+		return privateKey;
+	}
+}

+ 23 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/task/AliPayCuspayTask.java

@@ -0,0 +1,23 @@
+package com.kmall.admin.cuspay.task;
+
+import com.kmall.admin.cuspay.biz.ali.AliCusDeclareBiz;
+import com.kmall.admin.cuspay.biz.ali.AliCusDeclareQueryBiz;
+import com.kmall.admin.cuspay.biz.merch.MerchantNoticeBiz;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+public class AliPayCuspayTask {
+    @Autowired
+    private MerchantNoticeBiz merchantNoticeBiz;
+
+    @Autowired
+    private AliCusDeclareQueryBiz aliCusDeclareQueryBiz;
+
+    @Autowired
+    private AliCusDeclareBiz aliCusDeclareBiz;
+
+    @Scheduled(fixedDelay = 5000L)
+    public void task() {
+    }
+}

+ 33 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/task/CuspayTask.java

@@ -0,0 +1,33 @@
+package com.kmall.admin.cuspay.task;
+
+import com.kmall.admin.cuspay.biz.merch.MerchantNoticeBiz;
+import com.kmall.admin.cuspay.biz.wx.WxCusDeclareBiz;
+import com.kmall.admin.cuspay.biz.wx.WxCusDeclareQueryBiz;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ * 定时任务
+ * @author zx
+ * @version 1.0
+ * 2018-05-23 09:31
+ */
+@Component
+public class CuspayTask {
+    @Autowired
+    private MerchantNoticeBiz merchantNoticeBiz;
+
+    @Autowired
+    private WxCusDeclareBiz wxCusDeclareBiz;
+
+    @Autowired
+    private WxCusDeclareQueryBiz wxCusDeclareQueryBiz;
+
+    @Scheduled(fixedRate = 10000)
+    public void task() {
+       // todo,商户通知请求回执
+       // merchantNoticeBiz.biz(null);
+    }
+}

+ 152 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/util/Contants.java

@@ -0,0 +1,152 @@
+package com.kmall.admin.cuspay.util;
+
+/**
+ * 该类为ccnet-general项目下复制过来
+ */
+public class Contants {
+    public static final String WMSH = "WMSH";
+
+    public static final String WM = "WM";
+
+    public static final String WX = "WX";
+
+    // 订单类型
+    public static final String ORDER_TYPE = "I";
+
+    // 证件类型
+    public static final String ID_TYPE = "1";
+
+    //创建人编号
+    public static final String CREATER_NUMBER = "1";
+
+    //请求/响应的状态:初始化
+    public static final String INIT_STATUS = "0";
+    //发送中
+    public static final String SENDING_STATUS = "1";
+    //成功
+    public static final String SUCCESS_STATUS = "2";
+    //失败
+    public static final String FAIL_STATUS = "3";
+    //申报中
+    public static final String DECLARATION_STATUS = "4";
+    //申报成功
+    public static final String DECLARATION_SUCCESS_STATUS = "5";
+    //清关成功
+    public static final String INVET_SUCCESS = "6";
+
+    /**************************支付宝*************************/
+
+    //响应的是否成功
+    public static final String SUCCESS = "T";
+    public static final String SUCCESS_CODE = "SUCCESS";
+    //失败
+    public static final String FAIL = "F";
+    public static final String FAIL_CODE = "FAIL";
+
+    //支付公司标识:支付宝
+    public static final String ALIPAY = "00";
+    //微信
+    public static final String WECHAT = "10";
+    //工行
+    public static final String ICBC = "20";
+
+    /*****************************电子************************/
+
+    //业务状态1、暂存/报送类型:1、新增
+    public static final String APP_STATUS_DECLARE = "1";
+
+    //2、申报/2、修改
+    public static final String APP_STATUS_SEPARETE = "2";
+
+    //币制
+    public static final String CURRENCY = "142";
+
+    //申报回调状态 失败:-19
+    public static final String RESPONSE_FAIL = "-19";
+
+    //成功:20
+    public static final String RESPONSE_SUCCESS = "20";
+
+    //平台回执状态定义:00--平台退单
+    public static final String ORDER_PLAT_FAIL = "00";
+    //01--提示锁定
+    public static final String ORDER_PLAT_SUCCESS = "01";
+
+    //海关回执状态定义:2--电子口岸申报中
+    public static final String CUS_DECLARATION = "2";
+
+    //3--发送海关成功
+    public static final String CUS_SUCCESS = "3";
+
+    //4--发送海关失败
+    public static final String CUS_FAIL = "4";
+
+    //100--海关退单
+    public static final String CUS_CHARGEBACK = "100";
+
+    //120--海关入库
+    public static final String CUS_STORAGE = "120";
+
+    //国检回执状态定义:0--系统接收成功
+    public static final String CIQ_RECEIVE_SUCCESS = "0";
+
+    //1--入库单、商品备案:审核通过 清单:接收成功,比对成功
+    public static final String CIQ_SUCCESS = "1";
+
+    //2--审核不通过
+    public static final String CIQ_FAIL = "2";
+
+    //3--清单:接收成功,比对不成功
+    public static final String CIQ_SUCCESS_FAIL = "3";
+
+    //4--系统接收失败
+    public static final String CIQ_RECEIVE_FAIL = "4";
+
+    //回调的总状态 0:成功,1:失败,2:进行中
+    public static final String ORDER_RESPONSE_SUCCESS = "0";
+
+    public static final String ORDER_RESPONSE_FAIL = "1";
+
+    public static final String ORDER_RESPONSE_SENDING = "2";
+
+    public static final String PD_PRODUCT_RECORD = "pd_product_record";
+
+    public static final String SYS_ADMIN_DIVI_GOV = "admin_divi_gov";
+
+    /**
+     * 统一行政区划 name 为key
+     */
+    public static final String ADMIN_DIVI_GOV_HASH = "admin_divi_gov_hash";
+
+    /**********************海关运单******************************/
+
+    //商户订单状态0:海关支付单,1:海关电子订单,2:海关运单
+    public static final String MERCH_ALIPAY_TYPE = "0";
+
+    public static final String MERCH_ORDER_TYPE = "1";
+
+    public static final String MERCH_WAY_TYPE = "2";
+
+    //成功
+    public static final String OMS_SUCCESS_CODE = "0";
+
+    //csp回执返回成功
+    public static final String CSP_RESPONSE_SUCCESS = "0";
+    // 重复成功
+    public static final String CSP_RESPONSE_RESEND_SUCCESS = "3";
+
+    //支付方式
+    public static final String PAY_TYPE_WX = "weixin";
+
+    //海关编码
+    public static final String CUSTOMER_NO = "06";
+
+    /**************************wx当前状态******************************/
+    //0:失败;1:成功;2:进行中
+    public static final String WX_FAIL = "0";
+
+    public static final String WX_SUCC = "1";
+
+    public static final String WX_UNDERWAY = "2";
+
+}

+ 227 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/util/MapBeanUtils.java

@@ -0,0 +1,227 @@
+package com.kmall.admin.cuspay.util;
+
+import org.apache.commons.beanutils.BeanUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * map bean 相互转换
+ *
+ * @author Scott Chen
+ * @version 1.0
+ * 2017-09-19 16:58
+ */
+public class MapBeanUtils {
+    private static final Logger logger = LoggerFactory.getLogger(MapBeanUtils.class);
+
+
+    /**
+     * map 转 bean by BeanUtils
+     * @param map
+     * @param beanClass
+     * @param <T>
+     * @return
+     * @throws Exception
+     */
+    public static <T> T toObject(Map<String, Object> map, Class<T> beanClass) {
+        T bean;
+        if (map == null) {
+            return null;
+        }
+
+        try {
+            bean = beanClass.newInstance();
+            BeanUtils.populate(bean, map);
+        } catch (Exception e) {
+            logger.error("map转bean异常:{}", e.getCause());
+            return null;
+        }
+        return bean;
+    }
+
+    /**
+     * bean 转 map   by Introspector
+     *
+     * @param bean
+     * @return
+     */
+    public static <T> Map<String, Object> fromObject(T bean) {
+        if (bean == null) {
+            return null;
+        }
+        return fromObjectByIntrospector(bean);
+    }
+
+    //----------  使用Introspector进行转换 ----------
+
+    /**
+     * map 转 bean by Introspector
+     * @param map
+     * @param beanClass
+     * @param <T>
+     * @return
+     */
+    public static <T> T toObjectByIntrospector(Map<String, Object> map, Class<T> beanClass) {
+        if (map == null) {
+            return null;
+        }
+        T obj = null;
+
+        try {
+            obj = beanClass.newInstance();
+
+            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
+            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
+            for (PropertyDescriptor property : propertyDescriptors) {
+                Method setter = property.getWriteMethod();
+                if (setter != null) {
+                    setter.invoke(obj, map.get(property.getName()));
+                }
+            }
+        } catch (InstantiationException e) {
+            String info = "[toObjectByIntrospector] InstantiationException::Map转换Bean失败";
+            logger.error(info);
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            String info = "[toObjectByIntrospector] IllegalAccessException::Map转换Bean失败";
+            logger.error(info);
+            e.printStackTrace();
+        } catch (IntrospectionException e) {
+            String info = "[toObjectByIntrospector] IntrospectionException::Map转换Bean失败";
+            logger.error(info);
+            e.printStackTrace();
+        } catch (InvocationTargetException e) {
+            String info = "[toObjectByIntrospector] InvocationTargetException::Map转换Bean失败";
+            logger.error(info);
+            e.printStackTrace();
+        }
+        return obj;
+    }
+
+    /**
+     * bean 转 map   by Introspector
+     * @param obj
+     * @param <T>
+     * @return
+     */
+    public static <T> Map<String, Object> fromObjectByIntrospector(T obj) {
+        if (obj == null) {
+            return null;
+        }
+
+        Map<String, Object> map = new HashMap<String, Object>();
+
+        try {
+            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
+            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
+            for (PropertyDescriptor property : propertyDescriptors) {
+                String key = property.getName();
+                if (key.compareToIgnoreCase("class") == 0) {
+                    continue;
+                }
+                Method getter = property.getReadMethod();
+                Object value = getter != null ? getter.invoke(obj) : null;
+                map.put(key, value);
+            }
+        } catch (IntrospectionException e) {
+            String info = "[fromObjectByIntrospector] IntrospectionException::Bean转换Map失败";
+            logger.error(info);
+            e.printStackTrace();
+        } catch (InvocationTargetException e) {
+            String info = "[fromObjectByIntrospector] InvocationTargetException::Bean转换Map失败";
+            logger.error(info);
+            e.printStackTrace();
+        } catch (IllegalArgumentException e) {
+            String info = "[fromObjectByIntrospector] IllegalArgumentException::Bean转换Map失败,";
+            logger.error(info);
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            String info = "[fromObjectByIntrospector] IllegalAccessException::Bean转换Map失败";
+            logger.error(info);
+            e.printStackTrace();
+        }
+
+        return map;
+    }
+
+    //----------  使用reflect进行转换 ----------
+
+    /**
+     * map 转 bean  by Reflect
+     * @param map
+     * @param beanClass
+     * @param <T>
+     * @return
+     */
+    public static <T> T toObjectByReflect(Map<String, Object> map, Class<T> beanClass) {
+        if (map == null) {
+            return null;
+        }
+
+        T obj = null;
+        try {
+            obj = beanClass.newInstance();
+
+            Field[] fields = obj.getClass().getDeclaredFields();
+            for (Field field : fields) {
+                int mod = field.getModifiers();
+                if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
+                    continue;
+                }
+
+                field.setAccessible(true);
+                field.set(obj, map.get(field.getName()));
+            }
+        }catch (InstantiationException e) {
+            String info = "[toObjectByReflect] InstantiationException::Map转换Bean失败";
+            logger.error(info);
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            String info = "[toObjectByReflect] IllegalAccessException::Map转换Bean失败";
+            logger.error(info);
+            e.printStackTrace();
+        }
+        return obj;
+    }
+
+    /**
+     * bean 转 map   by Reflect
+     * @param obj
+     * @param <T>
+     * @return
+     */
+    public static <T> Map<String, Object> fromObjectByReflect(T obj) {
+        if (obj == null) {
+            return null;
+        }
+
+        Map<String, Object> map = new HashMap<String, Object>();
+
+        try{
+            Field[] declaredFields = obj.getClass().getDeclaredFields();
+            for (Field field : declaredFields) {
+                field.setAccessible(true);
+                map.put(field.getName(), field.get(obj));
+            }
+        } catch (IllegalAccessException e) {
+            String info = "[fromObjectByReflect] IllegalAccessException::Bean转换Map失败";
+            logger.error(info);
+            e.printStackTrace();
+        }
+
+        return map;
+    }
+
+
+}

+ 140 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/util/OkHttpUtils.java

@@ -0,0 +1,140 @@
+package com.kmall.admin.cuspay.util;
+
+import okhttp3.*;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author Scott Chen
+ * @date 2017/3/13
+ */
+public class OkHttpUtils {
+
+    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
+    public static final long CONNEC_TIME = 20L;
+    public static final long READ_TIME = 30L;
+    public static final long WRITE_TIME = 30L;
+
+    private static OkHttpClient okHttpClient = null;
+    static{
+        okHttpClient = new OkHttpClient.Builder()
+                .connectTimeout(CONNEC_TIME, TimeUnit.SECONDS)
+                .readTimeout(READ_TIME, TimeUnit.SECONDS)
+                .writeTimeout(WRITE_TIME, TimeUnit.SECONDS)
+                .build();
+    }
+
+    /**
+     * 构造RequestBody
+     *
+     * @param params
+     * @return
+     */
+    public static RequestBody buildRequestBody(Map<String, String> params) {
+        FormBody.Builder builder = new FormBody.Builder();
+        Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();
+        while (iterator.hasNext()) {
+            Map.Entry<String, String> entry = iterator.next();
+            builder.add(entry.getKey(), entry.getValue());
+        }
+        return builder.build();
+    }
+
+    /**
+     * 以字符串数据构建Request(未使用)
+     * @param url
+     * @param json
+     * @return
+     */
+    public static Request buildRequest(String url, String json) {
+        RequestBody body = RequestBody.create(JSON, json);
+        return buildRequest(url, body);
+    }
+
+    /**
+     * 构建Request
+     * @param url
+     * @param body
+     * @return
+     */
+    public static Request buildRequest(String url, RequestBody body) {
+        return new Request.Builder()
+                .url(url)
+                .post(body)
+                .build();
+    }
+
+    /**
+     * 同步访问,返回结果字符串
+     * 可能超时
+     *
+     * @param request
+     * @return
+     * @throws IOException
+     */
+    public static String post(Request request) throws IOException {
+        Response response = okHttpClient.newCall(request).execute();
+        String result = "";
+        if (response.isSuccessful()) {
+            result = response.body().string();
+        }else {
+            throw new IOException("okhttp3 post exception: " + response);
+        }
+        return result;
+    }
+
+    public static String get(String url) throws IOException {
+        Request request = (new Request.Builder()).get().url(url).build();
+        Call call = okHttpClient.newCall(request);
+        Response response = call.execute();
+
+        return byte2String(response.body().bytes());
+    }
+
+    private static String byte2String(byte[] bytes) {
+        return new String(bytes);
+    }
+
+    /**
+     * 同步访问,返回Response
+     * 可能超时
+     *
+     * @param request
+     * @return
+     * @throws IOException
+     */
+    public static Response postReturnResponse(Request request)  throws IOException {
+        return okHttpClient.newCall(request).execute();
+    }
+
+    /**
+     * 异步访问,回调结果
+     * @param request
+     * @param responseCallback
+     */
+    public static void asyncPostCallback(Request request, Callback responseCallback) {
+        okHttpClient.newCall(request).enqueue(responseCallback);
+    }
+
+    /**
+     * 异步访问,无结果返回
+     * @param request
+     */
+    public static void asyncPost(Request request) {
+        okHttpClient.newCall(request).enqueue(new Callback() {
+            @Override
+            public void onFailure(Call call, IOException e) {
+
+            }
+
+            @Override
+            public void onResponse(Call call, Response response) throws IOException {
+
+            }
+        });
+    }
+
+}

+ 85 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/util/ReaderXmlForDOM4J.java

@@ -0,0 +1,85 @@
+package com.kmall.admin.cuspay.util;
+
+import com.kmall.admin.cuspay.ccnet2cuspay.dto.wx.WxQuerySuccessResponseMsgDto;
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+
+import java.util.Iterator;
+
+/**
+ * 获取请求微信订单查询接口返回xml中的state
+ * @author huangyq
+ * @version 1.0
+ * 2018-05-24 15:53
+ */
+public class ReaderXmlForDOM4J {
+
+    public static WxQuerySuccessResponseMsgDto parse(String protocolXML, int count) {
+        WxQuerySuccessResponseMsgDto querySuccessResponseDto = new WxQuerySuccessResponseMsgDto();
+        try {
+            Document doc=(Document) DocumentHelper.parseText(protocolXML);
+            Element books = doc.getRootElement();
+            // Iterator users_subElements = books.elementIterator("UID");//指定获取那个元素
+            Iterator Elements = books.elementIterator();
+            while(Elements.hasNext()){
+                Element user = (Element)Elements.next();
+                String state ="state_"+(count);
+                String subOrderNo ="sub_order_no_"+(count);
+                String subOrderId ="sub_order_id_"+(count);
+                String mchCustomsNo ="mch_customs_no_"+(count);
+                String customs ="customs_"+(count);
+                String feeType ="fee_type_"+(count);
+                String orderFee ="order_fee_"+(count);
+                String duty ="duty_"+(count);
+                String transportFee ="transport_fee_"+(count);
+                String productFee ="product_fee_"+(count);
+                String explanation ="explanation_"+(count);
+                String modifyTime ="modify_time_"+(count);
+                String certCheckResult ="cert_check_result_"+(count);
+                if(state.equalsIgnoreCase(user.getName())){
+                    querySuccessResponseDto.setState(user.getText());
+                }
+                if(subOrderNo.equalsIgnoreCase(user.getName())){
+                    querySuccessResponseDto.setSubOrderNo(user.getText());
+                }
+                if(subOrderId.equalsIgnoreCase(user.getName())){
+                    querySuccessResponseDto.setSubOrderId(user.getText());
+                }
+                if(mchCustomsNo.equalsIgnoreCase(user.getName())){
+                    querySuccessResponseDto.setMchCustomsNo(user.getText());
+                }
+                if(customs.equalsIgnoreCase(user.getName())){
+                    querySuccessResponseDto.setCustoms(user.getText());
+                }
+                if(feeType.equalsIgnoreCase(user.getName())){
+                    querySuccessResponseDto.setFeeType(user.getText());
+                }
+                if(orderFee.equalsIgnoreCase(user.getName())){
+                    querySuccessResponseDto.setOrderFee(Integer.parseInt(user.getText()));
+                }
+                if(duty.equalsIgnoreCase(user.getName())){
+                    querySuccessResponseDto.setDuty(Integer.parseInt(user.getText()));
+                }
+                if(transportFee.equalsIgnoreCase(user.getName())){
+                    querySuccessResponseDto.setTransportFee(Integer.parseInt(user.getText()));
+                }
+                if(productFee.equalsIgnoreCase(user.getName())){
+                    querySuccessResponseDto.setProductFee(Integer.parseInt(user.getText()));
+                }
+                if(explanation.equalsIgnoreCase(user.getName())){
+                    querySuccessResponseDto.setExplanation(user.getText());
+                }
+                if(modifyTime.equalsIgnoreCase(user.getName())){
+                    querySuccessResponseDto.setModifyTime(user.getText());
+                }
+                if(certCheckResult.equalsIgnoreCase(user.getName())){
+                    querySuccessResponseDto.setCertCheckResult(user.getText());
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return querySuccessResponseDto;
+    }
+}

+ 114 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/util/SerializeUtils.java

@@ -0,0 +1,114 @@
+package com.kmall.admin.cuspay.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+
+public class SerializeUtils {
+	
+	private static Logger logger = LoggerFactory.getLogger(SerializeUtils.class);
+
+	public static Object deserialize(byte[] bytes) {
+		return deserialize(bytes, Object.class);
+	}
+
+	/**
+	 * 反序列化
+	 * @param bytes
+	 * @return
+	 */
+	public static <T> T deserialize(byte[] bytes, Class<T>... clazz) {
+
+		Object result = null;
+
+		if (isEmpty(bytes)) {
+			return null;
+		}
+
+		try {
+			ByteArrayInputStream byteStream = null;
+			ObjectInputStream objectInputStream = null;
+			try {
+				try {
+					byteStream = new ByteArrayInputStream(bytes);
+					objectInputStream = new ObjectInputStream(byteStream);
+					result = objectInputStream.readObject();
+				}
+				catch (ClassNotFoundException ex) {
+					throw new Exception("Failed to deserialize object type", ex);
+				}finally {
+					close(objectInputStream);
+					close(byteStream);
+				}
+			}
+			catch (Throwable ex) {
+				throw new Exception("Failed to deserialize", ex);
+			}finally {
+				close(objectInputStream);
+				close(byteStream);
+			}
+		} catch (Exception e) {
+			logger.error("Failed to deserialize",e);
+		}
+		return (T)result;
+	}
+
+	public static boolean isEmpty(byte[] data) {
+		return (data == null || data.length == 0);
+	}
+
+
+	public static byte[] serialize(Object object) {
+		return serialize(object, Object.class);
+	}
+	/**
+	 * 序列化
+	 * @param object
+	 * @return
+	 */
+	public static <T> byte[] serialize(T object, Class<T> clazz) {
+
+		byte[] result = null;
+
+		if (object == null) {
+			return new byte[0];
+		}
+		try {
+			ByteArrayOutputStream byteStream = null;
+			ObjectOutputStream objectOutputStream = null;
+			try  {
+				if (!(object instanceof Serializable)) {
+					throw new IllegalArgumentException(SerializeUtils.class.getSimpleName() + " requires a Serializable payload " +
+							"but received an object of type [" + object.getClass().getName() + "]");
+				}
+				byteStream = new ByteArrayOutputStream(128);
+				objectOutputStream = new ObjectOutputStream(byteStream);
+				objectOutputStream.writeObject(object);
+				objectOutputStream.flush();
+				result =  byteStream.toByteArray();
+			}
+			catch (Throwable ex) {
+				throw new Exception("Failed to serialize", ex);
+			}finally {
+				close(objectOutputStream);
+				close(byteStream);
+			}
+		} catch (Exception ex) {
+			logger.error("Failed to serialize",ex);
+		}
+		return result;
+	}
+
+	private static void close(Closeable closeable) {
+		if (closeable != null) {
+			try {
+				closeable.close();
+			} catch (IOException e) {
+				logger.error("close stream error");
+				e.printStackTrace();
+			}
+		}
+	}
+
+}

+ 28 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/util/SpringContextSupport.java

@@ -0,0 +1,28 @@
+package com.kmall.admin.cuspay.util;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+public class SpringContextSupport implements ApplicationContextAware {
+
+	private static ApplicationContext applicationContext; // Spring应用上下文环境
+
+	/*
+	 * 实现了ApplicationContextAware 接口,必须实现该方法; 通过传递applicationContext参数初始化成员变量applicationContext
+	 */
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		SpringContextSupport.applicationContext = applicationContext;
+	}
+
+	public static ApplicationContext getApplicationContext() {
+		return applicationContext;
+	}
+
+	@SuppressWarnings("unchecked")
+	public static <T> T getBean(String name) throws BeansException {
+		return (T) applicationContext.getBean(name);
+	}
+}

+ 44 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/util/SysContants.java

@@ -0,0 +1,44 @@
+package com.kmall.admin.cuspay.util;
+
+/**
+ * 该类为ccnet-general项目下复制过来
+ */
+public class SysContants {
+
+    //微盟订单列表
+    public static final String wm_order = "WOLT";
+
+    //微盟订单商品表
+    public static final String wm_order_goods = "WOGS";
+
+    //微盟订单商品记录表
+    public static final String wm_order_record = "WORD";
+
+    //微盟订单详情记录表
+    public static final String wm_order_detail_record = "WODR";
+
+    //微盟获取商品详情记录表
+    public static final String wm_goods_record = "WGRD";
+
+    //商品详情
+    public static final String wm_goods_detail = "WGDL";
+
+    //微信支付单证
+    public static final String wx_pay_doc = "WXPD";
+
+    //微信支付单状态
+    public static final String wx_cuspay_status = "WXCS";
+
+    //微信支付单回执
+    public static final String wx_cuspay_resp = "WXCR";
+
+    // 支付宝支付单证
+    public static final String alipay_pay_doc = "WXPD";
+
+    // 支付宝支付单状态
+    public static final String alipay_cuspay_status = "WXCS";
+
+    // 支付宝支付单回执
+    public static final String alipay_cuspay_resp = "WXCR";
+
+}

+ 72 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/util/Validator.java

@@ -0,0 +1,72 @@
+package com.kmall.admin.cuspay.util;
+
+import com.kmall.admin.cuspay.support.msg.resp.ResponseMessage;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseStatus;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * @author zx
+ * @version 1.0
+ * 2018-05-15 16:48
+ */
+public abstract class Validator {
+    /**
+     * 非空校验
+     *
+     * @param beVerified 要验证的字段 <code>{"字段名","错误消息"}</code>
+     * @param valideDate       验证数据
+     * @return
+     */
+    public static ResponseMessage isEmpty(Map<String, Object> beVerified, Map<String, Object> valideDate) {
+
+
+        /**
+         * 验证数据为空
+         */
+        if (valideDate == null) {
+            return new ResponseMessage.Builder()
+                        .setCode(ResponseStatus.ERROR.getItem())
+                        .setMsg("验证数据为空")
+                        .build();
+        }
+
+        /**
+         * 没有要验证的
+         */
+        if (beVerified == null) {
+            return new ResponseMessage.Builder()
+                    .setCode(ResponseStatus.ERROR.getItem())
+                    .setMsg("验证数据为空")
+                    .build();
+        }
+
+        for (String key : beVerified.keySet()) {
+            //验证数据没有要验证的字段, 或有要验证的字段,但字段为空
+            if (!valideDate.containsKey(key) ||
+                    (valideDate.containsKey(key) && StringUtils.isBlank(String.valueOf(valideDate.get(key)))) ||
+                    String.valueOf(valideDate.get(key)).equals("null")) {
+                return  ResponseMessage.builder(ResponseStatus.ERROR.getItem(), beVerified.get(key)+"为空").build();
+            }
+        }
+        return new ResponseMessage.Builder()
+                    .setCode(ResponseStatus.SUCCESS.getItem())
+                    .build();
+    }
+
+    /**
+     * 验证身份证号
+     * 大陆是18位
+     * 香港是15位
+     */
+    public static boolean isCardNo(String str)throws PatternSyntaxException {
+        String regExp = "^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$|(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{2}$)";
+        Pattern p = Pattern.compile(regExp);
+        Matcher m = p.matcher(str);
+        return m.matches();
+    }
+}

+ 236 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/util/XmlUtils.java

@@ -0,0 +1,236 @@
+package com.kmall.admin.cuspay.util;
+
+import org.dom4j.Attribute;
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLFilterImpl;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.Source;
+import javax.xml.transform.sax.SAXSource;
+import java.io.File;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.*;
+
+/**
+ * XML处理类
+ *
+ * @author Scott Chen
+ * @date 2016/11/15
+ */
+public class XmlUtils {
+
+    public static String toXML(Object obj, boolean format) throws Exception {
+        try {
+            JAXBContext context = JAXBContext.newInstance(obj.getClass());
+            Marshaller marshaller = context.createMarshaller();
+
+            //编码格式
+            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
+
+            // 是否格式化生成的xml串
+            if (format) {
+                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+            }else{
+                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE);
+            }
+
+            // 是否省略xm头声明信息
+            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.FALSE);
+
+            StringWriter writer = new StringWriter();
+            marshaller.marshal(obj, writer);
+            return writer.toString();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static String toXMLInFile(Object obj, String filePath, boolean format) throws Exception {
+        try {
+            JAXBContext context = JAXBContext.newInstance(obj.getClass());
+            Marshaller marshaller = context.createMarshaller();
+
+            //编码格式
+            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
+
+            // 是否格式化生成的xml串
+            if (format) {
+                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+            }else{
+                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE);
+            }
+
+            // 是否省略xm头声明信息
+            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.FALSE);
+
+            File file = new File(filePath);
+            marshaller.marshal(obj, file);
+
+            StringWriter writer = new StringWriter();
+            marshaller.marshal(obj, writer);
+            return writer.toString();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T fromXML(String xmlStr, Class<T> valueType, boolean ignoreNs) throws Exception {
+        try {
+            JAXBContext context = JAXBContext.newInstance(valueType);
+            Unmarshaller unmarshaller = context.createUnmarshaller();
+            StringReader reader = new StringReader(xmlStr);
+
+            //解析时,是否忽略命名空间
+            if (ignoreNs) {
+                /**
+                 * 忽略命名空间
+                 * 在序列化和反序列化时通过XMLFilterImpl的匿名实现类实现命名空间及xml节点名称的控制
+                 */
+                SAXParserFactory sax = SAXParserFactory.newInstance();
+                //false:忽略命名空间
+                sax.setNamespaceAware(false);
+                XMLReader xmlReader = sax.newSAXParser().getXMLReader();
+
+                XMLFilterImpl nsfFilter = new XMLFilterImpl() {
+                    private boolean ignoreNamespace = false;
+
+                    @Override
+                    public void startDocument() throws SAXException {
+                        super.startDocument();
+                    }
+
+                    @Override
+                    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+                        if (this.ignoreNamespace){
+                            uri = "";
+                        }
+
+                        super.startElement(uri, localName, qName, atts);
+                    }
+
+                    @Override
+                    public void endElement(String uri, String localName, String qName) throws SAXException {
+                        if (this.ignoreNamespace){
+                            uri = "";
+                        }
+
+                        super.endElement(uri, localName, localName);
+                    }
+
+                    @Override
+                    public void startPrefixMapping(String prefix, String url) throws SAXException {
+                        if (!this.ignoreNamespace){
+                            super.startPrefixMapping("", url);
+                        }
+                    }
+                };
+                nsfFilter.setParent(xmlReader);
+
+                Source source = new SAXSource(xmlReader, new InputSource(reader));
+                return (T) unmarshaller.unmarshal(source);
+            }
+            return (T) unmarshaller.unmarshal(reader);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static String map2Xml(Map<String, String> map) {
+        StringBuffer sb = new StringBuffer();
+        sb.append("<xml>");
+        Set es = map.entrySet();
+        Iterator it = es.iterator();
+        while(it.hasNext()) {
+            Map.Entry entry = (Map.Entry)it.next();
+            String k = (String)entry.getKey();
+            String v = (String)entry.getValue();
+            //注意,有一些值要用![CDATA[value]]来表示
+//            if ("attach".equalsIgnoreCase(k)||"body".equalsIgnoreCase(k)||"sign".equalsIgnoreCase(k)) {
+//                sb.append("<"+k+">"+"<![CDATA["+v+"]]></"+k+">");
+//                continue;
+//            }else {
+                sb.append("<"+k+">"+v+"</"+k+">");
+//            }
+        }
+        sb.append("</xml>");
+        return sb.toString();
+    }
+
+    public static Map<String, Object> Dom2Map(Document doc) {
+        Map<String, Object> map = new HashMap<>();
+        if (doc == null)
+            return map;
+        Element root = doc.getRootElement();
+        for (Iterator<Element> iterator = root.elementIterator(); iterator.hasNext(); ) {
+            Element e = iterator.next();
+            List list = e.elements();
+            if (list.size() > 0) {
+                map.put(e.getName(), Dom2Map(e));
+                continue;
+            }
+            map.put(e.getName(), e.getText());
+        }
+        return map;
+    }
+
+    private static Map Dom2Map(Element e) {
+        Map<Object, Object> map = new HashMap<>();
+        List<Element> list = e.elements();
+        if (list.size() > 0) {
+            for (int i = 0; i < list.size(); i++) {
+                Element iter = list.get(i);
+                List<Object> mapList = new ArrayList();
+                String iterValue = iter.getName();
+                if (iter.attributes().size() != 0) {
+                    Attribute attribute = iter.attribute(0);
+                    iterValue = attribute.getValue();
+                }
+                if (iter.elements().size() > 0) {
+                    Map m = Dom2Map(iter);
+                    if (map.get(iterValue) != null) {
+                        Object obj = map.get(iterValue);
+                        if (!obj.getClass().getName().equals("java.util.ArrayList")) {
+                            mapList = new ArrayList();
+                            mapList.add(obj);
+                            mapList.add(m);
+                        }
+                        if (obj.getClass().getName().equals("java.util.ArrayList")) {
+                            mapList = (List<Object>)obj;
+                            mapList.add(m);
+                        }
+                        map.put(iterValue, mapList);
+                    } else {
+                        map.put(iterValue, m);
+                    }
+                } else if (map.get(iterValue) != null) {
+                    Object obj = map.get(iterValue);
+                    if (!obj.getClass().getName().equals("java.util.ArrayList")) {
+                        mapList = new ArrayList();
+                        mapList.add(obj);
+                        mapList.add(iter.getText());
+                    }
+                    if (obj.getClass().getName().equals("java.util.ArrayList")) {
+                        mapList = (List<Object>)obj;
+                        mapList.add(iter.getText());
+                    }
+                    map.put(iterValue, mapList);
+                } else {
+                    map.put(iterValue, iter.getText());
+                }
+            }
+        } else {
+            map.put(e.getName(), e.getText());
+        }
+        return map;
+    }
+}

+ 23 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/util/date/DateConstant.java

@@ -0,0 +1,23 @@
+package com.kmall.admin.cuspay.util.date;
+
+/**
+ * @author Scott Chen
+ * @since 1.0
+ * 2018-02-03
+ */
+public class DateConstant {
+
+    public static final String DATE_TIME_SECOND_ZONE = "yyyy-MM-dd HH:mm:ssZ";
+    public static final String DATE_TIME_SECOND_MILL = "yyyy-MM-dd HH:mm:ss.SSS";
+    public static final String DATE_TIME_SECOND = "yyyy-MM-dd HH:mm:ss";
+    public static final String DATE_TIME_MINUTE = "yyyy-MM-dd HH:mm";
+
+    public static final String TIME_SECOND_MILL = "HH:mm:ss.SSS";
+    public static final String TIME_SECOND = "HH:mm:ss";
+    public static final String TIME_MINUTE = "HH:mm";
+
+    public static final String DATE_MONTH_DAY = "yyyy-MM-dd";
+    public static final String DATE_MONTH = "yyyy-MM";
+    public static final String MONTH_DAY = "MM-dd";
+
+}

+ 69 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/util/jackson/JacksonStringUnicodeSerializer.java

@@ -0,0 +1,69 @@
+package com.kmall.admin.cuspay.util.jackson;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.io.CharTypes;
+import com.fasterxml.jackson.core.json.JsonWriteContext;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+import java.io.IOException;
+
+/**
+ * jackson处理以unicode方式编码中文
+ */
+public class JacksonStringUnicodeSerializer extends JsonSerializer<String> {
+
+	private final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
+	private final int[] ESCAPE_CODES = CharTypes.get7BitOutputEscapes();
+
+	private void writeUnicodeEscape(JsonGenerator gen, char c) throws IOException {
+		gen.writeRaw('\\');
+		gen.writeRaw('u');
+		gen.writeRaw(HEX_CHARS[(c >> 12) & 0xF]);
+		gen.writeRaw(HEX_CHARS[(c >> 8) & 0xF]);
+		gen.writeRaw(HEX_CHARS[(c >> 4) & 0xF]);
+		gen.writeRaw(HEX_CHARS[c & 0xF]);
+	}
+
+	private void writeShortEscape(JsonGenerator gen, char c) throws IOException {
+		gen.writeRaw('\\');
+		gen.writeRaw(c);
+	}
+
+	@Override
+	public void serialize(String str, JsonGenerator gen,
+			SerializerProvider provider) throws IOException,
+            JsonProcessingException {
+		int status = ((JsonWriteContext) gen.getOutputContext()).writeValue();
+	    switch (status) {
+	      case JsonWriteContext.STATUS_OK_AFTER_COLON:
+	        gen.writeRaw(':');
+	        break;
+	      case JsonWriteContext.STATUS_OK_AFTER_COMMA:
+	        gen.writeRaw(',');
+	        break;
+	      case JsonWriteContext.STATUS_EXPECT_NAME:
+	        throw new JsonParseException(null, "Can not write string value here");
+	    }
+	    gen.writeRaw('"');//写入JSON中字符串的开头引号
+	    for (char c : str.toCharArray()) {
+	      if (c >= 0x80){
+	    	  writeUnicodeEscape(gen, c); // 为所有非ASCII字符生成转义的unicode字符
+	      }else {
+	        // 为ASCII字符中前128个字符使用转义的unicode字符
+	        int code = (c < ESCAPE_CODES.length ? ESCAPE_CODES[c] : 0);
+	        if (code == 0){
+	        	gen.writeRaw(c); // 此处不用转义
+	        }else if (code < 0){
+	        	writeUnicodeEscape(gen, (char) (-code - 1)); // 通用转义字符
+	        }else {
+	        	writeShortEscape(gen, (char) code); // 短转义字符 (\n \t ...)
+	        }
+	      }
+	    }
+	    gen.writeRaw('"');//写入JSON中字符串的结束引号
+	}
+
+}

+ 337 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/util/jackson/JacksonUtil.java

@@ -0,0 +1,337 @@
+package com.kmall.admin.cuspay.util.jackson;
+
+import com.kmall.admin.cuspay.common.date.DateTimeDeserializer;
+import com.kmall.admin.cuspay.common.date.DateTimeSerializer;
+import com.kmall.admin.cuspay.util.date.DateConstant;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * JacksonUtils 工具类
+ * @author Scott Chen
+ * @version 1.0
+ * 2017-09-18 18:42
+ */
+public class JacksonUtil {
+
+    private static final Logger logger = LoggerFactory.getLogger(JacksonUtil.class);
+
+    private static ObjectMapper objectMapper;
+
+    private static final ThreadLocal<JacksonUtil> jacksonUtilThreadLocal = new ThreadLocal<>();
+
+    private static final ThreadLocal<ObjectMapper> objectMapperThreadLocal = new ThreadLocal<>();
+
+    /**
+     * 禁止调用无参构造
+     */
+    private JacksonUtil() {}
+
+    /**
+     * JacksonUtils 工具类实例
+     * @return
+     */
+    public static JacksonUtil instance() {
+        JacksonUtil jacksonUtil = jacksonUtilThreadLocal.get();
+        if (jacksonUtil == null) {
+            jacksonUtil = new JacksonUtil();
+            jacksonUtilThreadLocal.set(jacksonUtil);
+        }
+        return jacksonUtil;
+    }
+
+    /**
+     * ObjectMapper实例
+     * @return
+     */
+    public static ObjectMapper objectMapper() {
+        objectMapper = objectMapperThreadLocal.get();
+        if (objectMapper== null){
+            objectMapper= new ObjectMapper();
+
+            // 格式化国家环境指定
+            objectMapper.setLocale(Locale.SIMPLIFIED_CHINESE);
+
+            //序列化时,如果没有为类型找到访问者,则会抛出异常以将其指定为非可序列化类型; 如果禁用,它们将被序列化为空对象
+            objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+            //反序列化时,遇到未知属性是否抛JsonMappingException异常.默认JsonMappingException
+            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+            //设置null值不参与序列化(字段不被显示)
+            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+
+            //注册序列化LocalDateTime模块
+            objectMapper.registerModule(localDateTimeSerializer());
+            //注册反序列化LocalDateTime模块
+            objectMapper.registerModule(localDateTimeDeserializer());
+
+            //注册序列化Date模块
+            objectMapper.registerModule(dateTimeSerializer());
+            //注册反序列化Date模块
+            objectMapper.registerModule(dateTimeDeserializer());
+
+            //序列化Unicode编码非ASCII字符
+            //objectMapper.registerModule(unicodeSerModule());
+
+        }
+        objectMapperThreadLocal.set(objectMapper);
+        return objectMapper;
+    }
+
+
+    /**
+     * 序列化Date
+     * 自定义
+     * @return
+     */
+    private static SimpleModule dateTimeSerializer(){
+        SimpleModule module = new SimpleModule();
+        module.addSerializer(Date.class, new DateTimeSerializer());
+        return module;
+    }
+
+    /**
+     * 反列化Date
+     * 自定义
+     * @return
+     */
+    private static SimpleModule dateTimeDeserializer(){
+        SimpleModule module = new SimpleModule();
+        module.addDeserializer(Date.class, new DateTimeDeserializer());
+        return module;
+    }
+
+    /**
+     * 序列化LocalDateTime时间
+     * 使用 <code>jackson-datatype-jsr310</code>
+     * @return
+     */
+    private static SimpleModule localDateTimeSerializer() {
+        SimpleModule module = new SimpleModule();
+        module.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DateConstant.DATE_MONTH_DAY, Locale.SIMPLIFIED_CHINESE)));
+        module.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DateConstant.TIME_SECOND, Locale.SIMPLIFIED_CHINESE)));
+        module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DateConstant.DATE_TIME_SECOND, Locale.SIMPLIFIED_CHINESE)));
+        return module;
+    }
+
+    /**
+     * 反序列化LocalDateTime时间
+     * 使用 <code>jackson-datatype-jsr310</code>
+     * @return
+     */
+    private static SimpleModule localDateTimeDeserializer() {
+        SimpleModule module = new SimpleModule();
+        module.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DateConstant.DATE_MONTH_DAY, Locale.SIMPLIFIED_CHINESE)));
+        module.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DateConstant.TIME_SECOND, Locale.SIMPLIFIED_CHINESE)));
+        module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DateConstant.DATE_TIME_SECOND, Locale.SIMPLIFIED_CHINESE)));
+        return module;
+    }
+
+
+    /**
+     * 序列化Unicode编码非ASCII字符
+     */
+    private static SimpleModule unicodeSerModule() {
+        SimpleModule unicodeSerModule = new SimpleModule();
+        unicodeSerModule.addSerializer(String.class, new JacksonStringUnicodeSerializer());
+        return unicodeSerModule;
+    }
+
+    /**
+     * 创建Json处理器的静态方法
+     * 用于序列化
+     * @param content Json字符串
+     * @return
+     */
+    private static JsonParser getParser(String content){
+        try{
+            return objectMapper().getFactory().createParser(content);
+        }catch (IOException ioe){
+            return null;
+        }
+    }
+
+    /**
+     * 创建Byte Json处理器的静态方法
+     * 用于序列化
+     * @param data byte array
+     * @return
+     */
+    private static JsonParser getByteParser(byte[] data){
+        try{
+            return objectMapper().getFactory().createParser(data);
+        }catch (IOException ioe){
+            return null;
+        }
+    }
+
+    /**
+     * 创建Reader Json处理器的静态方法
+     * 用于序列化
+     * @param r Reader
+     * @return
+     */
+    private static JsonParser getReaderParser(Reader r){
+        try{
+            return objectMapper().getFactory().createParser(r);
+        }catch (IOException ioe){
+            return null;
+        }
+    }
+
+    /**
+     * 创建InputStream Json处理器的静态方法
+     * 用于序列化
+     * @param in InputStream
+     * @return
+     */
+    private static JsonParser getReaderParser(InputStream in){
+        try{
+            return objectMapper().getFactory().createParser(in);
+        }catch (IOException ioe){
+            return null;
+        }
+    }
+
+
+    /**
+     * 创建Json生成器的静态方法, 使用标准输出
+     * 用于反序列化
+     * @return
+     */
+    private static JsonGenerator getGenerator(StringWriter sw){
+        try{
+            return objectMapper().getFactory().createGenerator(sw);
+        }catch (IOException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Json对象序列化
+     */
+    public static String toJson(Object obj){
+        StringWriter sw= new StringWriter();
+        JsonGenerator jsonGen= getGenerator(sw);
+        if (jsonGen== null){
+            try {
+                sw.close();
+            } catch (IOException e) {
+            }
+            return null;
+        }
+        try {
+            //由于在getGenerator方法中指定了OutputStream为sw
+            //因此调用writeObject会将数据输出到sw
+            jsonGen.writeObject(obj);
+            //由于采用流式输出 在输出完毕后务必清空缓冲区并关闭输出流
+            jsonGen.flush();
+            jsonGen.close();
+            return sw.toString();
+        } catch (JsonGenerationException jge) {
+            logger.error("toJSON序列化失败, 异常类型【JsonGenerationException】,错误原因:{}", jge.getMessage());
+        } catch (IOException ioe) {
+            logger.error("toJSON序列化失败, 异常类型【IOException】, 错误原因:{}", ioe.getMessage());
+            ioe.printStackTrace();
+        }
+        return null;
+    }
+
+
+    /**
+     * 将Json Byte反序列化成对象
+     *
+     * @param data
+     * @param clazz
+     * @return
+     */
+    public static <T> T fromByteJson(byte[] data, Class<T> clazz) {
+        try {
+            JsonParser jp= getByteParser(data);
+            return jp.readValueAs(clazz);
+        } catch (JsonParseException e){
+            logger.error(String.format("fromByteJson反序列化失败, 异常类型【JsonParseException】, 错误原因:{}", e.getMessage()));
+        } catch (JsonMappingException e){
+            logger.error(String.format("fromByteJson反序列化失败, 异常类型【JsonMappingException】, 错误原因:{}", e.getMessage()));
+        } catch (IOException e){
+            logger.error(String.format("fromByteJson反序列化失败, 异常类型【IOException】, 错误原因:{}", e.getMessage()));
+        }
+        return null;
+    }
+
+    /**
+     * 将Json String反序列化成对象
+     *
+     * @param json
+     * @param clazz
+     * @return
+     */
+    public static <T> T fromStringJson(String json, Class<T> clazz) {
+        try {
+            JsonParser jp= getParser(json);
+            return (T) jp.readValueAs(clazz);
+        } catch (JsonParseException e) {
+            logger.error(String.format("fromStringJson反序列化失败, 异常类型【JsonParseException】, 错误原因:{}", e.getMessage()));
+            logger.error("decode(String, Class<T>)", e);
+        } catch (JsonMappingException e) {
+            logger.error(String.format("fromStringJson反序列化失败, 异常类型【JsonMappingException】, 错误原因:{}", e.getMessage()));
+            logger.error("decode(String, Class<T>)", e);
+        } catch (IOException e) {
+            logger.error(String.format("fromStringJson反序列化失败, 异常类型【IOException】, 错误原因:{}", e.getMessage()));
+            logger.error("decode(String, Class<T>)", e);
+        }
+        return null;
+    }
+
+    /**
+     * 将Json Array或List反序列化为对象
+     *
+     * @param json
+     * @return
+     */
+    public static <T> T fromListJson(String json, TypeReference<?> typeReference) {
+        try {
+            //写成List.class是不行的
+            JsonParser jp= getParser(json);
+            return (T) jp.readValueAs(typeReference);
+        } catch (JsonParseException e) {
+            logger.error(String.format("fromListJson反序列化失败, 异常类型【JsonParseException】, 错误原因:{}", e.getMessage()));
+            logger.error("decode(String, Class<T>)", e);
+        } catch (JsonMappingException e) {
+            logger.error(String.format("fromListJson反序列化失败, 异常类型【JsonMappingException】, 错误原因:{}", e.getMessage()));
+            logger.error("decode(String, Class<T>)", e);
+        } catch (IOException e) {
+            logger.error(String.format("fromListJson反序列化失败, 异常类型【IOException】, 错误原因:{}", e.getMessage()));
+            logger.error("decode(String, Class<T>)", e);
+        }
+        return null;
+    }
+
+}

+ 54 - 0
kmall-admin/src/main/java/com/kmall/admin/cuspay/web/controller/merch/MerchPaymentController.java

@@ -0,0 +1,54 @@
+package com.kmall.admin.cuspay.web.controller.merch;
+
+import com.kmall.admin.cuspay.entity.merch.MerchPayCfg;
+import com.kmall.admin.cuspay.service.MerchPaymentService;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseMessage;
+import com.kmall.admin.cuspay.support.msg.resp.ResponseStatus;
+import com.kmall.admin.cuspay.util.MapBeanUtils;
+import com.kmall.admin.cuspay.util.Validator;
+import com.google.common.collect.Maps;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+/**
+ * 新增商户支付配置
+ * @author zx
+ * @version 1.0
+ * 2018-05-17 11:58
+ */
+
+@RestController
+@RequestMapping("/merch")
+public class MerchPaymentController {
+
+    @Autowired
+    private MerchPaymentService merchPaymentService;
+
+    /**
+     * 新增商户支付配置
+     * @param merchPayCfg
+     * @return
+     */
+    @RequestMapping(value = "add", method = RequestMethod.POST)
+    public ResponseMessage add(MerchPayCfg merchPayCfg) {
+        //校验数据
+        Map<String, Object> validate = MapBeanUtils.fromObject(merchPayCfg);
+        Map<String, Object> beVerified = Maps.newHashMap();
+
+        beVerified.put("appid", "appid");
+        beVerified.put("merchWxApiKey","api密钥");
+        beVerified.put("notifyUrl","商户通知回调接口");
+        beVerified.put("payChnlFlag", "支付通道标识(weixin:微信,alipay:蚂蚁金服)");
+
+        ResponseMessage rst = Validator.isEmpty(beVerified, validate);
+        if (ResponseStatus.ERROR.getItem().equals(rst.getCode())) {
+            return  rst;
+        }
+
+        return merchPaymentService.addMerchPayCfg(merchPayCfg);
+    }
+}

+ 26 - 0
kmall-admin/src/main/java/com/kmall/admin/dao/cuspay/ali/AliCbPayDocMapper.java

@@ -0,0 +1,26 @@
+package com.kmall.admin.dao.cuspay.ali;
+
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.ali.AliCbPayDoc;
+
+import java.util.List;
+
+public interface AliCbPayDocMapper {
+
+    int deleteByPrimaryKey(String paramString);
+
+    int insertSelective(AliCbPayDoc paramAliCbPayDoc);
+
+    AliCbPayDoc selectByPrimaryKey(String paramString);
+
+    AliCbPayDoc selectByOutRequestNo(String paramString);
+
+    int updateByPrimaryKeySelective(AliCbPayDoc paramAliCbPayDoc);
+
+    List<AliCbPayDoc> selectBeDeclaredData(Integer paramInteger);
+
+    int insertBatch(List<AliCbPayDoc> paramList);
+
+    int updateBatch(List<AliCbPayDoc> paramList);
+
+    List<AliCbPayDoc> selectPayDocByDocStatus(Integer paramInteger);
+}

+ 19 - 0
kmall-admin/src/main/java/com/kmall/admin/dao/cuspay/ali/AliPayErrorMapper.java

@@ -0,0 +1,19 @@
+package com.kmall.admin.dao.cuspay.ali;
+
+import com.kmall.admin.cuspay.ccnet2cuspay.entity.ali.AliPayError;
+
+import java.util.List;
+
+
+public interface AliPayErrorMapper {
+
+    int deleteByPrimaryKey(String errorSn);
+
+    int insertSelective(AliPayError record);
+
+    AliPayError selectByPrimaryKey(String errorSn);
+
+    int updateByPrimaryKeySelective(AliPayError record);
+
+    int insertAliPayErrorBatch(List<AliPayError> records);
+}

+ 20 - 0
kmall-admin/src/main/java/com/kmall/admin/dao/cuspay/merch/MerchCusCfgMapper.java

@@ -0,0 +1,20 @@
+package com.kmall.admin.dao.cuspay.merch;
+
+
+import com.kmall.admin.cuspay.entity.merch.MerchCusCfg;
+
+import java.util.List;
+
+
+public interface MerchCusCfgMapper {
+
+    int deleteByPrimaryKey(String cusCfgSn);
+
+    int insertSelective(MerchCusCfg record);
+
+    MerchCusCfg selectByPrimaryKey(String cusCfgSn);
+
+    int updateByPrimaryKeySelective(MerchCusCfg record);
+
+    List<MerchCusCfg> getMerchCusCfgByMerchSn(String merchSn);
+}

+ 28 - 0
kmall-admin/src/main/java/com/kmall/admin/dao/cuspay/merch/MerchNotiMapper.java

@@ -0,0 +1,28 @@
+package com.kmall.admin.dao.cuspay.merch;
+
+
+import com.kmall.admin.cuspay.entity.merch.MerchNoti;
+
+import java.util.List;
+
+
+public interface MerchNotiMapper {
+
+    int deleteByPrimaryKey(String notiSn);
+
+    int insertSelective(MerchNoti record);
+
+
+    MerchNoti selectByPrimaryKey(String notiSn);
+
+
+    int updateByPrimaryKeySelective(MerchNoti record);
+
+    List<MerchNoti> selectMerchNotis(Integer limit);
+
+    int insertBatch(List<MerchNoti> records);
+
+    int updateBatch(List<MerchNoti> records);
+
+    List<MerchNoti> getMerchNotiByCodeAndOrderNo(MerchNoti merchNoti);
+}

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است