///<summary>Parameters starting at authCode are optional, because our eServices probably reference this function as well.</summary> public static PayConnectService.creditCardRequest BuildSaleRequest(decimal amount, string cardNumber, int expYear, int expMonth, string nameOnCard, string securityCode, string zip, string magData, PayConnectService.transType transtype, string refNumber, bool tokenRequested, string authCode = "", bool isForced = false) { PayConnectService.creditCardRequest request = new PayConnectService.creditCardRequest(); request.Amount = amount; request.AmountSpecified = true; request.CardNumber = cardNumber; request.Expiration = new PayConnectService.expiration(); request.Expiration.year = expYear; request.Expiration.month = expMonth; if (magData != null) //MagData is the data returned from magnetic card readers. Will only be present if a card was swiped. { request.MagData = magData; } request.NameOnCard = nameOnCard; request.RefNumber = refNumber; request.SecurityCode = securityCode; request.TransType = transtype; request.Zip = zip; request.PaymentTokenRequestedSpecified = true; request.PaymentTokenRequested = tokenRequested; //request.AuthCode=authCode;//This field does not exist in the WSDL yet. Dentalxchange will let us know once they finish adding it. request.ForceDuplicateSpecified = true; request.ForceDuplicate = isForced; return(request); }
///<summary>Builds a receipt string for a web service transaction.</summary> public static string BuildReceiptString(PayConnectService.creditCardRequest request, PayConnectService.transResponse response, PayConnectService.signatureResponse sigResponse, long clinicNum) { if (response == null) { return(""); } int sigResponseStatusCode = GetSigResponseStatusCode(sigResponse); return(BuildReceiptString(request.TransType, response.RefNumber, request.NameOnCard, request.CardNumber, request.MagData, response.AuthCode, response.Status.description, response.Messages == null ? null : response.Messages.ToList(), request.Amount, sigResponseStatusCode, clinicNum)); }
///<summary>Shows a message box on error.</summary> public static PayConnectService.transResponse ProcessCreditCard(PayConnectService.creditCardRequest request) { try{ Program prog = Programs.GetCur(ProgramName.PayConnect); PayConnectService.Credentials cred = GetCredentials(prog); PayConnectService.MerchantService ms = new OpenDental.PayConnectService.MerchantService(); PayConnectService.transResponse response = ms.processCreditCard(cred, request); ms.Dispose(); if (response.Status.code != 0) //Error { MessageBox.Show(Lan.g("PayConnect", "Payment failed") + ". " + response.Status.description); } return(response); }catch (Exception ex) { MessageBox.Show(Lan.g("PayConnect", "Payment failed") + ". " + ex.Message); } return(null); }
///<summary>For web services.</summary> public PayConnectResponse(PayConnectService.transResponse response, PayConnectService.creditCardRequest request) { if (response != null) { AuthCode = response.AuthCode; RefNumber = response.RefNumber; if (response.Status != null) { Description = response.Status.description; StatusCode = response.Status.code.ToString(); } if (response.PaymentToken != null) { PaymentToken = response.PaymentToken.TokenId; if (response.PaymentToken.Expiration != null) { TokenExpiration = new DateTime(response.PaymentToken.Expiration.year, response.PaymentToken.Expiration.month, 1); } } CardType = CreditCardUtils.GetCardType(request.CardNumber); } }
///<summary>Shows a message box on error.</summary> public static PayConnectService.transResponse ProcessCreditCard(PayConnectService.creditCardRequest request, long clinicNum, Action <string> showError) { try { Program prog = Programs.GetCur(ProgramName.PayConnect); PayConnectService.Credentials cred = GetCredentials(prog, clinicNum); PayConnectService.MerchantService ms = new PayConnectService.MerchantService(); ms.Url = Introspection.GetOverride(Introspection.IntrospectionEntity.PayConnectRestURL, "https://webservices.dentalxchange.com/merchant/MerchantService?wsdl"); #if DEBUG ms.Url = "https://prelive.dentalxchange.com/merchant/MerchantService?wsdl"; #endif PayConnectService.transResponse response = ms.processCreditCard(cred, request); ms.Dispose(); if (response.Status.code != 0 && response.Status.description.ToLower().Contains("duplicate")) { showError(Lans.g("PayConnect", "Payment failed") + ". \r\n" + Lans.g("PayConnect", "Error message from") + " Pay Connect: \"" + response.Status.description + "\"\r\n" + Lans.g("PayConnect", "Try using the Force Duplicate checkbox if a duplicate is intended.")); } if (response.Status.code != 0 && response.Status.description.ToLower().Contains("invalid user")) { showError(Lans.g("PayConnect", "Payment failed") + ".\r\n" + Lans.g("PayConnect", "PayConnect username and password combination invalid.") + "\r\n" + Lans.g("PayConnect", "Verify account settings by going to") + "\r\n" + Lans.g("PayConnect", "Setup | Program Links | PayConnect. The PayConnect username and password are probably the same as the DentalXChange login ID and password.")); } else if (response.Status.code != 0) //Error { showError(Lans.g("PayConnect", "Payment failed") + ". \r\n" + Lans.g("PayConnect", "Error message from") + " Pay Connect: \"" + response.Status.description + "\""); } return(response); } catch (Exception ex) { showError(Lans.g("PayConnect", "Payment failed") + ". \r\n" + Lans.g("PayConnect", "Error message") + ": \"" + ex.Message + "\""); } return(null); }
///<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)); } }