/// <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); }
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 CheckState(Object stateInfo) { if (Canceling) { return; // Запущен процесс остановки службы } GWRequest gw = ((CheckInfo)stateInfo).gw; try { // Увеличим счетчик процессов RegisterBackgroundProcess(); // Если отладка не производится... if (gw.Provider == Settings.Cyber.Name) { gw = new GWCyberRequest(gw); } // else if (gw.Provider == Settings.Mts.Name) // gw = new GWMtsRequest(gw); else if (gw.Provider == Settings.Ekt.Name) { gw = new GWEktRequest(gw); } else if (gw.Provider == "boriska") { gw = new ServerGate(gw); } else if (gw.Provider == Settings.Rt.Name) { gw = new RT.RTClass16(gw); } else if (gw.Provider == Settings.Rapida.Name) { gw = new GWRapidaRequest(gw); } else if (gw.Provider == Settings.Xsolla.Name) { gw = new GWXsolllaRequest(gw); } if (gw != null) { gw.SetLock(1); gw.ReportRequest("REDO - strt"); // Синхронизация с БД Город gw.Sync(false); // Выполнение допроведения if (gw.State < 6) { gw.Processing(false); } gw.ReportRequest("REDO"); } } catch (Exception ex) { Log(ex.ToString()); gw.ReportRequest("REDO"); } finally { if (gw != null) { gw.SetLock(0); } // Уменьшим счетчик процессов UnregisterBackgroundProcess(); } }