大理新接口实现初版
authorkaixiang.xia <kaixiang.xia@supwisdom.com>
Tue, 2 Feb 2021 07:50:14 +0000 (15:50 +0800)
committerkaixiang.xia <kaixiang.xia@supwisdom.com>
Tue, 2 Feb 2021 07:50:14 +0000 (15:50 +0800)
20 files changed:
payapi/build.gradle
payapi/libs/ynrcc-mbp-1.0-RELEASE.jar [deleted file]
payapi/libs/ynrcc-mbp-1.1-RELEASE.jar [new file with mode: 0644]
payapi/sql/update-210106.sql
payapi/src/main/java/com/supwisdom/dlpay/agent/AgentResponse.java
payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayCommonResp.java [new file with mode: 0644]
payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayResp.java [new file with mode: 0644]
payapi/src/main/java/com/supwisdom/dlpay/agent/ynrccpay/YnrccPayUtil.java
payapi/src/main/java/com/supwisdom/dlpay/citizencard/dao/YnrccPaySignDao.java [new file with mode: 0644]
payapi/src/main/java/com/supwisdom/dlpay/framework/util/Subject.java
payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java
payapi/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/impl/ynrcc_netpay_service_impl.kt
payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/ynrcc_netpay_service.kt
payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/user_api_controller.kt
payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/ynrcc_netpay_business_service.kt [new file with mode: 0644]
payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/ynrcc_netpay_business_service.kt [new file with mode: 0644]
payapi/src/main/kotlin/com/supwisdom/dlpay/framework/controller/framework_controller.kt
payapi/src/main/resources/payment_merchant.properties

index ce57fe2..2fe80c4 100644 (file)
@@ -115,7 +115,7 @@ dependencies {
 //    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 (file)
index 0a481dd..0000000
Binary files a/payapi/libs/ynrcc-mbp-1.0-RELEASE.jar and /dev/null 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 (file)
index 0000000..34da472
Binary files /dev/null and b/payapi/libs/ynrcc-mbp-1.1-RELEASE.jar differ
index acf987c..803b182 100644 (file)
@@ -8,3 +8,25 @@ INSERT INTO "tb_subject" ("subjid","subjno", "balflag", "displayflag", "endflag"
 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;
index 149c3ae..caa0ce4 100644 (file)
@@ -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 @@ public class AgentResponse<T> {
   private DtlStatus dtlStatus;
 
   private T payload;
+  private Map<String,String> params;
 
   public String getAgentBody() {
     return agentBody;
@@ -70,6 +73,14 @@ public class AgentResponse<T> {
     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 (file)
index 0000000..8c9f27d
--- /dev/null
@@ -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 (file)
index 0000000..71f9200
--- /dev/null
@@ -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;
+  }
+}
index 17959f3..d0a3474 100644 (file)
@@ -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
-
-    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 SUCCESS = "ZF0000";
+  public static final String WAIT_FOR_QUERY = "ZF0098"; //等待查询结果
 
 
-  /**
-   * 接口名称
-   * */
-  public static final String TRANSNAME_IQSR="QueryMerchantEpay.do";
+  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 IQSR="IQSR";
+  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", "平台已冻结或已注销")));
 
+    //自定义错误 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 (file)
index 0000000..d8b0949
--- /dev/null
@@ -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);
+}
index e80344a..21602c4 100644 (file)
@@ -78,6 +78,11 @@ public class Subject {
    */
   public static final String SUBJNO_PAY_CITIZEN_CARD = "112234";
 
+  /**
+   * 应收账款 - 农商行网关快捷支付
+   */
+  public static final String SUBJNO_YNRCC_NETPAY = "112235";
+
 
   //======================= 负债类 =====================//
 
index b78049f..29f3921 100644 (file)
@@ -13,6 +13,8 @@ public class TradeCode {
 
   public static final int TRANSCODE_ALIPAY = 3040;//支付宝支付
 
+  public static final int TRANSCODE_YNRCC_NETPAY = 3050;//农商行网关快捷支付
+
   // QRcode 聚合支付
   public static final int TRANSCODE_QRCODE = 1002;
 
index 161b1c7..ae9aafe 100644 (file)
@@ -81,6 +81,7 @@ public class TradeDict {
   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内支付
index 2d94e30..3c1c7e7 100644 (file)
@@ -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 @@ import java.nio.charset.StandardCharsets
 @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)
+
+        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 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 {
+            return error("ZE0099","请求农商行网关【$opt】失败!http status=[${result.statusCodeValue}]")
+        }
     }
 
-    override fun doYnrccPaySign() {
+    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["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}")
+        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 {
-            //fail
-            println("return status=${resp.statusCodeValue},json=${resp.body}")
+            logger.error(resp.error())
         }
+        return resp
     }
+
 }
\ No newline at end of file
index e6ab5fb..f2e5bdc 100644 (file)
@@ -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
index d539a41..16ceadb 100644 (file)
@@ -59,6 +59,9 @@ class ConsumeAPIController {
     @Autowired
     private lateinit var qrCodeService: QRCodeService
 
+    @Autowired
+    private lateinit var ynrccNetPayBusinessService: YnrccNetPayBusinessService
+
     /**
      * ============================================================================
      * 消费流水结果查询统一接口
@@ -844,15 +847,55 @@ class ConsumeAPIController {
      * ============================================================================
      * */
     @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()
+                    .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(YnrccPayOrderResponse(), "交易初始化成功"))
+                    .success(resp, "交易初始化成功"))
Content-type: text/html Supwisdom Source - epayment/food_payapi.git/commitdiff


500 - Internal Server Error

Unknown encoding 'gb18030' at /usr/local/share/gitweb/gitweb.cgi line 1539