Home > Software engineering >  Add application fee for first payment of every month but not for months which dont receive any payme
Add application fee for first payment of every month but not for months which dont receive any payme

Time:11-03

I am trying to figure out the logic for a fee addition which renews everymonth. The idea is a charge candidates for only processing months, which means only when they get a contribution.

Currently, what I am doing is checking the month of current contribution and if that changes, I charge the Candidate the extra 7.99 fee. Shared below is a snippet from my candidate.rb

   def determine_fee(amount_cents)
    amount = ((amount_cents * ((merchant_rate.to_f * 100)   2.9) / 100)   25).to_i #normal fee 
    unless fee_paid_on&.month == Time.zone.now.month # comparing with current month
      amount = ((amount_cents * ((merchant_rate.to_f * 100)   2.9) / 100)   25   799).to_i #fee to be added for first contribution of every month
      self.update_attributes(fee_paid_on: Time.zone.now)
    end
    amount
  end 

However, the draw back with this approach is that Candidates are not charged as per 30 day time interval.For instance, the first contribution came at 28th of Nov, it would be charged the extra 7.99 and the rest of the contributions for Nov would be charged wihtout the 7.99 fee. And again, if they receive a contribution on 1st of dec, it would be charged the extra 7.99. Instead, i would want to the first contribution which comes after 28th of Dec to be charged the extra 7.99.

I am considering adding an extra month and comparing the fee, but cant establish the logic given the limited time. Any suggestion would be appreciated

Contribution_form.rb:

def process_stripe_payment
  applicable_fee = candidate.determine_fee(amount_cents)
  Stripe::Charge.create({
    amount: amount_cents,
    currency: candidate.candidate_country[candidate.country.to_s.to_sym][:currency],
    source: stripe_token,
    application_fee_amount: applicable_fee,
  # application_fee_amount: ((amount_cents * ((candidate.merchant_rate.to_f * 100)   2.9) / 100)   25).to_i,
   statement_descriptor_suffix: "#{get_statement_descriptor.to_s.upcase}",
    on_behalf_of: candidate.stripe_gateway_id,
    transfer_data: {
      destination: candidate.stripe_gateway_id,
    },
  }, stripe_version: '2019-12-03',)
end

CodePudding user response:

How rigid are the models you're using? One idea that comes to mind is adding a column to your model which represents the date_last_charged. You only add the fee to contributions that occur a month following this date and update it when you have done so.

CodePudding user response:

Your code will be simpler to follow (now and in the future) if you break the calculation into its parts.

MONTHLY_FEE = 799 # constant so it's easy to change in the future

def determine_amount(contribution_cents)
  if fee_paid_this_month?
    processing_fee(contribution_cents)   MONTHLY_FEE
  else
    processing_fee(contribution_cents)
  end
end

def processing_fee(contribution_cents)
  # Note: use to_d instead of to_f to force the use of decimal over float
  ((amount_cents * ((merchant_rate.to_d * 100)   2.9) / 100)   25).to_i
end

def fee_paid_this_month?
  last_paid_on >= Date.today.beginning_of_month
end

This code intentionally skips the update of the last_paid_on date. That logic does not belong in the method that calculates the payment. For the sake of your business, put it after the successful call to Stripe in process_stripe_payment.

  • Related