///<summary>Deletes the PaySimple token if there is one. Returns false if deleting the token failed.</summary> private bool DeletePaySimpleToken() { if (CreditCardCur.PaySimpleToken != "") { Cursor = Cursors.WaitCursor; try { if (CreditCardCur.CCSource == CreditCardSource.PaySimpleACH) { PaySimple.DeleteACHAccount(CreditCardCur); } else if (CreditCardCur.CCSource == CreditCardSource.PaySimple) //Credit card { PaySimple.DeleteCreditCard(CreditCardCur); } } catch (PaySimpleException ex) { MessageBox.Show(ex.Message); if (ex.ErrorType == PaySimpleError.CustomerDoesNotExist && MsgBox.Show(this, MsgBoxButtons.OKCancel, "Delete the link to the customer id for this patient?")) { PatientLinks.DeletePatNumTos(ex.CustomerId, PatientLinkType.PaySimple); } return(false); } catch (Exception ex) { if (MessageBox.Show(Lans.g(this, "Error when deleting from PaySimple:") + "\r\n" + ex.Message + "\r\n\r\n" + Lans.g(this, "Do you still want to delete the card from ") + PrefC.GetString(PrefName.SoftwareName) + "?", "", MessageBoxButtons.YesNo) == DialogResult.No) { return(false); } } finally { Cursor = Cursors.Default; } } return(true); }
private void WebhookHelper(string username, string key, long clinicNum) { if (username == "" || key == "") { return; } try { Cursor = Cursors.WaitCursor; List <PaySimple.ApiWebhookResponse> listWebhooks = PaySimple.GetAchWebhooks(clinicNum); List <string> listHooksNeeded = new List <string>(); if (listWebhooks.SelectMany(x => x.WebhookTypes.FindAll(y => y == "payment_failed")).Count() == 0) { //no payment_failed webhook exists, created one. listHooksNeeded.Add("payment_failed"); } if (listWebhooks.SelectMany(x => x.WebhookTypes.FindAll(y => y == "payment_returned")).Count() == 0) { //no payment_returned webhook exists, created one. listHooksNeeded.Add("payment_returned"); } if (listWebhooks.SelectMany(x => x.WebhookTypes.FindAll(y => y == "payment_settled")).Count() == 0) { //no payment_settled webhook exists, created one. listHooksNeeded.Add("payment_settled"); } if (listHooksNeeded.Count > 0) { string url = WebServiceMainHQProxy.GetWebServiceMainHQInstance().GetPaySimpleWebHookUrl(); PaySimple.PostWebhook(clinicNum, listHooksNeeded.ToArray(), url); } } catch (Exception ex) { FriendlyException.Show("Unable to register for payment responses from PaySimple.", ex); } finally { Cursor = Cursors.Default; } }
///<summary>Processes a PaySimple ACH payment via the PaySimple API.</summary> private PaySimple.ApiResponse ProcessPaymentACH() { PaySimple.ApiResponse retVal = null; string accountNumber = textCheckSaveNumber.Text; //if the user has chosen to store CC tokens and the stored CC has a token and the token is not expired, //then use it instead of the CC number and CC expiration. if (!checkOneTimePaymentACH.Checked && _creditCardCur != null && //if the user selected a saved CC !string.IsNullOrWhiteSpace(_creditCardCur.PaySimpleToken) && //there is a stored token for this card _creditCardCur.CCSource == CreditCardSource.PaySimpleACH) { accountNumber = _creditCardCur.PaySimpleToken; } else if (PIn.Bool(ProgramProperties.GetPropVal(_progCur.ProgramNum, PaySimple.PropertyDescs.PaySimplePreventSavingNewCC, _clinicNum))) { MsgBox.Show(this, "Cannot add a new ACH payment."); return(null); } try { if (_isAddingCard) { retVal = PaySimple.AddACHAccount(_patCur, textRoutingNumber.Text, textCheckSaveNumber.Text, textBankName.Text, radioCheckings.Checked, _clinicNum); } else { retVal = PaySimple.MakePaymentACH(_patCur, _creditCardCur, PIn.Decimal(textAmountACH.Text), textRoutingNumber.Text, textCheckSaveNumber.Text, textBankName.Text, radioCheckings.Checked, checkOneTimePaymentACH.Checked, _clinicNum); try { string result = WebServiceMainHQProxy.GetWebServiceMainHQInstance() .InsertPaySimpleACHId(PayloadHelper.CreatePayload( PayloadHelper.CreatePayloadContent(retVal.RefNumber.ToString(), "PaymentId"), eServiceCode.PaySimple)); PayloadHelper.CheckForError(result); } catch (Exception ex) { FriendlyException.Show("Unable to register for ACH Settled event", ex); } } } catch (PaySimpleException ex) { MessageBox.Show(ex.Message); if (ex.ErrorType == PaySimpleError.CustomerDoesNotExist && MsgBox.Show(this, MsgBoxButtons.OKCancel, "Delete the link to the customer id for this patient?")) { PatientLinks.DeletePatNumTos(ex.CustomerId, PatientLinkType.PaySimple); } return(null); } catch (ODException ex) { MessageBox.Show(ex.Message); //This should have already been Lans.g if applicable. return(null); } catch (Exception ex) { FriendlyException.Show(Lan.g(this, "Error:") + " " + ex.Message, ex); return(null); } if (!_isAddingCard) { retVal.BuildReceiptString(accountNumber, -1, -1, _patCur?.GetNameFL(), _clinicNum, wasSwiped: false, isACH: true); PrintReceipt(retVal.TransactionReceipt); } if (checkOneTimePaymentACH.Checked) //not storing the account token { return(retVal); } UpsertCreditCard(retVal, textCheckSaveNumber.Text.Right(4).PadLeft(textCheckSaveNumber.Text.Length, '*'), CreditCardSource.PaySimpleACH, DateTime.MinValue); return(retVal); }
///<summary>Processes a PaySimple payment via the PaySimple API.</summary> private PaySimple.ApiResponse ProcessPayment(int expYear, int expMonth) { PaySimple.ApiResponse retVal = null; string refNumber = ""; if (_trantype == PaySimple.TransType.VOID || _trantype == PaySimple.TransType.RETURN) { refNumber = textRefNumber.Text; } string magData = null; if (_parser != null) { magData = _parser.Track2; } string cardNumber = textCardNumber.Text; //if using a stored CC and there is an X-Charge token saved for the CC and the user enters the whole card number to get a PaySimple token //and the number entered doesn't have the same last 4 digits and exp date, then assume it's not the same card and clear out the X-Charge token. if (_creditCardCur != null && //using a saved CC !string.IsNullOrEmpty(_creditCardCur.XChargeToken) && //there is an X-Charge token saved (cardNumber.Right(4) != _creditCardCur.CCNumberMasked.Right(4) || //the card number entered doesn't have the same last 4 digits expYear != _creditCardCur.CCExpiration.Year || //the card exp date entered doesn't have the same year expMonth != _creditCardCur.CCExpiration.Month)) //the card exp date entered doesn't have the same month { if (MsgBox.Show(this, MsgBoxButtons.YesNo, "The card number or expiration date entered does not match the X-Charge card on file. Do you wish " + "to replace the X-Charge card with this one?")) { _creditCardCur.XChargeToken = ""; } else { Cursor = Cursors.Default; return(null); } } //if the user has chosen to store CC tokens and the stored CC has a token and the token is not expired, //then use it instead of the CC number and CC expiration. if (!checkOneTimePayment.Checked && _creditCardCur != null && //if the user selected a saved CC !string.IsNullOrWhiteSpace(_creditCardCur.PaySimpleToken)) //there is a stored token for this card { cardNumber = _creditCardCur.PaySimpleToken; expYear = _creditCardCur.CCExpiration.Year; expMonth = _creditCardCur.CCExpiration.Month; } else if (PIn.Bool(ProgramProperties.GetPropVal(_progCur.ProgramNum, PaySimple.PropertyDescs.PaySimplePreventSavingNewCC, _clinicNum))) { MsgBox.Show(this, "Cannot add a new credit card."); return(null); } try { switch (_trantype) { case PaySimple.TransType.SALE: //If _patCur is null or the PatNum is 0, we will make a one time payment for an UNKNOWN patient. //This is currently only intended for prepaid insurance cards. retVal = PaySimple.MakePayment((_patCur == null ? 0 : _patCur.PatNum), _creditCardCur, PIn.Decimal(textAmount.Text), textCardNumber.Text , new DateTime(expYear, expMonth, 1), checkOneTimePayment.Checked, textZipCode.Text, textSecurityCode.Text, _clinicNum, _carrierName); break; case PaySimple.TransType.AUTH: //Will retreive a new customer id from PaySimple if the patient doesn't exist already. long paySimpleCustomerId = PaySimple.GetCustomerIdForPat(_patCur.PatNum, _patCur.FName, _patCur.LName, _clinicNum); //I have no idea if an insurance can make an auth payment but incase they can I check for it. if (paySimpleCustomerId == 0) //Insurance payment, make a new customer id every time per Nathan on 04/26/2018 { if ((_patCur == null || _patCur.PatNum == 0)) { paySimpleCustomerId = PaySimple.AddCustomer("UNKNOWN", "UNKNOWN", "", _clinicNum); } else { throw new ODException(Lan.g(this, "Invalid PaySimple Customer Id found.")); } } try { retVal = PaySimple.AddCreditCard(paySimpleCustomerId, textCardNumber.Text, new DateTime(expYear, expMonth, 1), textZipCode.Text, _clinicNum); } catch (PaySimpleException ex) { PaySimple.HandlePaySimpleException(ex, paySimpleCustomerId); } break; case PaySimple.TransType.RETURN: if (string.IsNullOrWhiteSpace(textRefNumber.Text)) { throw new ODException(Lan.g(this, "Invalid PaySimple Payment ID.")); } if (!MsgBox.Show(this, MsgBoxButtons.OKCancel, "You are about to return a payment. This action is irreversible. Continue?")) { throw new ODException(Lan.g(this, "Payment return was cancelled by user.")); } retVal = PaySimple.ReversePayment(textRefNumber.Text, _clinicNum); break; case PaySimple.TransType.VOID: if (string.IsNullOrWhiteSpace(textRefNumber.Text)) { throw new ODException(Lan.g(this, "Invalid PaySimple Payment ID.")); } if (!MsgBox.Show(this, MsgBoxButtons.OKCancel, "You are about to void a payment. This action is irreversible. Continue?")) { throw new ODException(Lan.g(this, "Payment void was cancelled by user.")); } retVal = PaySimple.VoidPayment(textRefNumber.Text, _clinicNum); break; default: throw new Exception("Invalid transmission type: " + _trantype.ToString()); } } catch (PaySimpleException ex) { MessageBox.Show(ex.Message); if (ex.ErrorType == PaySimpleError.CustomerDoesNotExist && MsgBox.Show(this, MsgBoxButtons.OKCancel, "Delete the link to the customer id for this patient?")) { PatientLinks.DeletePatNumTos(ex.CustomerId, PatientLinkType.PaySimple); } return(null); } catch (ODException wex) { MessageBox.Show(wex.Message); //This should have already been Lans.g if applicable. return(null); } catch (Exception ex) { MessageBox.Show(Lan.g(this, "Error:") + " " + ex.Message); return(null); } if (_trantype.In(PaySimple.TransType.SALE, PaySimple.TransType.RETURN, PaySimple.TransType.VOID)) //Only print a receipt if transaction is an approved SALE, RETURN, or VOID //The isSwiped boolean could be incorrectly set if the user swipes a card and then changes the data that was entered to a different card. { retVal.BuildReceiptString(cardNumber, expMonth, expYear, textNameOnCard.Text, _clinicNum, _parser != null); PrintReceipt(retVal.TransactionReceipt); } if (checkOneTimePayment.Checked) //not storing the card token { return(retVal); } UpsertCreditCard(retVal, textCardNumber.Text.Right(4).PadLeft(textCardNumber.Text.Length, 'X'), CreditCardSource.PaySimple, new DateTime(expYear, expMonth, DateTime.DaysInMonth(expYear, expMonth))); return(retVal); }