/// <summary> /// Performs the third step of adding a new payment schedule /// </summary> /// <param name="financialGateway">The financial gateway.</param> /// <param name="resultQueryString">The result query string from step 2.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException">tokenId</exception> public FinancialScheduledTransaction AddScheduledPaymentStep3(FinancialGateway financialGateway, string resultQueryString, out string errorMessage) { errorMessage = string.Empty; try { var rootElement = GetRoot(financialGateway, "complete-action"); rootElement.Add(new XElement("token-id", resultQueryString.Substring(10))); XDocument xdoc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"), rootElement); var result = PostToGateway(financialGateway, xdoc); if (result == null) { errorMessage = "Invalid Response from NMI!"; return(null); } if (result.GetValueOrNull("result") != "1") { errorMessage = result.GetValueOrNull("result-text"); return(null); } var scheduledTransaction = new FinancialScheduledTransaction(); scheduledTransaction.IsActive = true; scheduledTransaction.GatewayScheduleId = result.GetValueOrNull("subscription-id"); scheduledTransaction.FinancialGatewayId = financialGateway.Id; scheduledTransaction.FinancialPaymentDetail = new FinancialPaymentDetail(); string ccNumber = result.GetValueOrNull("billing_cc-number"); if (!string.IsNullOrWhiteSpace(ccNumber)) { // cc payment var curType = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD); scheduledTransaction.FinancialPaymentDetail.CurrencyTypeValueId = curType != null ? curType.Id : (int?)null; scheduledTransaction.FinancialPaymentDetail.CreditCardTypeValueId = CreditCardPaymentInfo.GetCreditCardType(ccNumber.Replace('*', '1').AsNumeric())?.Id; scheduledTransaction.FinancialPaymentDetail.AccountNumberMasked = ccNumber.Masked(true); string mmyy = result.GetValueOrNull("billing_cc-exp"); if (!string.IsNullOrWhiteSpace(mmyy) && mmyy.Length == 4) { scheduledTransaction.FinancialPaymentDetail.ExpirationMonthEncrypted = Encryption.EncryptString(mmyy.Substring(0, 2)); scheduledTransaction.FinancialPaymentDetail.ExpirationYearEncrypted = Encryption.EncryptString(mmyy.Substring(2, 2)); } } else { // ach payment var curType = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH); scheduledTransaction.FinancialPaymentDetail.CurrencyTypeValueId = curType != null ? curType.Id : (int?)null; scheduledTransaction.FinancialPaymentDetail.AccountNumberMasked = result.GetValueOrNull("billing_account_number").Masked(true); } GetScheduledPaymentStatus(scheduledTransaction, out errorMessage); return(scheduledTransaction); } catch (WebException webException) { string message = GetResponseMessage(webException.Response.GetResponseStream()); errorMessage = webException.Message + " - " + message; return(null); } catch (Exception ex) { errorMessage = ex.Message; return(null); } }
/// <summary> /// Performs the final step of a three-step charge. /// </summary> /// <param name="financialGateway">The financial gateway.</param> /// <param name="resultQueryString">The result query string from step 2.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public FinancialTransaction ChargeStep3(FinancialGateway financialGateway, string resultQueryString, out string errorMessage) { errorMessage = string.Empty; try { var rootElement = GetRoot(financialGateway, "complete-action"); rootElement.Add(new XElement("token-id", resultQueryString.Substring(10))); XDocument xdoc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"), rootElement); var result = PostToGateway(financialGateway, xdoc); if (result == null) { errorMessage = "Invalid Response from NMI!"; return(null); } if (result.GetValueOrNull("result") != "1") { errorMessage = result.GetValueOrNull("result-text"); string resultCodeMessage = GetResultCodeMessage(result); if (resultCodeMessage.IsNotNullOrWhiteSpace()) { errorMessage += string.Format(" ({0})", resultCodeMessage); } // write result error as an exception ExceptionLogService.LogException(new Exception($"Error processing NMI transaction. Result Code: {result.GetValueOrNull( "result-code" )} ({resultCodeMessage}). Result text: {result.GetValueOrNull( "result-text" )}. Card Holder Name: {result.GetValueOrNull( "first-name" )} {result.GetValueOrNull( "last-name" )}. Amount: {result.GetValueOrNull( "total-amount" )}. Transaction id: {result.GetValueOrNull( "transaction-id" )}. Descriptor: {result.GetValueOrNull( "descriptor" )}. Order description: {result.GetValueOrNull( "order-description" )}.")); return(null); } var transaction = new FinancialTransaction(); transaction.TransactionCode = result.GetValueOrNull("transaction-id"); transaction.ForeignKey = result.GetValueOrNull("customer-vault-id"); transaction.FinancialPaymentDetail = new FinancialPaymentDetail(); string ccNumber = result.GetValueOrNull("billing_cc-number"); if (!string.IsNullOrWhiteSpace(ccNumber)) { // cc payment var curType = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD); transaction.FinancialPaymentDetail.NameOnCardEncrypted = Encryption.EncryptString($"{result.GetValueOrNull( "billing_first-name" )} {result.GetValueOrNull( "billing_last-name" )}"); transaction.FinancialPaymentDetail.CurrencyTypeValueId = curType != null ? curType.Id : (int?)null; transaction.FinancialPaymentDetail.CreditCardTypeValueId = CreditCardPaymentInfo.GetCreditCardType(ccNumber.Replace('*', '1').AsNumeric())?.Id; transaction.FinancialPaymentDetail.AccountNumberMasked = ccNumber.Masked(true); string mmyy = result.GetValueOrNull("billing_cc-exp"); if (!string.IsNullOrWhiteSpace(mmyy) && mmyy.Length == 4) { transaction.FinancialPaymentDetail.ExpirationMonthEncrypted = Encryption.EncryptString(mmyy.Substring(0, 2)); transaction.FinancialPaymentDetail.ExpirationYearEncrypted = Encryption.EncryptString(mmyy.Substring(2, 2)); } } else { // ach payment var curType = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH); transaction.FinancialPaymentDetail.CurrencyTypeValueId = curType != null ? curType.Id : (int?)null; transaction.FinancialPaymentDetail.AccountNumberMasked = result.GetValueOrNull("billing_account-number").Masked(true); } transaction.AdditionalLavaFields = new Dictionary <string, object>(); foreach (var keyVal in result) { transaction.AdditionalLavaFields.Add(keyVal.Key, keyVal.Value); } return(transaction); } catch (WebException webException) { string message = GetResponseMessage(webException.Response.GetResponseStream()); errorMessage = webException.Message + " - " + message; return(null); } catch (Exception ex) { errorMessage = ex.Message; return(null); } }