///<summary></summary> public static void Update(PayConnectResponseWeb payConnectResponseWeb) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { Meth.GetVoid(MethodBase.GetCurrentMethod(), payConnectResponseWeb); return; } Crud.PayConnectResponseWebCrud.Update(payConnectResponseWeb); }
///<summary></summary> public static long Insert(PayConnectResponseWeb payConnectResponseWeb) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { payConnectResponseWeb.PayConnectResponseWebNum = Meth.GetLong(MethodBase.GetCurrentMethod(), payConnectResponseWeb); return(payConnectResponseWeb.PayConnectResponseWebNum); } return(Crud.PayConnectResponseWebCrud.Insert(payConnectResponseWeb)); }
///<summary>Outputs the URL for making a payment through PayConnect. ///Sets the responseWeb's payment token to be updated. ///Throws exceptions if the request/response is invalid.</summary> public static void PostPaymentRequest(PayConnectResponseWeb responseWeb, out string url) { #region Response Object var resObj = new { PayToken = "", Url = "", Status = new { code = -1, description = "", }, Messages = new { Message = new string[0] } }; #endregion //var res=PostPaymentRequestResponseMock(resObj); List <string> listHeaders = GetClientRequestHeadersForWebURL(); listHeaders.Add("AccountToken: " + responseWeb.AccountToken); string postBody = JsonConvert.SerializeObject(new { Amount = responseWeb.Amount, InvoiceNumber = responseWeb.PayConnectResponseWebNum, }); var res = Request(ApiRoute.PaymentRequest, HttpMethod.Post, listHeaders, postBody, resObj); if (res == null) { 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 request.\r\nResponse message(s):\r\n" + string.Join("\r\n", res.Messages.Message); } throw new ODException(err); } if (string.IsNullOrWhiteSpace(res.PayToken) || string.IsNullOrWhiteSpace(res.Url)) { throw new ODException("Invalid payment token or URL was retrieved from PayConnect." + (res.Status == null ? "" : "\r\n" + "Response code: " + res.Status.code)); } url = res.Url; responseWeb.PayToken = res.PayToken; HandleResponseSuccess(responseWeb, JsonConvert.SerializeObject(res), true); }
///<summary>Sets the necessary fields for the given responseWeb object. ///expDate should be in yyMM format.</summary> private static void HandleResponseSuccess(PayConnectResponseWeb responseWeb, string resStr, bool isPending) { if (isPending) { responseWeb.ProcessingStatus = PayConnectWebStatus.Pending; responseWeb.DateTimePending = MiscData.GetNowDateTime(); } else { responseWeb.ProcessingStatus = PayConnectWebStatus.Completed; responseWeb.DateTimeCompleted = MiscData.GetNowDateTime(); } responseWeb.LastResponseStr = resStr; }
public static void HandleResponseError(PayConnectResponseWeb responseWeb, string resStr) { responseWeb.LastResponseStr = resStr; if (responseWeb.ProcessingStatus == PayConnectWebStatus.Created) { responseWeb.ProcessingStatus = PayConnectWebStatus.CreatedError; } else if (responseWeb.ProcessingStatus == PayConnectWebStatus.Pending) { responseWeb.ProcessingStatus = PayConnectWebStatus.PendingError; } else { responseWeb.ProcessingStatus = PayConnectWebStatus.UnknownError; } responseWeb.DateTimeLastError = MiscData.GetNowDateTime(); }
///<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; } }
///<summary>Make a payment using HPF directly. Throws exceptions.</summary> public static void MakePaymentWithAlias(Patient pat, string payNote, double amount, CreditCard cc) { if (pat == null) { throw new ODException("No Patient Found", ODException.ErrorCodes.NoPatientFound); } 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); } if (cc == null) { throw new ODException("No Credit Card Found", ODException.ErrorCodes.OtkArgsInvalid); } if (string.IsNullOrEmpty(cc.PayConnectToken)) { throw new ODException("Invalid CC Alias", ODException.ErrorCodes.OtkArgsInvalid); } //request a PayConnect token, if a token was already saved PayConnect will return the same token, //otherwise replace CCNumberMasked with the returned token if the sale successful PayConnectService.creditCardRequest payConnectRequest = PayConnect.BuildSaleRequest( (decimal)amount, cc.PayConnectToken, cc.CCExpiration.Year, cc.CCExpiration.Month, pat.GetNameFLnoPref(), "", cc.Zip, null, PayConnectService.transType.SALE, "", true); //clinicNumCur could be 0, and the practice level or 'Headquarters' PayConnect credentials would be used for this charge PayConnectService.transResponse payConnectResponse = PayConnect.ProcessCreditCard(payConnectRequest, pat.ClinicNum, x => throw new ODException(x)); if (payConnectRequest != null && payConnectResponse.Status.code == 0) //Success { string receipt = BuildReceiptString(payConnectRequest.TransType, payConnectResponse.RefNumber, payConnectRequest.NameOnCard, payConnectRequest.CardNumber, payConnectRequest.MagData, payConnectResponse.AuthCode, payConnectResponse.Status.description, payConnectResponse.Messages.ToList(), payConnectRequest.Amount, 0, pat.ClinicNum); DateTime dateTimeProcessed = DateTime.Now; string formattedNote = Lans.g("PayConnect", "Amount:") + " " + amount.ToString("f") + "\r\n" + Lans.g("PayConnect", "Card Number:") + " " + cc.CCNumberMasked + "\r\n" + Lans.g("PayConnect", "Transaction ID:") + " " + payConnectRequest.RefNumber + "\r\n" + Lans.g("PayConnect", "Processed:") + " " + dateTimeProcessed.ToShortDateString() + " " + dateTimeProcessed.ToShortTimeString() + "\r\n" + Lans.g("PayConnect", "Note:") + " " + payNote; long payNum = Payments.InsertFromPayConnect(pat.PatNum, pat.PriProv, pat.ClinicNum, amount, formattedNote, receipt, CreditCardSource.PayConnectPortal); PayConnectResponseWeb responseWeb = new PayConnectResponseWeb() { Amount = amount, PatNum = pat.PatNum, ProcessingStatus = PayConnectWebStatus.Completed, PayNote = payNote, CCSource = cc.CCSource, IsTokenSaved = true, PayNum = payNum, DateTimeCompleted = MiscData.GetNowDateTime(), RefNumber = payConnectResponse.RefNumber, TransType = PayConnectService.transType.SALE, PaymentToken = cc.PayConnectToken, }; //Insert a new payconnectresponse row for historical record in the transaction window. PayConnectResponseWebs.Insert(responseWeb); } else //Failed { throw new ODException("Unable to process payment for this credit card: " + (payConnectResponse == null ? "Unknown error" : payConnectResponse.Status.description)); } }