/// <summary> /// 发送Post支付请求 /// </summary> /// <param name="url"></param> /// <param name="paramsStr"></param> /// <returns></returns> public static QctPayReturn SendPost(this string url, string paramsStr) { string reqUrl = url + "?" + paramsStr; PayLogServer.WriteInfo(string.Format("发送交易请求:{0}", reqUrl)); try { var httpRequest = (HttpWebRequest)WebRequest.Create(url); httpRequest.Method = "POST"; httpRequest.ContentType = "application/x-www-form-urlencoded"; httpRequest.Timeout = 45000; byte[] byteRequest = System.Text.Encoding.UTF8.GetBytes(paramsStr); httpRequest.ContentLength = byteRequest.Length; Stream requestStream = httpRequest.GetRequestStream(); requestStream.Write(byteRequest, 0, byteRequest.Length); requestStream.Close(); //获取服务端返回 var response = (HttpWebResponse)httpRequest.GetResponse(); //获取服务端返回数据 StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8); var result = sr.ReadToEnd().Trim(); sr.Close(); result = HttpUtility.UrlDecode(result, Encoding.UTF8); return(QctPayReturn.Success(data: result)); } catch (Exception ex) { var logEng = new LogEngine(); logEng.WriteError(string.Format("发送交易请求异常:{0},请求地址:{1}", ex.Message, reqUrl), ex, LogModule.支付交易); return(QctPayReturn.Fail(code: PayConst.FAIL_CODE_20000, msg: "订单请求失败,服务器繁忙!")); } }
/// <summary> /// 根据商户信息获得门店支付权限,若只传商户ID,则返回全部门店的状态信息,若传门店ID则只返回指定门店的支付权限信息 /// </summary> /// <param name="cid">商户号</param> /// <param name="storeId">门店号(可选)</param> /// <returns></returns> public QctPayReturn GetMerchStorePayInfos(int cid, string storeId = "") { var merchObj = PaySvc.GetMerchByCID(cid); if (merchObj == null) { return(QctPayReturn.Fail("请先申请开通商户,若您已经申请,请等待审核")); } var query = TStoreRepost.GetQuery().Where(o => o.CID == cid); if (string.IsNullOrWhiteSpace(storeId)) { query = query.Where(o => o.State == (short)TraderStoreState.Enabled); } else { query = query.Where(o => o.StoreNum == storeId); } var queryStore = (from s in query select new MerchStorePayItem { StoreId = s.StoreNum, State = s.State == (short)TraderStoreState.Enabled ? DataItemState.Enabled : DataItemState.Disabled }).ToList(); var data = new MerchStorePayModel() { CID = cid, Items = queryStore }; return(QctPayReturn.Success(data: data)); }
/// <summary> /// 创建生产退款订单 /// </summary> /// <param name="reqModel"></param> /// <returns></returns> public override QctPayReturn Build(RefundApplyRequest reqModel) { WithReqModel(reqModel); WithOutTradeNo(reqModel.Out_Refund_No); var canObj = CanBuilder(); if (!canObj.Successed) { return(canObj); } else { ReqModel.ResetRfdNotifyUrl(MerchModel.RfdNotifyUrl); var tradeOrder = new TradeOrder(ReqModel, MerchStoreModel) { TradeNo = OrderHelper.GetMaxTradeNo(), OutTradeNo = ReqModel.Out_Refund_No, OldOutTradeNo = ReqModel.Out_Trade_No, TotalAmount = ReqModel.Refund_Amount, SourceType = MerchModel.SourceType, ApiNo = MerchModel.ApiNo, State = (short)RefundState.RefundIng, RfdNotifyUrl = ReqModel.Refund_Notify_Url, OrderType3 = ((short)SxfOrderType.CommonOrder), TradeType = (short)QctTradeType.Expense, FeeType = (short)PayFeeType.RMB, BuyerMobile = "" }; var result = PaySvc.SaveTradeOrder(tradeOrder); if (result) { //构建Sxf请求参数,签名,发起请求 var sxfReqModel = new SxfRefundApplyRequest(tradeOrder, PayConfig.SxfRefundNotifyUrl); var rstObj = SendPost <SxfRefundApplyRequest, SxfRefundApplyResponse>(MerchStoreModel.ApiUrl, sxfReqModel); if (rstObj.Successed) { //处理返回成功结果,保存退款结果,后进行Qct签名并返回结果回发给商户,fishtodo:暂忽略验证Sxf返回的响应结果签名 var sxfRspModel = (SxfRefundApplyResponse)rstObj.Data; //保存退款结果 var rfdApplyRsp = new RefundApplyResponse(tradeOrder, sxfRspModel) { Out_Trade_No = sxfReqModel.OldOutTradeNo }; return(QctPayReturn.Success(data: PaySignHelper.ToDicAndSign(rfdApplyRsp, MerchModel.SecretKey, "sign"))); } else { return(rstObj); } } else { return(ResultFail(msg: "订单提交失败", logMsg: string.Format("退款请求失败:{0},异常信息:{1}", reqModel.ToJson(), tradeOrder.ToJson()))); } } }
/// <summary> /// 验证参数格式 /// </summary> /// <returns></returns> public QctPayReturn VerifyParams() { var errorMsg = ReqModel.TryValidateObject(); if (errorMsg.IsNullOrEmpty()) { return(QctPayReturn.Success()); } else { return(QctPayReturn.Fail(code: PayConst.FAIL_CODE_40001, msg: errorMsg)); } }
/// <summary> /// 判断订单号是否重复 /// </summary> /// <returns></returns> public QctPayReturn CanCreateOrder() { var can = PaySvc.CanCreateOrder(ReqModel.Mch_Id, OutTradeNo); if (can) { return(QctPayReturn.Success()); } else { return(QctPayReturn.Fail(msg: "订单号已存在,不能重复提交")); } }
/// <summary> /// 是否可创建交易订单 /// </summary> /// <returns></returns> public QctPayReturn CanBuilder() { var result = CanAccess(); if (!result.Successed) { return(result); } result = CanCreateOrder(); if (!result.Successed) { return(result); } return(QctPayReturn.Success()); }
/// <summary> /// 创建生成支付订单,购买者付款扫码,(对应融合支付:主扫支付动态二维码) /// </summary> /// <param name="reqModel"></param> /// <returns></returns> public override QctPayReturn Build(PayBuyerScanDynaRequest reqModel) { try { WithReqModel(reqModel); WithOutTradeNo(reqModel.Out_Trade_No); var canObj = CanBuilder(); if (!canObj.Successed) { return(canObj); } else { var tradeOrder = new TradeOrder(ReqModel, MerchStoreModel, OrderHelper.GetMaxTradeNo()); var result = PaySvc.SaveTradeOrder(tradeOrder); if (result) { //构建Sxf请求参数,签名,发起请求 var sxfBuildReq = new SxfBuildPayTokenRequest(tradeOrder, PayConfig.SxfPayNotifyUrl); sxfBuildReq.OrderType = "1"; var rstObj = SendPost <SxfBuildPayTokenRequest, SxfBuildPayTokenResponse>(MerchStoreModel.ApiUrl, sxfBuildReq); if (rstObj.Successed) { //处理返回成功结果,将返回结果进行Qct签名并返回给商户,fishtodo:暂忽略验证Sxf返回的响应结果签名 var resultObj = new PayBuyerScanDynaResponse(tradeOrder, (SxfBuildPayTokenResponse)rstObj.Data); WithRspModel(resultObj); return(QctPayReturn.Success(data: PaySignHelper.ToDicAndSign(resultObj, MerchModel.SecretKey, "sign"))); } return(rstObj); } else { return(ResultFail(msg: "订单提交失败", logMsg: string.Format("购买者付款扫码请求失败:{0},异常信息:{1}", ReqModel.ToJson(), tradeOrder.ToJson()))); } } } catch (Exception ex) { return(ResultFail(msg: "订单提交失败", logMsg: string.Format("购买者付款扫码请求异常:{0},异常信息:{1}", ex.Message, ReqModel.ToJson()))); } }
/// <summary> /// 创建生成支付订单,商家收款扫码,(对应融合支付:被扫支付) /// </summary> /// <param name="reqModel"></param> /// <returns></returns> public override QctPayReturn Build(PayMerchScanRequest reqModel) { WithReqModel(reqModel); WithOutTradeNo(reqModel.Out_Trade_No); var canObj = CanBuilder(); if (!canObj.Successed) { return(canObj); } else { var tradeOrder = new TradeOrder(ReqModel, MerchStoreModel, OrderHelper.GetMaxTradeNo()); tradeOrder.BuyerPayToken = ReqModel.Buyer_Pay_Token; var result = PaySvc.SaveTradeOrder(tradeOrder); if (result) { //构建Sxf请求参数,签名,发起请求 var sxfReqModel = new SxfScanPayRequest(tradeOrder, PayConfig.SxfPayNotifyUrl); var rstObj = SendPost <SxfScanPayRequest, SxfScanPayResponse>(MerchStoreModel.ApiUrl, sxfReqModel); if (rstObj.Successed) { //处理返回成功结果,保存商家收款扫码结果,后进行Qct签名并返回结果回发给商户,fishtodo:暂忽略验证Sxf返回的响应结果签名 var sxfRspModel = (SxfScanPayResponse)rstObj.Data; PaySvc.SaveMerchScanResult(sxfRspModel, out tradeOrder); var merchScanRsp = new PayMerchScanResponse(tradeOrder, sxfRspModel); return(QctPayReturn.Success(data: PaySignHelper.ToDicAndSign(merchScanRsp, MerchModel.SecretKey, "sign"))); } else { return(rstObj); } } else { return(ResultFail(msg: "订单提交失败", logMsg: string.Format("商家收款扫码请求失败:{0},异常信息:{1}", reqModel.ToJson(), tradeOrder.ToJson()))); } } }
/// <summary> /// 检查商户通道是否可用 /// </summary> /// <param name="cid"></param> /// <param name="method"></param> /// <returns></returns> public QctPayReturn CheckMerchAccess(int cid, string method, decimal version) { var payLicense = GetPayLicense(cid, (short)TraderPayLicenseState.Audited); if (payLicense == null) { return(QctPayReturn.Fail(code: PayConst.FAIL_CODE_20001, msg: "请先申请支付许可")); } var merchBankAccount = GetBankAccount(cid, (short)TraderBalanceAccountState.Enabled); if (merchBankAccount == null) { return(QctPayReturn.Fail(code: PayConst.FAIL_CODE_20001, msg: "您的商户结算账户不可用,请先确保商户结算账户可用再提交支付订单")); } var merchChannel = GetTraderPaySecretKeyAndChannel(cid, (short)TraderPayCchannelState.Enabled); if (merchChannel == null) { return(QctPayReturn.Fail(code: PayConst.FAIL_CODE_20001, msg: "您的商户不可用,请先确认是否已经成功申请商户")); } var payApiObj = GetPayApi(merchChannel.ChannelNo, method, version); if (payApiObj == null) { return(QctPayReturn.Fail(code: PayConst.FAIL_CODE_40001, msg: "非法支付接口参数名")); } var merchObj = GetMerchByID(cid, payApiObj); if (merchObj == null) { return(QctPayReturn.Fail(code: PayConst.FAIL_CODE_20001, msg: "找不到对应商户密钥配置信息,请先申请开通商户")); } merchObj.SourceType = payLicense.SourceType; merchObj.ApiNo = payApiObj.ApiNo; merchObj.ApiUrl = payApiObj.ApiUrl; merchObj.Method = payApiObj.Method; merchObj.OptType = payApiObj.OptType; return(QctPayReturn.Success(data: merchObj)); }
/// <summary> /// 根据CID获取商户的支付类型列表 /// </summary> /// <param name="cid"></param> /// <returns></returns> public QctPayReturn GetMerchPayModes(int cid) { var payLicenseObj = PaySvc.GetPayLicense(cid, (short)TraderPayLicenseState.Audited); if (payLicenseObj == null) { return(QctPayReturn.Fail("请先申请支付许可")); } var merchObj = PaySvc.GetMerchByCID(cid); if (merchObj == null) { return(QctPayReturn.Fail("请先申请开通商户,若您已经申请,请等待审核")); } var query = (from p in PayApiRepost.GetQuery() join jtpsk in TPaySecretKeyRepost.GetQuery() on p.ChannelNo equals jtpsk.ChannelNo into itpsk from tpsk in itpsk.DefaultIfEmpty() where tpsk.CID == cid && p.State == (short)PayApiState.HasReleased && p.OptType == (short)PayOperateType.Receipt select new MerchPayModeItem() { Title = p.Title, ChannelNo = p.ChannelNo, PayMode = p.TradeMode, State = DataItemState.Enabled }); var objs = query.ToList(); var data = new MerchPayMode() { CID = cid, Items = objs }; return(QctPayReturn.Success(data: objs)); }
/// <summary> /// 发送请求 /// </summary> /// <returns></returns> public QctPayReturn SendPost <TSxfReqModel, TSxfRspModel>(string url, TSxfReqModel sxfReqModel) where TSxfReqModel : SxfBaseTradeRequest where TSxfRspModel : SxfBaseTradeResponse { //var resultStr = string.Empty; try { var postResult = PayHelper.SendPost(url, PaySignHelper.ToDicAndSign(sxfReqModel, MerchModel.SecretKey3, "signature")); if (postResult.Successed) { var resultObj = JsonConvert.DeserializeObject <TSxfRspModel>(postResult.Data.ToString()); if (resultObj.IsSuccess()) { return(QctPayReturn.Success(data: resultObj)); } else { //处理返回失败结果 LogEngine.WriteError(string.Format("发送交易请求成功但返回交易错误信息:请求参数:{0},返回参数:{1}]", sxfReqModel.ToJson(), postResult), null, LogModule.支付交易); if (string.IsNullOrWhiteSpace(resultObj.RspMsg)) { resultObj.RspMsg = "服务器请求失败"; } return(QctPayReturn.Fail(PayTradeHelper.TransCodeBySxf(resultObj.RspCod), resultObj.RspMsg)); } } else { return(postResult); } } catch (Exception ex) { return(ResultFail(msg: "订单请求失败", logMsg: string.Format("发送交易请求异常:服务器异常,请求参数:{0},异常信息:{1}]", sxfReqModel.ToJson(), ex.Message))); } }
/// <summary> /// 是否有访问接口权限 /// </summary> /// <returns></returns> public QctPayReturn CanAccess() { var result = VerifyParams(); if (!result.Successed) { return(result); } result = VerifyMerchAccess(); if (!result.Successed) { return(result); } var merchStoreModel = GetMerchStore(); if (merchStoreModel == null) { return(QctPayReturn.Fail("找不到商户门店信息")); } return(QctPayReturn.Success()); }