///<summary>Creates and returns the HPF URL and validation OTK which can be used to make a payment for an unspecified credit card. Throws exceptions.</summary> public static string GetHpfUrlForPayment(Patient pat, string accountToken, string payNote, bool isMobile, double amount, bool saveToken, CreditCardSource ccSource) { if (pat == null) { throw new ODException("No Patient Found", ODException.ErrorCodes.NoPatientFound); } if (string.IsNullOrWhiteSpace(accountToken)) { throw new ODException("Invalid Account Token", ODException.ErrorCodes.OtkArgsInvalid); } if (amount < 0.00 || amount > 99999.99) { throw new ODException("Invalid Amount", ODException.ErrorCodes.OtkArgsInvalid); } if (string.IsNullOrEmpty(payNote)) { throw new ODException("Invalid PayNote", ODException.ErrorCodes.OtkArgsInvalid); } PayConnectResponseWeb responseWeb = new PayConnectResponseWeb() { Amount = amount, AccountToken = accountToken, PatNum = pat.PatNum, ProcessingStatus = PayConnectWebStatus.Created, PayNote = payNote, CCSource = ccSource, IsTokenSaved = saveToken, }; PayConnectResponseWebs.Insert(responseWeb); try { string url; PayConnectREST.PostPaymentRequest(responseWeb, out url); PayConnectResponseWebs.Update(responseWeb); WakeupWebPaymentsMonitor?.Invoke(url, new EventArgs()); return(url); } catch (Exception e) { PayConnectResponseWebs.HandleResponseError(responseWeb, "Error calling PostPaymentRequest: " + e.Message); PayConnectResponseWebs.Update(responseWeb); throw; } }
///<summary>Poll the existing PayConnectResponseWeb for status changes. ///This method will update the ResponseJSON/ProcessingStatus with any changes</summary> public static void GetPaymentStatus(PayConnectResponseWeb responseWeb) { #region Response Object var resObj = new { Amount = -1.00, TransactionType = "", TransactionStatus = "", TransactionDate = DateTime.MinValue, StatusDescription = "", //Used to poll for getting the payment status to see if the user has made a payment. PayToken = "", CreditCardNumber = "", CreditCardExpireDate = "", TransactionID = -1, RefNumber = "", Pending = true, Status = new { code = -1, description = "", }, Messages = new { Message = new string[0] }, //Used for future payments with this card. Do not confuse this with PayToken. PaymentToken = new { TokenId = "", Expiration = new { month = "", year = "", }, Messages = new { Message = new string[0] }, }, }; #endregion List <string> listHeaders = GetClientRequestHeadersForWebURL(); listHeaders.Add("AccountToken: " + responseWeb.AccountToken); try { var res = Request(ApiRoute.PaymentStatus, HttpMethod.Get, listHeaders, "", resObj, $"?payToken={responseWeb.PayToken}"); if (res == null) { PayConnectResponseWebs.HandleResponseError(responseWeb, JsonConvert.SerializeObject(res)); throw new ODException("Invalid response from PayConnect."); } int code = -1; string codeMsg = ""; if (res.Status != null) { code = res.Status.code; codeMsg = "Response code: " + res.Status.code + "\r\n"; } if (code > 0) { string err = "Invalid response from PayConnect.\r\nResponse code: " + code; if (res.Messages != null && res.Messages.Message != null && res.Messages.Message.Length > 0) { err += "\r\nError retrieving payment status.\r\nResponse message(s):\r\n" + string.Join("\r\n", res.Messages.Message); } PayConnectResponseWebs.HandleResponseError(responseWeb, JsonConvert.SerializeObject(res)); throw new ODException(err); } if (res.Pending) { HandleResponseSuccess(responseWeb, JsonConvert.SerializeObject(res), true); } else if (res.TransactionStatus != null && (res.TransactionStatus.Contains("Timeout") || res.TransactionStatus.Contains("Cancelled") || res.TransactionStatus.Contains("Declined"))) { responseWeb.LastResponseStr = JsonConvert.SerializeObject(res); responseWeb.ProcessingStatus = res.TransactionStatus.Contains("Declined") ? PayConnectWebStatus.Declined : (res.TransactionStatus.Contains("Cancelled") ? PayConnectWebStatus.Cancelled : PayConnectWebStatus.Expired); responseWeb.DateTimeExpired = MiscData.GetNowDateTime(); } else if (res.TransactionStatus != null && res.TransactionStatus.Contains("Approved")) { string expYear = res.PaymentToken.Expiration.year.Substring(res.PaymentToken.Expiration.year.Length - 2); //Last 2 digits only string expMonth = res.PaymentToken.Expiration.month.PadLeft(2, '0'); //2 digit month with leading 0 if needed responseWeb.PaymentToken = res.PaymentToken.TokenId; responseWeb.ExpDateToken = expYear + expMonth; //yyMM format responseWeb.RefNumber = res.RefNumber; responseWeb.TransType = PayConnectService.transType.SALE; HandleResponseSuccess(responseWeb, JsonConvert.SerializeObject(res), res.Pending); } else { responseWeb.LastResponseStr = JsonConvert.SerializeObject(res); responseWeb.ProcessingStatus = PayConnectWebStatus.Unknown; responseWeb.DateTimeLastError = MiscData.GetNowDateTime(); } } catch (Exception ex) { PayConnectResponseWebs.HandleResponseError(responseWeb, ex.Message); throw; } }