农商行快捷支付接口定义
diff --git a/payapi/build.gradle b/payapi/build.gradle
index d144174..c6d7dd4 100644
--- a/payapi/build.gradle
+++ b/payapi/build.gradle
@@ -115,6 +115,7 @@
 //    implementation files('libs/ojdbc6.jar')
     implementation 'commons-dbcp:commons-dbcp:1.4'
     implementation 'commons-beanutils:commons-beanutils:1.9.3'
+    implementation files('libs/ynrcc-mbp-1.0-RELEASE.jar')
 
     implementation 'log4j:log4j:1.2.17'
     implementation 'com.alibaba:fastjson:1.2.60'
diff --git a/payapi/libs/ynrcc-mbp-1.0-RELEASE.jar b/payapi/libs/ynrcc-mbp-1.0-RELEASE.jar
new file mode 100644
index 0000000..0a481dd
--- /dev/null
+++ b/payapi/libs/ynrcc-mbp-1.0-RELEASE.jar
Binary files differ
diff --git a/payapi/sql/update-210106.sql b/payapi/sql/update-210106.sql
new file mode 100644
index 0000000..acf987c
--- /dev/null
+++ b/payapi/sql/update-210106.sql
@@ -0,0 +1,10 @@
+-- 农商行网关支付
+INSERT INTO "tb_sourcetype" ("sourcetype_id", "sourcetype", "checkable", "paydesc", "enable", "charge_enable", "consume_enable", "anonymous_enable", "reversable", "pay_subjno", "deposite_subjno", "tplusn", "start_chktime", "tenantid")
+VALUES ('B837FFDD20C0CA07E05011AC03000113', 'ynrccpay', 't', '农商行网关支付', 't', 'f', 't', 'f', 't', '112235', '-', 1, null, '{tenantid}');
+commit;
+
+--新加农商行支付款
+INSERT INTO "tb_subject" ("subjid","subjno", "balflag", "displayflag", "endflag", "fsubjno", "opendate", "subjlevel", "subjname", "subjtype", "tenantid")
+VALUES (33, '112235', 1, 'y', 1, '1122', '20210106', 2, '农商行支付款', 1, '{tenantid}');
+commit;
+
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/ConcatUtil.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/ConcatUtil.java
new file mode 100644
index 0000000..1315114
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/ConcatUtil.java
@@ -0,0 +1,30 @@
+package com.supwisdom.dlpay.agent.ynrccpay;
+
+public class ConcatUtil {
+  private String delimiter;
+  private StringBuilder builder;
+
+  public ConcatUtil(String delimiter) {
+    if (delimiter == null) {
+      throw new RuntimeException("Delimiter must not be null");
+    }
+    this.delimiter = delimiter;
+    builder = new StringBuilder();
+  }
+
+  public ConcatUtil add(String field) {
+    if (field == null) {
+      throw new RuntimeException("added value must not be null");
+    }
+    if (builder.length() > 0) {
+      builder.append(this.delimiter);
+    }
+    builder.append(field);
+    return this;
+  }
+
+  @Override
+  public String toString() {
+    return builder.toString();
+  }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayUtil.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayUtil.java
new file mode 100644
index 0000000..17959f3
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayUtil.java
@@ -0,0 +1,40 @@
+package com.supwisdom.dlpay.agent.ynrccpay;
+
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class YnrccPayUtil {
+
+  public static final Map<String, String> transName;
+
+  static {
+    transName = new HashMap<String, String>(0);
+    transName.put("IQSR","QueryMerchantEpay.do");  //单笔查询交易IQSR
+    transName.put("IPSR","MerchantWithdraw.do");  //单笔退货交易IPSR
+    transName.put("IDFR","MerchantCheckFileQry.do");  //清算对账IDFR
+    //网关支付IFPR有三种可供选择
+    transName.put("IFPR","PayGateFastPay4M.do"); //网关快捷支付IFPR
+    transName.put("IFPR_PC","PayGateFastPay.do"); //fixme:普通网关支付IFPR
+    transName.put("IFPR_H5","PayGateFastPay4MNoCtrl.do"); //fixme:手机端普通网关支付IFPR
+
+    transName.put("IFCR","PayGateFastPayCancelSign.do"); //网关快捷支付解约IFCR
+
+    //网关支付限额修改IFMR有两种可供选择
+    transName.put("IFMR","PayGateFastPayModify4M.do"); //网关快捷支付限额修改IFMR
+    transName.put("IFMR_PC","PayGateFastPayModify.do"); //fixme:普通网关支付限额修改IFMR
+  }
+
+
+  /**
+   * 接口名称
+   * */
+  public static final String TRANSNAME_IQSR="QueryMerchantEpay.do";
+
+
+  /**
+   * 交易码
+   * */
+  public static final String IQSR="IQSR";
+
+}
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/ynrcc_netpay_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/ynrcc_netpay_service_impl.kt
new file mode 100644
index 0000000..2d94e30
--- /dev/null
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/ynrcc_netpay_service_impl.kt
@@ -0,0 +1,62 @@
+package com.supwisdom.dlpay.agent.service.impl
+
+import com.supwisdom.dlpay.agent.service.YnrccNetPayService
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayUtil
+import com.supwisdom.dlpay.api.service.SourceTypeService
+import com.supwisdom.dlpay.framework.service.SystemUtilService
+import org.springframework.http.HttpEntity
+import org.springframework.http.HttpHeaders
+import org.springframework.http.MediaType
+import org.springframework.http.ResponseEntity
+import org.springframework.http.converter.StringHttpMessageConverter
+import org.springframework.stereotype.Service
+import org.springframework.util.LinkedMultiValueMap
+import org.springframework.util.MultiValueMap
+import org.springframework.web.client.RestTemplate
+import java.nio.charset.StandardCharsets
+
+@Service
+class YnrccNetPayServiceImpl(val restTemplate: RestTemplate,
+                             val systemUtilService: SystemUtilService,
+                             val sourceTypeService: SourceTypeService): YnrccNetPayService {
+
+    private fun postForm(url: String, params: Map<String, String>): ResponseEntity<String> {
+        val httpHeaders = HttpHeaders()
+        httpHeaders.contentType = MediaType.APPLICATION_FORM_URLENCODED //Form表单提交
+
+        val requestParams = LinkedMultiValueMap<String, String>()
+        params.forEach(requestParams::add)
+        val httpEntity = HttpEntity<MultiValueMap<String, String>>(requestParams, httpHeaders)
+
+        restTemplate.messageConverters[1] = StringHttpMessageConverter(StandardCharsets.UTF_8) //UTF-8接收
+        return restTemplate.postForEntity(url, httpEntity, String::class.java)
+    }
+
+    override fun doYnrccPaySign() {
+        val params = hashMapOf<String, String>()
+//        params["stuempno"]="111"
+//        params["partner_id"]="100006"
+//        params["timestamp"]=systemUtilService.sysdatetime.hostdatetime
+//        params["sign_method"]="HMAC"
+//        params["sign"]="X"
+//        val url = "http://localhost:8581/epayapi/services/servicehall//common/queryaccountinfo"
+
+        val url ="http://220.163.130.136:8087/pweb/PayGateFastPaySign4MNoCtrl.do?LoginType=C&BankId=9999&_locale=zh_CN"
+        val plain = "TransId=IFSR~~Mer_Id=700003~~MerURL=http://ykt.supwisdom.com"
+//        val sign = YnrccPayUtil.sign(plain);
+        val sign = "123"
+
+        params["TransName"]="IFSR"
+        params["Plain"]=plain
+        params["Signature"]=sign
+
+        var resp = postForm(url,params)
+        if(200 == resp.statusCodeValue){
+            //success
+            println("return json=${resp.body}")
+        } else {
+            //fail
+            println("return status=${resp.statusCodeValue},json=${resp.body}")
+        }
+    }
+}
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/ynrcc_netpay_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/ynrcc_netpay_service.kt
new file mode 100644
index 0000000..e6ab5fb
--- /dev/null
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/ynrcc_netpay_service.kt
@@ -0,0 +1,5 @@
+package com.supwisdom.dlpay.agent.service
+
+interface YnrccNetPayService {
+    fun doYnrccPaySign()
+}
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
index 692be0c..d539a41 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
@@ -838,5 +838,57 @@
         })
     }
 
+    /**
+     * ============================================================================
+     *                           农商行网关快捷支付【初始化下单】
+     * ============================================================================
+     * */
+    @PostMapping("/ynrccpay/order")
+    fun ynrccPayOrder(@Valid @RequestBody param: YnrccPayOrderParam): ResponseEntity<Any>{
+        val success=true
+        if(success){
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .success(YnrccPayOrderResponse(), "交易初始化成功"))
+        }
+
+        return ResponseEntity.ok(ResponseBodyBuilder.create()
+                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
+    }
+
+    /**
+     * ============================================================================
+     *                           农商行网关快捷支付【下单支付确认】
+     * ============================================================================
+     * */
+    @PostMapping("/ynrccpay/confirm")
+    fun ynrccPayConfirm(@Valid @RequestBody param: YnrccPayConfirmParam): ResponseEntity<Any> {
+        val success=true
+        if(success){
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .success(YnrccPayConfirmResponse(), "交易初始化成功"))
+        }
+
+        return ResponseEntity.ok(ResponseBodyBuilder.create()
+                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
+
+    }
+
+    /**
+     * ============================================================================
+     *                           农商行网关快捷支付【退款】
+     * ============================================================================
+     * */
+    @PostMapping("/ynrccpay/refund")
+    fun ynrccPayRefund(@Valid @RequestBody param:YnrccPayRefundParam): ResponseEntity<Any>{
+        val success=true
+        if(success){
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .success(YnrccPayRefundResponse(), "交易初始化成功"))
+        }
+
+        return ResponseEntity.ok(ResponseBodyBuilder.create()
+                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
+
+    }
 
 }
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/user_api_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/user_api_controller.kt
index 0171ced..90cbd5c 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/user_api_controller.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/user_api_controller.kt
@@ -20,6 +20,7 @@
 import org.springframework.http.ResponseEntity
 import org.springframework.web.bind.annotation.*
 import java.net.URLDecoder
+import javax.validation.Valid
 
 @RestController
 @RequestMapping("/api/user")
@@ -446,4 +447,76 @@
                     .fail(ret.retcode, ret.retmsg))
         }
     }
+
+    /**
+     * ============================================================================
+     *                           农商行快捷支付【签约申请】
+     * ============================================================================
+     * */
+    @PostMapping("/ynrccpaySignApply")
+    fun applyYnrccPaySign(@Valid @RequestBody param: YnrccPaySignApplyParam): ResponseEntity<Any> {
+        val success=true
+        if(success){
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .success(YnrccPaySignApplyResponse(), "交易初始化成功"))
+        }
+
+        return ResponseEntity.ok(ResponseBodyBuilder.create()
+                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
+
+    }
+
+    /**
+     * ============================================================================
+     *                           农商行快捷支付【签约确认】
+     * ============================================================================
+     * */
+    @PostMapping("/ynrccpaySignConfirm")
+    fun confirmYnrccPaySign(@Valid @RequestBody param:YnrccPaySignConfirmParam): ResponseEntity<Any>{
+        val success=true
+        if(success){
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .success(YnrccPaySignConfirmResponse(), "交易初始化成功"))
+        }
+
+        return ResponseEntity.ok(ResponseBodyBuilder.create()
+                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
+
+    }
+
+    /**
+     * ============================================================================
+     *                           农商行快捷支付【解约】
+     * ============================================================================
+     * */
+    @PostMapping("/ynrccpaySignCancel")
+    fun cancelYnrccPaySign(@Valid @RequestBody param:YnrccPaySignCancelParam):ResponseEntity<Any>{
+        val success=true
+        if(success){
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .success(YnrccPaySignCancelResponse(), "交易初始化成功"))
+        }
+
+        return ResponseEntity.ok(ResponseBodyBuilder.create()
+                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
+
+    }
+
+    /**
+     * ============================================================================
+     *                           农商行快捷支付【修改限额】
+     * ============================================================================
+     * */
+    @PostMapping("/ynrccpayModifyLimit")
+    fun modifyYnrccPayLimit(@Valid @RequestBody param:YnrccPayLimitModifyParam):ResponseEntity<Any>{
+        val success=true
+        if(success){
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .success(YnrccPayLimitModifyResponse(), "交易初始化成功"))
+        }
+
+        return ResponseEntity.ok(ResponseBodyBuilder.create()
+                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
+
+    }
 }
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/controller/framework_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/controller/framework_controller.kt
index a55845f..b80d573 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/controller/framework_controller.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/controller/framework_controller.kt
@@ -1,8 +1,11 @@
 package com.supwisdom.dlpay.framework.controller
 
 import com.jcabi.manifests.Manifests
+import com.supwisdom.dlpay.agent.service.YnrccNetPayService
 import com.supwisdom.dlpay.api.bean.ApiVersionResponse
 import com.supwisdom.dlpay.framework.ResponseBodyBuilder
+import com.supwisdom.dlpay.framework.redisrepo.ApiClientRepository
+import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.ResponseEntity
 import org.springframework.web.bind.annotation.GetMapping
 import org.springframework.web.bind.annotation.RequestMapping
@@ -12,9 +15,13 @@
 @RestController
 @RequestMapping("/api/common")
 class AboutController {
+    @Autowired
+    lateinit var ynrccNetPayService: YnrccNetPayService
+
     @GetMapping("/version")
     fun version(): ResponseEntity<Any> {
         return try {
+            ynrccNetPayService.doYnrccPaySign()
             Manifests.read("Payapi-Version").let {
                 ResponseEntity.ok(ResponseBodyBuilder.create()
                         .success(ApiVersionResponse(it)))
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/domain/TBMobileUser.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/domain/TBMobileUser.kt
index 339e607..0fc534c 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/domain/TBMobileUser.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/domain/TBMobileUser.kt
@@ -6,7 +6,6 @@
 import org.springframework.security.core.GrantedAuthority
 import org.springframework.security.core.userdetails.UserDetails
 import javax.persistence.*
-import javax.validation.constraints.NotNull
 
 @Entity
 @Table(name = "TB_MOBILE_USER",indexes = [Index(name = "mobile_user_loginid_idx", columnList = "loginid", unique = true)])
@@ -54,8 +53,7 @@
      * 登录id
      * */
 
-    @Column(name = "loginid", length = 64)
-    @NotNull
+    @Column(name = "loginid", nullable = false, length = 64)
     var loginid: String = ""
 
     /**
diff --git a/payapi/src/main/resources/payment_merchant.properties b/payapi/src/main/resources/payment_merchant.properties
new file mode 100644
index 0000000..b2f94dc
--- /dev/null
+++ b/payapi/src/main/resources/payment_merchant.properties
@@ -0,0 +1,11 @@
+development=no
+# \u8BC1\u4E66\u8DEF\u5F84,\u5FC5\u987B\u6307\u5B9A\u670D\u52A1\u5668\u7AEF\u8BC1\u4E66\u5BB9\u5668\u7EDD\u5BF9\u8DEF\u5F84
+cafile=D:/ynrccpay/merchant.jks
+# \u8BC1\u4E66\u5E93\u5BC6\u7801
+store_password=111111
+# \u7528\u4E8E\u5546\u6237\u7B7E\u540D\u7684\u79D8\u94A5\u522B\u540D
+key_alias=merchant_key
+# \u79D8\u94A5\u5BC6\u7801
+key_password=111111
+# \u9A8C\u7B7E\u79D8\u94A5\u522B\u540D
+alias_paygate=alias_paygate
\ No newline at end of file