/// <summary> /// Создаёт запрос check/pay/status /// </summary> /// <param name="old_state"></param> /// <returns></returns> public override int MakeRequest(int old_state) { try { if (old_state == 0) { // jreq.reqTime = Pcdate.AsCF(); // checkParam // freq.reqType = "queryPayeeInfo"; // Log($"MakeRequest for {freq.ToString()}"); } // Создать запрос Pay else if (old_state == 1) { if (Service.ToLower() == "rt-acc") { preq.svcTypeId = FindFilial(); preq.svcNum = Account; } else { preq.svcNum = '7' + Phone; } // preq.svcSubNum = jreq.svcSubNum; preq.payTime = XConvert.AsDateTZ(DateTime.Now, Settings.Tz); preq.reqTime = XConvert.AsDateTZ(Pcdate, Settings.Tz); preq.payAmount = (int?)(Amount * 100m); preq.payComment = $"Оплата {preq.payAmount} {preq.srcPayId} {preq.svcNum}"; preq.srcPayId = Tid.ToString(); preq.payerContact = Contact; stRequest = JsonConvert.SerializeObject(preq); Log($"Создан запрос\r\n{stRequest}"); return(0); } // Создать запрос Status else if (old_state == 3) { sreq.srcPayId = Tid.ToString(); stRequest = JsonConvert.SerializeObject(sreq); Log($"Создан запрос\r\n{stRequest}"); } // Запрос на отмену платежа else if (old_state == 8) { stRequest = JsonConvert.SerializeObject(ureq); Log($"Создан запрос\r\n{stRequest}"); } else { errCode = 2; errDesc = string.Format("Неизвестное состояние ({0}) платежа", old_state); state = 11; Log(ErrDesc); RootLog(ErrDesc); return(1); } } catch (Exception ex) { RootLog(ex.ToString()); return(1); } // stRequest = JsonConvert.SerializeObject(jreq); // Log($"Создан запрос\r\n{stRequest}"); return(0); }
public override int Undo() { byte old_state = state; int OK = 1; string x = !string.IsNullOrEmpty(Phone) ? Phone : !string.IsNullOrEmpty(Account) ? Account : !string.IsNullOrEmpty(Number) ? Number : ""; // Log("{0} Попытка отмены платежа", Tid); RootLog($"{Tid} [UNDO - начало] Num = {x} State = {State}"); ureq.srcPayId = Tid.ToString(); ureq.reqTime = XConvert.AsDateTZ(Pcdate, Settings.Tz); stRequest = JsonConvert.SerializeObject(ureq); if (MakeRequest(8) == 0 && PostJson(Host, stRequest) == 0 && ParseAnswer(stResponse) == 0) { Log($"{Tid} [UNDO - конец] reqStatus = {resp.reqStatus} payStatus = {resp.payStatus}"); if (resp.payStatus == 3) { errCode = 6; errDesc = "Платёж отменён оператором"; state = 10; } else if (resp.payStatus == 103) { errCode = 1; state = 3; errDesc = String.Format($"Платёж {Tid} отменяется: {ReqNote}"); } else { if (old_state == 6) { errCode = 3; } else if (old_state == 12) { errCode = 6; } else { errCode = 1; } errDesc = String.Format($"Ошибка отмены платежа: {ReqNote}"); } // Log("{0} err={1} desc={2} st={3}", Tid, ErrCode, ErrDesc, State); OK = 0; } else { errCode = 2; state = 11; } UpdateState(Tid, errCode: ErrCode, errDesc: ErrDesc, locked: 0, state: state); MakeAnswer(); return(OK); }
/// <summary> /// Выполнение запроса /// </summary> /// <param name="host">Хост (не используется)</param> /// <param name="old_state">Текущее состояние 0 - check, 1 - pay, 3 - staus</param> /// <param name="try_state">Состояние, присваиваемое при успешном завершении операции</param> /// <returns></returns> public override int DoPay(byte old_state, byte try_state) { // Создадим платеж с статусом=0 и locId = 1 // state 0 - новый // state 1 - получено разрешение int retcode = 0; // Создание шаблона сообщения check/pay/status pcdate = DateTime.Now.AddHours(-1); terminalDate = pcdate; tz = 6; RootLog("{3} Корректировка времени PC={0} old TD={1} new TD={2}", XConvert.AsDateTZ(Pcdate, Settings.Tz), XConvert.AsDateTZ(TerminalDate, Tz), XConvert.AsDateTZ(pcdate + TimeSpan.FromHours(Tz - Settings.Tz), Tz), Tid); if (Exec("UpdateTime", Tid, pcdate: Pcdate, terminalDate: terminalDate) != 0) { return(-1); } // Проверка времени создания платежа // Если платёж кис больше часа, скорректировать время /* * if (old_state == 0 && DateTime.Now.Ticks - Pcdate.Ticks > TimeSpan.TicksPerHour * 1) * { * pcdate = DateTime.Now; * * // Корректировка времени -1 * pcdate = pcdate.AddHours(-1); * * Random rnd = new Random((int)DateTime.Now.Ticks); * DateTime time = new DateTime(pcdate.Ticks - TimeSpan.TicksPerSecond * (long)(rnd.NextDouble() * 10.0)); * RootLog("{3} Корректировка времени PC={0} old TD={1} new TD={2}", * XConvert.AsDateTZ(Pcdate, Settings.Tz), * XConvert.AsDateTZ(TerminalDate, Tz), * XConvert.AsDateTZ(time + TimeSpan.FromHours(Tz - Settings.Tz), Tz), * Tid); * if (Exec("UpdateTime", Tid, pcdate :Pcdate, terminalDate :terminalDate) != 0) * return -1; * } */ // БД уже доступна, не будем её проверять if (MakeRequest(old_state) == 0) { // retcode = 0 - OK // retcode = 1 - TCP-error // retcode = 2 - Message sends, but no answer recieved. // retcode < 0 - System error if ((retcode = SendRequest(Host)) == 0) { if ((retcode = ParseAnswer(stResponse)) == 0) // Ответ получен и разобран; 1 - Timeout { if (old_state == 0) { errDesc = "Разрешение на платёж получено"; state = 1; errCode = 1; // ReportRequest("check "); // ReportCheck(); } else { state = 6; errCode = 3; // errCode = 3; errDesc = "Платёж проведён"; } UpdateState(tid, state: state, errCode: errCode, errDesc: errDesc, opname: Opname, opcode: Opcode, fio: fio, outtid: Outtid, account: Account, limit: Limit, limitEnd: XConvert.AsDate(LimitDate), acceptdate: XConvert.AsDate2(Acceptdate), acceptCode: AcceptCode, locked: state == 6 ? (byte)0 : (byte)1); // Разблокировать если проведён // ReportRequest("DoPay"); return(0); } } } // Запрос на разрешение платежа switch (retcode) { case 1: case 502: // Истекло время обработки state = old_state; break; case 358: // Нет запроса на прием платежа state = 0; break; case 103: // "Домашняя" БС абонента на профилактике или недоступна. case 106: // ЦМ не доступен state = times > 20 ? (byte)12 : old_state; break; case 200: // Прием платежа невозможен. Прием платежа запрещен (без детализации причины) case 201: // Номер телефона в БС не найден. case 202: // Приложение обслуживания не найдено. case 203: // Счет неактивен. case 205: // Описание клиента не найдено. case 206: // Абонент не найден // state = Pcdate.AddDays(1.0) <= DateTime.Now ? (byte)12 : old_state; // state = times > 20 ? (byte)12 : old_state; state = 12; break; case 301: // Нет денег state = 0; break; case 354: // Терминал не зарегистрирован // state = Pcdate.AddDays(1.0) <= DateTime.Now ? (byte)12 : old_state; state = old_state == 0? (byte)0: (byte)12; break; case 66: // ПЦ ЕСПП. Техническая ошибка сервера приложений state = 12; break; case 362: case 501: // Превышена пропускная способность case 367: // Номер уже обработан в ЕСПП case -20367: state = 11; break; case 357: // Платеж уже существует case 398: // Истекло время акцептования документа case 651: // Платеж в требуемом состоянии не найден if (old_state == 3 && lastcode == 357) { state = 12; } else { state = times > 20? (byte)12: (byte)3; } break; case 363: // Запрещен прием платежей с будущей датой операции вне допустимого диапазона RootLog("Дата вне диапазона Now={0} Pc={1} TD={2}", XConvert.AsDate2(DateTime.Now), XConvert.AsDate2(Pcdate), TerminalDate != null? XConvert.AsDate2(TerminalDate.Value): XConvert.AsDate2(DateTime.Now) ); state = 0; break; case 650: // Не определено состояние платежа state = 1; // разрешение получено, отпарвить зфн break; default: state = 12; break; } UpdateState(tid, state: state, errCode: retcode, errDesc: errDesc, locked: 0); return(1); }
/// <summary> /// Создать запрос к серверу ЕСПП. Скрывает базовый запрос. /// </summary> /// <param name="old_state">Статус (если не прошёл проверку 12)</param> /// <returns>0 - ОК, 1 - нет</returns> public new int MakeRequest(int old_state) { if (Settings.LogLevel.IndexOf("PARS") != -1) { RootLog("Параметры запроса:\r\nTimeout={0}\r\nPhone={1}\r\nAmount={2}\r\nCUR={3}\r\nService={4}\r\nTerminal={5}\r\nType={6}\r\nAS-VPS={7}\r\nContract={8}\r\nAccount={10}\r\nPrincipal={11}", TimeOut(), Phone, XConvert.AsAmount(Amount), Cur, Service, MtsTerminalId, TerminalType, Asvps, Contract, Account, Gateway); } switch (old_state) { case 0: using (StreamReader check = new StreamReader(Settings.Templates + (string.IsNullOrEmpty(Phone) ? "a": "p") + "-0104010-" + ProvidersSettings.Mts.Ott + "-" + ProvidersSettings.Mts.Xsd + ".tpl")) { checkTemplate = check.ReadToEnd(); } if (string.IsNullOrEmpty(Phone)) { stRequest = string.Format(checkTemplate, TimeOut(), XConvert.AsAmount(Amount), Cur, Service, MtsTerminalId, TerminalType, Asvps, Contract, Account, Gateway); } else { stRequest = string.Format(checkTemplate, TimeOut(), Phone, XConvert.AsAmount(Amount), Cur, Service, MtsTerminalId, TerminalType, Asvps, Contract, Gateway); } break; case 1: using (StreamReader pay = new StreamReader(Settings.Templates + (string.IsNullOrEmpty(Phone) ? "a" : "p") + "-0104090-" + ProvidersSettings.Mts.Ott + "-" + ProvidersSettings.Mts.Xsd + ".tpl")) { payTemplate = pay.ReadToEnd(); } controlCode = String.Format("{0}&{1}&{2}&{3}&{4}&{5}&{6}&{7}&{8}&{9}&{10}&{11}&{12}", Phone, XConvert.AsAmount(Amount), Cur, Service, Oid, Tid, XConvert.AsDate(Pcdate), Asvps, MtsTerminalId, TerminalType, XConvert.AsDateTZ(TerminalDate, Tz), string.IsNullOrEmpty(Phone)? Account: "", Gateway); if (Settings.LogLevel.IndexOf("DEBUG") != -1) { Log("DoPay: Cc=\"{0}\"", ControlCode); } using (Crypto sign = new Crypto(CommonName)) controlCode = sign.Sign(ControlCode); if (string.IsNullOrEmpty(Phone)) { stRequest = string.Format(payTemplate, XConvert.AsAmount(Amount), Cur, Service, Oid, MakeCheckNumber(), Tid, XConvert.AsDate(Pcdate), Outtid, Asvps, MtsTerminalId, TerminalType, Opcode, XConvert.AsDateTZ(TerminalDate, Tz), ControlCode, Contract, Account, Gateway); } else { stRequest = string.Format(payTemplate, Phone, XConvert.AsAmount(Amount), Cur, Service, Oid, MakeCheckNumber(), Tid, XConvert.AsDate(Pcdate), Outtid, Asvps, MtsTerminalId, TerminalType, Opcode, XConvert.AsDateTZ(TerminalDate, Tz), ControlCode, Contract, Gateway); } break; case 3: using (StreamReader status = new StreamReader(Settings.Templates + "0104085-" + ProvidersSettings.Mts.Ott + "-" + ProvidersSettings.Mts.Xsd + ".tpl")) { statusTemplate = status.ReadToEnd(); } stRequest = string.Format(statusTemplate, TimeOut(), Outtid, Asvps, Contract); break; } if (CheckXML(stRequest) != 0) { RootLog("Mts.MakeRequest {0}", ErrDesc); state = (byte)old_state; errCode = 11; } return(state == 12 ? 1 : 0); }
void TraceRequest() { StringBuilder sb = new StringBuilder(); if (Tid > 0) { sb.AppendFormat("srcPayId = {0} ", Tid); } sb.AppendFormat("reqType = {0} svcTypeId = {1} svcNum = {2} svcSubNum = {3} svcPurpose = 0 amount = {4}\r\n\t\t\tsvcComment = {5}\r\n", ReqType, SvcTypeID, SvcNum, SvcSubNum, XConvert.AsAmount(Amount), SvcComment); // Непустой для РТ-Мобайл if (!string.IsNullOrEmpty(agentAccount)) { sb.AppendFormat("\t\t\tagentAccount = {0}\r\n", agentAccount); } if (ReqTime != null) { sb.AppendFormat("\t\t\treqTime = {0}\r\n", XConvert.AsDateTZ(ReqTime.Value)); } if (Acceptdate != DateTime.MinValue) { sb.AppendFormat("\t\t\tacceptedTme/abandonedTime = {0}\r\n", XConvert.AsDateTZ(Acceptdate)); } if (!string.IsNullOrEmpty(Outtid)) { sb.AppendFormat("\t\t\tesppPayId = {0}\r\n", Outtid); } if (ReqStatus != null) { sb.AppendFormat("\t\t\treqStatus = {0}\r\n", ReqStatus); } if (PayStatus != null) { sb.AppendFormat("\t\t\tpayStatus = {0}\r\n", PayStatus); } if (DupFlag != null) { sb.AppendFormat("\t\t\tdupFlag = {0}\r\n", DupFlag); } if (!string.IsNullOrEmpty(ReqNote)) { sb.AppendFormat("\t\t\treqNote = {0}\r\n", ReqNote); } if (!string.IsNullOrEmpty(AddInfo)) { sb.AppendFormat("\t\t\treqUsrMsg = {0}\r\n", AddInfo); } if (!string.IsNullOrEmpty(Opname)) { sb.AppendFormat("dstDepCode = {0}\r\n", Opname); } if (!string.IsNullOrEmpty(Fio)) { sb.AppendFormat("\t\t\tpayeeName = {0}\r\n", Fio); } if (Price != decimal.MinusOne) { sb.AppendFormat("\t\t\tpayeeRemain = {0}\r\n", XConvert.AsAmount(Price)); } if (sb.ToString().Length > 0) { Log(sb.ToString()); } }
/// <summary> /// Создаёт запрос check/pay/status /// </summary> /// <param name="old_state"></param> /// <returns></returns> public override int MakeRequest(int old_state) { StringBuilder p = new StringBuilder(); try { pcdate = Pcdate.AddHours(-1); } catch (Exception) { pcdate = DateTime.Now.AddHours(-1); } operdate = DateTime.Now.AddHours(-1); try { // выполнить проверку возможности платежа и вернуть баланс счёта if (old_state == 0) { ReqType = "queryPayeeInfo"; p.AppendFormat("reqType={0}", ReqType); if (!string.IsNullOrEmpty(SvcTypeID)) { p.AppendFormat("&svcTypeId={0}", HttpUtility.UrlEncode(SvcTypeID)); } p.AppendFormat("&svcNum={0}", SvcNum); if (!string.IsNullOrEmpty(Phone) && Provider == "rt") { p.AppendFormat("&svcNum=7{0}", SvcNum); } if (!string.IsNullOrEmpty(SvcSubNum)) { p.AppendFormat("&svcSubNum={0}", SvcSubNum); } p.Append("&queryFlags=13"); // Остаток на счёте p.AppendFormat("&agentAccount={0}", agentAccount); // Остаток на счёте } // Создать запрос Pay else if (old_state == 1) { ReqType = "createPayment"; p.AppendFormat("reqType={0}", ReqType); p.AppendFormat("&srcPayId={0}", Tid); if (!string.IsNullOrEmpty(SvcTypeID)) { p.AppendFormat("&svcTypeId={0}", HttpUtility.UrlEncode(SvcTypeID)); } // p.AppendFormat("&svcNum={0}", SvcNum); if (!string.IsNullOrEmpty(Phone) && Provider == "rt") { p.AppendFormat("&svcNum=7{0}", SvcNum); } else { p.AppendFormat("&svcNum={0}", SvcNum); } if (!string.IsNullOrEmpty(SvcSubNum)) { p.AppendFormat("&svcSubNum={0}", SvcSubNum); } // Непустой для РТ-Мобайл // if (!string.IsNullOrEmpty(agentAccount)) // p.AppendFormat("&payTime={0}", HttpUtility.UrlEncode(XConvert.AsDateTZ(Pcdate, Settings.Tz))); p.AppendFormat("&payTime={0}", HttpUtility.UrlEncode(XConvert.AsDateTZ(Operdate, Settings.Tz))); p.AppendFormat("&reqTime={0}", HttpUtility.UrlEncode(XConvert.AsDateTZ(Pcdate, Settings.Tz))); p.AppendFormat("&payAmount={0}", (int)(Amount * 100m)); p.AppendFormat("&agentAccount={0}", agentAccount); // PayDetails = string.Format("{0}|{1}|{3}", SvcSubNum, PayAmount, PayPurpose); p.Append("&payCurrId=RUB"); p.Append("&payPurpose=0"); p.AppendFormat("&payComment={0}", HttpUtility.UrlEncode(Comment)); } // Создать запрос Status else if (old_state == 3) { if (queryFlag != "") { p.Append("reqType=getPaymentStatus"); if (!string.IsNullOrEmpty(Account)) { p.AppendFormat("&svcNum={0}", Account); } if (!string.IsNullOrEmpty(AccountParam)) { p.AppendFormat("&svcSubNum={0}", AccountParam); } if (SvcTypeID != "") { p.AppendFormat("&svcTypeId={0}", HttpUtility.UrlEncode(SvcTypeID)); } p.AppendFormat("&queryFlags={0}", queryFlag); } else if (Tid != 0 && Tid != int.MinValue) { p.Append("reqType=getPaymentStatus"); } else { p.Append("reqType=getPaymentsStatus"); } if (Tid != 0 && Tid != int.MinValue) { p.AppendFormat("&srcPayId={0}", Tid); } if (StatusType != null) { p.AppendFormat("&statusType={0}", StatusType); } if (StartDate != null) { p.AppendFormat("&startDate={0}", HttpUtility.UrlEncode(XConvert.AsDateTZ(StartDate, Settings.Tz))); } if (EndDate != null) { p.AppendFormat("&endDate={0}", HttpUtility.UrlEncode(XConvert.AsDateTZ(EndDate, Settings.Tz))); } // Непустой для РТ-Мобайл // if (!string.IsNullOrEmpty(agentAccount)) p.AppendFormat("&agentAccount={0}", agentAccount); } // Запрос на отмену платежа else if (old_state == 8) { ReqType = "abandonPayment"; p.AppendFormat("reqType={0}", ReqType); p.AppendFormat("&srcPayId={0}", Tid); p.AppendFormat("&reqTime={0}", HttpUtility.UrlEncode(XConvert.AsDateTZ(Pcdate, Settings.Tz))); // Непустой для РТ-Мобайл // if (!string.IsNullOrEmpty(agentAccount)) p.AppendFormat("&agentAccount={0}", agentAccount); } else { errCode = 2; errDesc = string.Format("Неизвестное состояние ({0}) платежа", old_state); state = 11; Log(ErrDesc); RootLog(ErrDesc); return(1); } } catch (Exception ex) { RootLog("{0}\r\n{1}", ex.Message, ex.StackTrace); } // p.AppendFormat("&reqTime={0}", UrlEncode(XConvert.AsDateTZ(Pcdate))); // stRequest = HttpUtility.UrlEncode(p.ToString()).Replace(HttpUtility.UrlEncode("&"), "&").Replace(HttpUtility.UrlEncode("="), "="); stRequest = p.ToString(); Log("\r\nComment: {0}", SvcComment); // Log("Запрос к {0}\r\n=======================================\r\n{1}", Host, stRequest.Replace("&", "\r\n")); // Log(stRequest); // stRequest = HttpUtility.UrlEncode(stRequest); // Log(" \r\n--------------------------------------\r\n{0}", stRequest.Replace("%26", "\r\n")); return(0); }