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
.