/// <summary> /// Adds the scheduled payment. /// </summary> /// <param name="financialGateway">The financial gateway.</param> /// <param name="schedule">The schedule.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override FinancialScheduledTransaction AddScheduledPayment( FinancialGateway financialGateway, PaymentSchedule schedule, PaymentInfo paymentInfo, out string errorMessage ) { errorMessage = string.Empty; var scheduledTransaction = new FinancialScheduledTransaction(); scheduledTransaction.IsActive = true; scheduledTransaction.StartDate = schedule.StartDate; scheduledTransaction.NextPaymentDate = schedule.StartDate; scheduledTransaction.TransactionCode = "T" + RockDateTime.Now.ToString("yyyyMMddHHmmssFFF"); scheduledTransaction.GatewayScheduleId = "P" + RockDateTime.Now.ToString("yyyyMMddHHmmssFFF"); scheduledTransaction.LastStatusUpdateDateTime = RockDateTime.Now; return scheduledTransaction; }
/// <summary> /// Sets the status. /// </summary> /// <param name="scheduledTransaction">The scheduled transaction.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public bool GetStatus( FinancialScheduledTransaction scheduledTransaction, out string errorMessages ) { if ( scheduledTransaction.GatewayEntityType != null ) { var gateway = Rock.Financial.GatewayContainer.GetComponent( scheduledTransaction.GatewayEntityType.Guid.ToString() ); if ( gateway != null && gateway.IsActive ) { return gateway.GetScheduledPaymentStatus( scheduledTransaction, out errorMessages ); } } errorMessages = "Gateway is invalid or not active"; return false; }
/// <summary> /// Adds the scheduled payment. /// </summary> /// <param name="financialGateway">The financial gateway.</param> /// <param name="schedule">The schedule.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override FinancialScheduledTransaction AddScheduledPayment(FinancialGateway financialGateway, PaymentSchedule schedule, PaymentInfo paymentInfo, out string errorMessage) { errorMessage = string.Empty; if (ValidateCard(financialGateway, paymentInfo, out errorMessage)) { var scheduledTransaction = new FinancialScheduledTransaction(); scheduledTransaction.IsActive = true; scheduledTransaction.StartDate = schedule.StartDate; scheduledTransaction.NextPaymentDate = schedule.StartDate; scheduledTransaction.TransactionCode = "T" + RockDateTime.Now.ToString("yyyyMMddHHmmssFFF"); scheduledTransaction.GatewayScheduleId = "Subscription_" + RockDateTime.Now.ToString("yyyyMMddHHmmssFFF"); scheduledTransaction.LastStatusUpdateDateTime = RockDateTime.Now; return(scheduledTransaction); } return(null); }
/// <summary> /// Reactivates the scheduled payment. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool ReactivateScheduledPayment(FinancialScheduledTransaction transaction, out string errorMessage) { errorMessage = string.Empty; var financialGateway = GetFinancialGateway(transaction); var ppTransaction = new RecurringReActivateTransaction(GetUserInfo(financialGateway), GetConnection(financialGateway), GetRecurring(transaction), PayflowUtility.RequestId); var ppResponse = ppTransaction.SubmitTransaction(); if (ppResponse != null) { TransactionResponse txnResponse = ppResponse.TransactionResponse; if (txnResponse != null) { if (txnResponse.Result == 0) // Success { RecurringResponse recurringResponse = ppResponse.RecurringResponse; if (recurringResponse != null) { return(true); } else { errorMessage = "Invalid recurring response from the financial gateway"; } } else { errorMessage = string.Format("[{0}] {1}", txnResponse.Result, txnResponse.RespMsg); } } else { errorMessage = "Invalid transaction response from the financial gateway"; } } else { errorMessage = "Invalid response from the financial gateway."; } return(false); }
/// <summary> /// Gets the scheduled payment status. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool GetScheduledPaymentStatus(FinancialScheduledTransaction transaction, out string errorMessage) { errorMessage = string.Empty; var ppTransaction = new RecurringInquiryTransaction(GetUserInfo(), GetConnection(), GetRecurring(transaction), PayflowUtility.RequestId); var ppResponse = ppTransaction.SubmitTransaction(); if (ppResponse != null) { TransactionResponse txnResponse = ppResponse.TransactionResponse; if (txnResponse != null) { if (txnResponse.Result == 0) // Success { RecurringResponse recurringResponse = ppResponse.RecurringResponse; if (recurringResponse != null) { transaction.IsActive = recurringResponse.Status.ToUpper() == "ACTIVE"; transaction.StartDate = GetDate(recurringResponse.Start) ?? transaction.StartDate; transaction.NextPaymentDate = GetDate(recurringResponse.NextPayment) ?? transaction.NextPaymentDate; transaction.NumberOfPayments = recurringResponse.Term.AsIntegerOrNull() ?? transaction.NumberOfPayments; transaction.LastStatusUpdateDateTime = RockDateTime.Now; return(true); } return(true); } else { errorMessage = string.Format("[{0}] {1}", txnResponse.Result, txnResponse.RespMsg); } } else { errorMessage = "Invalid transaction response from the financial gateway"; } } else { errorMessage = "Invalid response from the financial gateway."; } return(false); }
public void RockCleanup_Execute_ShouldUpdatePeopleWithFinancialScheduledTransactionToAccountProtectionProfileHigh() { var personGuid = Guid.NewGuid(); var personWithFinancialScheduledTransaction = new Person { FirstName = "Test", LastName = personGuid.ToString(), Email = $"{personGuid}@test.com", Guid = personGuid }; using (var rockContext = new RockContext()) { var personService = new PersonService(rockContext); personService.Add(personWithFinancialScheduledTransaction); rockContext.SaveChanges(); personWithFinancialScheduledTransaction = personService.Get(personWithFinancialScheduledTransaction.Id); var financialScheduledTransaction = new FinancialScheduledTransaction { AuthorizedPersonAliasId = personWithFinancialScheduledTransaction.PrimaryAliasId.Value, TransactionFrequencyValueId = DefinedValueCache.GetId(Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME.AsGuid()) ?? 0 }; var service = new FinancialScheduledTransactionService(rockContext); service.Add(financialScheduledTransaction); rockContext.SaveChanges(); } ExecuteRockCleanupJob(); using (var rockContext = new RockContext()) { var actualPerson = new PersonService(rockContext).Get(personGuid); Assert.That.AreEqual(AccountProtectionProfile.High, actualPerson.AccountProtectionProfile); } }
/// <summary> /// Handles the Click event of the btnSaveAccount control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> protected void SaveNewFinancialPersonSavedAccount(FinancialScheduledTransaction financialScheduledTransaction) { var rockContext = new RockContext(); var scheduledTransaction = this.GetFinancialScheduledTransaction(rockContext); var targetPerson = scheduledTransaction.AuthorizedPersonAlias.Person; var financialGatewayComponent = this.FinancialGatewayComponent; var financialGateway = this.FinancialGateway; var savedAccount = new FinancialPersonSavedAccount(); var paymentDetail = financialScheduledTransaction.FinancialPaymentDetail; savedAccount.PersonAliasId = targetPerson.PrimaryAliasId; savedAccount.ReferenceNumber = paymentDetail.GatewayPersonIdentifier; savedAccount.Name = tbSaveAccount.Text; savedAccount.TransactionCode = financialScheduledTransaction.TransactionCode; savedAccount.GatewayPersonIdentifier = paymentDetail.GatewayPersonIdentifier; savedAccount.FinancialGatewayId = financialGateway.Id; savedAccount.FinancialPaymentDetail = new FinancialPaymentDetail(); savedAccount.FinancialPaymentDetail.AccountNumberMasked = paymentDetail.AccountNumberMasked; savedAccount.FinancialPaymentDetail.CurrencyTypeValueId = paymentDetail.CurrencyTypeValueId; savedAccount.FinancialPaymentDetail.CreditCardTypeValueId = paymentDetail.CreditCardTypeValueId; savedAccount.FinancialPaymentDetail.NameOnCard = paymentDetail.NameOnCard; savedAccount.FinancialPaymentDetail.ExpirationMonth = paymentDetail.ExpirationMonth; savedAccount.FinancialPaymentDetail.ExpirationYear = paymentDetail.ExpirationYear; savedAccount.FinancialPaymentDetail.BillingLocationId = paymentDetail.BillingLocationId; var savedAccountService = new FinancialPersonSavedAccountService(rockContext); savedAccountService.Add(savedAccount); rockContext.SaveChanges(); savedAccount.FinancialPaymentDetail.FinancialPersonSavedAccountId = savedAccount.Id; }
/// <summary> /// Cancels the scheduled payment. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool CancelScheduledPayment(FinancialScheduledTransaction transaction, out string errorMessage) { errorMessage = string.Empty; if (transaction != null && !string.IsNullOrWhiteSpace(transaction.GatewayScheduleId) && transaction.FinancialGateway != null) { var rootElement = GetRoot(transaction.FinancialGateway, "delete-subscription"); rootElement.Add(new XElement("subscription-id", transaction.GatewayScheduleId)); XDocument xdoc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"), rootElement); var result = PostToGateway(transaction.FinancialGateway, xdoc); if (result == null) { errorMessage = "Invalid Response from NMI!"; return(false); } if (result.GetValueOrNull("result") != "1") { errorMessage = result.GetValueOrNull("result-text"); return(false); } transaction.IsActive = false; return(true); } else { errorMessage = "Invalid original transaction, transaction code, or gateway."; } return(false); }
/// <summary> /// Cancels the scheduled payment. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool CancelScheduledPayment(FinancialScheduledTransaction transaction, out string errorMessage) { transaction.IsActive = false; errorMessage = string.Empty; return(true); }
/// <summary> /// Updates the scheduled payment. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool UpdateScheduledPayment(FinancialScheduledTransaction transaction, PaymentInfo paymentInfo, out string errorMessage) { errorMessage = string.Empty; return(true); }
/// <summary> /// Cancels the scheduled payment. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool CancelScheduledPayment( FinancialScheduledTransaction transaction, out string errorMessage ) { transaction.IsActive = false; errorMessage = string.Empty; return true; }
private RecurringInfo GetRecurring( FinancialScheduledTransaction schedule ) { var ppRecurringInfo = new RecurringInfo(); ppRecurringInfo.OrigProfileId = schedule.GatewayScheduleId; ppRecurringInfo.Start = schedule.StartDate.ToString( "MMddyyyy" ); if ( schedule.TransactionFrequencyValueId > 0 ) { SetPayPeriod( ppRecurringInfo, DefinedValueCache.Read( schedule.TransactionFrequencyValueId ) ); } return ppRecurringInfo; }
/// <summary> /// Gets the scheduled payment status. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool GetScheduledPaymentStatus( FinancialScheduledTransaction transaction, out string errorMessage ) { errorMessage = string.Empty; var ppTransaction = new RecurringInquiryTransaction( GetUserInfo(), GetConnection(), GetRecurring( transaction ), PayflowUtility.RequestId ); var ppResponse = ppTransaction.SubmitTransaction(); if ( ppResponse != null ) { TransactionResponse txnResponse = ppResponse.TransactionResponse; if ( txnResponse != null ) { if ( txnResponse.Result == 0 ) // Success { RecurringResponse recurringResponse = ppResponse.RecurringResponse; if ( recurringResponse != null ) { transaction.IsActive = recurringResponse.Status.ToUpper() == "ACTIVE"; transaction.StartDate = GetDate( recurringResponse.Start ) ?? transaction.StartDate; transaction.NextPaymentDate = GetDate( recurringResponse.NextPayment ) ?? transaction.NextPaymentDate; transaction.NumberOfPayments = recurringResponse.Term.AsIntegerOrNull() ?? transaction.NumberOfPayments; transaction.LastStatusUpdateDateTime = RockDateTime.Now; return true; } return true; } else { errorMessage = string.Format( "[{0}] {1}", txnResponse.Result, txnResponse.RespMsg ); } } else { errorMessage = "Invalid transaction response from the financial gateway"; } } else { errorMessage = "Invalid response from the financial gateway."; } return false; }
/// <summary> /// Gets the scheduled payment status. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool GetScheduledPaymentStatus( FinancialScheduledTransaction transaction, out string errorMessage ) { errorMessage = string.Empty; var financialGateway = transaction.FinancialGateway; RequestMessage verifyRequest = GetMerchantInfo( financialGateway ); verifyRequest.paySubscriptionRetrieveService = new PaySubscriptionRetrieveService(); verifyRequest.paySubscriptionRetrieveService.run = "true"; verifyRequest.recurringSubscriptionInfo = new RecurringSubscriptionInfo(); verifyRequest.recurringSubscriptionInfo.subscriptionID = transaction.TransactionCode; // Get the payment status ReplyMessage reply = SubmitTransaction( financialGateway, verifyRequest, out errorMessage ); if ( reply != null && reply.reasonCode.Equals( GATEWAY_RESPONSE_SUCCESS ) ) { transaction.IsActive = reply.paySubscriptionRetrieveReply.status.ToUpper() == "CURRENT"; var startDate = GetDate( reply.paySubscriptionRetrieveReply.startDate ); transaction.StartDate = startDate ?? transaction.StartDate; transaction.NextPaymentDate = NextPaymentDate( startDate, reply.paySubscriptionRetrieveReply.frequency ) ?? transaction.NextPaymentDate; transaction.NumberOfPayments = reply.paySubscriptionRetrieveReply.totalPayments.AsIntegerOrNull() ?? transaction.NumberOfPayments; transaction.LastStatusUpdateDateTime = DateTime.Now; return true; } else if ( string.IsNullOrEmpty( errorMessage ) ) { errorMessage = ProcessError( reply ); } return false; }
/// <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> /// Gets an optional reference identifier needed to process future transaction from saved account. /// </summary> /// <param name="scheduledTransaction">The scheduled transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override string GetReferenceNumber(FinancialScheduledTransaction scheduledTransaction, out string errorMessage) { errorMessage = string.Empty; return(string.Empty); }
/// <summary> /// Gets the payment information. /// </summary> /// <returns></returns> private PaymentInfo GetPaymentInfo( PersonService personService, FinancialScheduledTransaction scheduledTransaction ) { PaymentInfo paymentInfo = null; if ( hfPaymentTab.Value == "ACH" ) { if ( rblSavedAch.Items.Count > 0 && ( rblSavedAch.SelectedValueAsId() ?? 0 ) > 0 ) { paymentInfo = GetReferenceInfo( rblSavedAch.SelectedValueAsId().Value ); } else { paymentInfo = GetACHInfo(); } } else if ( hfPaymentTab.Value == "CreditCard" ) { if ( rblSavedCC.Items.Count > 0 && ( rblSavedCC.SelectedValueAsId() ?? 0 ) > 0 ) { paymentInfo = GetReferenceInfo( rblSavedCC.SelectedValueAsId().Value ); } else { paymentInfo = GetCCInfo(); } } else { paymentInfo = new PaymentInfo(); } if ( paymentInfo != null ) { paymentInfo.Amount = SelectedAccounts.Sum( a => a.Amount ); var authorizedPerson = scheduledTransaction.AuthorizedPersonAlias.Person; paymentInfo.FirstName = authorizedPerson.FirstName; paymentInfo.LastName = authorizedPerson.LastName; paymentInfo.Email = authorizedPerson.Email; bool displayPhone = GetAttributeValue( "DisplayPhone" ).AsBoolean(); if ( displayPhone ) { var phoneNumber = personService.GetPhoneNumber( authorizedPerson, DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME ) ) ); paymentInfo.Phone = phoneNumber != null ? phoneNumber.ToString() : string.Empty; } Guid addressTypeGuid = Guid.Empty; if ( !Guid.TryParse( GetAttributeValue( "AddressType" ), out addressTypeGuid ) ) { addressTypeGuid = new Guid( Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME ); } var groupLocation = personService.GetFirstLocation( authorizedPerson.Id, DefinedValueCache.Read( addressTypeGuid ).Id ); if ( groupLocation != null && groupLocation.Location != null ) { paymentInfo.Street1 = groupLocation.Location.Street1; paymentInfo.Street2 = groupLocation.Location.Street2; paymentInfo.City = groupLocation.Location.City; paymentInfo.State = groupLocation.Location.State; paymentInfo.PostalCode = groupLocation.Location.PostalCode; paymentInfo.Country = groupLocation.Location.Country; } } return paymentInfo; }
/// <summary> /// Sets the frequency. /// </summary> /// <param name="scheduledTransaction">The scheduled transaction.</param> private void SetFrequency( FinancialScheduledTransaction scheduledTransaction ) { // Enable payment options based on the configured gateways bool ccEnabled = false; bool achEnabled = false; if ( scheduledTransaction != null && Gateway != null ) { if ( scheduledTransaction.FinancialPaymentDetail != null && scheduledTransaction.FinancialPaymentDetail.CurrencyTypeValueId == DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD ).Id ) { ccEnabled = true; txtCardFirstName.Visible = Gateway.SplitNameOnCard; var authorizedPerson = scheduledTransaction.AuthorizedPersonAlias.Person; txtCardFirstName.Text = authorizedPerson.FirstName; txtCardLastName.Visible = Gateway.SplitNameOnCard; txtCardLastName.Text = authorizedPerson.LastName; txtCardName.Visible = !Gateway.SplitNameOnCard; txtCardName.Text = authorizedPerson.FullName; var groupLocation = new PersonService( new RockContext() ).GetFirstLocation( authorizedPerson.Id, DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME.AsGuid() ).Id ); if ( groupLocation != null ) { acBillingAddress.SetValues( groupLocation.Location ); } else { acBillingAddress.SetValues( null ); } mypExpiration.MinimumYear = RockDateTime.Now.Year; } if ( scheduledTransaction.FinancialPaymentDetail != null && scheduledTransaction.FinancialPaymentDetail.CurrencyTypeValueId == DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH ).Id ) { achEnabled = true; } if ( Gateway.SupportedPaymentSchedules.Any() ) { var oneTimeFrequency = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME ); divRepeatingPayments.Visible = true; btnFrequency.DataSource = Gateway.SupportedPaymentSchedules; btnFrequency.DataBind(); btnFrequency.SelectedValue = scheduledTransaction.TransactionFrequencyValueId.ToString(); } liCreditCard.Visible = ccEnabled; divCCPaymentInfo.Visible = ccEnabled; liACH.Visible = achEnabled; divACHPaymentInfo.Visible = achEnabled; if ( ccEnabled ) { divCCPaymentInfo.AddCssClass( "tab-pane" ); } if ( achEnabled ) { divACHPaymentInfo.AddCssClass( "tab-pane" ); } } }
/// <summary> /// Shows the view. /// </summary> /// <param name="financialScheduledTransaction">The TXN.</param> private void ShowView(FinancialScheduledTransaction financialScheduledTransaction) { if (financialScheduledTransaction == null) { return; } hlStatus.Text = financialScheduledTransaction.IsActive ? "Active" : "Inactive"; hlStatus.LabelType = financialScheduledTransaction.IsActive ? LabelType.Success : LabelType.Danger; string rockUrlRoot = ResolveRockUrl("/"); Person person = null; if (financialScheduledTransaction.AuthorizedPersonAlias != null) { person = financialScheduledTransaction.AuthorizedPersonAlias.Person; } var detailsLeft = new DescriptionList().Add("Person", person); var detailsRight = new DescriptionList() .Add("Amount", (financialScheduledTransaction.ScheduledTransactionDetails.Sum(d => ( decimal? )d.Amount) ?? 0.0M).FormatAsCurrency()) .Add("Frequency", financialScheduledTransaction.TransactionFrequencyValue != null ? financialScheduledTransaction.TransactionFrequencyValue.Value : string.Empty) .Add("Start Date", financialScheduledTransaction.StartDate.ToShortDateString()) .Add("End Date", financialScheduledTransaction.EndDate.HasValue ? financialScheduledTransaction.EndDate.Value.ToShortDateString() : string.Empty) .Add("Next Payment Date", financialScheduledTransaction.NextPaymentDate.HasValue ? financialScheduledTransaction.NextPaymentDate.Value.ToShortDateString() : string.Empty) .Add("Last Status Refresh", financialScheduledTransaction.LastStatusUpdateDateTime.HasValue ? financialScheduledTransaction.LastStatusUpdateDateTime.Value.ToString("g") : string.Empty); detailsLeft.Add("Source", financialScheduledTransaction.SourceTypeValue != null ? financialScheduledTransaction.SourceTypeValue.Value : string.Empty); if (financialScheduledTransaction.FinancialPaymentDetail != null && financialScheduledTransaction.FinancialPaymentDetail.CurrencyTypeValue != null) { var paymentMethodDetails = new DescriptionList(); var currencyType = financialScheduledTransaction.FinancialPaymentDetail.CurrencyTypeValue; if (currencyType.Guid.Equals(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD.AsGuid())) { // Credit Card paymentMethodDetails.Add("Type", currencyType.Value + (financialScheduledTransaction.FinancialPaymentDetail.CreditCardTypeValue != null ? (" - " + financialScheduledTransaction.FinancialPaymentDetail.CreditCardTypeValue.Value) : string.Empty)); paymentMethodDetails.Add("Name on Card", financialScheduledTransaction.FinancialPaymentDetail.NameOnCard.Trim()); paymentMethodDetails.Add("Account Number", financialScheduledTransaction.FinancialPaymentDetail.AccountNumberMasked); paymentMethodDetails.Add("Expires", financialScheduledTransaction.FinancialPaymentDetail.ExpirationDate); } else { // ACH paymentMethodDetails.Add("Type", currencyType.Value); paymentMethodDetails.Add("Account Number", financialScheduledTransaction.FinancialPaymentDetail.AccountNumberMasked); } detailsLeft.Add("Payment Method", paymentMethodDetails.GetFormattedList("{0}: {1}").AsDelimited("<br/>")); } GatewayComponent gateway = null; if (financialScheduledTransaction.FinancialGateway != null) { gateway = financialScheduledTransaction.FinancialGateway.GetGatewayComponent(); if (gateway != null) { detailsLeft.Add("Payment Gateway", GatewayContainer.GetComponentName(gateway.TypeName)); } } detailsLeft .Add("Transaction Code", financialScheduledTransaction.TransactionCode) .Add("Schedule Id", financialScheduledTransaction.GatewayScheduleId); lSummary.Visible = financialScheduledTransaction.Summary.IsNotNullOrWhiteSpace(); lSummary.Text = financialScheduledTransaction.Summary.ConvertCrLfToHtmlBr(); lDetailsLeft.Text = detailsLeft.Html; lDetailsRight.Text = detailsRight.Html; gAccountsView.DataSource = financialScheduledTransaction.ScheduledTransactionDetails.ToList(); gAccountsView.DataBind(); btnRefresh.Visible = gateway != null && gateway.GetScheduledPaymentStatusSupported; btnUpdate.Visible = gateway != null && gateway.UpdateScheduledPaymentSupported; btnCancelSchedule.Visible = financialScheduledTransaction.IsActive; btnReactivateSchedule.Visible = !financialScheduledTransaction.IsActive && gateway != null && gateway.ReactivateScheduledPaymentSupported; }
/// <summary> /// Updates the scheduled payment. /// </summary> /// <param name="schedule">The schedule.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool UpdateScheduledPayment( FinancialScheduledTransaction transaction, PaymentInfo paymentInfo, out string errorMessage ) { errorMessage = string.Empty; var financialGateway = transaction.FinancialGateway; RequestMessage request = GetPaymentInfo( financialGateway, paymentInfo ); if ( request == null ) { errorMessage = "Payment type not implemented"; return false; } if ( request.recurringSubscriptionInfo == null ) { request.recurringSubscriptionInfo = new RecurringSubscriptionInfo(); request.recurringSubscriptionInfo.subscriptionID = transaction.TransactionCode; } request.recurringSubscriptionInfo.amount = paymentInfo.Amount.ToString(); request.paySubscriptionUpdateService = new PaySubscriptionUpdateService(); request.paySubscriptionUpdateService.run = "true"; request.purchaseTotals = GetTotals(); request.billTo = GetBillTo( paymentInfo ); request.item = GetItems( paymentInfo ); request.subscription = new Subscription(); if ( !paymentInfo.CurrencyTypeValue.Guid.Equals( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD ) ) ) { request.subscription.paymentMethod = "check"; } else { request.subscription.paymentMethod = "credit card"; } // Update the schedule ReplyMessage reply = SubmitTransaction( financialGateway, request, out errorMessage ); if ( reply != null && reply.reasonCode.Equals( GATEWAY_RESPONSE_SUCCESS ) ) { return true; } else if ( string.IsNullOrEmpty( errorMessage ) ) { errorMessage = string.Format( "Unable to update this transaction. {0}", ProcessError( reply ) ); } return false; }
/// <summary> /// Reactivates the scheduled payment (CyberSource not supported). /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool ReactivateScheduledPayment( FinancialScheduledTransaction transaction, out string errorMessage ) { errorMessage = string.Empty; return false; }
/// <summary> /// Adds the scheduled payment. /// </summary> /// <param name="schedule">The schedule.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override FinancialScheduledTransaction AddScheduledPayment( FinancialGateway financialGateway, PaymentSchedule schedule, PaymentInfo paymentInfo, out string errorMessage ) { errorMessage = string.Empty; RequestMessage request = GetPaymentInfo( financialGateway, paymentInfo ); if ( request == null ) { errorMessage = "Payment type not implemented"; return null; } if ( request.recurringSubscriptionInfo == null ) { request.recurringSubscriptionInfo = new RecurringSubscriptionInfo(); } request.recurringSubscriptionInfo.startDate = GetStartDate( schedule ); request.recurringSubscriptionInfo.frequency = GetFrequency( schedule ); request.recurringSubscriptionInfo.amount = paymentInfo.Amount.ToString(); request.paySubscriptionCreateService = new PaySubscriptionCreateService(); request.paySubscriptionCreateService.run = "true"; request.purchaseTotals = GetTotals(); request.billTo = GetBillTo( paymentInfo ); request.item = GetItems( paymentInfo ); request.subscription = new Subscription(); if ( !paymentInfo.CurrencyTypeValue.Guid.Equals( new Guid( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD ) ) ) { request.subscription.paymentMethod = "check"; } if ( paymentInfo is ReferencePaymentInfo ) { request.paySubscriptionCreateService.paymentRequestID = ( (ReferencePaymentInfo)paymentInfo ).TransactionCode; } // Schedule the payment ReplyMessage reply = SubmitTransaction( financialGateway, request, out errorMessage ); if ( reply != null && reply.reasonCode.Equals( GATEWAY_RESPONSE_SUCCESS ) ) { var transactionGuid = new Guid( reply.merchantReferenceCode ); var scheduledTransaction = new FinancialScheduledTransaction { Guid = transactionGuid }; scheduledTransaction.TransactionCode = reply.paySubscriptionCreateReply.subscriptionID; scheduledTransaction.GatewayScheduleId = reply.paySubscriptionCreateReply.subscriptionID; scheduledTransaction.FinancialGateway = financialGateway; scheduledTransaction.FinancialGatewayId = financialGateway.Id; GetScheduledPaymentStatus( scheduledTransaction, out errorMessage ); return scheduledTransaction; } else if ( string.IsNullOrEmpty( errorMessage ) ) { errorMessage = string.Format( "Your order was not approved.{0}", ProcessError( reply ) ); } return null; }
/// <summary> /// Shows the view. /// </summary> /// <param name="txn">The TXN.</param> private void ShowView(FinancialScheduledTransaction txn) { if (txn != null) { hlStatus.Text = txn.IsActive ? "Active" : "Inactive"; hlStatus.LabelType = txn.IsActive ? LabelType.Success : LabelType.Danger; string rockUrlRoot = ResolveRockUrl("/"); var detailsLeft = new DescriptionList() .Add("Person", (txn.AuthorizedPersonAlias != null && txn.AuthorizedPersonAlias.Person != null) ? txn.AuthorizedPersonAlias.Person.GetAnchorTag(rockUrlRoot) : string.Empty); var detailsRight = new DescriptionList() .Add("Amount", (txn.ScheduledTransactionDetails.Sum(d => (decimal?)d.Amount) ?? 0.0M).FormatAsCurrency()) .Add("Frequency", txn.TransactionFrequencyValue != null ? txn.TransactionFrequencyValue.Value : string.Empty) .Add("Start Date", txn.StartDate.ToShortDateString()) .Add("End Date", txn.EndDate.HasValue ? txn.EndDate.Value.ToShortDateString() : string.Empty) .Add("Next Payment Date", txn.NextPaymentDate.HasValue ? txn.NextPaymentDate.Value.ToShortDateString() : string.Empty) .Add("Last Status Refresh", txn.LastStatusUpdateDateTime.HasValue ? txn.LastStatusUpdateDateTime.Value.ToString("g") : string.Empty); detailsLeft.Add("Source", txn.SourceTypeValue != null ? txn.SourceTypeValue.Value : string.Empty); if (txn.FinancialPaymentDetail != null && txn.FinancialPaymentDetail.CurrencyTypeValue != null) { var paymentMethodDetails = new DescriptionList(); var currencyType = txn.FinancialPaymentDetail.CurrencyTypeValue; if (currencyType.Guid.Equals(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD.AsGuid())) { // Credit Card paymentMethodDetails.Add("Type", currencyType.Value + (txn.FinancialPaymentDetail.CreditCardTypeValue != null ? (" - " + txn.FinancialPaymentDetail.CreditCardTypeValue.Value) : string.Empty)); paymentMethodDetails.Add("Name on Card", txn.FinancialPaymentDetail.NameOnCard.Trim()); paymentMethodDetails.Add("Account Number", txn.FinancialPaymentDetail.AccountNumberMasked); paymentMethodDetails.Add("Expires", txn.FinancialPaymentDetail.ExpirationDate); } else { // ACH paymentMethodDetails.Add("Type", currencyType.Value); paymentMethodDetails.Add("Account Number", txn.FinancialPaymentDetail.AccountNumberMasked); } detailsLeft.Add("Payment Method", paymentMethodDetails.GetFormattedList("{0}: {1}").AsDelimited("<br/>")); } GatewayComponent gateway = null; if (txn.FinancialGateway != null) { gateway = txn.FinancialGateway.GetGatewayComponent(); if (gateway != null) { detailsLeft.Add("Payment Gateway", GatewayContainer.GetComponentName(gateway.TypeName)); } } detailsLeft .Add("Transaction Code", txn.TransactionCode) .Add("Schedule Id", txn.GatewayScheduleId); lDetailsLeft.Text = detailsLeft.Html; lDetailsRight.Text = detailsRight.Html; gAccountsView.DataSource = txn.ScheduledTransactionDetails.ToList(); gAccountsView.DataBind(); var noteType = NoteTypeCache.Read(Rock.SystemGuid.NoteType.SCHEDULED_TRANSACTION_NOTE.AsGuid()); if (noteType != null) { var rockContext = new RockContext(); rptrNotes.DataSource = new NoteService(rockContext).Get(noteType.Id, txn.Id) .Where(n => n.CreatedDateTime.HasValue) .OrderBy(n => n.CreatedDateTime) .ToList() .Select(n => new { n.Caption, Text = n.Text.ConvertCrLfToHtmlBr(), Person = (n.CreatedByPersonAlias != null && n.CreatedByPersonAlias.Person != null) ? n.CreatedByPersonAlias.Person.FullName : "", Date = n.CreatedDateTime.HasValue ? n.CreatedDateTime.Value.ToShortDateString() : "", Time = n.CreatedDateTime.HasValue ? n.CreatedDateTime.Value.ToShortTimeString() : "" }) .ToList(); rptrNotes.DataBind(); } lbRefresh.Visible = gateway != null && gateway.GetScheduledPaymentStatusSupported; lbUpdate.Visible = gateway != null && gateway.UpdateScheduledPaymentSupported; lbCancelSchedule.Visible = txn.IsActive; lbReactivateSchedule.Visible = !txn.IsActive && gateway != null && gateway.ReactivateScheduledPaymentSupported; } }
/// <summary> /// Raises the <see cref="E:System.Web.UI.Control.Load" /> event. /// </summary> /// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param> protected override void OnLoad( EventArgs e ) { base.OnLoad( e ); nbClosedWarning.Visible = false; nbResult.Visible = false; var contextEntity = this.ContextEntity(); if ( contextEntity != null ) { if ( contextEntity is Person ) { _person = contextEntity as Person; } else if ( contextEntity is FinancialBatch ) { _batch = contextEntity as FinancialBatch; gfTransactions.Visible = false; } else if ( contextEntity is FinancialScheduledTransaction ) { _scheduledTxn = contextEntity as FinancialScheduledTransaction; gfTransactions.Visible = false; } else if ( contextEntity is Registration ) { _registration = contextEntity as Registration; gfTransactions.Visible = false; } } if ( !Page.IsPostBack ) { BindFilter(); BindGrid(); } else { ShowDialog(); } if ( _canEdit && _batch != null ) { string script = string.Format( @" $('#{0}').change(function( e ){{ var count = $(""#{1} input[id$='_cbSelect_0']:checked"").length; if (count == 0) {{ {2}; }} else {{ var $ddl = $(this); if ($ddl.val() != '') {{ Rock.dialogs.confirm('Are you sure you want to move the selected transactions to a new batch (the control amounts on each batch will be updated to reflect the moved transaction\'s amounts)?', function (result) {{ if (result) {{ {2}; }} $ddl.val(''); }}); }} }} }}); ", _ddlMove.ClientID, gTransactions.ClientID, Page.ClientScript.GetPostBackEventReference( this, "MoveTransactions" ) ); ScriptManager.RegisterStartupScript( _ddlMove, _ddlMove.GetType(), "moveTransaction", script, true ); } }
/// <summary> /// Updates the scheduled payment. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool UpdateScheduledPayment(FinancialScheduledTransaction transaction, PaymentInfo paymentInfo, out string errorMessage) { errorMessage = "This gateway does not support updating scheduled transactions. Transactions should be updated through the Reach interface."; return(false); }
/// <summary> /// Cancels the scheduled payment. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool CancelScheduledPayment( FinancialScheduledTransaction transaction, out string errorMessage ) { errorMessage = string.Empty; var financialGateway = transaction.FinancialGateway; RequestMessage request = GetMerchantInfo( transaction.FinancialGateway, false ); request.recurringSubscriptionInfo = new RecurringSubscriptionInfo(); request.recurringSubscriptionInfo.subscriptionID = transaction.TransactionCode; request.paySubscriptionUpdateService = new PaySubscriptionUpdateService(); request.recurringSubscriptionInfo.status = "cancel"; request.paySubscriptionUpdateService.run = "true"; // Cancel the payment ReplyMessage reply = SubmitTransaction( financialGateway, request, out errorMessage ); if ( reply != null && reply.reasonCode.Equals( GATEWAY_RESPONSE_SUCCESS ) ) { return true; } else if ( string.IsNullOrEmpty( errorMessage ) ) { errorMessage = string.Format( "Unable to cancel this transaction. {0}", ProcessError( reply ) ); } return false; }
/// <summary> /// Fetches the old (to be transferred) scheduled transaction and verifies /// that the target person is the same on the scheduled transaction. Then /// it puts it into the _scheduledTransactionToBeTransferred private field /// for use throughout the entry process so that its values can be used on /// the form for the new transaction. /// </summary> /// <param name="scheduledTransactionId">The scheduled transaction identifier.</param> private void InitializeTransfer( int? scheduledTransactionId ) { if ( scheduledTransactionId == null ) { return; } RockContext rockContext = new RockContext(); var scheduledTransaction = new FinancialScheduledTransactionService( rockContext ).Get( scheduledTransactionId.Value ); var personService = new PersonService( rockContext ); // get business giving id var givingIds = personService.GetBusinesses( _targetPerson.Id ).Select( g => g.GivingId ).ToList(); // add the person's regular giving id givingIds.Add( _targetPerson.GivingId ); // Make sure the current person is the authorized person, otherwise return if ( scheduledTransaction == null || ! givingIds.Contains( scheduledTransaction.AuthorizedPersonAlias.Person.GivingId ) ) { return; } _scheduledTransactionToBeTransferred = scheduledTransaction; // Set the frequency to be the same on the initial page build if ( !IsPostBack ) { btnFrequency.SelectedValue = scheduledTransaction.TransactionFrequencyValueId.ToString(); dtpStartDate.SelectedDate = ( scheduledTransaction.NextPaymentDate.HasValue ) ? scheduledTransaction.NextPaymentDate : RockDateTime.Today.AddDays( 1 ); } }
/// <summary> /// Raises the <see cref="E:System.Web.UI.Control.Load" /> event. /// </summary> /// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param> protected override void OnLoad( EventArgs e ) { base.OnLoad( e ); bool promptWithFilter = true; var contextEntity = this.ContextEntity(); if ( contextEntity != null ) { if ( contextEntity is Person ) { _person = contextEntity as Person; promptWithFilter = false; } else if ( contextEntity is FinancialBatch ) { _batch = contextEntity as FinancialBatch; gfTransactions.Visible = false; promptWithFilter = false; } else if ( contextEntity is FinancialScheduledTransaction ) { _scheduledTxn = contextEntity as FinancialScheduledTransaction; gfTransactions.Visible = false; promptWithFilter = false; } } if ( !Page.IsPostBack ) { BindFilter(); if ( promptWithFilter && gfTransactions.Visible ) { //// NOTE: Special Case for this List Block since there could be a very large number of transactions: //// If the filter is shown and we aren't filtering by anything else, don't automatically populate the grid. Wait for them to hit apply on the filter gfTransactions.Show(); } else { BindGrid(); } } if ( _canEdit && _batch != null ) { string script = string.Format( @" $('#{0}').change(function( e ){{ var count = $(""#{1} input[id$='_cbSelect_0']:checked"").length; if (count == 0) {{ eval({2}); }} else {{ var $ddl = $(this); if ($ddl.val() != '') {{ Rock.dialogs.confirm('Are you sure you want to move the selected transactions to a new batch (the control amounts on each batch will be updated to reflect the moved transaction\'s amounts)?', function (result) {{ if (result) {{ eval({2}); }} $ddl.val(''); }}); }} }} }}); ", _ddlMove.ClientID, gTransactions.ClientID, Page.ClientScript.GetPostBackEventReference( this, "MoveTransactions" ) ); ScriptManager.RegisterStartupScript( _ddlMove, _ddlMove.GetType(), "moveTransaction", script, true ); } }
/// <summary> /// Sets the status. /// </summary> /// <param name="scheduledTransaction">The scheduled transaction.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public bool GetStatus( FinancialScheduledTransaction scheduledTransaction, out string errorMessages ) { if ( scheduledTransaction != null && scheduledTransaction.FinancialGateway != null && scheduledTransaction.FinancialGateway.IsActive ) { if ( scheduledTransaction.FinancialGateway.Attributes == null ) { scheduledTransaction.FinancialGateway.LoadAttributes( (RockContext)this.Context ); } var gateway = scheduledTransaction.FinancialGateway.GetGatewayComponent(); if ( gateway != null ) { return gateway.GetScheduledPaymentStatus( scheduledTransaction, out errorMessages ); } } errorMessages = "Gateway is invalid or not active"; return false; }
/// <summary> /// Adds the scheduled payment. /// </summary> /// <param name="schedule">The schedule.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override FinancialScheduledTransaction AddScheduledPayment(FinancialGateway financialGateway, PaymentSchedule schedule, PaymentInfo paymentInfo, out string errorMessage) { errorMessage = string.Empty; RequestMessage request = GetPaymentInfo(financialGateway, paymentInfo); if (request == null) { errorMessage = "Payment type not implemented"; return(null); } if (request.recurringSubscriptionInfo == null) { request.recurringSubscriptionInfo = new RecurringSubscriptionInfo(); } request.recurringSubscriptionInfo.startDate = GetStartDate(schedule); request.recurringSubscriptionInfo.frequency = GetFrequency(schedule); request.recurringSubscriptionInfo.amount = paymentInfo.Amount.ToString(); request.paySubscriptionCreateService = new PaySubscriptionCreateService(); request.paySubscriptionCreateService.run = "true"; request.purchaseTotals = GetTotals(paymentInfo); request.billTo = GetBillTo(paymentInfo); request.item = GetItems(paymentInfo); request.subscription = new Subscription(); if (!paymentInfo.CurrencyTypeValue.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD))) { request.subscription.paymentMethod = "check"; } if (paymentInfo is ReferencePaymentInfo) { request.paySubscriptionCreateService.paymentRequestID = ((ReferencePaymentInfo)paymentInfo).TransactionCode; } ReplyMessage reply = SubmitTransaction(financialGateway, request); if (reply != null) { if (reply.reasonCode.Equals("100")) // SUCCESS { var transactionGuid = new Guid(reply.merchantReferenceCode); var scheduledTransaction = new FinancialScheduledTransaction { Guid = transactionGuid }; scheduledTransaction.TransactionCode = reply.paySubscriptionCreateReply.subscriptionID; scheduledTransaction.GatewayScheduleId = reply.paySubscriptionCreateReply.subscriptionID; scheduledTransaction.FinancialGateway = financialGateway; scheduledTransaction.FinancialGatewayId = financialGateway.Id; GetScheduledPaymentStatus(scheduledTransaction, out errorMessage); return(scheduledTransaction); } else { errorMessage = string.Format("Your order was not approved.{0}", ProcessError(reply)); } } else { errorMessage = "Invalid response from the financial gateway."; } return(null); }
/// <summary> /// Gets an optional reference identifier needed to process future transaction from saved account. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override string GetReferenceNumber( FinancialScheduledTransaction scheduledTransaction, out string errorMessage ) { errorMessage = string.Empty; return string.Empty; }
/// <summary> /// Reactivates the scheduled payment (CyberSource not supported). /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool ReactivateScheduledPayment(FinancialScheduledTransaction transaction, out string errorMessage) { errorMessage = string.Empty; return(false); }
/// <summary> /// Updates the scheduled payment. /// </summary> /// <param name="schedule">The schedule.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool UpdateScheduledPayment( FinancialScheduledTransaction transaction, PaymentInfo paymentInfo, out string errorMessage ) { errorMessage = string.Empty; RecurringModifyTransaction ppTransaction = null; if ( paymentInfo != null ) { ppTransaction = new RecurringModifyTransaction( GetUserInfo(), GetConnection(), GetRecurring( transaction ), GetInvoice( paymentInfo ), GetTender( paymentInfo ), PayflowUtility.RequestId ); } else { ppTransaction = new RecurringModifyTransaction( GetUserInfo(), GetConnection(), GetRecurring( transaction ), PayflowUtility.RequestId ); } var ppResponse = ppTransaction.SubmitTransaction(); if ( ppResponse != null ) { TransactionResponse txnResponse = ppResponse.TransactionResponse; if ( txnResponse != null ) { if ( txnResponse.Result == 0 ) // Success { RecurringResponse recurringResponse = ppResponse.RecurringResponse; if ( recurringResponse != null ) { return true; } else { errorMessage = "Invalid recurring response from the financial gateway"; } } else { errorMessage = string.Format( "[{0}] {1}", txnResponse.Result, txnResponse.RespMsg ); } } else { errorMessage = "Invalid transaction response from the financial gateway"; } } else { errorMessage = "Invalid response from the financial gateway."; } return false; }
/// <summary> /// Gets the payment information. /// </summary> /// <returns></returns> private PaymentInfo GetPaymentInfo(PersonService personService, FinancialScheduledTransaction scheduledTransaction) { PaymentInfo paymentInfo = null; if ( hfPaymentTab.Value == "ACH" ) { if ( rblSavedAch.Items.Count > 0 && ( rblSavedAch.SelectedValueAsId() ?? 0 ) > 0 ) { paymentInfo = GetReferenceInfo( rblSavedAch.SelectedValueAsId().Value ); } else { paymentInfo = GetACHInfo(); } } else if ( hfPaymentTab.Value == "CreditCard" ) { if ( rblSavedCC.Items.Count > 0 && ( rblSavedCC.SelectedValueAsId() ?? 0 ) > 0 ) { paymentInfo = GetReferenceInfo( rblSavedCC.SelectedValueAsId().Value ); } else { paymentInfo = GetCCInfo(); } } else { paymentInfo = new PaymentInfo(); } if ( paymentInfo != null ) { paymentInfo.Amount = SelectedAccounts.Sum( a => a.Amount ); paymentInfo.FirstName = scheduledTransaction.AuthorizedPerson.FirstName; paymentInfo.LastName = scheduledTransaction.AuthorizedPerson.LastName; paymentInfo.Email = scheduledTransaction.AuthorizedPerson.Email; bool displayPhone = false; if ( bool.TryParse( GetAttributeValue( "DisplayPhone" ), out displayPhone ) && displayPhone ) { var phoneNumber = personService.GetPhoneNumber( scheduledTransaction.AuthorizedPerson, DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME ) ) ); paymentInfo.Phone = phoneNumber != null ? phoneNumber.NumberFormatted : string.Empty; } Guid addressTypeGuid = Guid.Empty; if ( !Guid.TryParse( GetAttributeValue( "AddressType" ), out addressTypeGuid ) ) { addressTypeGuid = new Guid( Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME ); } var address = personService.GetFirstLocation( scheduledTransaction.AuthorizedPerson, DefinedValueCache.Read( addressTypeGuid ).Id ); if ( address != null ) { paymentInfo.Street = address.Street1; paymentInfo.City = address.City; paymentInfo.State = address.State; paymentInfo.Zip = address.Zip; } } return paymentInfo; }
private void GetAccounts(FinancialScheduledTransaction scheduledTransaction) { var selectedGuids = GetAttributeValues( "Accounts" ).Select( Guid.Parse ).ToList(); bool showAll = !selectedGuids.Any(); bool additionalAccounts = true; if ( !bool.TryParse( GetAttributeValue( "AdditionalAccounts" ), out additionalAccounts ) ) { additionalAccounts = true; } SelectedAccounts = new List<AccountItem>(); AvailableAccounts = new List<AccountItem>(); // Enumerate through all active accounts that have a public name foreach ( var account in new FinancialAccountService().Queryable() .Where( f => f.IsActive && f.PublicName != null && f.PublicName.Trim() != "" && ( f.StartDate == null || f.StartDate <= DateTime.Today ) && ( f.EndDate == null || f.EndDate >= DateTime.Today ) ) .OrderBy( f => f.Order ) ) { var accountItem = new AccountItem( account.Id, account.Order, account.Name, account.CampusId ); if ( showAll ) { SelectedAccounts.Add( accountItem ); } else { if ( selectedGuids.Contains( account.Guid ) ) { SelectedAccounts.Add( accountItem ); } else { if ( additionalAccounts ) { AvailableAccounts.Add( accountItem ); } } } } foreach ( var txnDetail in scheduledTransaction.ScheduledTransactionDetails ) { var selectedAccount = SelectedAccounts.Where( a => a.Id == txnDetail.AccountId ).FirstOrDefault(); if ( selectedAccount != null ) { selectedAccount.Amount = txnDetail.Amount; } else { var selected = AvailableAccounts.Where( a => a.Id == txnDetail.AccountId ).ToList(); if ( selected != null ) { selected.ForEach( a => a.Amount = txnDetail.Amount ); AvailableAccounts = AvailableAccounts.Except( selected ).ToList(); SelectedAccounts.AddRange( selected ); } } } BindAccounts(); }
/// <summary> /// Gets the scheduled payment status. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool GetScheduledPaymentStatus(FinancialScheduledTransaction transaction, out string errorMessage) { errorMessage = "This gateway does not support scheduled transactions. Transactions should be managed through the Reach interface."; return(false); }
private GatewayComponent GetGateway(FinancialScheduledTransaction scheduledTransaction) { if (scheduledTransaction.GatewayEntityType != null) { Guid gatewayGuid = scheduledTransaction.GatewayEntityType.Guid; var gateway = GatewayContainer.GetComponent(gatewayGuid.ToString()); if (gateway != null && gateway.IsActive) { return gateway; } } return null; }
/// <summary> /// Calculates the next payment date based off of frequency and last transaction date. /// </summary> /// <param name="scheduledTransaction">The scheduled transaction.</param> /// <param name="lastTransactionDate">The last transaction date.</param> /// <returns></returns> public DateTime?CalculateNextPaymentDate(FinancialScheduledTransaction scheduledTransaction, DateTime?lastTransactionDate) { // If scheduled transaction is null, just return null if (scheduledTransaction == null) { return(null); } // If start date is today or in future, return that value if (scheduledTransaction.StartDate >= RockDateTime.Today.Date) { return(scheduledTransaction.StartDate); } // If scheduled transaction does not have a frequency, just return null if (scheduledTransaction.TransactionFrequencyValue == null) { return(null); } // Calculate the later of start date or last transaction date, and use that to calculate next payment var startDate = scheduledTransaction.StartDate; if (lastTransactionDate.HasValue && lastTransactionDate > startDate) { startDate = lastTransactionDate.Value; } // Calculate the next payment date based on the frequency DateTime?nextPayment = null; switch (scheduledTransaction.TransactionFrequencyValue.Guid.ToString().ToUpper()) { case SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_WEEKLY: nextPayment = startDate.AddDays(7); break; case SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_BIWEEKLY: nextPayment = startDate.AddDays(14); break; case SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_TWICEMONTHLY: nextPayment = startDate.AddDays(15); break; case SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_MONTHLY: nextPayment = startDate.AddMonths(1); break; case SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_QUARTERLY: nextPayment = startDate.AddMonths(3); break; case SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_TWICEYEARLY: nextPayment = startDate.AddMonths(6); break; case SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_YEARLY: nextPayment = startDate.AddYears(1); break; } // If a date was calculated and it is not in the past, return that value if (nextPayment.HasValue && nextPayment.Value >= RockDateTime.Now.Date) { return(nextPayment); } return(null); }
private void SetFrequency(FinancialScheduledTransaction scheduledTransaction) { // Enable payment options based on the configured gateways bool ccEnabled = false; bool achEnabled = false; if (Gateway != null) { if (Gateway.TypeGuid.Equals(GetAttributeValue( "CCGateway" ).AsGuid())) { ccEnabled = true; txtCardFirstName.Visible = Gateway.SplitNameOnCard; txtCardFirstName.Text = scheduledTransaction.AuthorizedPerson.FirstName; txtCardLastName.Visible = Gateway.SplitNameOnCard; txtCardLastName.Text = scheduledTransaction.AuthorizedPerson.LastName; txtCardName.Visible = !Gateway.SplitNameOnCard; txtCardName.Text = scheduledTransaction.AuthorizedPerson.FullName; var address = new PersonService().GetFirstLocation( scheduledTransaction.AuthorizedPerson, DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME.AsGuid() ).Id ); if ( address != null ) { txtBillingStreet.Text = address.Street1; txtBillingCity.Text = address.City; ddlBillingState.SelectedValue = address.State; txtBillingZip.Text = address.Zip; } mypExpiration.MinimumYear = DateTime.Now.Year; } if (Gateway.TypeGuid.Equals(GetAttributeValue( "ACHGateway" ).AsGuid())) { achEnabled = true; } } if ( ccEnabled || achEnabled ) { if ( ccEnabled ) { divCCPaymentInfo.AddCssClass( "tab-pane" ); divCCPaymentInfo.Visible = ccEnabled; } if ( achEnabled ) { divACHPaymentInfo.AddCssClass( "tab-pane" ); divACHPaymentInfo.Visible = achEnabled; } if ( Gateway.SupportedPaymentSchedules.Any() ) { var oneTimeFrequency = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME ); divRepeatingPayments.Visible = true; btnFrequency.DataSource = Gateway.SupportedPaymentSchedules; btnFrequency.DataBind(); btnFrequency.SelectedValue = scheduledTransaction.TransactionFrequencyValueId.ToString(); } } }
/// <summary> /// Shows the view. /// </summary> /// <param name="txn">The TXN.</param> private void ShowView( FinancialScheduledTransaction txn ) { if ( txn != null ) { hlStatus.Text = txn.IsActive ? "Active" : "Inactive"; hlStatus.LabelType = txn.IsActive ? LabelType.Success : LabelType.Danger; string rockUrlRoot = ResolveRockUrl( "/" ); var detailsLeft = new DescriptionList() .Add( "Person", ( txn.AuthorizedPersonAlias != null && txn.AuthorizedPersonAlias.Person != null ) ? txn.AuthorizedPersonAlias.Person.GetAnchorTag( rockUrlRoot ) : string.Empty ); var detailsRight = new DescriptionList() .Add( "Amount", ( txn.ScheduledTransactionDetails.Sum( d => (decimal?)d.Amount ) ?? 0.0M ).ToString( "C2" ) ) .Add( "Frequency", txn.TransactionFrequencyValue != null ? txn.TransactionFrequencyValue.Value : string.Empty ) .Add( "Start Date", txn.StartDate.ToShortDateString() ) .Add( "End Date", txn.EndDate.HasValue ? txn.EndDate.Value.ToShortDateString() : string.Empty ) .Add( "Next Payment Date", txn.NextPaymentDate.HasValue ? txn.NextPaymentDate.Value.ToShortDateString() : string.Empty ) .Add( "Last Status Refresh", txn.LastStatusUpdateDateTime.HasValue ? txn.LastStatusUpdateDateTime.Value.ToString( "g" ) : string.Empty ); if ( txn.FinancialPaymentDetail != null && txn.FinancialPaymentDetail.CurrencyTypeValue != null ) { string currencyType = txn.FinancialPaymentDetail.CurrencyTypeValue.Value; if ( txn.FinancialPaymentDetail.CurrencyTypeValue.Guid.Equals( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD.AsGuid() ) ) { currencyType += txn.FinancialPaymentDetail.CreditCardTypeValue != null ? ( " - " + txn.FinancialPaymentDetail.CreditCardTypeValue.Value ) : string.Empty; } detailsLeft.Add( "Currency Type", currencyType ); } if ( txn.FinancialGateway != null ) { detailsLeft.Add( "Payment Gateway", Rock.Financial.GatewayContainer.GetComponentName( txn.FinancialGateway.Name ) ); } detailsLeft .Add( "Transaction Code", txn.TransactionCode ) .Add( "Schedule Id", txn.GatewayScheduleId ); lDetailsLeft.Text = detailsLeft.Html; lDetailsRight.Text = detailsRight.Html; gAccountsView.DataSource = txn.ScheduledTransactionDetails.ToList(); gAccountsView.DataBind(); var noteType = NoteTypeCache.Read( Rock.SystemGuid.NoteType.SCHEDULED_TRANSACTION_NOTE.AsGuid() ); if ( noteType != null ) { var rockContext = new RockContext(); rptrNotes.DataSource = new NoteService( rockContext ).Get( noteType.Id, txn.Id ) .Where( n => n.CreatedDateTime.HasValue ) .OrderBy( n => n.CreatedDateTime ) .ToList() .Select( n => new { n.Caption, Text = n.Text.ConvertCrLfToHtmlBr(), Person = ( n.CreatedByPersonAlias != null && n.CreatedByPersonAlias.Person != null ) ? n.CreatedByPersonAlias.Person.FullName : "", Date = n.CreatedDateTime.HasValue ? n.CreatedDateTime.Value.ToShortDateString() : "", Time = n.CreatedDateTime.HasValue ? n.CreatedDateTime.Value.ToShortTimeString() : "" } ) .ToList(); rptrNotes.DataBind(); } lbCancelSchedule.Visible = txn.IsActive; lbReactivateSchedule.Visible = !txn.IsActive; } }
/// <summary> /// Gets the scheduled payment status. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool GetScheduledPaymentStatus(FinancialScheduledTransaction transaction, out string errorMessage) { transaction.LastStatusUpdateDateTime = RockDateTime.Now; errorMessage = string.Empty; return(true); }
/// <summary> /// Handles the Click event of the btnGive control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> protected void btnGive_Click(object sender, EventArgs e) { Person person = FindPerson(); using (new UnitOfWorkScope()) { RockTransactionScope.WrapTransaction(() => { var groupLocationService = new GroupLocationService(); var groupMemberService = new GroupMemberService(); var phoneService = new PhoneNumberService(); var locationService = new LocationService(); var groupService = new GroupService(); GroupLocation groupLocation; Location homeAddress; Group familyGroup; var homeLocationType = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.LOCATION_TYPE_HOME); var addressList = locationService.Queryable().Where(l => l.Street1 == txtStreet.Text && l.City == txtCity.Text && l.State == ddlState.SelectedValue && l.Zip == txtZip.Text && l.LocationTypeValueId == homeLocationType.Id).ToList(); if (!addressList.Any()) { homeAddress = new Location(); locationService.Add(homeAddress, person.Id); } else { homeAddress = addressList.FirstOrDefault(); } homeAddress.Street1 = txtStreet.Text ?? homeAddress.Street1; homeAddress.City = txtCity.Text ?? homeAddress.City; homeAddress.State = ddlState.SelectedValue ?? homeAddress.State; homeAddress.Zip = txtZip.Text ?? homeAddress.Zip; homeAddress.IsActive = true; homeAddress.IsLocation = true; homeAddress.Country = "US"; homeAddress.LocationTypeValueId = homeLocationType.Id; locationService.Save(homeAddress, person.Id); GroupType familyGroupType = new GroupTypeService().Get(new Guid(Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY)); var familyGroupList = groupMemberService.Queryable().Where(g => g.PersonId == person.Id && g.Group.GroupType.Guid == familyGroupType.Guid).Select(g => g.Group).ToList(); if (!familyGroupList.Any()) { familyGroup = new Group(); familyGroup.IsActive = true; familyGroup.IsSystem = false; familyGroup.IsSecurityRole = false; familyGroup.Name = "The " + txtLastName.Text + " Family"; familyGroup.GroupTypeId = familyGroupType.Id; groupService.Add(familyGroup, person.Id); groupService.Save(familyGroup, person.Id); var familyMember = new GroupMember(); familyMember.IsSystem = false; familyMember.GroupId = familyGroup.Id; familyMember.PersonId = person.Id; familyMember.GroupRoleId = new GroupRoleService().Get(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT)).Id; groupMemberService.Add(familyMember, person.Id); groupMemberService.Save(familyMember, person.Id); } else { familyGroup = familyGroupList.FirstOrDefault(); } var groupLocationList = groupLocationService.Queryable().Where(g => g.GroupLocationTypeValueId == familyGroupType.Id && g.GroupId == familyGroup.Id).ToList(); if (!groupLocationList.Any()) { groupLocation = new GroupLocation(); groupLocation.GroupId = familyGroup.Id; groupLocation.LocationId = homeAddress.Id; groupLocation.IsMailing = true; groupLocation.IsLocation = true; groupLocation.GroupLocationTypeValueId = homeLocationType.Id; groupLocationService.Add(groupLocation, person.Id); groupLocationService.Save(groupLocation, person.Id); } else { groupLocation = groupLocationList.FirstOrDefault(); } groupLocation.LocationId = homeAddress.Id; groupLocationService.Save(groupLocation, person.Id); var homePhoneType = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME); string phoneNumeric = txtPhone.Text.AsNumeric(); if (!phoneService.Queryable().Where(n => n.PersonId == person.Id && n.NumberTypeValueId == homePhoneType.Id && n.Number == phoneNumeric).Any()) { var homePhone = new PhoneNumber(); homePhone.Number = phoneNumeric; homePhone.PersonId = person.Id; homePhone.IsSystem = false; homePhone.IsMessagingEnabled = false; homePhone.IsUnlisted = false; homePhone.NumberTypeValueId = homePhoneType.Id; phoneService.Add(homePhone, person.Id); phoneService.Save(homePhone, person.Id); } }); } var amountList = (Dictionary <FinancialAccount, Decimal>)Session["CachedAmounts"]; var profileId = (int)Session["CachedProfileId"]; Location giftLocation = new Location(); var configValues = (Dictionary <string, object>)Session["CachedMergeFields"]; configValues.Add("Date", DateTimeOffset.Now.ToString("MM/dd/yyyy hh:mm tt")); var receiptTemplate = GetAttributeValue("ReceiptMessage"); lReceipt.Text = receiptTemplate.ResolveMergeFields(configValues); var summaryTemplate = GetAttributeValue("SummaryMessage"); string summaryMessage = summaryTemplate.ResolveMergeFields(configValues); var creditProcessorId = GetAttributeValue("CreditCardProvider"); var achProcessorId = GetAttributeValue("Checking/ACHProvider"); var gatewayService = new FinancialGatewayService(); FinancialGateway gateway; if (!string.IsNullOrEmpty(txtCreditCard.Text) && !string.IsNullOrWhiteSpace(creditProcessorId)) { int creditId = Convert.ToInt32(creditProcessorId); gateway = new FinancialGatewayService().Get(creditId); } else if (!string.IsNullOrEmpty(txtAccountNumber.Text) && !string.IsNullOrWhiteSpace(achProcessorId)) { int achId = Convert.ToInt32(achProcessorId); gateway = new FinancialGatewayService().Get(achId); } else { gateway = gatewayService.Queryable().FirstOrDefault(); } // #TODO test card through gateway if (btnFrequency.SelectedIndex > -1 && btnFrequency.SelectedValueAsInt() != DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_TYPE_ONE_TIME).Id) { using (new UnitOfWorkScope()) { RockTransactionScope.WrapTransaction(() => { var scheduledTransactionDetailService = new FinancialScheduledTransactionDetailService(); var scheduledTransactionService = new FinancialScheduledTransactionService(); FinancialScheduledTransaction scheduledTransaction; var detailList = amountList.ToList(); if (profileId > 0) { scheduledTransaction = scheduledTransactionService.Get(profileId); } else { scheduledTransaction = new FinancialScheduledTransaction(); scheduledTransactionService.Add(scheduledTransaction, person.Id); } DateTime startDate = (DateTime)dtpStartDate.SelectedDate; if (startDate != null) { scheduledTransaction.StartDate = startDate; } scheduledTransaction.TransactionFrequencyValueId = (int)btnFrequency.SelectedValueAsInt(); scheduledTransaction.AuthorizedPersonId = person.Id; scheduledTransaction.IsActive = true; if (!string.IsNullOrEmpty(txtCreditCard.Text)) { scheduledTransaction.CardReminderDate = mypExpiration.SelectedDate; } if (chkLimitGifts.Checked && !string.IsNullOrWhiteSpace(txtLimitNumber.Text)) { scheduledTransaction.NumberOfPayments = Convert.ToInt32(txtLimitNumber.Text); } foreach (var detail in amountList.ToList()) { var scheduledTransactionDetail = new FinancialScheduledTransactionDetail(); scheduledTransactionDetail.AccountId = detail.Key.Id; scheduledTransactionDetail.Amount = detail.Value; scheduledTransactionDetail.ScheduledTransactionId = scheduledTransaction.Id; scheduledTransactionDetailService.Add(scheduledTransactionDetail, person.Id); scheduledTransactionDetailService.Save(scheduledTransactionDetail, person.Id); } // implement gateway charge() scheduledTransactionService.Save(scheduledTransaction, person.Id); }); } } else { using (new UnitOfWorkScope()) { RockTransactionScope.WrapTransaction(() => { var transactionService = new FinancialTransactionService(); var tdService = new FinancialTransactionDetailService(); var transaction = new FinancialTransaction(); var detailList = amountList.ToList(); transaction.Summary = summaryMessage; transaction.Amount = detailList.Sum(d => d.Value); transaction.TransactionTypeValueId = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION).Id; transaction.TransactionDateTime = DateTimeOffset.Now.DateTime; transaction.AuthorizedPersonId = person.Id; transactionService.Add(transaction, person.Id); foreach (var detail in detailList) { var td = new FinancialTransactionDetail(); td.TransactionId = transaction.Id; td.AccountId = detail.Key.Id; td.Amount = detail.Value; td.TransactionId = transaction.Id; tdService.Add(td, person.Id); tdService.Save(td, person.Id); } // #TODO implement gateway.charge() transactionService.Save(transaction, person.Id); }); } } Session["CachedMergeFields"] = configValues; pnlConfirm.Visible = false; pnlComplete.Visible = true; pnlContribution.Update(); }
/// <summary> /// Adds the scheduled payment. /// </summary> /// <param name="financialGateway"></param> /// <param name="schedule">The schedule.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override FinancialScheduledTransaction AddScheduledPayment(FinancialGateway financialGateway, PaymentSchedule schedule, PaymentInfo paymentInfo, out string errorMessage) { errorMessage = string.Empty; var recurring = GetRecurring(schedule); if (paymentInfo is CreditCardPaymentInfo) { recurring.OptionalTrx = "A"; } var ppTransaction = new RecurringAddTransaction(GetUserInfo(financialGateway), GetConnection(financialGateway), GetInvoice(paymentInfo), GetTender(paymentInfo), recurring, PayflowUtility.RequestId); if (paymentInfo is ReferencePaymentInfo) { var reference = paymentInfo as ReferencePaymentInfo; ppTransaction.OrigId = reference.TransactionCode; } var ppResponse = ppTransaction.SubmitTransaction(); if (ppResponse != null) { TransactionResponse txnResponse = ppResponse.TransactionResponse; if (txnResponse != null) { if (txnResponse.Result == 0) // Success { RecurringResponse recurringResponse = ppResponse.RecurringResponse; if (recurringResponse != null) { var scheduledTransaction = new FinancialScheduledTransaction(); scheduledTransaction.TransactionCode = recurringResponse.TrxPNRef; scheduledTransaction.GatewayScheduleId = recurringResponse.ProfileId; scheduledTransaction.FinancialGatewayId = financialGateway.Id; GetScheduledPaymentStatus(scheduledTransaction, out errorMessage); return(scheduledTransaction); } else { errorMessage = "Invalid recurring response from the financial gateway"; } } else { errorMessage = string.Format("[{0}] {1}", txnResponse.Result, txnResponse.RespMsg); } } else { errorMessage = "Invalid transaction response from the financial gateway"; } } else { errorMessage = "Invalid response from the financial gateway."; } return(null); }
/// <summary> /// Updates the scheduled payment. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool UpdateScheduledPayment( FinancialScheduledTransaction transaction, PaymentInfo paymentInfo, out string errorMessage ) { errorMessage = string.Empty; return true; }
private FinancialGateway GetFinancialGateway(FinancialScheduledTransaction scheduledTransaction) { return(scheduledTransaction != null?GetFinancialGateway(scheduledTransaction.FinancialGateway, scheduledTransaction.FinancialGatewayId) : null); }
/// <summary> /// Gets the scheduled payment status. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool GetScheduledPaymentStatus( FinancialScheduledTransaction transaction, out string errorMessage ) { errorMessage = string.Empty; return true; }
/// <summary> /// Safely load entities that have not yet been assigned a non-null value based on the arguments. /// </summary> private void LoadEntities() { if (_automatedPaymentArgs.ScheduledTransactionId.HasValue && _financialScheduledTransaction == null) { _financialScheduledTransaction = _financialScheduledTransactionService.Queryable() .AsNoTracking() .Include(s => s.TransactionFrequencyValue) .FirstOrDefault(s => s.Id == _automatedPaymentArgs.ScheduledTransactionId.Value); } if (_authorizedPerson == null) { _authorizedPerson = _personAliasService.GetPersonNoTracking(_automatedPaymentArgs.AuthorizedPersonAliasId); } if (_financialGateway == null) { _financialGateway = _financialGatewayService.GetNoTracking(_automatedPaymentArgs.AutomatedGatewayId); } if (_financialGateway != null && _automatedGatewayComponent == null) { _automatedGatewayComponent = _financialGateway.GetGatewayComponent(); } if (_financialAccounts == null) { var accountIds = _automatedPaymentArgs.AutomatedPaymentDetails.Select(d => d.AccountId).ToList(); _financialAccounts = _financialAccountService.GetByIds(accountIds).AsNoTracking().ToDictionary(fa => fa.Id, fa => fa); } if (_authorizedPerson != null && _financialPersonSavedAccount == null && _financialGateway != null) { // Pick the correct saved account based on args or default for the user var financialGatewayId = _financialGateway.Id; var savedAccounts = _financialPersonSavedAccountService .GetByPersonId(_authorizedPerson.Id) .AsNoTracking() .Where(sa => sa.FinancialGatewayId == financialGatewayId) .Include(sa => sa.FinancialPaymentDetail) .OrderByDescending(sa => sa.CreatedDateTime ?? DateTime.MinValue) .ToList(); if (_automatedPaymentArgs.FinancialPersonSavedAccountId.HasValue) { // If there is an indicated saved account to use, don't assume any other saved account even with a schedule var savedAccountId = _automatedPaymentArgs.FinancialPersonSavedAccountId.Value; _financialPersonSavedAccount = savedAccounts.FirstOrDefault(sa => sa.Id == savedAccountId); } else { // If there is a schedule and no indicated saved account to use, try to use payment info associated with the schedule if (_financialScheduledTransaction != null) { _financialPersonSavedAccount = // sa.ReferenceNumber == fst.TransactionCode savedAccounts.FirstOrDefault(sa => !string.IsNullOrEmpty(sa.ReferenceNumber) && sa.ReferenceNumber == _financialScheduledTransaction.TransactionCode) ?? // sa.GatewayPersonIdentifier == fst.TransactionCode savedAccounts.FirstOrDefault(sa => !string.IsNullOrEmpty(sa.GatewayPersonIdentifier) && sa.GatewayPersonIdentifier == _financialScheduledTransaction.TransactionCode) ?? // sa.FinancialPaymentDetailId == fst.FinancialPaymentDetailId savedAccounts.FirstOrDefault(sa => sa.FinancialPaymentDetailId.HasValue && sa.FinancialPaymentDetailId == _financialScheduledTransaction.FinancialPaymentDetailId) ?? // sa.TransactionCode == fst.TransactionCode savedAccounts.FirstOrDefault(sa => !string.IsNullOrEmpty(sa.TransactionCode) && sa.TransactionCode == _financialScheduledTransaction.TransactionCode); } if (_financialPersonSavedAccount == null) { // Use the default or first if no default _financialPersonSavedAccount = savedAccounts.FirstOrDefault(sa => sa.IsDefault) ?? savedAccounts.FirstOrDefault(); } } } if (_financialPersonSavedAccount != null && _referencePaymentInfo == null) { _referencePaymentInfo = _financialPersonSavedAccount.GetReferencePayment(); } if (_transactionType == null) { _transactionType = DefinedValueCache.Get(_automatedPaymentArgs.TransactionTypeGuid ?? SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION.AsGuid()); } if (_financialSource == null) { _financialSource = DefinedValueCache.Get(_automatedPaymentArgs.FinancialSourceGuid ?? SystemGuid.DefinedValue.FINANCIAL_SOURCE_TYPE_WEBSITE.AsGuid()); } }
/// <summary> /// Adds the scheduled payment. /// </summary> /// <param name="schedule">The schedule.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override FinancialScheduledTransaction AddScheduledPayment( PaymentSchedule schedule, PaymentInfo paymentInfo, out string errorMessage ) { errorMessage = string.Empty; var scheduledTransaction = new FinancialScheduledTransaction(); scheduledTransaction.TransactionCode = "T" + RockDateTime.Now.ToString("yyyyMMddHHmmssFFF"); scheduledTransaction.GatewayScheduleId = "P" + RockDateTime.Now.ToString("yyyyMMddHHmmssFFF"); return scheduledTransaction; }
/// <summary> /// Updates the scheduled payment. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool UpdateScheduledPayment(FinancialScheduledTransaction transaction, PaymentInfo paymentInfo, out string errorMessage) { errorMessage = "The payment gateway associated with this scheduled transaction (NMI) does not support updating an existing scheduled transaction. A new scheduled transaction should be created instead."; return(false); }
/// <summary> /// Updates the scheduled payment. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public abstract bool UpdateScheduledPayment(FinancialScheduledTransaction transaction, PaymentInfo paymentInfo, out string errorMessage);
/// <summary> /// Gets the scheduled payment status. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override bool GetScheduledPaymentStatus(FinancialScheduledTransaction transaction, out string errorMessage) { // NMI does not support getting the status of a scheduled transaction. errorMessage = string.Empty; return(true); }
/// <summary> /// Reactivates the scheduled payment. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public abstract bool ReactivateScheduledPayment(FinancialScheduledTransaction transaction, out string errorMessage);
/// <summary> /// Gets the next payment date. /// </summary> /// <param name="scheduledTransaction">The transaction.</param> /// <param name="lastTransactionDate">The last transaction date.</param> /// <returns></returns> public override DateTime?GetNextPaymentDate(FinancialScheduledTransaction scheduledTransaction, DateTime?lastTransactionDate) { return(CalculateNextPaymentDate(scheduledTransaction, lastTransactionDate)); }
/// <summary> /// Gets the scheduled payment status. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public abstract bool GetScheduledPaymentStatus(FinancialScheduledTransaction transaction, out string errorMessage);
private void SaveScheduledTransaction( FinancialGateway financialGateway, GatewayComponent gateway, Person person, PaymentInfo paymentInfo, PaymentSchedule schedule, FinancialScheduledTransaction scheduledTransaction, RockContext rockContext ) { scheduledTransaction.TransactionFrequencyValueId = schedule.TransactionFrequencyValue.Id; scheduledTransaction.StartDate = schedule.StartDate; scheduledTransaction.AuthorizedPersonAliasId = person.PrimaryAliasId.Value; scheduledTransaction.FinancialGatewayId = financialGateway.Id; if ( scheduledTransaction.FinancialPaymentDetail == null ) { scheduledTransaction.FinancialPaymentDetail = new FinancialPaymentDetail(); } scheduledTransaction.FinancialPaymentDetail.SetFromPaymentInfo( paymentInfo, gateway, rockContext ); Guid sourceGuid = Guid.Empty; if ( Guid.TryParse( GetAttributeValue( "Source" ), out sourceGuid ) ) { var source = DefinedValueCache.Read( sourceGuid ); if ( source != null ) { scheduledTransaction.SourceTypeValueId = source.Id; } } var changeSummary = new StringBuilder(); changeSummary.AppendFormat( "{0} starting {1}", schedule.TransactionFrequencyValue.Value, schedule.StartDate.ToShortDateString() ); changeSummary.AppendLine(); changeSummary.Append( paymentInfo.CurrencyTypeValue.Value ); if ( paymentInfo.CreditCardTypeValue != null ) { changeSummary.AppendFormat( " - {0}", paymentInfo.CreditCardTypeValue.Value ); } changeSummary.AppendFormat( " {0}", paymentInfo.MaskedNumber ); changeSummary.AppendLine(); foreach ( var account in SelectedAccounts.Where( a => a.Amount > 0 ) ) { var transactionDetail = new FinancialScheduledTransactionDetail(); transactionDetail.Amount = account.Amount; transactionDetail.AccountId = account.Id; scheduledTransaction.ScheduledTransactionDetails.Add( transactionDetail ); changeSummary.AppendFormat( "{0}: {1}", account.Name, account.Amount.FormatAsCurrency() ); changeSummary.AppendLine(); } if ( !string.IsNullOrWhiteSpace( paymentInfo.Comment1 ) ) { changeSummary.Append( paymentInfo.Comment1 ); changeSummary.AppendLine(); } var transactionService = new FinancialScheduledTransactionService( rockContext ); transactionService.Add( scheduledTransaction ); rockContext.SaveChanges(); // If this is a transfer, now we can delete the old transaction if ( _scheduledTransactionToBeTransferred != null ) { DeleteOldTransaction( _scheduledTransactionToBeTransferred.Id ); } // Add a note about the change var noteType = NoteTypeCache.Read( Rock.SystemGuid.NoteType.SCHEDULED_TRANSACTION_NOTE.AsGuid() ); if ( noteType != null ) { var noteService = new NoteService( rockContext ); var note = new Note(); note.NoteTypeId = noteType.Id; note.EntityId = scheduledTransaction.Id; note.Caption = "Created Transaction"; note.Text = changeSummary.ToString(); noteService.Add( note ); } rockContext.SaveChanges(); ScheduleId = scheduledTransaction.GatewayScheduleId; TransactionCode = scheduledTransaction.TransactionCode; }
/// <summary> /// Gets an optional reference number needed to process future transaction from saved account. /// </summary> /// <param name="scheduledTransaction">The scheduled transaction.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public abstract string GetReferenceNumber(FinancialScheduledTransaction scheduledTransaction, out string errorMessage);
/// <summary> /// Deletes the specified item. /// </summary> /// <param name="item">The item.</param> /// <returns></returns> public override bool Delete( FinancialScheduledTransaction item ) { if ( item.FinancialPaymentDetailId.HasValue ) { var paymentDetailsService = new FinancialPaymentDetailService( (Rock.Data.RockContext)this.Context ); var paymentDetail = paymentDetailsService.Get( item.FinancialPaymentDetailId.Value ); if ( paymentDetail != null ) { paymentDetailsService.Delete( paymentDetail ); } } return base.Delete( item ); }
/// <summary> /// Gets the next payment date. /// </summary> /// <param name="scheduledTransaction">The transaction.</param> /// <param name="lastTransactionDate">The last transaction date.</param> /// <returns></returns> public virtual DateTime?GetNextPaymentDate(FinancialScheduledTransaction scheduledTransaction, DateTime?lastTransactionDate) { return(scheduledTransaction.NextPaymentDate); }
/// <summary> /// Reactivates the specified scheduled transaction. /// </summary> /// <param name="scheduledTransaction">The scheduled transaction.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public bool Reactivate( FinancialScheduledTransaction scheduledTransaction, out string errorMessages ) { if ( scheduledTransaction != null && scheduledTransaction.FinancialGateway != null && scheduledTransaction.FinancialGateway.IsActive ) { if ( scheduledTransaction.FinancialGateway.Attributes == null ) { scheduledTransaction.FinancialGateway.LoadAttributes( (RockContext)this.Context ); } var gateway = scheduledTransaction.FinancialGateway.GetGatewayComponent(); if ( gateway != null ) { if ( gateway.ReactivateScheduledPayment( scheduledTransaction, out errorMessages ) ) { var noteTypeService = new NoteTypeService( (RockContext)this.Context ); var noteType = noteTypeService.Get( Rock.SystemGuid.NoteType.SCHEDULED_TRANSACTION_NOTE.AsGuid() ); if ( noteType != null ) { var noteService = new NoteService( (RockContext)this.Context ); var note = new Note(); note.NoteTypeId = noteType.Id; note.EntityId = scheduledTransaction.Id; note.Caption = "Reactivated Transaction"; noteService.Add( note ); } return true; } else { return false; } } } errorMessages = "Gateway is invalid or not active"; return false; }
/// <summary> /// Adds the scheduled payment. /// </summary> /// <param name="schedule">The schedule.</param> /// <param name="paymentInfo">The payment info.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> public override FinancialScheduledTransaction AddScheduledPayment( PaymentSchedule schedule, PaymentInfo paymentInfo, out string errorMessage ) { errorMessage = string.Empty; var recurring = GetRecurring( schedule ); if ( paymentInfo is CreditCardPaymentInfo ) { recurring.OptionalTrx = "A"; } var ppTransaction = new RecurringAddTransaction( GetUserInfo(), GetConnection(), GetInvoice( paymentInfo ), GetTender( paymentInfo ), recurring, PayflowUtility.RequestId ); if ( paymentInfo is ReferencePaymentInfo ) { var reference = paymentInfo as ReferencePaymentInfo; ppTransaction.OrigId = reference.TransactionCode; } var ppResponse = ppTransaction.SubmitTransaction(); if ( ppResponse != null ) { TransactionResponse txnResponse = ppResponse.TransactionResponse; if ( txnResponse != null ) { if ( txnResponse.Result == 0 ) // Success { RecurringResponse recurringResponse = ppResponse.RecurringResponse; if ( recurringResponse != null ) { var scheduledTransaction = new FinancialScheduledTransaction(); scheduledTransaction.TransactionCode = recurringResponse.TrxPNRef; scheduledTransaction.GatewayScheduleId = recurringResponse.ProfileId; GetScheduledPaymentStatus( scheduledTransaction, out errorMessage ); return scheduledTransaction; } else { errorMessage = "Invalid recurring response from the financial gateway"; } } else { errorMessage = string.Format( "[{0}] {1}", txnResponse.Result, txnResponse.RespMsg ); } } else { errorMessage = "Invalid transaction response from the financial gateway"; } } else { errorMessage = "Invalid response from the financial gateway."; } return null; }