/// <summary> /// 获取有效的支付记录 /// </summary> /// <param name="orderId">订单编号</param> /// <param name="payType">支付类型</param> /// <returns></returns> public static PayResultInfo GetValidPayResult(string orderId, AppEnum.PayType payType) { string sql = @" SELECT SysNo, RequestSysNo, OrderId, TradeNo, PaymentAmt, PayType, ExecuteResult, ResultDesc, NotifyStatus, CreateTime, ExtTradeNo FROM Pay_Result WHERE OrderId=@orderId AND PayType=@payType AND ExecuteResult=@result"; var resultInfo = DbHelper.QuerySingle <PayResultInfo>(sql, new { orderId = orderId, payType = (int)payType, result = (int)ResultStatus.Success }); return(resultInfo); }
/// <summary> /// 根据订单编号和支付方式,查询有效的支付请求记录 /// </summary> /// <param name="orderId"></param> /// <param name="payType"></param> /// <returns></returns> public static PayRequestInfo GetValidPayRequest(string orderId, AppEnum.PayType payType) { string sql = @" SELECT SysNo, OrderId, PaymentAmt, PayType, NotifyUrl, ReturnUrl, ExecuteResult, ResultDesc, AppId, Status, CreateTime FROM Pay_Request WHERE OrderId=@orderId AND PayType=@payType AND Status=@status ORDER BY SysNo"; PayRequestInfo requestInfo = DbHelper.QuerySingle <PayRequestInfo>(sql, new { orderId = orderId, payType = (int)payType, status = (int)AppEnum.GlobalStatus.Valid }); return(requestInfo); }
/// <summary> /// 校验退款参数 /// </summary> /// <param name="data">业务数据报文</param> /// <param name="payType">支付方式</param> /// <param name="requestInfo">退款请求记录</param> /// <returns></returns> public virtual ExecuteResult <RefundOrderInfo> CheckParamaters(string data, AppEnum.PayType payType, RefundRequestInfo requestInfo) { var result = this.CheckParamaters(data, payType); if (result.Status != ResultStatus.Success) { requestInfo.ExecuteResult = (int)ResultStatus.Failure; requestInfo.ResultDesc = result.Message; RefundRequestDAL.Update(requestInfo); } return(result); }
/// <summary> /// 是否存在有效的支付结果记录 /// </summary> /// <param name="orderId"></param> /// <param name="payType"></param> /// <returns></returns> public static bool ExistValidPayResult(string orderId, AppEnum.PayType payType) { string sql = "SELECT COUNT(1) FROM Pay_Result WHERE OrderId=@orderId AND PayType=@payType AND ExecuteResult=@result"; int count = DbHelper.QueryScalar <int>(sql, new { orderId = orderId, payType = (int)payType, result = (int)ResultStatus.Success }); return(count > 0); }
/// <summary> /// 获取订单已退款的总金额 /// </summary> /// <param name="orderId"></param> /// <param name="payType"></param> /// <returns></returns> public static decimal GetRefundedAmt(string orderId, AppEnum.PayType payType) { string sql = "SELECT ISNULL(SUM(RefundAmt),0) FROM Refund_Result WHERE OrderId=@orderId AND PayType=@payType AND ExecuteResult=@result"; var refundedAmt = DbHelper.QueryScalar <decimal>(sql, new { orderId = orderId, payType = (int)payType, result = (int)ResultStatus.Success }); return(refundedAmt); }
/// <summary> /// 保存退款请求记录 /// </summary> /// <param name="data"></param> /// <param name="payType"></param> /// <returns></returns> public static PayRefundInfo SavePayRefund(string data, AppEnum.PayType payType) { var payRefund = new PayRefundInfo() { PayType = (int)payType, RequestData = data, ExecuteResult = (int)ResultStatus.None, CreateTime = DateTime.Now, }; payRefund.SysNo = PayRefundDAL.Insert(payRefund); return(payRefund); }
/// <summary> /// 保存支付结果请求 /// </summary> /// <param name="data">业务数据报文</param> /// <param name="payType">支付方式</param> /// <returns></returns> public virtual PayResultInfo SaveRequest(string data, AppEnum.PayType payType) { var resultInfo = new PayResultInfo() { PayType = (int)payType, RequestData = data, ExecuteResult = (int)ResultStatus.None, NotifyStatus = (int)AppEnum.NotifyStatus.Original, CreateTime = DateTime.Now, }; resultInfo.SysNo = PayResultDAL.Insert(resultInfo); return(resultInfo); }
/// <summary> /// 保存支付结果异步回执记录 /// </summary> /// <param name="data"></param> /// <param name="payType"></param> /// <returns></returns> public static PayResultInfo SavePayResult(string data, AppEnum.PayType payType) { var payResult = new PayResultInfo() { PayType = (int)payType, RequestData = data, ExecuteResult = (int)ResultStatus.None, NotifyStatus = (int)AppEnum.GlobalStatus.Invalid, CreateTime = DateTime.Now, }; payResult.SysNo = PayResultDAL.Insert(payResult); return(payResult); }
/// <summary> /// 保存退款请求 /// </summary> /// <param name="appId">业务系统ID</param> /// <param name="data">业务数据报文</param> /// <param name="payType">支付方式</param> /// <returns></returns> public virtual RefundRequestInfo SaveRequest(string appId, string data, AppEnum.PayType payType) { var requestInfo = new RefundRequestInfo() { PayType = (int)payType, RequestData = data, ExecuteResult = (int)ResultStatus.None, AppId = appId, Status = (int)AppEnum.GlobalStatus.Valid, CreateTime = DateTime.Now, }; requestInfo.SysNo = RefundRequestDAL.Insert(requestInfo); return(requestInfo); }
/// <summary> /// 校验退款参数 /// </summary> /// <param name="data">业务数据报文</param> /// <param name="payType">支付方式</param> /// <returns></returns> private ExecuteResult <RefundOrderInfo> CheckParamaters(string data, AppEnum.PayType payType) { //校验结果 var result = new ExecuteResult <RefundOrderInfo>(); //参数名称 string paramName = null; //金额匹配表达式(最多保留2位小数正实数) string amtReg = @"^\d+(\.[0-9]{1,2}0*)?$"; #region 校验退款报文结构 var info = JsonHelper.Deserialize <RefundOrderInfo>(data); if (info == null) { result.Status = ResultStatus.Failure; result.Message = "参数data格式不正确"; return(result); } #endregion #region 校验参数类型和取值范围 #region 校验订单编号 paramName = "orderId"; if (string.IsNullOrWhiteSpace(info.OrderId)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } #endregion #region 校验下单时间 paramName = "orderTime"; if (string.IsNullOrWhiteSpace(info.OrderTime)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } DateTime orderTime; if (!DateTime.TryParseExact(info.OrderTime, "yyyyMMddHHmmss", new CultureInfo("zh-CN", true), DateTimeStyles.None, out orderTime)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}格式错误", paramName); return(result); } #endregion #region 校验交易流水号 paramName = "tradeNo"; if (string.IsNullOrWhiteSpace(info.TradeNo)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } #endregion #region 校验支付金额 paramName = "paymentAmt"; if (string.IsNullOrWhiteSpace(info.PaymentAmt)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } decimal paymentAmt = 0; if (!Regex.IsMatch(info.PaymentAmt, amtReg) || !decimal.TryParse(info.PaymentAmt, out paymentAmt)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}类型错误", paramName); return(result); } if (paymentAmt <= 0) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}必须大于0", paramName); return(result); } #endregion #region 校验退款单编号 paramName = "refundOrderId"; if (string.IsNullOrWhiteSpace(info.RefundOrderId)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } #endregion #region 校验退款金额 paramName = "refundAmt"; if (string.IsNullOrWhiteSpace(info.RefundAmt)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } decimal refundAmt = 0; if (!Regex.IsMatch(info.RefundAmt, amtReg) || !decimal.TryParse(info.RefundAmt, out refundAmt)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}类型错误", paramName); return(result); } if (refundAmt <= 0) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}必须大于0", paramName); return(result); } #endregion #region 校验退款完成的通知地址 paramName = "notifyUrl"; if (string.IsNullOrWhiteSpace(info.NotifyUrl)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } if (!info.NotifyUrl.IsUrl()) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}格式错误", paramName); return(result); } #endregion #endregion #region 校验退款金额合法性 if (refundAmt > paymentAmt) { result.Status = ResultStatus.Failure; result.Message = "退款金额不能大于支付金额"; return(result); } //var refundedAmt = RefundResultDAL.GetRefundedAmt(info.OrderId, payType); //if (paymentAmt - refundedAmt < refundAmt) //{ // result.Status = ResultStatus.Failure; // result.Message = "订单剩余可退款额度小于退款金额,不能完成退款"; // return result; //} #endregion result.Status = ResultStatus.Success; result.Data = info; return(result); }
/// <summary> /// 根据订单编号、退款单编号和支付方式,查询有效的退款请求记录 /// </summary> /// <param name="orderId"></param> /// <param name="refundOrderId"></param> /// <param name="payType"></param> /// <returns></returns> public static RefundRequestInfo GetValidRefundRequest(string orderId, string refundOrderId, AppEnum.PayType payType) { string sql = @" SELECT SysNo, OrderId, TradeNo, RefundOrderId, RefundAmt, NotifyUrl, PayType, ExecuteResult, AppId FROM Refund_Request WHERE OrderId=@orderId AND RefundOrderId=@refundOrderId AND PayType=@payType AND Status=@status ORDER BY SysNo"; var requestInfo = DbHelper.QuerySingle <RefundRequestInfo>(sql, new { orderId = orderId, refundOrderId = refundOrderId, payType = (int)payType, status = (int)AppEnum.GlobalStatus.Valid }); return(requestInfo); }
/// <summary> /// 校验在线支付参数 /// </summary> /// <param name="data"></param> /// <returns></returns> public static ExecuteResult <PayOrderInfo> ValidateOnlinePayParams(string data, AppEnum.PayType payType) { //校验结果 var result = new ExecuteResult <PayOrderInfo>(); //参数名称 string paramName = null; //金额匹配表达式(最多保留2位小数正实数) string amtReg = @"^\d+(\.[0-9]{1,2}0*)?$"; #region 校验支付报文结构 var info = JsonHelper.Deserialize <PayOrderInfo>(data); if (info == null) { result.Status = ResultStatus.Failure; result.Message = "参数data格式不正确"; return(result); } #endregion #region 校验参数类型和值 #region 校验订单编号 paramName = "orderId"; if (string.IsNullOrWhiteSpace(info.OrderId)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } #endregion #region 校验支付金额 paramName = "paymentAmt"; if (string.IsNullOrWhiteSpace(info.PaymentAmt)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } decimal paymentAmt = 0; if (!Regex.IsMatch(info.PaymentAmt, amtReg) || !decimal.TryParse(info.PaymentAmt, out paymentAmt)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}类型错误", paramName); return(result); } if (paymentAmt <= 0) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}必须大于0", paramName); return(result); } #endregion #region 校验下单时间 paramName = "orderTime"; if (string.IsNullOrWhiteSpace(info.OrderTime)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } DateTime orderTime; if (!DateTime.TryParseExact(info.OrderTime, "yyyyMMddHHmmss", new CultureInfo("zh-CN", true), DateTimeStyles.None, out orderTime)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}格式错误", paramName); return(result); } #endregion #region 校验支付完成的通知地址 paramName = "notifyUrl"; if (string.IsNullOrWhiteSpace(info.NotifyUrl)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } if (!info.NotifyUrl.IsUrl()) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}格式错误", paramName); return(result); } #endregion #region 校验支付完成的返回地址 paramName = "returnUrl"; if (string.IsNullOrWhiteSpace(info.ReturnUrl)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } if (!info.ReturnUrl.IsUrl()) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}格式错误", paramName); return(result); } #endregion #region 校验跨境支付订单 if (info.CrossboardType == "1") { #region 校验货款金额 paramName = "goodsPrice"; if (string.IsNullOrWhiteSpace(info.GoodsPrice)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } decimal goodsPrice = 0; if (!Regex.IsMatch(info.GoodsPrice, amtReg) || !decimal.TryParse(info.GoodsPrice, out goodsPrice)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}类型错误", paramName); return(result); } if (goodsPrice <= 0) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}必须大于0", paramName); return(result); } #endregion #region 校验税费金额 paramName = "taxPrice"; if (string.IsNullOrWhiteSpace(info.TaxPrice)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } decimal taxPrice = 0; if (!Regex.IsMatch(info.TaxPrice, amtReg) || !decimal.TryParse(info.TaxPrice, out taxPrice)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}类型错误", paramName); return(result); } if (taxPrice < 0) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}必须大于等于0", paramName); return(result); } #endregion #region 校验运费金额 paramName = "freightPrice"; if (string.IsNullOrWhiteSpace(info.FreightPrice)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } decimal freightPrice = 0; if (!Regex.IsMatch(info.FreightPrice, amtReg) || !decimal.TryParse(info.FreightPrice, out freightPrice)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}类型错误", paramName); return(result); } if (freightPrice < 0) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}必须大于等于0", paramName); return(result); } #endregion #region 校验货款、税费、运费与支付金额的关系 if (paymentAmt != goodsPrice + taxPrice + freightPrice) { result.Status = ResultStatus.Failure; result.Message = "关系“paymentAmt = goodsPrice + taxPrice + freightPrice”不成立"; return(result); } #endregion #region 校验购买人姓名 paramName = "buyerName"; if (string.IsNullOrWhiteSpace(info.BuyerName)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } #endregion #region 校验购买人手机号码 paramName = "buyerCellphone"; if (string.IsNullOrWhiteSpace(info.BuyerCellphone)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } #endregion #region 校验购买人身份证号 paramName = "buyerIdCardNo"; if (string.IsNullOrWhiteSpace(info.BuyerIdCardNo)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } #endregion } #endregion #region 校验业务系统编号 paramName = "systemId"; if (!string.IsNullOrWhiteSpace(info.SystemId)) { int systemId = 0; if (!int.TryParse(info.SystemId, out systemId)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}类型错误", paramName); return(result); } if (systemId <= 0) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}必须大于0", paramName); return(result); } } #endregion #endregion #region 校验是否已支付 if (PayRequestDAL.ExistValidPayResult(info.OrderId, payType)) { result.Status = ResultStatus.Failure; result.Message = "该订单已成功支付,不能重复支付"; return(result); } #endregion result.Status = ResultStatus.Success; result.Data = info; return(result); }
/// <summary> /// 校验条形码支付参数 /// </summary> /// <param name="data"></param> /// <returns></returns> public static ExecuteResult <PayOrderInfo> ValidateBarcodePayParams(string data, AppEnum.PayType payType) { //校验结果 var result = new ExecuteResult <PayOrderInfo>(); //参数名称 string paramName = null; //金额匹配表达式(最多保留2位小数正实数) string amtReg = @"^\d+(\.[0-9]{1,2}0*)?$"; #region 校验支付报文结构 var info = JsonHelper.Deserialize <PayOrderInfo>(data); if (info == null) { result.Status = ResultStatus.Failure; result.Message = "参数data格式不正确"; return(result); } #endregion #region 校验参数类型和值 #region 校验订单编号 paramName = "orderId"; if (string.IsNullOrWhiteSpace(info.OrderId)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } #endregion #region 校验支付金额 paramName = "paymentAmt"; if (string.IsNullOrWhiteSpace(info.PaymentAmt)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } decimal paymentAmt = 0; if (!Regex.IsMatch(info.PaymentAmt, amtReg) || !decimal.TryParse(info.PaymentAmt, out paymentAmt)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}类型错误", paramName); return(result); } if (paymentAmt <= 0) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}必须大于0", paramName); return(result); } #endregion #region 校验支付条形码 paramName = "barcode"; if (string.IsNullOrWhiteSpace(info.Barcode)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } #endregion #region 校验业务系统编号 paramName = "systemId"; if (!string.IsNullOrWhiteSpace(info.SystemId)) { int systemId = 0; if (!int.TryParse(info.SystemId, out systemId)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}类型错误", paramName); return(result); } if (systemId <= 0) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}必须大于0", paramName); return(result); } } #endregion #endregion #region 校验是否已支付 if (PayRequestDAL.ExistValidPayResult(info.OrderId, payType)) { result.Status = ResultStatus.Failure; result.Message = "该订单已成功支付,不能重复支付"; return(result); } #endregion result.Status = ResultStatus.Success; result.Data = info; return(result); }
/// <summary> /// 校验支付参数 /// </summary> /// <param name="data">业务数据报文</param> /// <param name="payType">支付方式</param> /// <returns></returns> private ExecuteResult <PayOrderInfo> CheckParamaters(string data, AppEnum.PayType payType) { //校验结果 var result = new ExecuteResult <PayOrderInfo>(); //参数名称 string paramName = null; //金额匹配表达式(最多保留2位小数正实数) string amtReg = @"^\d+(\.[0-9]{1,2}0*)?$"; #region 校验支付报文结构 var info = JsonHelper.Deserialize <PayOrderInfo>(data); if (info == null) { result.Status = ResultStatus.Failure; result.Message = "参数data格式不正确"; return(result); } #endregion #region 校验参数类型和取值范围 #region 校验订单编号 paramName = "orderId"; if (string.IsNullOrWhiteSpace(info.OrderId)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } #endregion #region 校验支付金额 paramName = "paymentAmt"; if (string.IsNullOrWhiteSpace(info.PaymentAmt)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } decimal paymentAmt = 0; if (!Regex.IsMatch(info.PaymentAmt, amtReg) || !decimal.TryParse(info.PaymentAmt, out paymentAmt)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}类型错误", paramName); return(result); } if (paymentAmt <= 0) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}必须大于0", paramName); return(result); } #endregion #region 校验下单时间 paramName = "orderTime"; if (string.IsNullOrWhiteSpace(info.OrderTime)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } DateTime orderTime; if (!DateTime.TryParseExact(info.OrderTime, "yyyyMMddHHmmss", new CultureInfo("zh-CN", true), DateTimeStyles.None, out orderTime)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}格式错误", paramName); return(result); } #endregion #region 校验支付完成的通知地址 paramName = "notifyUrl"; if (string.IsNullOrWhiteSpace(info.NotifyUrl)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } if (!info.NotifyUrl.IsUrl()) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}格式错误", paramName); return(result); } #endregion #region 校验支付完成的返回地址 paramName = "returnUrl"; if (string.IsNullOrWhiteSpace(info.ReturnUrl)) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}不能为空", paramName); return(result); } if (!info.ReturnUrl.IsUrl()) { result.Status = ResultStatus.Failure; result.Message = string.Format("参数{0}格式错误", paramName); return(result); } #endregion #endregion #region 校验是否已支付 if (PayResultDAL.ExistValidPayResult(info.OrderId, payType)) { result.Status = ResultStatus.Failure; result.Message = "该订单已成功支付,不能重复支付"; return(result); } #endregion result.Status = ResultStatus.Success; result.Data = info; return(result); }
/// <summary> /// 校验支付参数 /// </summary> /// <param name="data">业务数据报文</param> /// <param name="payType">支付方式</param> /// <param name="requestInfo">支付请求记录</param> /// <returns></returns> public abstract ExecuteResult <PayOrderInfo> CheckParamaters(string data, AppEnum.PayType payType, PayRequestInfo requestInfo);