// Отправить ответ клиенту private void SendAnswer(RequestInfo dataHolder, GWRequest gw) { string stResponse = "<XML><Result>OK</Result></XML>"; try { // Создаем ответ byte[] buffer = dataHolder.ClientEncoding.GetBytes(dataHolder.ClientEncoding.CodePage == 1251 ? Properties.Settings.Default.XmlHeader1251 + "\r\n" + stResponse : Properties.Settings.Default.XmlHeader + "\r\n" + stResponse); dataHolder.Context.Response.ContentLength64 = buffer.Length; // Utility.Log("tid={0}. Ответ MTS-GATE --> OE\r\n{1}", tid, stResponse); System.IO.Stream output = dataHolder.Context.Response.OutputStream; output.Write(buffer, 0, buffer.Length); } catch (WebException we) { Log("[{0}]: Tid={1}, ({2}){3}", gw.RequestType, gw.Tid, Convert.ToInt32(we.Status) + 10000, we.Message); } catch (Exception ex) { Log("[{0}]: Tid={1}, {2}\r\n{3}", gw.RequestType, gw.Tid, ex.Message, ex.StackTrace); } } // makeResponse
public GWPccRequest(GWRequest src, string cn = "") : this(cn) { this.provider = src.Provider; this.tid = src.Tid; this.phone = src.Phone; this.phoneParam = src.PhoneParam; this.account = src.Account; // Номер л/с this.accountParam = src.AccountParam; this.filial = src.Filial; // Номер филиала. this.filialParam = src.FilialParam; this.amount = src.Amount; this.amountAll = src.AmountAll; this.pcdate = src.Pcdate; this.commonName = src.CommonName; this.service = src.Service; this.terminal = src.Terminal; this.transaction = src.Transaction; this.templateName = src.TemplateName; }
GWRequest Reposting(GWRequest Request) { GWRequest Current = Request; DateTime OperDate = DateTime.Now; try { string x = null; byte old_state = Request.State; x = !string.IsNullOrEmpty(Request.Phone)? Request.Phone: !string.IsNullOrEmpty(Request.Account)? Request.Account: !string.IsNullOrEmpty(Request.Number)? Request.Number: ""; DateTime?LastAttempt = LastOperDate(Request.Tid); int last = (int)((DateTime.Now.Ticks - LastAttempt.Value.Ticks) / TimeSpan.TicksPerSecond); Log("{0} [REPT - strt] last={1} st={2} Num={3} S={4} A={5} err={6} {7}", Request.Tid, last, Request.State, x, XConvert.AsAmount(Request.AmountAll), XConvert.AsAmount(Request.Amount), Request.ErrCode, Request.ErrDesc); // Если запрос отправлен менее минуты назат - перепровести if (last > 60) { // Т.к. запрос частично затёрт вызовом GetSate() - сделаем новый разбор // Разбор входного запроса. 0 - запрос разобран. Request.Dispose(); Request = new GWRequest(); // Параметры заполнены на основе входного запроса Request.Parse(m_data.stRequest); Request.State = 0; Request.errCode = 0; Request.errDesc = "Перепроведение платежа"; Request.UpdatePayment(); // Для начала определимя с провайдером: switch (Request.Provider) { case "rt": Current = new RTClass16(Request); break; case "ekt": Current = new GWEktRequest(Request); break; case "cyber": Current = new GWCyberRequest(Request); break; case "mts": Current = new GWMtsRequest(Request); break; } // Current.Processing(old_state, 1, "Перепроведение платежа"); // Перепроведение Current.Processing(false); x = !string.IsNullOrEmpty(Current.Phone)? Current.Phone: !string.IsNullOrEmpty(Current.Account)? Current.Account: !string.IsNullOrEmpty(Current.Number)? Current.Number: ""; } else { Log("{0} [REPT - stop] перепроведение не производится", Request.Tid); } // Log("Tid={0} [REPOST - конец] st={1} Num={2} S={3} A={4} err={5} {6}", // Current.Tid, Current.State, x, XConvert.AsAmount(Current.AmountAll), XConvert.AsAmount(Current.Amount), Current.ErrCode, Current.ErrDesc); } catch (Exception ex) { Current.errDesc = string.Format(Messages.InternalPaymentError, ex.Message); Log("{0}\r\n{1}", Current.errDesc, ex.StackTrace); Current.UpdateState(Current.Tid, state: Current.State, errCode: Current.ErrCode, errDesc: Current.ErrDesc); } finally { if (Current != null) { Current.SetLock(0); } } return(Current); }
/// <summary> /// Конвейер обработки запроса /// </summary> public void Run() { // m_data.stRequest - содержит клиентский запрос // HttpListenerRequest request = m_data.Context.Request; // Разбор входного запроса. 0 - запрос разобран. GWRequest Request = new GWRequest(); GWRequest Current = Request; string step = ""; bool ValidProvider = true; try { if (Request?.Parse(m_data.stRequest) == 0) { // Запустим цикл выполнения запроса: // Check --> // Pay --> // и если необходимо Status. // Log($"REQ: Provider=\"{Request.Provider}\" Request=\"{Request.RequestType}\" Service=\"{Request.Service}\""); // Для начала определимся с провайдером: switch (Request.Provider) { case "rt": Current = new RTClass16(Request); break; case "ekt": Current = new GWEktRequest(Request); break; case "boriska": Current = new ServerGate(Request); break; case "cyber": Current = new GWCyberRequest(Request); break; case "mts": Current = new GWMtsRequest(Request); break; case "rapida": Current = new GWRapidaRequest(Request); break; case "xsolla": Current = new GWXsolllaRequest(Request); break; case "school": Current = new SchoolGateway.SchoolGatewayClass(Request); break; // case "smtp": // Current = new Oldi.Smtp.Smtp(Request); // break; default: // Log(Messages.UnknownProvider, Request.Provider); if (Request.RequestType.ToLower() != "status") { Current.ErrCode = 6; Current.State = 12; Current.ErrDesc = string.Format(Messages.UnknownProvider, Request.Provider); Log($"Processing.Run(): Unknown provider \"{Request.Provider}\""); Current.UpdateState(Current.Tid, state: Current.State, errCode: Current.ErrCode, errDesc: Current.ErrDesc); ValidProvider = false; } break; } if (ValidProvider) { switch (Request.RequestType.ToLower()) { case "check": Current.ReportRequest("CHCK - strt"); step = "CHCK - stop"; Current.Check(); break; case "find": Current.ReportRequest("CHCK - strt"); step = "CHCK - stop"; Current.Check(); break; case "status": // Прочитать из БД информацию о запросе // Request.ReportRequest("STATUS - начало"); // step = "STAT - stop"; if (Request.Provider == "rt") { Current.GetPaymentStatus(); Current.UpdateState(Current.Tid, state: Current.State, errCode: Current.ErrCode, errDesc: Current.ErrDesc); // gw.ReportRequest("status".ToUpper()); } else { Current.GetState(); if (Current.State == 255) { // Log(string.Format(Messages.PayNotFound, Current.Tid)); Current.State = 12; Current.errCode = 11; Current.errDesc = string.Format(Messages.PayNotFound, Current.Tid); } } // Log(Messages.StatusRequest, Current.Tid, Current.ErrDesc); break; case "getpaymentsstatus": Current = new RTClass16(Request); Log(Messages.StatusRequest, Current.Tid); Current.GetPaymentStatus(); Current.UpdateState(Current.Tid, state: Current.State, errCode: Current.ErrCode, errDesc: Current.ErrDesc); break; // Отмена платежа // Отменяет платёж на шлюзе, затем в процессинге case "undo": Current.GetPaymentInfo(); Current.ReportRequest("UNDO - strt"); step = "UNDO - stop"; // Добавим в Undo запрос в иноват // Добавим запрос в Ростелеком-Test if (Current.Provider == "rt" || Current.Provider == "school") { Current.Undo(); } else { Current.ErrCode = 6; Current.State = 12; Current.ErrDesc = string.Format(Messages.ManualUndo, Request.Provider); Current.UpdateState(Current.Tid, state: Current.State, errCode: Current.ErrCode, errDesc: Current.ErrDesc); } break; // Создание и попытка проведения нового платежа case "payment": // Проверим наличие платежа и его статус. Current.GetState(); // Log($"{Current.Tid} [PAYM strt] Status={Current.State}"); // Если платёж не существует (state == 255) if (Current.State == 255) { Current.State = 0; Current.GetTerminalInfo(); Current.ReportRequest("PAYM - strt"); step = "PAYM - stop"; // Поиск дублей int Doubles = 0; // Если sub_inner_tid содержит 3 '-' возвращает непустую строку // string SubInnertid = Current.GetGorodSub(); // Искать задвоенные платежи по параметрам: // Point_oid // Template_tid // User_id // Account // Amount, Commission, Summary_amount // if (!string.IsNullOrEmpty(SubInnertid) && (Doubles = Current.GetDoubles(SubInnertid)) > 0) if (Current.GetDoubles() > 0) { Log($"{Current.Tid} [Check doubles] Для acc={Current.ID()} найдено {Doubles} дублей"); Current.State = 12; Current.errCode = 6; Current.errDesc = $"Найдено {Doubles} подобных платежей в пределах 10 часов. Платёж отменяется."; Current.UpdateState(Current.Tid, state: Current.State, errCode: Current.ErrCode, errDesc: Current.ErrDesc); } // if (!string.IsNullOrEmpty(SubInnertid)) // Log("{0} [DOUB - stop] {1}", Request.Tid, Request.ErrDesc); // Если статус равен 0 // И если возможность есть -- провести его if (Current.State == 0) { Current.Processing(true); } } // Платёж существует - вернём его статус else if (Current.Provider == "rt" || Current.Provider == "rt-test") { Current.GetPaymentStatus(); Current.UpdateState(Current.Tid, state: Current.State, errCode: Current.ErrCode, errDesc: Current.ErrDesc); // gw.ReportRequest("status".ToUpper()); } else if (/* Request.State == 12 || */ Request.State == 11) { Current = Reposting(Current); step = "REPT - stop"; } else { step = "STAT - stop"; } break; // Перепроведение // case "reposting": // break; default: Current.errDesc = $"Неизвестный запрос {Request.RequestType}"; Log($"Неизвестный запрос \"{Request.RequestType}\" в {m_data.stRequest}"); break; // m_data.stResponse = string.Format(Properties.Settings.Default.FailResponse, 6, "Неверный запрос"); // SendAnswer(m_data); // return; } } } else { Log(Messages.ParseError, Current.errCode, Current.errDesc); } } catch (Exception ex) { Current.errCode = 11; Current.errDesc = ex.Message; Log(ex.ToString()); } finally { Current?.SetLock(0); } if (Current.RequestType.ToLower() != "status") { Current.ReportRequest(step); } SendAnswer(m_data, Current); Interlocked.Decrement(ref GWListener.processes); }
/// <summary> /// Отпарвляет ответ OE /// </summary> /// <param name="dataHolder">Контекст запроса OE</param> /// <param name="r">Платёж</param> private void SendAnswer(RequestInfo dataHolder, GWRequest r) { if (r == null) { SendAnswer(dataHolder); return; } string stResponse = r.Answer; string errDesc = !string.IsNullOrEmpty(r.ErrDesc)? HttpUtility.HtmlEncode(r.ErrDesc): ""; // Log($"[SendAnswer] Provider={r.Provider} stResponse={stResponse}"); try { if (r.Provider != Settings.Rt.Name && r.Provider != Settings.Rapida.Name && r.Gateway != "lyapko") // уже заполненнвй Answer { if (r.State == 6 || r.State == 0 /* && r.Provider == "rapida" */) { // stResponse = string.Format(Properties.Settings.Default.Response, 3, gw.ErrDesc, gw.Outtid, gw.Acceptdate, gw.AcceptCode, gw.Account, gw.AddInfo); int pos = 0; string addInfo = r.AddInfo ?? ""; if (addInfo.Length > 250) { pos = addInfo.IndexOf(";"); if (pos > 0) { addInfo = addInfo.Substring(pos + 2); } if (addInfo.Length > 250) { addInfo = addInfo.Substring(0, 250); } } stResponse = string.Format(Properties.Settings.Default.Response, 3, errDesc, r.Outtid, r.Acceptdate, r.AcceptCode, r.Account, addInfo, XConvert.AsAmount(r.Price)); // errDesc = r.ErrDesc; } else if (r.State == 12) { stResponse = string.Format(Properties.Settings.Default.FailResponse, 6, errDesc); } else if (r.State == 0 && r.ErrCode == 7) // Передача управляющих кодов 7 { stResponse = string.Format(Properties.Settings.Default.FailResponse, r.ErrCode, errDesc); } else if (r.ErrCode == 11 || r.ErrCode == 12) // Передача управляющих кодов 11, 12 { stResponse = string.Format(Properties.Settings.Default.FailResponse, r.ErrCode, errDesc); } else if (r.State == 11) // Отложен { stResponse = string.Format(Properties.Settings.Default.FailResponse, 2, errDesc); } else if (r.State == 1) // { stResponse = string.Format(Properties.Settings.Default.FailResponse, 2, errDesc); } else { stResponse = string.Format(Properties.Settings.Default.FailResponse, 1, r.Price > 0M ? string.Format("{0} \"{1} {2}\"", errDesc, Messages.SumWait, XConvert.AsAmount(r.Price)): errDesc); } } if (string.IsNullOrEmpty(stResponse)) { stResponse = string.Format("<Response><ErrCode>{0}</ErrCode><ErrDesc>{1}</ErrDesc></Response>", r.ErrCode, r.ErrDesc); Log("{0} не получен ответ st={1} err={2} desc={3}", r.Tid, r.State, r.ErrDesc, r.ErrCode); } if (r.Gateway == "lyapko") { Log(stResponse); } // Создаем ответ string answer = string.Format("<?xml version=\"1.0\" encoding=\"{0}\"?>\r\n{1}", dataHolder.ClientEncoding.WebName, stResponse); byte[] buffer = dataHolder.ClientEncoding.GetBytes(answer); dataHolder.Context.Response.ContentLength64 = buffer.Length; if (Settings.LogLevel.IndexOf("OEREQ") != -1) { Log(Properties.Resources.MsgResponseGW, stResponse); } // Utility.Log("tid={0}. Ответ MTS-GATE --> OE\r\n{1}", tid, stResponse); System.IO.Stream output = dataHolder.Context.Response.OutputStream; output.Write(buffer, 0, buffer.Length); } catch (WebException we) { Log("[{0}]: Tid={1}, ({2}){3}", r.RequestType, r.Tid, Convert.ToInt32(we.Status) + 10000, we.Message); } catch (Exception ex) { Log("[{0}]: Tid={1}, {2}\r\n{3}", r.RequestType, r.Tid, ex.Message, ex.StackTrace); } } // makeResponse
public GWXsolllaRequest(GWRequest src) : base(src) { provider = src.Provider; templateName = src.TemplateName; tid = src.Tid; transaction = src.Transaction; terminal = src.Terminal; terminalType = src.TerminalType; realTerminalId = src.RealTerminalId; service = src.Service; gateway = src.Gateway; operdate = src.Operdate; pcdate = src.Pcdate; terminalDate = src.TerminalDate; tz = src.Tz; transaction = src.Transaction; checkNumber = src.CheckNumber; oid = src.Oid; cur = src.Cur; session = Properties.Settings.Default.SessionPrefix + tid.ToString(); // session = src.Session; state = src.State; lastcode = src.Lastcode; lastdesc = src.Lastdesc; times = src.Times; phone = src.Phone; phoneParam = src.PhoneParam; account = src.Account; accountParam = src.AccountParam; card = src.Card; amount = src.Amount; amountAll = src.AmountAll; number = src.Number; orgname = src.Orgname; docnum = src.Docnum; docdate = src.Docdate; purpose = src.Purpose; fio = src.Fio; address = src.Address; agree = 1; contact = src.Contact; inn = src.Inn; comment = src.Comment; acceptdate = src.Acceptdate; acceptCode = src.AcceptCode; outtid = src.Outtid; addinfo = src.AddInfo; errMsg = src.ErrMsg; opname = src.Opname; opcode = src.Opcode; pause = src.Pause; kpp = src.Kpp; payerInn = src.PayerInn; ben = src.Ben; bik = src.Bik; tax = src.Tax; kbk = src.KBK; okato = src.OKATO; payType = src.PayType; reason = src.Reason; statusType = src.StatusType; startDate = src.StartDate; endDate = src.EndDate; attributes = new AttributesCollection(); attributes.Add(src.Attributes); InitializeComponents(); }
public ServerGate(GWRequest src) : base(src) { terminal = src.Terminal; }