大理新接口实现初版
diff --git a/payapi/build.gradle b/payapi/build.gradle
index c6d7dd4..de710ba 100644
--- a/payapi/build.gradle
+++ b/payapi/build.gradle
@@ -115,7 +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 files('libs/ynrcc-mbp-1.1-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
deleted file mode 100644
index 0a481dd..0000000
--- a/payapi/libs/ynrcc-mbp-1.0-RELEASE.jar
+++ /dev/null
Binary files differ
diff --git a/payapi/libs/ynrcc-mbp-1.1-RELEASE.jar b/payapi/libs/ynrcc-mbp-1.1-RELEASE.jar
new file mode 100644
index 0000000..34da472
--- /dev/null
+++ b/payapi/libs/ynrcc-mbp-1.1-RELEASE.jar
Binary files differ
diff --git a/payapi/sql/update-210106.sql b/payapi/sql/update-210106.sql
index acf987c..803b182 100644
--- a/payapi/sql/update-210106.sql
+++ b/payapi/sql/update-210106.sql
@@ -8,3 +8,25 @@
 VALUES (33, '112235', 1, 'y', 1, '1122', '20210106', 2, '农商行支付款', 1, '{tenantid}');
 commit;
 
+-- ----------------------------
+-- Table structure for tb_ynrccpay_sign
+-- ----------------------------
+CREATE TABLE tb_ynrccpay_sign (
+	id varchar(32) NOT NULL,
+	bankcardno varchar(32) NOT NULL,
+	shopaccno varchar(10) NOT NULL,
+	userid varchar(32) NOT NULL,
+	status varchar(10) NOT NULL,
+	sign_flag bool NOT NULL,
+	customer_sign_no varchar(60),
+	sign_time varchar(14),
+	cancel_time varchar(14),
+	remark varchar(600),
+	createtime varchar(14)
+);
+ALTER TABLE tb_ynrccpay_sign ADD CONSTRAINT tb_ynrccpay_sign_pkey PRIMARY KEY (id);
+CREATE INDEX idx1_ynrccpay_sign ON tb_ynrccpay_sign(bankcardno,shopaccno,status);
+
+INSERT INTO "tb_transcode" ("transcode_id", "transcode", "transname", "tenantid")
+VALUES (4, 3050, '农商行网关快捷支付', '{tenantid}');
+commit;
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentResponse.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentResponse.java
index 149c3ae..caa0ce4 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentResponse.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/AgentResponse.java
@@ -1,5 +1,7 @@
 package com.supwisdom.dlpay.agent;
 
+import java.util.Map;
+
 public class AgentResponse<T> {
   public static final String AGENTCODE_SUCCESS = "0";
 
@@ -13,6 +15,7 @@
   private DtlStatus dtlStatus;
 
   private T payload;
+  private Map<String,String> params;
 
   public String getAgentBody() {
     return agentBody;
@@ -70,6 +73,14 @@
     this.payload = payload;
   }
 
+  public Map<String, String> getParams() {
+    return params;
+  }
+
+  public void setParams(Map<String, String> params) {
+    this.params = params;
+  }
+
   public AgentResponse() {
   }
 }
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayCommonResp.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayCommonResp.java
new file mode 100644
index 0000000..8c9f27d
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayCommonResp.java
@@ -0,0 +1,22 @@
+package com.supwisdom.dlpay.agent.ynrccpay;
+
+public class YnrccPayCommonResp {
+  private String Plain;
+  private String Signature;
+
+  public String getPlain() {
+    return Plain;
+  }
+
+  public void setPlain(String plain) {
+    Plain = plain;
+  }
+
+  public String getSignature() {
+    return Signature;
+  }
+
+  public void setSignature(String signature) {
+    Signature = signature;
+  }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayResp.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayResp.java
new file mode 100644
index 0000000..71f9200
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayResp.java
@@ -0,0 +1,185 @@
+package com.supwisdom.dlpay.agent.ynrccpay;
+
+public class YnrccPayResp {
+  private String code; //ZF0000 表示成功
+  private String message;
+
+  private String plain;
+  private String signature;
+
+  private String TransId;
+  private String Mer_Id;
+  private String TransSeqNo;
+
+  //退款
+  private String OrgTransAmt;
+  private String TransAmount;
+  private String MerchantSeqNo;
+
+  //查询
+  private String OrgTransId; //ZF01 - 支付;  ZF02 - 退货
+  private String OrderNo; //订单号
+  private String Amount; //交易金额
+  private String Amount1; //已退货金额
+  private String FeeAmt; //手续费金额
+  private String CurrencyType; //币种
+  private String PpDateTime; //支付系统交易时间
+  private String ClearingDate; //清算日期
+  private String TransStatus; //交易状态 00 - 交易成功; 01 - 交易失败; 02 - 撤消成功; 03 - 部分退货; 04 - 全部退货; 99 - 交易超时
+
+  public String error() {
+    return "code=[" + this.code + "],message=[" + this.message + "]";
+  }
+
+  public String getCode() {
+    return code;
+  }
+
+  public void setCode(String code) {
+    this.code = code;
+  }
+
+  public String getMessage() {
+    return message;
+  }
+
+  public void setMessage(String message) {
+    this.message = message;
+  }
+
+  public String getPlain() {
+    return plain;
+  }
+
+  public void setPlain(String plain) {
+    this.plain = plain;
+  }
+
+  public String getSignature() {
+    return signature;
+  }
+
+  public void setSignature(String signature) {
+    this.signature = signature;
+  }
+
+  public String getTransId() {
+    return TransId;
+  }
+
+  public void setTransId(String transId) {
+    TransId = transId;
+  }
+
+  public String getMer_Id() {
+    return Mer_Id;
+  }
+
+  public void setMer_Id(String mer_Id) {
+    Mer_Id = mer_Id;
+  }
+
+  public String getTransSeqNo() {
+    return TransSeqNo;
+  }
+
+  public void setTransSeqNo(String transSeqNo) {
+    TransSeqNo = transSeqNo;
+  }
+
+  public String getTransStatus() {
+    return TransStatus;
+  }
+
+  public void setTransStatus(String transStatus) {
+    TransStatus = transStatus;
+  }
+
+  public String getOrgTransAmt() {
+    return OrgTransAmt;
+  }
+
+  public void setOrgTransAmt(String orgTransAmt) {
+    OrgTransAmt = orgTransAmt;
+  }
+
+  public String getTransAmount() {
+    return TransAmount;
+  }
+
+  public void setTransAmount(String transAmount) {
+    TransAmount = transAmount;
+  }
+
+  public String getMerchantSeqNo() {
+    return MerchantSeqNo;
+  }
+
+  public void setMerchantSeqNo(String merchantSeqNo) {
+    MerchantSeqNo = merchantSeqNo;
+  }
+
+  public String getOrgTransId() {
+    return OrgTransId;
+  }
+
+  public void setOrgTransId(String orgTransId) {
+    OrgTransId = orgTransId;
+  }
+
+  public String getOrderNo() {
+    return OrderNo;
+  }
+
+  public void setOrderNo(String orderNo) {
+    OrderNo = orderNo;
+  }
+
+  public String getAmount() {
+    return Amount;
+  }
+
+  public void setAmount(String amount) {
+    Amount = amount;
+  }
+
+  public String getAmount1() {
+    return Amount1;
+  }
+
+  public void setAmount1(String amount1) {
+    Amount1 = amount1;
+  }
+
+  public String getFeeAmt() {
+    return FeeAmt;
+  }
+
+  public void setFeeAmt(String feeAmt) {
+    FeeAmt = feeAmt;
+  }
+
+  public String getCurrencyType() {
+    return CurrencyType;
+  }
+
+  public void setCurrencyType(String currencyType) {
+    CurrencyType = currencyType;
+  }
+
+  public String getPpDateTime() {
+    return PpDateTime;
+  }
+
+  public void setPpDateTime(String ppDateTime) {
+    PpDateTime = ppDateTime;
+  }
+
+  public String getClearingDate() {
+    return ClearingDate;
+  }
+
+  public void setClearingDate(String clearingDate) {
+    ClearingDate = clearingDate;
+  }
+}
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
index 17959f3..d0a3474 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayUtil.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayUtil.java
@@ -1,40 +1,87 @@
 package com.supwisdom.dlpay.agent.ynrccpay;
 
 
+import com.google.gson.Gson;
+import com.supwisdom.dlpay.agent.AgentCode;
+import com.supwisdom.dlpay.agent.citizencard.YnrccRespCode;
+import org.springframework.data.util.Pair;
+
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 public class YnrccPayUtil {
+  public static final String GATEWAY = "ynrcc.netpay.URL";
+  public static final String MER_ID = "ynrcc.netpay.Mer_Id";
+  public static final String MER_NAME = "ynrcc.netpay.Mer_IdName";
+  public static final String MER_URL = "ynrcc.netpay.MerURL";
 
-  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
+  public static final String SUCCESS = "ZF0000";
+  public static final String WAIT_FOR_QUERY = "ZF0098"; //等待查询结果
 
-    transName.put("IFCR","PayGateFastPayCancelSign.do"); //网关快捷支付解约IFCR
 
-    //网关支付限额修改IFMR有两种可供选择
-    transName.put("IFMR","PayGateFastPayModify4M.do"); //网关快捷支付限额修改IFMR
-    transName.put("IFMR_PC","PayGateFastPayModify.do"); //fixme:普通网关支付限额修改IFMR
+  public static String toJson(Object obj) {
+    if (null == obj) return "";
+    Gson gson = new Gson();
+    return gson.toJson(obj);
   }
 
+  public static final List<Pair<AgentCode, YnrccRespCode>> errcode = new ArrayList<>(0);
 
-  /**
-   * 接口名称
-   * */
-  public static final String TRANSNAME_IQSR="QueryMerchantEpay.do";
+  static {
+    errcode.add(Pair.of(AgentCode.SUCCESS, new YnrccRespCode("ZF0000", "交易成功")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0001", "本机构无权查看机构的信息")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0003", "无效商户")));
+    errcode.add(Pair.of(AgentCode.SERVER_INTERNAL_ERROR, new YnrccRespCode("ZF0006", "网络不通")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0012", "无效交易")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0013", "无效金额")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0014", "无效卡号")));
+    errcode.add(Pair.of(AgentCode.REFNO_NOT_EXISTS, new YnrccRespCode("ZF0020", "原订单信息不存在")));
+    errcode.add(Pair.of(AgentCode.SERVER_INTERNAL_ERROR, new YnrccRespCode("ZF0022", "交易异常")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0030", "终端上送数据格式错")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0041", "账号被冻结或挂失")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0042", "无此帐户")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0048", "该客户号已关闭快速支付")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0049", "签约已撤消或冻结")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0050", "没有签约协议支付")));
+    errcode.add(Pair.of(AgentCode.SHORT_OF_BALANCE, new YnrccRespCode("ZF0051", "余额不足")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0055", "密码错误")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0058", "不允许商户进行的交易")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0061", "超出商户金额限制")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0062", "退货金额超限")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0063", "上笔交易正在处理中,现交易被拒绝")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0064", "原始交易金额不匹配")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0065", "超出取款限制次数")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0067", "不允许多次退货")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0075", "超出密码输入次数")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0077", "商户状态错误")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0082", "卡号已经被注销了")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0084", "账号不存在")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0085", "银联支付号被注销了")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0086", "身份证号不匹配")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0087", "无效证件号码")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0088", "简单密码")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0092", "上笔交易正在处理中")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0093", "违法交易,无法完成")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0094", "重复交易")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0096", "系统内部错")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0097", "无效终端,柜员号不存在")));
+    errcode.add(Pair.of(AgentCode.REQUIRE_QUERY, new YnrccRespCode("ZF0098", "交易超时,请查询")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0099", "支付密码不允许为空")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF00EI", "找不到机构号")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF00EB", "(商户)机构设置错误")));
 
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF00A0", "成功接收订单")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF00A1", "支付方取消订单")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0101", "无相关数据")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZF0214", "平台已冻结或已注销")));
 
-  /**
-   * 交易码
-   * */
-  public static final String IQSR="IQSR";
-
+    //自定义错误 ZExxxx
+    errcode.add(Pair.of(AgentCode.CONFIG_ERROR, new YnrccRespCode("ZE0001", "系统参数未配置")));
+    errcode.add(Pair.of(AgentCode.COMMON_ERROR, new YnrccRespCode("ZE0002", "签名计算错误")));
+    errcode.add(Pair.of(AgentCode.ILLEGAL_DATA, new YnrccRespCode("ZE0098", "请求农商行网关快捷支付返回数据为空")));
+    errcode.add(Pair.of(AgentCode.SERVER_INTERNAL_ERROR, new YnrccRespCode("ZE0099", "请求农商行网关快捷支付httpStatus非200")));
+  }
 }
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/dao/YnrccPaySignDao.java b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/dao/YnrccPaySignDao.java
new file mode 100644
index 0000000..d8b0949
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/dao/YnrccPaySignDao.java
@@ -0,0 +1,17 @@
+package com.supwisdom.dlpay.citizencard.dao;
+
+import com.supwisdom.dlpay.citizencard.domain.TYnrccPaySign;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface YnrccPaySignDao extends JpaRepository<TYnrccPaySign, String> {
+  @Query("from TYnrccPaySign t where t.bankcardno=?1 and t.shopaccno=?2 and t.status='normal'")
+  TYnrccPaySign getUserSign(String bankcardno, String shopaccno);
+
+  @Query("select count(t.id) from TYnrccPaySign t where t.bankcardno=?1 and t.shopaccno<>?2 and t.status='normal' and t.signFlag is true ")
+  int countByBankcardnoAndSignStatus(String bankcardno, String shopaccno);
+
+  TYnrccPaySign getById(String id);
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/Subject.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/Subject.java
index e80344a..21602c4 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/Subject.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/Subject.java
@@ -78,6 +78,11 @@
    */
   public static final String SUBJNO_PAY_CITIZEN_CARD = "112234";
 
+  /**
+   * 应收账款 - 农商行网关快捷支付
+   */
+  public static final String SUBJNO_YNRCC_NETPAY = "112235";
+
 
   //======================= 负债类 =====================//
 
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java
index b78049f..29f3921 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java
@@ -13,6 +13,8 @@
 
   public static final int TRANSCODE_ALIPAY = 3040;//支付宝支付
 
+  public static final int TRANSCODE_YNRCC_NETPAY = 3050;//农商行网关快捷支付
+
   // QRcode 聚合支付
   public static final int TRANSCODE_QRCODE = 1002;
 
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
index 161b1c7..ae9aafe 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
@@ -81,6 +81,7 @@
   public static final String PAYTYPE_CITIZEN_CARD = "citizenCard"; //市民卡
   public static final String PAYTYPE_YKT_CARD = "yktpay"; //一卡通
   public static final String PAYTYPE_OTHER_THIRDPART = "thirdpart"; //其他第三方
+  public static final String PAYTYPE_YNRCC_PAY="ynrccpay"; //农商行网关快捷支付
 
   public static final String PAYTYPE_APP = "APP"; //app内支付
   public static final String PAYTYPE_H5 = "H5"; //H5内支付
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
index 2d94e30..3c1c7e7 100644
--- 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
@@ -1,9 +1,28 @@
 package com.supwisdom.dlpay.agent.service.impl
 
+import com.csii.ynrcc.open.api.pay.YNRCCFastGateWayPayApi
+import com.google.gson.Gson
 import com.supwisdom.dlpay.agent.service.YnrccNetPayService
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayCommonResp
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayResp
 import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayUtil
+import com.supwisdom.dlpay.api.bean.YnrccPaySignApplyParam
+import com.supwisdom.dlpay.api.bean.YnrccPaySignApplyResponse
+import com.supwisdom.dlpay.api.dao.CardDao
+import com.supwisdom.dlpay.api.dao.PersonDao
+import com.supwisdom.dlpay.api.repositories.ShopaccService
 import com.supwisdom.dlpay.api.service.SourceTypeService
+import com.supwisdom.dlpay.citizencard.dao.YnrccPaySignDao
+import com.supwisdom.dlpay.citizencard.domain.TYnrccPaySign
+import com.supwisdom.dlpay.exception.TransactionProcessException
+import com.supwisdom.dlpay.framework.dao.ShopaccDao
 import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.dlpay.framework.util.MoneyUtil
+import com.supwisdom.dlpay.framework.util.StringUtil
+import com.supwisdom.dlpay.framework.util.TradeDict
+import com.supwisdom.dlpay.framework.util.TradeErrorCode
+import com.supwisdom.dlpay.util.ConstantUtil
+import mu.KotlinLogging
 import org.springframework.http.HttpEntity
 import org.springframework.http.HttpHeaders
 import org.springframework.http.MediaType
@@ -18,45 +37,306 @@
 @Service
 class YnrccNetPayServiceImpl(val restTemplate: RestTemplate,
                              val systemUtilService: SystemUtilService,
-                             val sourceTypeService: SourceTypeService): YnrccNetPayService {
+                             val sourceTypeService: SourceTypeService) : YnrccNetPayService {
+    private val logger = KotlinLogging.logger { }
 
-    private fun postForm(url: String, params: Map<String, String>): ResponseEntity<String> {
+    override fun doAnalysisSignature(shopaccno: String, plain: String, signature: String): Map<String, String> {
+        val config = sourceTypeService.getConsumePaytypeConfig(TradeDict.PAYTYPE_YNRCC_PAY, shopaccno, false, true)
+        val data = YNRCCFastGateWayPayApi.verify(signature, plain) //调SDK验证签名
+        val merId = config[YnrccPayUtil.MER_ID]
+        if (!merId.isNullOrEmpty() && merId != data["Mer_Id"]) {
+            throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "参数[Mer_Id]不匹配!")
+        }
+        return data
+    }
+
+    override fun doApplyYnrccPaySign(shopaccno: String): YnrccPayResp {
+        val resp = YnrccPayResp()
+        val config = sourceTypeService.getConsumePaytypeConfig(TradeDict.PAYTYPE_YNRCC_PAY, shopaccno, false, false)
+        val merId = config[YnrccPayUtil.MER_ID]
+        val merUrl = config[YnrccPayUtil.MER_URL]
+        if (merId.isNullOrEmpty()) {
+            resp.code = "ZE0001"
+            resp.message = "系统参数未配置[Mer_Id]"
+            logger.error(resp.error())
+            return resp
+        }
+        if (merUrl.isNullOrEmpty()) {
+            resp.code = "ZE0001"
+            resp.message = "系统参数未配置[MerURL]"
+            logger.error(resp.error())
+            return resp
+        }
+
+        val params = hashMapOf<String, String>()
+        params["TransId"] = "IFSR"
+        params["Mer_Id"] = merId.trim()
+        params["MerURL"] = merUrl.trim()
+
+        //调SDK生成签名
+        val signData = YNRCCFastGateWayPayApi.sign(params)
+
+        resp.code = YnrccPayUtil.SUCCESS
+        resp.message = "SUCCESS"
+        resp.plain = signData["Plain"]
+        resp.signature = signData["Signature"]
+        return resp
+    }
+
+    override fun doCancelYnrccPaySign(shopaccno: String, customerSignNo: String): YnrccPayResp {
+        val resp = YnrccPayResp()
+        val config = sourceTypeService.getConsumePaytypeConfig(TradeDict.PAYTYPE_YNRCC_PAY, shopaccno, false, false)
+        val gateWay = config[YnrccPayUtil.GATEWAY]
+        val merId = config[YnrccPayUtil.MER_ID]
+        if (gateWay.isNullOrEmpty()) {
+            resp.code = "ZE0001"
+            resp.message = "系统参数未配置[网关地址]"
+            logger.error(resp.error())
+            return resp
+        }
+        if (merId.isNullOrEmpty()) {
+            resp.code = "ZE0001"
+            resp.message = "系统参数未配置[Mer_Id]"
+            logger.error(resp.error())
+            return resp
+        }
+
+        val url = String.format(gateWay, "PayGateFastPayCancelSign.do") //赋予接口名
+        val params = hashMapOf<String, String>()
+        params["TransId"] = "IFCR"
+        params["Mer_Id"] = merId.trim()
+        params["CustomerSignNo"] = customerSignNo
+
+        val signData = YNRCCFastGateWayPayApi.sign(params) //调SDK生成签名
+        val plain = signData["Plain"]
+        val signature = signData["Signature"]
+        if (plain.isNullOrEmpty() || signature.isNullOrEmpty()) {
+            resp.code = "ZE0002"
+            resp.message = "签名计算错误!"
+            logger.error(resp.error())
+            return resp
+        }
+
+        val result = postForm(url, plain, signature, "解约") //发起表单提交
+        resp.code = result["RespCode"]
+        resp.message = result["RespDesc"]
+        if (YnrccPayUtil.SUCCESS == result["RespCode"]) {
+            resp.transId = result["TransId"]
+            resp.mer_Id = result["Mer_Id"]
+        } else {
+            logger.error(resp.error())
+        }
+        return resp
+    }
+
+    private fun error(code: String, message: String): Map<String, String> {
+        val error = hashMapOf<String, String>()
+        error["RespCode"] = code
+        error["RespDesc"] = message
+        return error
+    }
+
+    private fun postForm(url: String, plain: String, signature: String, opt:String): Map<String,String> {
         val httpHeaders = HttpHeaders()
         httpHeaders.contentType = MediaType.APPLICATION_FORM_URLENCODED //Form表单提交
-
         val requestParams = LinkedMultiValueMap<String, String>()
-        params.forEach(requestParams::add)
+        requestParams.add("Plain", plain);
+        requestParams.add("Signature", signature)
         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"
+        logger.info("农商行网关快捷支付请求【$opt】:\nurl=[$url]\nPlain=[$plain]\nSignature=[$signature]")
+        val result = restTemplate.postForEntity(url, httpEntity, String::class.java)
+        if (200 == result.statusCodeValue) {
+            //请求成功
+            val resJson = Gson().fromJson(result.body, YnrccPayCommonResp::class.java)
+            if (null == resJson || StringUtil.isEmpty(resJson.plain) || StringUtil.isEmpty(resJson.signature)) {
+                return error("ZE0098", "请求农商行网关【$opt】返回数据为空!")
+            }
 
-        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}")
+            val resData = YNRCCFastGateWayPayApi.verify(resJson.signature, resJson.plain) //调SDK验证签名
+            logger.info("农商行网关快捷支付请求【$opt】返回:\nurl=[$url]\nResponse=[" + YnrccPayUtil.toJson(resData) + "]")
+            return if (YnrccPayUtil.SUCCESS == resData["RespCode"]) {
+                resData["RespDesc"] = "SUCCESS"
+                resData
+            } else {
+                val errcode = resData["RespCode"]
+                val errmsg = YnrccPayUtil.errcode.firstOrNull {
+                    it.second.code == errcode
+                }?.second?.msg
+                resData["RespDesc"] = "$errcode $errmsg"  //设置失败信息
+                resData
+            }
         } else {
-            //fail
-            println("return status=${resp.statusCodeValue},json=${resp.body}")
+            return error("ZE0099","请求农商行网关【$opt】失败!http status=[${result.statusCodeValue}]")
         }
     }
+
+    override fun doYnrccPayInit(shopaccno: String, refno: String, amount: Int, transDateTime: String, productInfo: String, extData: String, custname: String, email: String, customerSignNo: String): YnrccPayResp {
+        val resp = YnrccPayResp()
+        val config = sourceTypeService.getConsumePaytypeConfig(TradeDict.PAYTYPE_YNRCC_PAY, shopaccno, false, false)
+        val merId = config[YnrccPayUtil.MER_ID]
+        val merIdName = config[YnrccPayUtil.MER_NAME]
+        val merUrl = config[YnrccPayUtil.MER_URL]
+        if (merId.isNullOrEmpty()) {
+            resp.code = "ZE0001"
+            resp.message = "系统参数未配置[Mer_Id]"
+            logger.error(resp.error())
+            return resp
+        }
+        if (merIdName.isNullOrEmpty()) {
+            resp.code = "ZE0001"
+            resp.message = "系统参数未配置[Mer_IdName]"
+            logger.error(resp.error())
+            return resp
+        }
+        if (merUrl.isNullOrEmpty()) {
+            resp.code = "ZE0001"
+            resp.message = "系统参数未配置[MerURL]"
+            logger.error(resp.error())
+            return resp
+        }
+
+        val params = hashMapOf<String, String>()
+        params["TransId"] = "IFPR"
+        params["Mer_Id"] = merId.trim()
+        params["Mer_IdName"] = merIdName
+        params["OrderNo"] = refno
+        params["Amount"] = MoneyUtil.formatYuanToString(amount / 100.0)
+        params["OrderDateTime"] = transDateTime
+        params["CurrencyType"] = "156"
+        params["CustomerName"] = custname
+        params["ProductInfo"] = productInfo
+        params["CustomerEMail"] = email
+        params["CustomerSignNo"] = customerSignNo
+        params["MerURL"] = merUrl
+        params["MsgExt"] = extData
+
+        //调SDK生成签名
+        val signData = YNRCCFastGateWayPayApi.sign(params)
+
+        resp.code = YnrccPayUtil.SUCCESS
+        resp.message = "SUCCESS"
+        resp.plain = signData["Plain"]
+        resp.signature = signData["Signature"]
+        return resp
+    }
+
+    override fun doYnrccPayRefund(shopaccno: String, orignRefno: String, amount: Int, orignTransDate: String): YnrccPayResp {
+        val resp = YnrccPayResp()
+        val config = sourceTypeService.getConsumePaytypeConfig(TradeDict.PAYTYPE_YNRCC_PAY, shopaccno, false, false)
+        val gateWay = config[YnrccPayUtil.GATEWAY]
+        val merId = config[YnrccPayUtil.MER_ID]
+        if (gateWay.isNullOrEmpty()) {
+            resp.code = "ZE0001"
+            resp.message = "系统参数未配置[网关地址]"
+            logger.error(resp.error())
+            return resp
+        }
+        if (merId.isNullOrEmpty()) {
+            resp.code = "ZE0001"
+            resp.message = "系统参数未配置[Mer_Id]"
+            logger.error(resp.error())
+            return resp
+        }
+
+        val url = String.format(gateWay, "MerchantWithdraw.do") //赋予接口名
+        val params = hashMapOf<String, String>()
+        params["TransId"] = "IPSR"
+        params["Mer_Id"] = merId.trim()
+        params["OrgMerchantSeqNo"] = orignRefno
+        params["Amount"] = MoneyUtil.formatYuanToString(amount / 100.0)
+        params["OrgMerchantDate"] = orignTransDate
+
+        val signData = YNRCCFastGateWayPayApi.sign(params) //调SDK生成签名
+        val plain = signData["Plain"]
+        val signature = signData["Signature"]
+        if (plain.isNullOrEmpty() || signature.isNullOrEmpty()) {
+            resp.code = "ZE0002"
+            resp.message = "签名计算错误!"
+            logger.error(resp.error())
+            return resp
+        }
+
+        val result = postForm(url, plain, signature, "退款") //发起表单提交
+        resp.code = result["RespCode"]
+        resp.message = result["RespDesc"]
+        if (YnrccPayUtil.SUCCESS == result["RespCode"]) {
+            resp.transId = result["TransId"]
+            resp.mer_Id = result["Mer_Id"]
+            resp.orgTransAmt = result["OrgTransAmt"]
+            resp.transAmount = result["TransAmount"]
+            resp.merchantSeqNo = result["MerchantSeqNo"]
+            resp.transSeqNo = result["TransSeqNo"]
+        } else {
+            logger.error(resp.error())
+        }
+        return resp
+    }
+
+    override fun doQueryYnrccPayResult(shopaccno: String, orignRefno: String, orignTransDate: String): YnrccPayResp {
+        val resp = YnrccPayResp()
+        val config = sourceTypeService.getConsumePaytypeConfig(TradeDict.PAYTYPE_YNRCC_PAY, shopaccno, false, false)
+        val gateWay = config[YnrccPayUtil.GATEWAY]
+        val merId = config[YnrccPayUtil.MER_ID]
+        val merIdName = config[YnrccPayUtil.MER_NAME]
+        if (gateWay.isNullOrEmpty()) {
+            resp.code = "ZE0001"
+            resp.message = "系统参数未配置[网关地址]"
+            logger.error(resp.error())
+            return resp
+        }
+        if (merId.isNullOrEmpty()) {
+            resp.code = "ZE0001"
+            resp.message = "系统参数未配置[Mer_Id]"
+            logger.error(resp.error())
+            return resp
+        }
+        if (merIdName.isNullOrEmpty()) {
+            resp.code = "ZE0001"
+            resp.message = "系统参数未配置[Mer_IdName]"
+            logger.error(resp.error())
+            return resp
+        }
+
+        val url = String.format(gateWay, "QueryMerchantEpay.do") //赋予接口名
+        val params = hashMapOf<String, String>()
+        params["TransId"] = "IQSR"
+        params["Mer_Id"] = merId.trim()
+        params["Mer_IdName"] = merIdName.trim()
+        params["OrderNo"] = orignRefno
+        params["OrderDate"] = orignTransDate
+
+        val signData = YNRCCFastGateWayPayApi.sign(params) //调SDK生成签名
+        val plain = signData["Plain"]
+        val signature = signData["Signature"]
+        if (plain.isNullOrEmpty() || signature.isNullOrEmpty()) {
+            resp.code = "ZE0002"
+            resp.message = "签名计算错误!"
+            logger.error(resp.error())
+            return resp
+        }
+
+        val result = postForm(url, plain, signature, "结果查询") //发起表单提交
+        resp.code = result["RespCode"]
+        resp.message = result["RespDesc"]
+        if (YnrccPayUtil.SUCCESS == result["RespCode"]) {
+            resp.transId = result["TransId"]
+            resp.mer_Id = result["Mer_Id"]
+            resp.orgTransId = result["OrgTransId"]
+            resp.orderNo = result["OrderNo"]
+            resp.amount = result["Amount"]
+            resp.amount1 = result["Amount1"]
+            resp.feeAmt = result["FeeAmt"]
+            resp.currencyType = result["CurrencyType"]
+            resp.transSeqNo = result["TransSeqNo"]
+            resp.ppDateTime = result["PpDateTime"]
+            resp.clearingDate = result["ClearingDate"]
+            resp.transStatus = result["TransStatus"]
+        } else {
+            logger.error(resp.error())
+        }
+        return resp
+    }
+
 }
\ 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
index e6ab5fb..f2e5bdc 100644
--- 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
@@ -1,5 +1,94 @@
 package com.supwisdom.dlpay.agent.service
 
+import com.supwisdom.dlpay.agent.AgentCode
+import com.supwisdom.dlpay.agent.AgentPayService
+import com.supwisdom.dlpay.agent.AgentResponse
+import com.supwisdom.dlpay.agent.DtlStatus
+import com.supwisdom.dlpay.agent.citizencard.YnrccRespCode
+import com.supwisdom.dlpay.agent.citizencard.YnrccUtil
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayResp
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayUtil
+import com.supwisdom.dlpay.api.domain.TTransactionMain
+import com.supwisdom.dlpay.framework.util.MoneyUtil
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Component
+
 interface YnrccNetPayService {
-    fun doYnrccPaySign()
+    fun doAnalysisSignature(shopaccno: String, plain: String, signature: String): Map<String, String>
+
+    fun doApplyYnrccPaySign(shopaccno: String): YnrccPayResp
+
+    fun doCancelYnrccPaySign(shopaccno: String, customerSignNo: String): YnrccPayResp
+
+    fun doYnrccPayInit(shopaccno: String, refno: String, amount: Int, transDateTime: String, productInfo: String,
+                       extData: String, custname: String, email: String, customerSignNo: String): YnrccPayResp
+
+    fun doYnrccPayRefund(shopaccno: String, orignRefno: String, amount: Int, orignTransDate: String): YnrccPayResp
+
+    fun doQueryYnrccPayResult(shopaccno: String, orignRefno: String, orignTransDate: String): YnrccPayResp
+}
+
+@Component("ynrccpayAgent")
+class YnrccNetPayAgent: AgentPayService<DtlStatus>{
+    @Autowired
+    private lateinit var ynrccNetPayService: YnrccNetPayService
+
+    private fun agentCode(code: String, msg: String?): org.springframework.data.util.Pair<AgentCode, YnrccRespCode> {
+        return YnrccPayUtil.errcode.firstOrNull {
+            it.second.code == code
+        }?.let {
+            org.springframework.data.util.Pair.of(it.first, YnrccRespCode(
+                    code, it.second.msg.replace("{message}", msg ?: "未知")
+            ))
+        } ?: org.springframework.data.util.Pair.of(AgentCode.COMMON_ERROR,
+                YnrccRespCode(code, msg ?: "未知"))
+    }
+
+    override fun auth(agentid: String?, billno: String?): AgentResponse<DtlStatus> {
+        return AgentResponse<DtlStatus>().apply {
+            this.code = AgentCode.NOT_SUPPORT
+        }
+    }
+
+    override fun pay(transaction: TTransactionMain): AgentResponse<DtlStatus> {
+        return AgentResponse<DtlStatus>().apply {
+            this.code = AgentCode.NOT_SUPPORT //fixme:支付由客户端发起,服务端无支付逻辑
+        }
+    }
+
+    override fun cancel(transaction: TTransactionMain): AgentResponse<DtlStatus> {
+        return refund(transaction)
+    }
+
+    override fun refund(transaction: TTransactionMain): AgentResponse<DtlStatus> {
+        val resp = ynrccNetPayService.doYnrccPayRefund(transaction.shopDtl.shopaccno, transaction.reverseRefno,
+                MoneyUtil.YuanToFen(transaction.personDtl.amount), transaction.shopDtl.accdate)
+        return AgentResponse<DtlStatus>().also {
+            val code = agentCode(resp.code, resp.message)
+            it.code = code.first
+            it.agentCode = code.second.code
+            it.agentMsg = code.second.msg
+            it.agentRefno = resp.transSeqNo
+        }
+    }
+
+    override fun query(transaction: TTransactionMain): AgentResponse<DtlStatus> {
+        val resp = ynrccNetPayService.doQueryYnrccPayResult(transaction.shopDtl.shopaccno, transaction.refno, transaction.shopDtl.transdate)
+
+        return AgentResponse<DtlStatus>().also {
+            val code = agentCode(resp.code, resp.message)
+            it.code = code.first
+            it.agentCode = code.second.code
+            it.agentMsg = code.second.msg
+            it.agentRefno = resp.transSeqNo
+            it.dtlStatus = when (resp.transStatus) {
+//                00 - 交易成功  01 - 交易失败  02 - 撤消成功  03 - 部分退货  04 - 全部退货    99 - 交易超时
+                "00" -> DtlStatus.SUCCESS
+                "03" -> DtlStatus.PARTIAL_REFUND
+                "04" -> DtlStatus.REFUND
+                else -> DtlStatus.FAIL
+            }
+        }
+    }
+
 }
\ 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 d539a41..16ceadb 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
@@ -59,6 +59,9 @@
     @Autowired
     private lateinit var qrCodeService: QRCodeService
 
+    @Autowired
+    private lateinit var ynrccNetPayBusinessService: YnrccNetPayBusinessService
+
     /**
      * ============================================================================
      * 消费流水结果查询统一接口
@@ -844,15 +847,55 @@
      * ============================================================================
      * */
     @PostMapping("/ynrccpay/order")
-    fun ynrccPayOrder(@Valid @RequestBody param: YnrccPayOrderParam): ResponseEntity<Any>{
-        val success=true
-        if(success){
+    fun ynrccPayOrder(@Valid @RequestBody param: YnrccPayOrderParam): ResponseEntity<Any> {
+        val userSign = ynrccNetPayBusinessService.queryUserYnrccPaySign(param.bankcardno, param.shopaccno)
+        val person = userService.findOnePersonByUserid(param.userid)
+        if (person.userid != userSign.userid) {
             return ResponseEntity.ok(ResponseBodyBuilder.create()
-                    .success(YnrccPayOrderResponse(), "交易初始化成功"))
+                    .fail(TradeErrorCode.INPUT_DATA_ERROR, "银行卡持有人错误!"))
+        } else if (!userSign.isSignFlag || StringUtil.isEmpty(userSign.customerSignNo)) {
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "用户未签约农商行网关快捷支付!"))
+        }
+        val dtlType = consumePayService.getDtltypeDictionary(param.dtltype, Dictionary.DTLTYPES)
+        if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_YNRCC_PAY)) {
+            val account = accountUtilServcie.readAccount(person.userid)
+            val shopacc = accountUtilServcie.readShopbyShopaccno(param.shopaccno)
+            val subject = accountUtilServcie.readSubject(Subject.SUBJNO_YNRCC_NETPAY)
+            val transaction = TransactionBuilder().apply {
+                setTransInfo(param.transdate, param.transtime,
+                        TradeCode.TRANSCODE_YNRCC_NETPAY,
+                        TradeDict.PAYTYPE_YNRCC_PAY)
+                setOutTransInfo(shopacc.shopaccno, param.billno)
+                operator(param.shopaccno, TradeDict.OPERTYPE_SHOP)
+                payinfo = userSign.customerSignNo //存放签约协议号
+                description = dtlType.dictcaption
+                dtltype = param.dtltype
+            }.person(account).apply {
+                setAmount(param.amount / 100.0, TradeDict.TRADE_FLAG_OUT)
+                setOpposite(AccountProxy(shopacc))
+            }.and().shop(shopacc).apply {
+                setAmount(param.amount / 100.0, TradeDict.TRADE_FLAG_IN)
+                setOpposite(AccountProxy(account))
+            }.and().addDebitCreditRecord(AccountProxy(subject), AccountProxy(account),
+                    param.amount / 100.0, dtlType.dictcaption)
+                    .addDebitCreditRecord(AccountProxy(account), AccountProxy(shopacc),
+                            param.amount / 100.0, dtlType.dictcaption)
+                    .also {
+//                        param.feelist?.also {
+//                            TODO("feelist 费用清单暂无!")
+//                        }
+                    }.init(transactionService)
+
+            //创建初始化流水后,返回客户端sdk需要的支付参数
+            val resp = ynrccNetPayBusinessService.doYnrccPayInit(transaction, userSign)
+
+            return ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .success(resp, "交易初始化成功"))
         }
 
         return ResponseEntity.ok(ResponseBodyBuilder.create()
-                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
+                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<农商行网关快捷支付>"))
     }
 
     /**
@@ -862,15 +905,27 @@
      * */
     @PostMapping("/ynrccpay/confirm")
     fun ynrccPayConfirm(@Valid @RequestBody param: YnrccPayConfirmParam): ResponseEntity<Any> {
-        val success=true
-        if(success){
-            return ResponseEntity.ok(ResponseBodyBuilder.create()
-                    .success(YnrccPayConfirmResponse(), "交易初始化成功"))
+        val dtl = transactionService.wip(param.refno)
+        val resp = ynrccNetPayBusinessService.doYnrccPayConfirm(dtl, param.plain, param.signature)
+        val ret = YnrccPayConfirmResponse(dtl.refno,dtl.outTradeNo,dtl.shopDtl.amount,resp.params)
+        when (resp.code) {
+            AgentCode.SUCCESS ->
+                transactionService.success(dtl.refno, resp.agentRefno, false).let {
+                    return ResponseEntity.ok(ResponseBodyBuilder.create()
+                            .success(ret, "交易确认成功"))
+                }
+            AgentCode.REQUIRE_QUERY -> {
+                //去查询
+                agentQueryResultTask.queryResult(dtl, 0)
+                return ResponseEntity.ok(ResponseBodyBuilder.create()
+                        .fail(ret, TradeErrorCode.WAIT_QUERY_RESULT, "请查询支付结果"))
+            }
+            else -> //失败
+                transactionService.fail(param.refno, resp.agentMsg).let {
+                    return ResponseEntity.ok(ResponseBodyBuilder.create()
+                            .fail(ret, TradeErrorCode.BUSINESS_DEAL_ERROR, "交易扣费失败-${resp.agentMsg}"))
+                }
         }
-
-        return ResponseEntity.ok(ResponseBodyBuilder.create()
-                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
-
     }
 
     /**
@@ -879,16 +934,53 @@
      * ============================================================================
      * */
     @PostMapping("/ynrccpay/refund")
-    fun ynrccPayRefund(@Valid @RequestBody param:YnrccPayRefundParam): ResponseEntity<Any>{
-        val success=true
-        if(success){
-            return ResponseEntity.ok(ResponseBodyBuilder.create()
-                    .success(YnrccPayRefundResponse(), "交易初始化成功"))
-        }
+    fun ynrccPayRefund(@Valid @RequestBody param: YnrccPayRefundParam): ResponseEntity<Any> {
+        consumePayService.getTransactionMainDtl(param.refno, param.billno, param.shopaccno)?.let { mainDtl ->
+            if (mainDtl.sourceType.isNotEmpty()) {
+                //判断能否冲正
+                if (mainDtl.shop) {
+                    consumePayService.checkCanReverse(mainDtl.sourceType, mainDtl.shopDtl.shopaccno)
+                } else {
+                    consumePayService.checkCanReverse(mainDtl.sourceType)
+                }
+            } else {
+                throw TransactionCheckException(TradeErrorCode.TRANSDTL_STATUS_ERROR,
+                        "该笔交易未定义sourcetype, 不支持退款")
+            }
 
-        return ResponseEntity.ok(ResponseBodyBuilder.create()
-                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
+            val builder = TransactionBuilder().apply {
+                setTransInfo(param.transdate, param.transtime, mainDtl.transCode, mainDtl.sourceType)
+                setOutTransInfo(mainDtl.outId, param.requestbillno)
+            }
+            val refundTrans = builder.refundInit(mainDtl.refno, param.refundAmount / 100.0, transactionService)
 
+            transactionService.wip(refundTrans.refno)
+            val service = createAgentService<Any>(mainDtl.sourceType)
+            val resp = service.refund(refundTrans)
+            when (resp.code) {
+                AgentCode.SUCCESS -> {
+                    transactionService.success(refundTrans.refno, resp.agentRefno, false)
+
+                    return ResponseEntity.ok(ResponseBodyBuilder.create()
+                            .success(YnrccPayRefundResponse(refundTrans.refno), "交易退款成功"))
+                }
+                AgentCode.REQUIRE_QUERY -> {
+                    //待查询
+                    agentQueryResultTask.queryResult(refundTrans, 0)
+                    return ResponseEntity.ok(ResponseBodyBuilder.create()
+                            .fail(YnrccPayRefundResponse(refundTrans.refno),
+                                    TradeErrorCode.WAIT_QUERY_RESULT, "请查询退款结果"))
+                }
+                else -> transactionService.fail(refundTrans.refno,
+                        "${resp.agentCode}-${resp.agentMsg}").let {
+                    return ResponseEntity.ok(ResponseBodyBuilder.create()
+                            .fail(YnrccPayRefundResponse(refundTrans.refno),
+                                    TradeErrorCode.BUSINESS_DEAL_ERROR, "退款失败!${resp.agentMsg}"))
+                }
+            }
+
+        } ?: return ResponseEntity.ok(ResponseBodyBuilder.create()
+                .fail(TradeErrorCode.TRANSACTION_NOT_EXISTS, "流水不存在"))
     }
 
 }
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 ec9624c..1c6750c 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
@@ -2,12 +2,10 @@
 
 import com.supwisdom.dlpay.agent.citizencard.YnrccUtil
 import com.supwisdom.dlpay.agent.service.CitizencardPayService
+import com.supwisdom.dlpay.agent.service.YnrccNetPayService
 import com.supwisdom.dlpay.api.bean.*
 import com.supwisdom.dlpay.api.exception.RequestParamCheckException
-import com.supwisdom.dlpay.api.service.CardService
-import com.supwisdom.dlpay.api.service.KafkaSendMsgService
-import com.supwisdom.dlpay.api.service.QRCodeService
-import com.supwisdom.dlpay.api.service.UserService
+import com.supwisdom.dlpay.api.service.*
 import com.supwisdom.dlpay.exception.TransactionException
 import com.supwisdom.dlpay.framework.ResponseBodyBuilder
 import com.supwisdom.dlpay.framework.util.TradeDict
@@ -41,8 +39,8 @@
     private lateinit var citizencardPayService: CitizencardPayService
     @Autowired
     private lateinit var qrcodeService: QRCodeService
-
-
+    @Autowired
+    private lateinit var ynrccNetPayBusinessService: YnrccNetPayBusinessService
 
     @PostMapping("/open")
     fun openAccount(@RequestBody param: OpenUserParam): ResponseEntity<Any> {
@@ -455,15 +453,9 @@
      * */
     @PostMapping("/ynrccpaySignQuery")
     fun queryYnrccPaySign(@Valid @RequestBody param: YnrccPaySignQueryParam): ResponseEntity<Any> {
-        val success=true
-        if(success){
-            return ResponseEntity.ok(ResponseBodyBuilder.create()
-                    .success(YnrccPaySignQueryResponse(), "交易初始化成功"))
-        }
-
+        val signFlag = ynrccNetPayBusinessService.checkUserYnrccPaySignStatus(param.userid,param.bankcardno,param.shopaccno)
         return ResponseEntity.ok(ResponseBodyBuilder.create()
-                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
-
+                .success(YnrccPaySignQueryResponse(signFlag), "查询成功"))
     }
 
     /**
@@ -473,15 +465,9 @@
      * */
     @PostMapping("/ynrccpaySignApply")
     fun applyYnrccPaySign(@Valid @RequestBody param: YnrccPaySignApplyParam): ResponseEntity<Any> {
-        val success=true
-        if(success){
-            return ResponseEntity.ok(ResponseBodyBuilder.create()
-                    .success(YnrccPaySignApplyResponse(), "交易初始化成功"))
-        }
-
+        val resp = ynrccNetPayBusinessService.applyUserYnrccPaySign(param)
         return ResponseEntity.ok(ResponseBodyBuilder.create()
-                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
-
+                .success(resp, "success"))
     }
 
     /**
@@ -490,16 +476,15 @@
      * ============================================================================
      * */
     @PostMapping("/ynrccpaySignConfirm")
-    fun confirmYnrccPaySign(@Valid @RequestBody param:YnrccPaySignConfirmParam): ResponseEntity<Any>{
-        val success=true
-        if(success){
-            return ResponseEntity.ok(ResponseBodyBuilder.create()
-                    .success(YnrccPaySignConfirmResponse(), "交易初始化成功"))
+    fun confirmYnrccPaySign(@Valid @RequestBody param: YnrccPaySignConfirmParam): ResponseEntity<Any> {
+        val resp = ynrccNetPayBusinessService.confirmUserYnrccPaySign(param)
+        return if (0 == resp.retcode) {
+            ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .success(resp, "success"))
+        } else {
+            ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .fail(resp.retcode, resp.retmsg))
         }
-
-        return ResponseEntity.ok(ResponseBodyBuilder.create()
-                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
-
     }
 
     /**
@@ -509,15 +494,14 @@
      * */
     @PostMapping("/ynrccpaySignCancel")
     fun cancelYnrccPaySign(@Valid @RequestBody param:YnrccPaySignCancelParam):ResponseEntity<Any>{
-        val success=true
-        if(success){
-            return ResponseEntity.ok(ResponseBodyBuilder.create()
-                    .success(YnrccPaySignCancelResponse(), "交易初始化成功"))
+        val resp = ynrccNetPayBusinessService.cancelUserYnrccPaySign(param)
+        return if (0 == resp.retcode) {
+            ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .success(resp, "success"))
+        } else {
+            ResponseEntity.ok(ResponseBodyBuilder.create()
+                    .fail(resp.retcode, resp.retmsg))
         }
-
-        return ResponseEntity.ok(ResponseBodyBuilder.create()
-                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
-
     }
 
     /**
@@ -527,14 +511,14 @@
      * */
     @PostMapping("/ynrccpayModifyLimit")
     fun modifyYnrccPayLimit(@Valid @RequestBody param:YnrccPayLimitModifyParam):ResponseEntity<Any>{
-        val success=true
+        val success=false
         if(success){
             return ResponseEntity.ok(ResponseBodyBuilder.create()
-                    .success(YnrccPayLimitModifyResponse(), "交易初始化成功"))
+                    .success(YnrccPayLimitModifyResponse(), "success"))
         }
 
         return ResponseEntity.ok(ResponseBodyBuilder.create()
-                .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
+                .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "暂无业务逻辑"))
 
     }
 }
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/ynrcc_netpay_business_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/ynrcc_netpay_business_service.kt
new file mode 100644
index 0000000..da4e581
--- /dev/null
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/ynrcc_netpay_business_service.kt
@@ -0,0 +1,256 @@
+package com.supwisdom.dlpay.api.service.impl
+
+import com.supwisdom.dlpay.agent.AgentCode
+import com.supwisdom.dlpay.agent.AgentResponse
+import com.supwisdom.dlpay.agent.DtlStatus
+import com.supwisdom.dlpay.agent.citizencard.YnrccRespCode
+import com.supwisdom.dlpay.agent.service.YnrccNetPayService
+import com.supwisdom.dlpay.agent.ynrccpay.YnrccPayUtil
+import com.supwisdom.dlpay.api.bean.*
+import com.supwisdom.dlpay.api.dao.CardDao
+import com.supwisdom.dlpay.api.dao.PersonDao
+import com.supwisdom.dlpay.api.dao.TransactionMainDao
+import com.supwisdom.dlpay.api.domain.TTransactionMain
+import com.supwisdom.dlpay.api.exception.RequestParamCheckException
+import com.supwisdom.dlpay.api.service.SourceTypeService
+import com.supwisdom.dlpay.api.service.TransactionService
+import com.supwisdom.dlpay.api.service.YnrccNetPayBusinessService
+import com.supwisdom.dlpay.api.types.IDTypes
+import com.supwisdom.dlpay.citizencard.dao.YnrccPaySignDao
+import com.supwisdom.dlpay.citizencard.domain.TYnrccPaySign
+import com.supwisdom.dlpay.exception.TransactionProcessException
+import com.supwisdom.dlpay.framework.dao.ShopaccDao
+import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.dlpay.framework.util.MoneyUtil
+import com.supwisdom.dlpay.framework.util.StringUtil
+import com.supwisdom.dlpay.framework.util.TradeDict
+import com.supwisdom.dlpay.framework.util.TradeErrorCode
+import com.supwisdom.dlpay.util.ConstantUtil
+import mu.KotlinLogging
+import org.springframework.stereotype.Service
+
+@Service
+class YnrccNetPayBusinessServiceImpl(val personDao: PersonDao,
+                                     val shopaccDao: ShopaccDao,
+                                     val ynrccPaySignDao: YnrccPaySignDao,
+                                     val cardDao: CardDao,
+                                     val transactionMainDao: TransactionMainDao,
+                                     val transactionService: TransactionService,
+                                     val systemUtilService: SystemUtilService,
+                                     val sourceTypeService: SourceTypeService,
+                                     val ynrccNetPayService: YnrccNetPayService) : YnrccNetPayBusinessService {
+    private val logger = KotlinLogging.logger { }
+
+    override fun checkUserYnrccPaySignStatus(userid: String, bankcardno: String, shopaccno: String): Boolean {
+        val person = personDao.findByUserid(userid)
+                ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "用户<$userid>不存在")
+        val shopacc = shopaccDao.findByShopaccno(shopaccno)
+                ?: throw TransactionProcessException(TradeErrorCode.SHOP_NOT_EXISTS, "商户<$shopaccno>不存在")
+        if (sourceTypeService.checkShopSourceType(shopacc.shopaccno, TradeDict.PAYTYPE_YNRCC_PAY, false)) {
+            val paySign = ynrccPaySignDao.getUserSign(bankcardno, shopacc.shopaccno)
+            if (null != paySign) {
+                if (person.userid != paySign.userid) {
+                    throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "银行卡持有人错误!")
+                }
+
+                return paySign.isSignFlag
+            }
+        }
+        return false
+    }
+
+    override fun applyUserYnrccPaySign(param: YnrccPaySignApplyParam): YnrccPaySignApplyResponse {
+        val person = personDao.findByUserid(param.userid)
+                ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "用户<${param.userid}>不存在")
+        val shopacc = shopaccDao.findByShopaccno(param.shopaccno)
+                ?: throw TransactionProcessException(TradeErrorCode.SHOP_NOT_EXISTS, "商户<${param.shopaccno}>不存在")
+        val bankCard = cardDao.findCardByCardnoAndCardtype(param.bankcardno.trim(), ConstantUtil.CARDTYPE_BANKCARD)
+        if (null != bankCard && person.userid != bankCard.userid) {
+            throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "银行卡持有人错误!")
+        }
+        val idType = IDTypes.findByValue(person.idtype)
+        if (idType < 0) {
+            throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "证件类型未识别[${person.idtype}]!")
+        }
+        sourceTypeService.checkShopSourceType(shopacc.shopaccno, TradeDict.PAYTYPE_YNRCC_PAY, false)
+
+        val isAuthSign = ynrccPaySignDao.countByBankcardnoAndSignStatus(param.bankcardno, shopacc.shopaccno) > 0
+        var userSign = ynrccPaySignDao.getUserSign(param.bankcardno, shopacc.shopaccno) ?: TYnrccPaySign().apply {
+            this.bankcardno = param.bankcardno.trim()
+            this.bankcardno = shopacc.shopaccno
+            this.userid = person.userid
+            this.status = TradeDict.STATUS_NORMAL
+            this.isSignFlag = false
+            this.createtime = systemUtilService.sysdatetime.hostdatetime
+        }
+        if (person.userid != userSign.userid) {
+            throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "银行卡持有人不匹配!")
+        } else if (userSign.isSignFlag) {
+            throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "该卡已签约!")
+        }
+        if (StringUtil.isEmpty(userSign.id)) {
+            ynrccPaySignDao.save(userSign) //新创建的保存申请记录
+        }
+
+        val signDataResp = ynrccNetPayService.doApplyYnrccPaySign(shopacc.shopaccno)
+        if (YnrccPayUtil.SUCCESS != signDataResp.code) {
+            throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, signDataResp.message)
+        }
+
+        val resp = YnrccPaySignApplyResponse()
+        resp.retcode = 0
+        resp.retmsg = "success"
+        resp.signNo = userSign.id
+        resp.isAuthSign = isAuthSign
+        resp.plain = signDataResp.plain
+        resp.signature = signDataResp.signature
+        resp.signUserData = YnrccPaySignUserData().apply {
+            this.name = person.name
+            this.idType = idType.toString()
+            this.idNo = person.idno
+            this.acNo = userSign.bankcardno
+        }
+        logger.info("申请签约返回:" + YnrccPayUtil.toJson(resp))
+        return resp
+    }
+
+    override fun confirmUserYnrccPaySign(param: YnrccPaySignConfirmParam): YnrccPaySignConfirmResponse {
+        val userSign = ynrccPaySignDao.getById(param.signNo.toString())
+                ?: throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "签约申请记录<${param.signNo}>不存在!")
+
+        val data = ynrccNetPayService.doAnalysisSignature(userSign.shopaccno, param.plain, param.signature)
+        logger.info("签约确认:" + YnrccPayUtil.toJson(data))
+        val respCode = data["RespCode"]
+        if (YnrccPayUtil.SUCCESS != respCode) {
+            val errmsg = YnrccPayUtil.errcode.firstOrNull {
+                it.second.code == respCode
+            }?.second?.msg
+            throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "$respCode $errmsg")
+        }
+
+        //签约成功
+        if (data["CustomerAcNo"] != userSign.bankcardno) {
+            throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "支付账号与签约号不匹配!")
+        } else if (userSign.isSignFlag && data["CustomerSignNo"] != userSign.customerSignNo) {
+            throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "用户已签约且快捷支付协议号不一致!")
+        }
+
+        if (!userSign.isSignFlag) {
+            userSign.isSignFlag = true
+            userSign.customerSignNo = data["CustomerSignNo"]?.trim()
+            userSign.signTime = systemUtilService.sysdatetime.hostdatetime
+            ynrccPaySignDao.save(userSign)
+        }
+
+        return YnrccPaySignConfirmResponse().apply {
+            this.retcode = 0
+            this.retmsg = "success"
+            this.signNo = userSign.id
+            this.data = data
+        }
+    }
+
+    override fun cancelUserYnrccPaySign(param: YnrccPaySignCancelParam): YnrccPaySignCancelResponse {
+        val userSign = ynrccPaySignDao.getUserSign(param.bankcardno.trim(), param.shopaccno)
+                ?: throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "签约记录不存在或已解约!")
+        if (userSign.userid != param.userid) {
+            throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "持卡人错误!")
+        } else if (!userSign.isSignFlag) {
+            throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "该卡还未签约,不能解约!")
+        }
+
+        val resp = YnrccPaySignCancelResponse()
+        val cancelResp = ynrccNetPayService.doCancelYnrccPaySign(userSign.shopaccno, userSign.customerSignNo)
+        if (YnrccPayUtil.SUCCESS == cancelResp.code) {
+            //解约成功
+            userSign.status = TradeDict.STATUS_CLOSED
+            userSign.isSignFlag = false
+            userSign.cancelTime = systemUtilService.sysdatetime.hostdatetime
+            ynrccPaySignDao.save(userSign)
+
+            resp.retcode = 0
+            resp.retmsg = "success"
+            resp.signNo = userSign.id
+            return resp
+        }
+
+        resp.retcode = 99
+        resp.retmsg = cancelResp.message
+        return resp
+    }
+
+    override fun queryUserYnrccPaySign(bankcardno: String, shopaccno: String): TYnrccPaySign {
+        return ynrccPaySignDao.getUserSign(bankcardno.trim(), shopaccno.trim())
+                ?: throw RequestParamCheckException("银行卡签约记录不存在!")
+    }
+
+    override fun doYnrccPayInit(transdtl: TTransactionMain, userSign: TYnrccPaySign): YnrccPayOrderResponse {
+        if (StringUtil.isEmpty(transdtl.refno) || null == transdtl.shopDtl || null == transdtl.shopDtl.amount) {
+            throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "流水初始化错误!")
+        } else if (TradeDict.DTL_STATUS_SUCCESS == transdtl.status) {
+            throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "非初始化交易流水!")
+        } else if (TradeDict.PAYTYPE_YNRCC_PAY != transdtl.sourceType || transdtl.shopDtl.shopaccno != userSign.shopaccno || transdtl.shopDtl.payInfo != userSign.customerSignNo) {
+            throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "交易流水与签约信息不符!")
+        }
+
+        val refno = transdtl.refno
+        val shopaccno = transdtl.shopDtl.shopaccno
+        val amount = MoneyUtil.YuanToFen(transdtl.shopDtl.amount)
+        val transDateTime = "${transdtl.shopDtl.transdate}${transdtl.shopDtl.transtime}"
+        val billno = transdtl.outTradeNo //billno放附加信息
+        val productInfo = "农商行网关快捷支付[${transdtl.shopDtl.transdesc}]"; //商品描述
+        val person = personDao.findByUserid(userSign.userid)
+                ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "用户不存在!")
+        val orderResp = ynrccNetPayService.doYnrccPayInit(shopaccno, refno, amount, transDateTime,
+                productInfo, billno, person.name, person.email, userSign.customerSignNo)
+
+        if (YnrccPayUtil.SUCCESS != orderResp.code) {
+            throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, orderResp.message)
+        }
+
+        val resp = YnrccPayOrderResponse()
+        resp.retcode = 0
+        resp.retmsg = "success"
+        resp.refno = refno
+        resp.billno = billno
+        resp.amount = transdtl.shopDtl.amount
+        resp.plain = orderResp.plain
+        resp.signature = orderResp.signature
+
+        logger.info("下单返回:" + YnrccPayUtil.toJson(resp))
+        return resp
+    }
+
+    override fun doYnrccPayConfirm(transaction: TTransactionMain, plain: String, signature: String): AgentResponse<DtlStatus> {
+        if (TradeDict.DTL_STATUS_SUCCESS == transaction.status) {
+            throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "流水已入账!")
+        }
+
+        val data = ynrccNetPayService.doAnalysisSignature(transaction.shopDtl.shopaccno, plain, signature)
+        logger.info("支付确认:" + YnrccPayUtil.toJson(data))
+        val respCode = data["RespCode"]?.trim()
+        val orderNo = data["OrderNo"]?.trim()
+        val payAmt = data["Amount"]?.trim()
+        val tradeNo = data["TransSeqNo"]?.trim()
+        if (transaction.refno != orderNo) {
+            throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "流水号错误,非此笔流水的确认信息!")
+        } else if (transaction.shopDtl.amount != payAmt?.toDouble()) {
+            throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "支付金额与流水交易金额不匹配!")
+        }
+
+        val agentCode = YnrccPayUtil.errcode.firstOrNull{
+            it.second.code == respCode
+        }?: org.springframework.data.util.Pair.of(AgentCode.COMMON_ERROR,
+                YnrccRespCode(respCode,  "未知错误[$respCode]"))
+
+        return AgentResponse<DtlStatus>().also {
+            it.code = agentCode.first
+            it.agentCode = agentCode.second.code
+            it.agentMsg = agentCode.first.message() + "-" + agentCode.second.msg
+            it.agentRefno = tradeNo
+            it.params = data
+        }
+    }
+
+
+}
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/ynrcc_netpay_business_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/ynrcc_netpay_business_service.kt
new file mode 100644
index 0000000..ad3527c
--- /dev/null
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/ynrcc_netpay_business_service.kt
@@ -0,0 +1,31 @@
+package com.supwisdom.dlpay.api.service
+
+import com.supwisdom.dlpay.agent.AgentResponse
+import com.supwisdom.dlpay.agent.DtlStatus
+import com.supwisdom.dlpay.api.bean.*
+import com.supwisdom.dlpay.api.domain.TTransactionMain
+import com.supwisdom.dlpay.citizencard.domain.TYnrccPaySign
+import org.springframework.transaction.annotation.Transactional
+
+interface YnrccNetPayBusinessService {
+    @Transactional(rollbackFor = [Exception::class], readOnly = true)
+    fun checkUserYnrccPaySignStatus(userid: String, bankcardno: String, shopaccno: String): Boolean
+
+    @Transactional(rollbackFor = [Exception::class])
+    fun applyUserYnrccPaySign(param: YnrccPaySignApplyParam): YnrccPaySignApplyResponse
+
+    @Transactional(rollbackFor = [Exception::class])
+    fun confirmUserYnrccPaySign(param: YnrccPaySignConfirmParam): YnrccPaySignConfirmResponse
+
+    @Transactional(rollbackFor = [Exception::class])
+    fun cancelUserYnrccPaySign(param: YnrccPaySignCancelParam): YnrccPaySignCancelResponse
+
+    @Transactional(rollbackFor = [Exception::class], readOnly = true)
+    fun queryUserYnrccPaySign(bankcardno: String, shopaccno: String): TYnrccPaySign
+
+    @Transactional(rollbackFor = [Exception::class], readOnly = true)
+    fun doYnrccPayInit(transdtl: TTransactionMain, userSign: TYnrccPaySign): YnrccPayOrderResponse
+
+    @Transactional(rollbackFor = [Exception::class])
+    fun doYnrccPayConfirm(transaction: TTransactionMain, plain: String, signature: String): AgentResponse<DtlStatus>
+}
\ No newline at end of file
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 b80d573..a55845f 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,11 +1,8 @@
 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
@@ -15,13 +12,9 @@
 @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/resources/payment_merchant.properties b/payapi/src/main/resources/payment_merchant.properties
index b2f94dc..f07cdea 100644
--- a/payapi/src/main/resources/payment_merchant.properties
+++ b/payapi/src/main/resources/payment_merchant.properties
@@ -6,6 +6,6 @@
 # \u7528\u4E8E\u5546\u6237\u7B7E\u540D\u7684\u79D8\u94A5\u522B\u540D
 key_alias=merchant_key
 # \u79D8\u94A5\u5BC6\u7801
-key_password=111111
+key_password=881220
 # \u9A8C\u7B7E\u79D8\u94A5\u522B\u540D
 alias_paygate=alias_paygate
\ No newline at end of file