API请求Sign计算优化
diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TPaytype.java b/src/main/java/com/supwisdom/dlpay/api/domain/TPaytype.java
index 5872560..be80103 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TPaytype.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TPaytype.java
@@ -21,6 +21,9 @@
@Column(name = "CONSUME_ENABLE",nullable = false, length = 10)
private String consumeEnable;
+ @Column(name = "ANONYMOUS_ENABLE", nullable = false, length = 10)
+ private String anonymousEnable;
+
@Column(name = "PAYDESC", length = 200)
private String paydesc;
@@ -56,6 +59,14 @@
this.consumeEnable = consumeEnable;
}
+ public String getAnonymousEnable() {
+ return anonymousEnable;
+ }
+
+ public void setAnonymousEnable(String anonymousEnable) {
+ this.anonymousEnable = anonymousEnable;
+ }
+
public String getPaydesc() {
return paydesc;
}
diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TShopPaytype.java b/src/main/java/com/supwisdom/dlpay/api/domain/TShopPaytype.java
index 81c893c..cb4662e 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TShopPaytype.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TShopPaytype.java
@@ -17,6 +17,9 @@
@Column(name = "CONSUME_ENABLE", nullable = false, length = 10)
private String consumeEnable;
+ @Column(name = "ANONYMOUS_ENABLE", nullable = false, length = 10)
+ private String anonymousEnable;
+
@Column(name = "REVERSE_ENABLE", nullable = false, length = 10)
private String reverseEnable;
@@ -47,6 +50,14 @@
this.consumeEnable = consumeEnable;
}
+ public String getAnonymousEnable() {
+ return anonymousEnable;
+ }
+
+ public void setAnonymousEnable(String anonymousEnable) {
+ this.anonymousEnable = anonymousEnable;
+ }
+
public String getReverseEnable() {
return reverseEnable;
}
diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TUserdtl.java b/src/main/java/com/supwisdom/dlpay/api/domain/TUserdtl.java
index fc89e32..aa195a7 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TUserdtl.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TUserdtl.java
@@ -7,7 +7,8 @@
indexes = {@Index(name = "userdtl_transdate_idx", columnList = "transdate"),
@Index(name = "userdtl_accdate_idx", columnList = "accdate"),
@Index(name = "userdtl_status_idx", columnList = "status"),
- @Index(name = "userdtl_reverse_idx", columnList = "REVERSE_FLAG")})
+ @Index(name = "userdtl_reverse_idx", columnList = "REVERSE_FLAG"),
+ @Index(name = "userdtl_outtradeno_uk", unique = true, columnList = "outtradeno,shopaccno")})
public class TUserdtl {
@Id
@Column(name = "REFNO", nullable = false, length = 32)
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/APIRequest.java b/src/main/java/com/supwisdom/dlpay/framework/util/APIRequest.java
deleted file mode 100644
index 6679181..0000000
--- a/src/main/java/com/supwisdom/dlpay/framework/util/APIRequest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.supwisdom.dlpay.framework.util;
-
-public class APIRequest {
- private String app_id;
- private String sign;
- private String sign_method;
- private String timestamp;
-
- public String getApp_id() {
- return app_id;
- }
-
- public void setApp_id(String app_id) {
- this.app_id = app_id;
- }
-
- public String getSign() {
- return sign;
- }
-
- public void setSign(String sign) {
- this.sign = sign;
- }
-
- public String getSign_method() {
- return sign_method;
- }
-
- public void setSign_method(String sign_method) {
- this.sign_method = sign_method;
- }
-
- public String getTimestamp() {
- return timestamp;
- }
-
- public void setTimestamp(String timestamp) {
- this.timestamp = timestamp;
- }
-
-}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/APIRequestParam.java b/src/main/java/com/supwisdom/dlpay/framework/util/APIRequestParam.java
new file mode 100644
index 0000000..78ea9d4
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/APIRequestParam.java
@@ -0,0 +1,99 @@
+package com.supwisdom.dlpay.framework.util;
+
+import org.apache.log4j.Logger;
+
+import java.beans.Introspector;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+public class APIRequestParam {
+ @Sign
+ private String sign;
+ @Sign
+ private String sign_type;
+ @Sign
+ private String version;
+
+ private static final Logger logger = Logger.getLogger(APIRequestParam.class);
+
+ public String getSign() {
+ return sign;
+ }
+
+ public void setSign(String sign) {
+ this.sign = sign;
+ }
+
+ public String getSign_type() {
+ return sign_type;
+ }
+
+ public void setSign_type(String sign_type) {
+ this.sign_type = sign_type;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ private boolean calcSignAndCheck(Map<String, String> map, String key) {
+ String sign = map.get("sign");
+ String signType = map.get("sign_type") == null ? "MD5" : map.get("sign_type");
+ if (StringUtil.isEmpty(sign)) return false;
+
+ String signdata = StringUtil.createLinkString(StringUtil.paraFilter(map));
+ logger.info("signdata=[" + signdata + "]");
+
+ String calcSign = null;
+ //fixme: 根据 signType 计算签名
+ if ("MD5".equalsIgnoreCase(signType)) {
+ calcSign = MD5.encodeByMD5(signdata + key); //默认MD5
+ }
+
+ if (sign.equalsIgnoreCase(calcSign)) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean checkSign(String key){
+ Class clazz = this.getClass();
+ Map<String, String> paramMap = new HashMap<>();
+ Method[] allGetter = clazz.getMethods();
+
+ for (Method meth : allGetter) {
+ if (meth.getName().startsWith("get") || meth.getName().startsWith("is")) {
+ String fieldName = Introspector.decapitalize(meth.getName().substring(meth.getName().startsWith("get") ? 3 : 2));
+ Field field;
+ try {
+ field = clazz.getDeclaredField(fieldName);
+ } catch (NoSuchFieldException e) {
+ try {
+ field = clazz.getSuperclass().getDeclaredField(fieldName);
+ } catch (NoSuchFieldException e1) {
+// e1.printStackTrace();
+ continue;
+ }
+ }
+
+ if (field.isAnnotationPresent(Sign.class)) {
+ Object value;
+ try {
+ value = meth.invoke(this);
+ } catch (Exception e) {
+ e.printStackTrace();
+ continue;
+ }
+ paramMap.put(fieldName, value == null ? null : value.toString());
+ }
+ }
+ }
+ return calcSignAndCheck(paramMap,key);
+ }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/Sign.java b/src/main/java/com/supwisdom/dlpay/framework/util/Sign.java
new file mode 100644
index 0000000..399da55
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/Sign.java
@@ -0,0 +1,12 @@
+package com.supwisdom.dlpay.framework.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface Sign {
+ int order() default 0;
+}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java b/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
index 2b392b3..7bec421 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
@@ -47,6 +47,7 @@
public static final String PAYTYPE_ALIPAY = "alipay"; //市民卡
public static final String PAYTYPE_WECHAT = "wechat"; //市民卡
public static final String PAYTYPE_CITIZEN_CARD = "citizenCard"; //市民卡
+ public static final String PAYTYPE_YKT_CARD = "yktpay"; //一卡通
/**
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt b/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
index 9087149..414da8e 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
@@ -1,45 +1,31 @@
package com.supwisdom.dlpay.api.bean
import com.supwisdom.dlpay.exception.RequestParamCheckException
-import com.supwisdom.dlpay.framework.util.DateUtil
-import com.supwisdom.dlpay.framework.util.MD5
-import com.supwisdom.dlpay.framework.util.StringUtil
-import com.supwisdom.dlpay.framework.util.TradeErrorCode
+import com.supwisdom.dlpay.framework.util.*
import com.supwisdom.dlpay.util.ConstantUtil
-open class APIRequestParam {
- open val param_map = mutableMapOf<String, String?>()
-
- open fun checkSign(key: String): Boolean {
- val sign = param_map["sign"]
- val signType = param_map["sign_type"] ?: "MD5"
- if (StringUtil.isEmpty(sign)) return false //未签名
-
- //判断签名
- val signdata = StringUtil.createLinkString(StringUtil.paraFilter(param_map))
- val md5Sign = MD5.encodeByMD5(signdata + key) //默认MD5
- if (sign.equals(md5Sign, true)) {
- return true
- }
- return false
- }
-}
-
-
// ============================ USER ============================ //
class OpenUserParam : APIRequestParam() {
+ @Sign
var uid: String = "" //第三方用户ID,必传
+ @Sign
var name: String = "" //必传
+ @Sign
var sex: String? = null
+ @Sign
var idtype: String = "" //必传
+ @Sign
var idno: String = "" //必传
+ @Sign
var mobile: String? = null
+ @Sign
var tel: String? = null
+ @Sign
var email: String? = null
+ @Sign
var address: String? = null
+ @Sign
var zipcode: String? = null
- var sign: String = "" //必传
- var sign_type: String? = null
fun checkParam(): Boolean {
if (StringUtil.isEmpty(uid)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "用户唯一号不能为空")
@@ -51,39 +37,46 @@
if (!StringUtil.isEmpty(mobile) && !StringUtil.isMobile(mobile)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "手机号格式错误")
if (!StringUtil.isEmpty(email) && !StringUtil.isEmail(email)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "邮箱格式错误")
- param_map.plus(mapOf("uid" to uid, "name" to name, "sex" to sex, "idtype" to idtype, "idno" to idno, "mobile" to mobile, "tel" to tel, "email" to email, "address" to address, "zipcode" to zipcode, "sign" to sign, "sign_type" to sign_type))
return true
}
}
class QueryUserParam : APIRequestParam() {
+ @Sign
var userid: String? = null // 用户ID二选一 (两者都传取userid)
+ @Sign
var uid: String? = null // 用户ID二选一
- var sign: String = "" //必传
- var sign_type: String? = null
fun checkParam(): Boolean {
if (StringUtil.isEmpty(userid) && StringUtil.isEmpty(uid)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "用户唯一号不能为空")
- param_map.plus(mapOf("userid" to userid, "uid" to uid, "sign" to sign, "sign_type" to sign_type))
return true
}
}
class ModifyUserParam : APIRequestParam() {
+ @Sign
var userid: String? = null // 用户ID二选一 (两者都传取userid)
+ @Sign
var uid: String? = null // 用户ID二选一
+ @Sign
var name: String? = null
+ @Sign
var sex: String? = null
+ @Sign
var idtype: String? = null
+ @Sign
var idno: String? = null
+ @Sign
var mobile: String? = null
+ @Sign
var tel: String? = null
+ @Sign
var email: String? = null
+ @Sign
var address: String? = null
+ @Sign
var zipcode: String? = null
- var sign: String = "" //必传
- var sign_type: String? = null
fun checkParam(): Boolean {
if (StringUtil.isEmpty(userid) && StringUtil.isEmpty(uid)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "用户唯一号不能为空")
@@ -95,8 +88,6 @@
if (!StringUtil.isEmpty(mobile) && !StringUtil.isMobile(mobile)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "手机号格式错误")
if (!StringUtil.isEmpty(email) && !StringUtil.isEmail(email)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "邮箱格式错误")
-
- param_map.plus(mapOf("userid" to userid, "uid" to uid, "name" to name, "sex" to sex, "idtype" to idtype, "idno" to idno, "mobile" to mobile, "tel" to tel, "email" to email, "address" to address, "zipcode" to zipcode, "sign" to sign, "sign_type" to sign_type))
return true
}
}
@@ -104,19 +95,28 @@
// ============================ SHOP ============================ //
class OpenShopParam : APIRequestParam() {
+ @Sign
var shopUniqueId: String = "" //必传
+ @Sign
var shoptype: Int = 1
+ @Sign
var fshopid: Int? = null
+ @Sign
var shopname: String = "" //必传
+ @Sign
var contactman: String? = null
+ @Sign
var idtype: String? = null
+ @Sign
var idno: String? = null
+ @Sign
var mobile: String? = null
+ @Sign
var email: String? = null
+ @Sign
var address: String? = null
+ @Sign
var zipcode: String? = null
- var sign: String = "" //必传
- var sign_type: String? = null
fun checkParam(): Boolean {
if (StringUtil.isEmpty(shopUniqueId)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "商户唯一号不能为空")
@@ -128,22 +128,21 @@
if (!StringUtil.isEmpty(mobile) && !StringUtil.isMobile(mobile)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "手机号格式错误")
if (!StringUtil.isEmpty(email) && !StringUtil.isEmail(email)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "邮箱格式错误")
- param_map.plus(mapOf("shopUniqueId" to shopUniqueId, "shoptype" to shoptype, "fshopid" to fshopid, "shopname" to shopname, "contactman" to contactman, "idtype" to idtype, "idno" to idno, "mobile" to mobile, "email" to email, "address" to address, "zipcode" to zipcode, "sign" to sign, "sign_type" to sign_type))
return true
}
}
class QueryShopParam : APIRequestParam() {
+ @Sign
var shopid: Int? = null //注册时返回的shopid
+ @Sign
var shopaccno: String? = null //注册时返回的shopaccno
+ @Sign
var shopUniqueId: String? = null //注册传的商户唯一号
- var sign: String = "" //必传
- var sign_type: String? = null
fun checkParam(): Boolean {
if (StringUtil.isEmpty(shopUniqueId) && null == shopid && StringUtil.isEmpty(shopaccno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "商户唯一标志不能为空")
- param_map.plus(mapOf("shopUniqueId" to shopUniqueId, "shopid" to shopid, "shopaccno" to shopaccno, "sign" to sign, "sign_type" to sign_type))
return true
}
}
@@ -153,34 +152,42 @@
class ConsumeFeetype {
var feetype: String = ""
var amount: Int = 0
+
+ override fun toString(): String {
+ return "{feetype='$feetype', amount=$amount}"
+ }
}
class QueryDtlResultParam : APIRequestParam() {
+ @Sign
var refno:String?=null //二选一
+ @Sign
var billno:String?=null //二选一 (billno+shopaccno) 传billno时,shopaccno必传
+ @Sign
var shopaccno: String?=null
- var sign: String = "" //必传
- var sign_type: String? = null
fun checkParam(): Boolean {
if (StringUtil.isEmpty(refno) && (StringUtil.isEmpty(billno) || StringUtil.isEmpty(shopaccno))) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "流水唯一号不能为空")
- param_map.plus(mapOf("refno" to refno, "billno" to billno, "shopaccno" to shopaccno, "sign" to sign, "sign_type" to sign_type))
return true
}
}
class CitizenCardPayinitParam : APIRequestParam() {
+ @Sign
var cardNo: String = "" //必传
+ @Sign
var shopaccno: String = "" //必传
+ @Sign
var amount: Int = 0 //必传
- var feelist: List<ConsumeFeetype>? = null// 的json字符串
+
+ var feelist: List<ConsumeFeetype>? = null //TODO: 怎么拼接签名字符串??
+ @Sign
var billno: String = "" //必传
+ @Sign
var transdate: String = "" //必传
+ @Sign
var transtime: String = "" //必传
- var extend_data: String? = null //扩展参数,原样返回
- var sign: String = "" //必传
- var sign_type: String? = null
fun checkParam(): Boolean {
if (StringUtil.isEmpty(cardNo)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "卡唯一号不能为空")
@@ -190,20 +197,17 @@
if (!DateUtil.checkDatetimeValid(transdate, DateUtil.DATE_FMT)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "交易日期错误[yyyyMMdd]")
if (!DateUtil.checkDatetimeValid(transtime, DateUtil.TIME_FMT)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "交易时间错误[HHmmss]")
- param_map.plus(mapOf("cardNo" to cardNo, "amount" to amount, "feelist" to feelist, "shopaccno" to shopaccno, "billno" to billno, "transdate" to transdate, "transtime" to transtime, "sign" to sign, "sign_type" to sign_type))
return true
}
}
class CitizenCardPayfinishParam : APIRequestParam() {
+ @Sign
var refno:String=""
- var sign: String = "" //必传
- var sign_type: String? = null
fun checkParam(): Boolean {
if (StringUtil.isEmpty(refno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "交易参考号不能为空")
- param_map.plus(mapOf("refno" to refno, "sign" to sign, "sign_type" to sign_type))
return true
}
}
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/comsume_builder.kt b/src/main/kotlin/com/supwisdom/dlpay/api/comsume_builder.kt
index 94e5a08..2c1555c 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/comsume_builder.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/comsume_builder.kt
@@ -85,6 +85,7 @@
lateinit var tradetype: Tradetype
lateinit var refno: String
lateinit var status: String
+ lateinit var shopaccno: String
val resultMap = mutableMapOf<String, String>() //存调第三方结果数据
var transcode = 0
@@ -196,20 +197,11 @@
}
}
- amount = 0.0
if (this.details.size < 1) {
throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "未指定交易明细")
}
- val buyer = accountUtil.readAccount(person.userid) //判断是一个人的流水
amount = this.details.sumByDouble { detail ->
- if (detail.debitSubjNo == buyer.subjno && detail.debitAccNo != buyer.accno) {
- throw throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "交易明细用户错误")
- }
-
- if (detail.creditSubjNo == buyer.subjno && detail.creditAccNo != buyer.accno) {
- throw throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "交易明细用户错误")
- }
detail.amount
}
@@ -225,6 +217,8 @@
if (StringUtil.isEmpty(this.outtradeno)) {
throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "未传递外部流水号")
}
+
+
}
private fun preCheckAccount() {
@@ -244,6 +238,7 @@
it.accno to it.subjno
}
AccountHolder.IDTYPE_SHOP -> holder.withLock<TShopacc>().let {
+ if(null==this.shopaccno) this.shopaccno=it.shopaccno
it.shopaccno to it.subjno
}
AccountHolder.IDTYPE_SUBJECT -> holder.withLock<TSubject>().let {
@@ -257,6 +252,7 @@
it.accno to it.subjno
}
AccountHolder.IDTYPE_SHOP -> holder.get<TShopacc>().let {
+ if(null==this.shopaccno) this.shopaccno=it.shopaccno
it.shopaccno to it.subjno
}
AccountHolder.IDTYPE_SUBJECT -> holder.get<TSubject>().let {
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
index debf0e5..a35b8ce 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
@@ -89,29 +89,34 @@
}
val person = userService.findPersonByIdentityCheckStatus(param.cardNo)
- val dtl = PersonTransBuilder.newBuilder(accountUtilServcie)
- .chooseTradetype(Tradetype.CONSUME) //消费
- .setOwner(person) //记名
- .setTransinfo(TradeCode.TRANSCODE_PAY, "支付交易")
- .setTransDatetime(param.transdate, param.transtime) //交易时间
- .selectPaytype(TradeDict.PAYTYPE_CITIZEN_CARD, param.cardNo)
- .addDetail(AccountHolder.subject(Subject.SUBJNO_PAY_CITIZEN_CARD),
- AccountHolder.shop(param.shopaccno),
- param.amount / 100.0, "市民卡代扣消费")
- .also { builder ->
- param.feelist?.forEach {
- builder.addDetail(AccountHolder.feetype(it.feetype, TradeDict.PAYTYPE_CITIZEN_CARD)
- .with(AccountHolder.shop(param.shopaccno))
- .with(AccountHolder.subject(Subject.SUBJNO_PAY_CITIZEN_CARD))
- , it.amount / 100.0)
+ if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_CITIZEN_CARD)) {
+ val dtl = PersonTransBuilder.newBuilder(accountUtilServcie)
+ .chooseTradetype(Tradetype.CONSUME) //消费
+ .setOwner(person) //记名
+ .setTransinfo(TradeCode.TRANSCODE_PAY, "支付交易")
+ .setTransDatetime(param.transdate, param.transtime) //交易时间
+ .selectPaytype(TradeDict.PAYTYPE_CITIZEN_CARD, param.cardNo)
+ .addDetail(AccountHolder.subject(Subject.SUBJNO_PAY_CITIZEN_CARD),
+ AccountHolder.shop(param.shopaccno),
+ param.amount / 100.0, "市民卡代扣消费")
+ .also { builder ->
+ param.feelist?.forEach {
+ builder.addDetail(AccountHolder.feetype(it.feetype, TradeDict.PAYTYPE_CITIZEN_CARD)
+ .with(AccountHolder.shop(param.shopaccno))
+ .with(AccountHolder.subject(Subject.SUBJNO_PAY_CITIZEN_CARD))
+ , it.amount / 100.0)
+ }
}
- }
- .init(personBalancePayService)
+ .init(personBalancePayService)
+
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .data("refno", dtl.refno)
+ .data("amount", dtl.amount)
+ .success("交易初始化成功"))
+ }
ResponseEntity.ok(ResponseBodyBuilder.create()
- .data("refno", dtl.refno)
- .data("amount", dtl.amount)
- .success("交易初始化成功"))
+ .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<市民卡代扣>"))
} catch (ex: RequestParamCheckException) {
ResponseEntity.ok(ResponseBodyBuilder.create()
@@ -166,6 +171,9 @@
}
}
+ /**
+ * 账户余额支付
+ * */
@PostMapping("/balance/pay")
fun balancePay(@RequestBody param: CitizenCardPayinitParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity<Any> {
return try {
@@ -175,29 +183,34 @@
}
val person = userService.findPersonByIdentityCheckStatus(param.cardNo)
- val dtl = PersonTransBuilder.newBuilder(accountUtilServcie)
- .chooseTradetype(Tradetype.CONSUME) //消费
- .setOwner(person) //记名
- .setTransinfo(TradeCode.TRANSCODE_PAY, "支付交易")
- .setTransDatetime(param.transdate, param.transtime) //交易时间
- .selectPaytype(TradeDict.PAYTYPE_BALANCE, param.cardNo)
- .addDetail(AccountHolder.person(person.userid),
- AccountHolder.shop(param.shopaccno),
- param.amount / 100.0, "账户余额消费")
- .also { builder ->
- param.feelist?.forEach {
- builder.addDetail(AccountHolder.feetype(it.feetype, TradeDict.PAYTYPE_BALANCE)
- .with(AccountHolder.shop(param.shopaccno))
- .with(AccountHolder.person(person.userid))
- , it.amount / 100.0)
+ if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_BALANCE)) {
+ val dtl = PersonTransBuilder.newBuilder(accountUtilServcie)
+ .chooseTradetype(Tradetype.CONSUME) //消费
+ .setOwner(person) //记名
+ .setTransinfo(TradeCode.TRANSCODE_PAY, "支付交易")
+ .setTransDatetime(param.transdate, param.transtime) //交易时间
+ .selectPaytype(TradeDict.PAYTYPE_BALANCE, param.cardNo)
+ .addDetail(AccountHolder.person(person.userid),
+ AccountHolder.shop(param.shopaccno),
+ param.amount / 100.0, "账户余额消费")
+ .also { builder ->
+ param.feelist?.forEach {
+ builder.addDetail(AccountHolder.feetype(it.feetype, TradeDict.PAYTYPE_BALANCE)
+ .with(AccountHolder.shop(param.shopaccno))
+ .with(AccountHolder.person(person.userid))
+ , it.amount / 100.0)
+ }
}
- }
- .done(personBalancePayService)
+ .done(personBalancePayService)
+
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .data("refno", dtl.refno)
+ .data("amount", dtl.amount)
+ .success("交易成功"))
+ }
ResponseEntity.ok(ResponseBodyBuilder.create()
- .data("refno", dtl.refno)
- .data("amount", dtl.amount)
- .success("交易成功"))
+ .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<账户余额>"))
} catch (ex: RequestParamCheckException) {
ResponseEntity.ok(ResponseBodyBuilder.create()
@@ -208,6 +221,59 @@
}
}
+ /**
+ * 一卡通支付
+ * */
+ @PostMapping("/ykt/payinit")
+ fun yktPayInit(@RequestBody param: CitizenCardPayinitParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity<Any> {
+ return try {
+ if (param.checkParam() && param.checkSign(commonService.getAppidSecretByRequest(request))) {
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误"))
+ }
+
+ var person = userService.findByThirdUniqueIdenty(param.cardNo) //可能匿名?
+ if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_YKT_CARD, person==null)) {
+ val dtl = PersonTransBuilder.newBuilder(accountUtilServcie)
+ .chooseTradetype(Tradetype.CONSUME) //消费
+ .also {
+ if(null!=person) it.setOwner(person)
+ }
+ .setTransinfo(TradeCode.TRANSCODE_PAY, "支付交易")
+ .setTransDatetime(param.transdate, param.transtime) //交易时间
+ .selectPaytype(TradeDict.PAYTYPE_YKT_CARD, param.cardNo)
+ .addDetail(AccountHolder.subject(Subject.SUBJNO_PAY_YKT),
+ AccountHolder.shop(param.shopaccno),
+ param.amount / 100.0, "一卡通支付")
+ .also { builder ->
+ param.feelist?.forEach {
+ builder.addDetail(AccountHolder.feetype(it.feetype, TradeDict.PAYTYPE_YKT_CARD)
+ .with(AccountHolder.shop(param.shopaccno))
+ .with(AccountHolder.subject(Subject.SUBJNO_PAY_YKT))
+ , it.amount / 100.0)
+ }
+ }
+ .init(personBalancePayService)
+
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .data("refno", dtl.refno)
+ .data("amount", dtl.amount)
+ .success("交易初始化成功"))
+
+
+ }
+
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<一卡通支付>"))
+ } catch (ex: RequestParamCheckException) {
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .requestException(ex, "请求参数错误"))
+ } catch (et: TransactionException) {
+ ResponseEntity.ok(ResponseBodyBuilder.create()
+ .transException(et, "业务处理错误"))
+ }
+ }
+
// ============================================== //
//
// @GetMapping("/account/payinit")
@@ -231,62 +297,8 @@
// .done(refno, TradeDict.DTL_STATUS_SUCCESS, personBalancePayService)
// return ResponseEntity.ok(dtl)
// }
-//
-// @PostMapping("/ykt/payinit")
-// fun yktPayInit(userid: String, amount: Int, manageFee: Int,
-// stuempno: String, shopid: String, transdate: String, transtime: String,
-// outtradeno: String, payinfo: String, feetype: String): ResponseEntity<Any> {
-// //一卡通支付款 112240
-// return try {
-// val paytype = paytypeService.getByPaytype(PaytypeUtil.YKTPAY)
-// if (paytype == null || ConstantUtil.ENABLE_YES != paytype.enable) {
-// ResponseEntity.ok(ResponseBodyBuilder.create()
-// .fail(1, "支付方式未开启"))
-// }
-// val person = userService.findByThirdUniqueIdenty(stuempno)
-// val dtl = PersonTransBuilder.newBuilder(accountUtilServcie)
-// .setTransDatetime(transdate, transtime)
-// .selectPaytype(PaytypeUtil.YKTPAY, payinfo)
-// .setOuttradeno(outtradeno)
-// .also {
-// if (null != person) it.setOwner(person)
-// }
-// .tryLock(true)
-// .setTransinfo(TradeCode.TRANSCODE_YKTPAY, "一卡通支付")
-// .chooseTradetype(Tradetype.CONSUME)
-// .also {
-// when (feetype) {
-// TradeDict.FEETYPE_CONSUME_MEALER -> {
-// it.addDetail(AccountHolder.subject(Subject.SUBJNO_PAY_YKT),
-// AccountHolder.shop(shopid),
-// amount / 100.0, "一卡通支付")
-// .addDetail(AccountHolder.transType(TranstypeCode.TT_CONSUUME_MANAGE_FEE)
-// .with(AccountHolder.shop(shopid)),
-// manageFee / 100.0)
-// }
-// TradeDict.FEETYPE_CONSUME_DISCOUNT -> {
-// it.addDetail(AccountHolder.subject(Subject.SUBJNO_PAY_YKT),
-// AccountHolder.shop(shopid),
-// (amount - manageFee) / 100.0, "一卡通支付")
-// .addDetail(AccountHolder.subject(Subject.SUBJNO_CONSUME_DISCOUNT),
-// AccountHolder.shop(shopid),
-// manageFee / 100.0, "优惠折扣")
-// }
-// else -> {
-// it.addDetail(AccountHolder.subject(Subject.SUBJNO_PAY_YKT),
-// AccountHolder.shop(shopid),
-// amount / 100.0, "一卡通支付")
-// }
-// }
-// }.done(personBalancePayService, false)
-// ResponseEntity.ok(ResponseBodyBuilder.create()
-// .data("refno", dtl.refno)
-// .success())
-// } catch (e: TransactionException) {
-// ResponseEntity.ok(ResponseBodyBuilder.create()
-// .transException(e, "交易初始化异常"))
-// }
-// }
+
+
//
// @PostMapping("/ykt/payfinish")
// fun yktPayFinish(refno: String, yktshopid: String, devphyid: String?): ResponseEntity<Any> {
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/consume_pay_service.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/consume_pay_service.kt
index 5d85e0f..a81b21a 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/service/consume_pay_service.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/consume_pay_service.kt
@@ -5,8 +5,8 @@
interface ConsumePayService{
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class))
- fun checkShopPaytype(shopaccno: String, paytype: String): Boolean
+ fun checkShopPaytype(shopaccno: String, paytype: String, anonymousflag: Boolean? = false): Boolean
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class))
- fun getPaytypeConfig(paytype: String, shopaccno: String, ignoreStatus: Boolean? = false): Map<String, String?>
+ fun getPaytypeConfig(paytype: String, shopaccno: String, anonymousflag: Boolean? = false, ignoreStatus: Boolean? = false): Map<String, String?>
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/Consume_pay_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/Consume_pay_service_impl.kt
index cdb134b..6f36155 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/Consume_pay_service_impl.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/Consume_pay_service_impl.kt
@@ -20,7 +20,7 @@
@Autowired
lateinit var shopPaytypeConfigDao: ShopPaytypeConfigDao
- override fun checkShopPaytype(shopaccno: String, paytype: String): Boolean{
+ override fun checkShopPaytype(shopaccno: String, paytype: String, anonymousflag: Boolean?): Boolean{
paytypeDao.getByPaytype(paytype).let {
if (null == it) {
throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "系统不支持支付方式[$paytype]")
@@ -28,6 +28,9 @@
if (ConstantUtil.ENABLE_YES != it.enable || ConstantUtil.ENABLE_YES != it.consumeEnable) {
throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "系统未启用支付方式[$paytype]消费")
}
+ if (true == anonymousflag && ConstantUtil.ENABLE_YES != it.anonymousEnable) {
+ throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "系统支付方式[$paytype]未启用匿名消费")
+ }
}
}
shopPaytypeDao.getById(paytype, shopaccno).let {
@@ -37,12 +40,15 @@
if (ConstantUtil.ENABLE_YES != it.consumeEnable) {
throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "该商户[$shopaccno]未启用支付方式[$paytype]")
}
+ if (true == anonymousflag && ConstantUtil.ENABLE_YES != it.anonymousEnable) {
+ throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "该商户[$shopaccno]的支付方式[$paytype]未启用匿名消费")
+ }
}
}
return true
}
- override fun getPaytypeConfig(paytype: String, shopaccno: String, ignoreStatus: Boolean?): Map<String, String?> {
+ override fun getPaytypeConfig(paytype: String, shopaccno: String, anonymousflag: Boolean?, ignoreStatus: Boolean?): Map<String, String?> {
paytypeDao.getByPaytype(paytype).let {
if (null == it) {
throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "系统不支持支付方式[$paytype]")
@@ -50,6 +56,9 @@
if (true != ignoreStatus && (ConstantUtil.ENABLE_YES != it.enable || ConstantUtil.ENABLE_YES != it.consumeEnable)) {
throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "系统未启用支付方式[$paytype]消费")
}
+ if (true != ignoreStatus && true == anonymousflag && ConstantUtil.ENABLE_YES != it.anonymousEnable) {
+ throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "系统支付方式[$paytype]未启用匿名消费")
+ }
}
}
@@ -60,6 +69,9 @@
if (true != ignoreStatus && ConstantUtil.ENABLE_YES != it.consumeEnable) {
throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "该商户[$shopaccno]未启用支付方式[$paytype]")
}
+ if (true != ignoreStatus && true == anonymousflag && ConstantUtil.ENABLE_YES != it.anonymousEnable) {
+ throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "该商户[$shopaccno]的支付方式[$paytype]未启用匿名消费")
+ }
}
}