我已经为Stripe fee添加了这个功能,它似乎工作得很好,但是我需要确定,因为涉及的付款至关重要。
这里的目标是只对候选人收取处理月份的费用,这意味着只有当他们收到当月的捐款时才收取费用。例如,如果候选人在2023年11月24日获得第一笔捐款,则应收取该特定付款的额外费用。然而,该月的其余付款应该是正常的。同样,在2023年12月24日之后的第一次付款将被收取额外费用。
contribution_form.rb
puts "starting else block ----->>#{amount_cents}"
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',)
candidate.rb
def determine_fee(amount_cents)
amount = ((amount_cents * ((merchant_rate.to_f * 100) + 2.9) / 100) + 25).to_i
return amount unless id == 3954
if fee_paid_on["started_date"].nil? || (next_start_date(fee_paid_on["started_date"].to_datetime, true) <= Time.zone.now)
amount = ((amount_cents * ((merchant_rate.to_f * 100) + 2.9) / 100) + 25 + 799).to_i
fee_paid_details
else
amount = ((amount_cents * ((merchant_rate.to_f * 100) + 2.9) / 100) + 25).to_i
fee_paid_details
end
amount
end
def next_start_date(start_date, flag = false)
puts "next start date ----->>#{start_date}"
return start_date + 1.month if flag
t = Time.zone.now
start_date.month != t.month ? Time.zone.parse("#{start_date.day}/#{t.month}/#{t.year}") : start_date + 1.month
end
#only updating start date and setting it as per next month
def fee_paid_details
started_date = fee_paid_on["started_date"]
new_started_date = (next_start_date(started_date.to_datetime) < Time.zone.now ? started_date.to_datetime : next_start_date(started_date.to_datetime)) if started_date
update_columns(
fee_paid_on: {
"started_date" => started_date.nil? ? Time.zone.now : new_started_date,
"last_paid_on" => Time.zone.now
}
)
end
我需要两个部门的洞察力:
我如何彻底测试这个?
谁能帮我优化我的代码
总的来说,你的实现看起来是正确的,尽管如果你接受多种货币,你可能需要做更多的工作,因为有汇率和转换费用(Stripe对货币转换收取额外的2%)。假设您不需要担心货币问题,并且不了解更多关于集成的信息,那么以下是一些注意事项:
我如何彻底测试这个?
最好的测试方法是将你计算的费用与实际费用进行比较。您将核对charge.application_fee_amount
与余额交易的费用。通过将expand
传递到Charge创建参数中,您可以扩展Stripe在创建Charge后返回的charge.balance_transaction
对象,如下所示:
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,
},
expand: ['balance_transaction'],
},
stripe_version: '2019-12-03',
)
上面的代码将在Charge创建后返回嵌套的Balance Transaction对象。
谁能帮我优化我的代码
看起来你把amount
的计算写了三次,这不符合DRY原则。类似地,您只需要一行代码就可以从determine_fee()
函数返回fee_paid_details
变量,因为它在if
和else
语句中都被返回。我注意到的另一件事是:您在代码中将started_date
从string
转换为datetime
。更有意义的是将其存储为datetime
变量,并仅在将其存储在数据库中时将其转换为string
。