/// <summary>Only used to void or refund transactions from PayConnectPortal. Creates new cloned payment and paysplits for the refund or void. /// Returns true if the transaction was successful, otherwise false.</summary public static bool VoidOrRefundPayConnectPortalTransaction(PayConnectResponseWeb pcResponseWeb, Payment payment, PayConnectService.transType transType, string refNum, decimal amount) { if (!transType.In(PayConnectService.transType.RETURN, PayConnectService.transType.VOID)) { return(false); } List <PaySplit> listPaySplits = PaySplits.GetForPayment(payment.PayNum); PayConnectService.creditCardRequest _payConnectRequest = new PayConnectService.creditCardRequest(); PayConnectResponse response = null; string receiptStr = ""; _payConnectRequest.TransType = transType; _payConnectRequest.RefNumber = refNum; _payConnectRequest.Amount = amount; PayConnectService.transResponse transResponse = PayConnect.ProcessCreditCard(_payConnectRequest, payment.ClinicNum, x => MsgBox.Show(x)); response = new PayConnectResponse(transResponse, _payConnectRequest); receiptStr = PayConnect.BuildReceiptString(_payConnectRequest, transResponse, null, payment.ClinicNum); if (response == null || response.StatusCode != "0") //error in transaction { return(false); } //Record a new payment for the voided transaction Payment clonePayment = payment.Clone(); clonePayment.PayAmt *= -1; //The negated amount of the original payment clonePayment.PayDate = DateTime.Now; clonePayment.Receipt = receiptStr; clonePayment.PayNote = Lan.g("PayConnectL", "Transaction Type") + ": " + Enum.GetName(typeof(PayConnectService.transType), transType) + Environment.NewLine + Lan.g("PayConnectL", "Status") + ": " + response.Description + Environment.NewLine + Lan.g("PayConnectL", "Amount") + ": " + clonePayment.PayAmt + Environment.NewLine + Lan.g("PayConnectL", "Auth Code") + ": " + response.AuthCode + Environment.NewLine + Lan.g("PayConnectL", "Ref Number") + ": " + response.RefNumber; clonePayment.PaymentSource = pcResponseWeb.CCSource; clonePayment.ProcessStatus = ProcessStat.OfficeProcessed; clonePayment.PayNum = Payments.Insert(clonePayment); List <PaySplit> listClonedPaySplits = new List <PaySplit>(); foreach (PaySplit paySplit in listPaySplits) { PaySplit copy = paySplit.Copy(); copy.SplitAmt *= -1; copy.PayNum = clonePayment.PayNum; copy.DatePay = clonePayment.PayDate; listClonedPaySplits.Add(copy); } PaySplits.InsertMany(listClonedPaySplits); PayConnectResponseWeb newPCResponseWeb = new PayConnectResponseWeb() { PatNum = payment.PatNum, PayNum = clonePayment.PayNum, CCSource = pcResponseWeb.CCSource, Amount = clonePayment.PayAmt, PayNote = Lan.g("PayConnectL", clonePayment.PayNote + Environment.NewLine + "From within Open Dental Proper."), ProcessingStatus = PayConnectWebStatus.Completed, DateTimeEntry = DateTime.Now, DateTimeCompleted = DateTime.Now, IsTokenSaved = false, RefNumber = transResponse.RefNumber, TransType = transType, PaymentToken = pcResponseWeb.PaymentToken, }; PayConnectResponseWebs.Insert(newPCResponseWeb); SecurityLogs.MakeLogEntry(Permissions.PaymentCreate, clonePayment.PatNum, Patients.GetLim(clonePayment.PatNum).GetNameLF() + ", " + clonePayment.PayAmt.ToString("c")); return(true); }
///<summary>Processes a PayConnect payment via the PayConnect web service.</summary> private bool ProcessPaymentWebService(int expYear, int expMonth) { string refNumber = ""; if (_trantype == PayConnectService.transType.VOID || _trantype == PayConnectService.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 PayConnect 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(false); } } //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 (checkSaveToken.Checked && _creditCardCur != null && //if the user selected a saved CC _creditCardCur.PayConnectToken != "" && //there is a stored token for this card _creditCardCur.PayConnectTokenExp.Date >= DateTime.Today.Date) //the token is not expired { cardNumber = _creditCardCur.PayConnectToken; expYear = _creditCardCur.PayConnectTokenExp.Year; expMonth = _creditCardCur.PayConnectTokenExp.Month; } else if (PIn.Bool(ProgramProperties.GetPropVal(_progCur.ProgramNum, PayConnect.ProgramProperties.PayConnectPreventSavingNewCC, _clinicNum))) { MsgBox.Show(this, "Cannot add a new credit card."); return(false); } string authCode = ""; if (_trantype == PayConnectService.transType.FORCE) { authCode = textRefNumber.Text; } _request = PayConnect.BuildSaleRequest(PIn.Decimal(textAmount.Text), cardNumber, expYear, expMonth, textNameOnCard.Text, textSecurityCode.Text, textZipCode.Text, magData, _trantype, refNumber, checkSaveToken.Checked, authCode, checkForceDuplicate.Checked); _response = PayConnect.ProcessCreditCard(_request, _clinicNum, x => MessageBox.Show(x)); if (_response == null || _response.Status.code != 0) //error in transaction { return(false); } PayConnectService.signatureResponse sigResponse = SendSignature(_response.RefNumber); if ((_trantype.In(PayConnectService.transType.SALE, PayConnectService.transType.RETURN, PayConnectService.transType.VOID)) && _response.Status.code == 0) //Only print a receipt if transaction is an approved SALE, RETURN, or VOID { _receiptStr = PayConnect.BuildReceiptString(_request, _response, sigResponse, _clinicNum); PrintReceipt(_receiptStr); } if (!PrefC.GetBool(PrefName.StoreCCnumbers) && !checkSaveToken.Checked) //not storing the card number or the token { return(true); } //response must be non-null and the status code must be 0=Approved //also, the user must have the pref StoreCCnumbers enabled or they have the checkSaveTokens checked if (_creditCardCur == null) //user selected Add new card from the payment window, save it or its token depending on settings { _creditCardCur = new CreditCard(); _creditCardCur.IsNew = true; _creditCardCur.PatNum = _patCur.PatNum; List <CreditCard> itemOrderCount = CreditCards.Refresh(_patCur.PatNum); _creditCardCur.ItemOrder = itemOrderCount.Count; } _creditCardCur.CCExpiration = new DateTime(expYear, expMonth, DateTime.DaysInMonth(expYear, expMonth)); if (PrefC.GetBool(PrefName.StoreCCnumbers)) { _creditCardCur.CCNumberMasked = textCardNumber.Text; } else { _creditCardCur.CCNumberMasked = textCardNumber.Text.Right(4).PadLeft(textCardNumber.Text.Length, 'X'); } _creditCardCur.Zip = textZipCode.Text; _creditCardCur.PayConnectToken = ""; _creditCardCur.PayConnectTokenExp = DateTime.MinValue; //Store the token and the masked CC number (only last four digits). if (checkSaveToken.Checked && _response.PaymentToken != null) { _creditCardCur.PayConnectToken = _response.PaymentToken.TokenId; _creditCardCur.PayConnectTokenExp = new DateTime(_response.PaymentToken.Expiration.year, _response.PaymentToken.Expiration.month, DateTime.DaysInMonth(_response.PaymentToken.Expiration.year, _response.PaymentToken.Expiration.month)); } _creditCardCur.CCSource = CreditCardSource.PayConnect; if (_creditCardCur.IsNew) { _creditCardCur.ClinicNum = _clinicNum; _creditCardCur.Procedures = PrefC.GetString(PrefName.DefaultCCProcs); CreditCards.Insert(_creditCardCur); } else { if (_creditCardCur.CCSource == CreditCardSource.XServer) //This card has also been added for XCharge. { _creditCardCur.CCSource = CreditCardSource.XServerPayConnect; } CreditCards.Update(_creditCardCur); } return(true); }