15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
# File 'lib/pay/stripe/charge.rb', line 15
def self.sync(charge_id, object: nil, stripe_account: nil, try: 0, retries: 1)
object ||= ::Stripe::Charge.retrieve({id: charge_id, expand: ["invoice.total_discount_amounts.discount", "invoice.total_tax_amounts.tax_rate", "refunds"]}, {stripe_account: stripe_account}.compact)
if object.customer.blank?
Rails.logger.debug "Stripe Charge #{object.id} does not have a customer"
return
end
pay_customer = Pay::Customer.find_by(processor: :stripe, processor_id: object.customer)
if pay_customer.blank?
Rails.logger.debug "Pay::Customer #{object.customer} is not in the database while syncing Stripe Charge #{object.id}"
return
end
refunds = []
object.refunds.auto_paging_each { |refund| refunds << refund }
payment_method = object.payment_method_details.try(object.payment_method_details.type)
attrs = {
amount: object.amount,
amount_captured: object.amount_captured,
amount_refunded: object.amount_refunded,
application_fee_amount: object.application_fee_amount,
bank: payment_method.try(:bank_name) || payment_method.try(:bank), brand: payment_method.try(:brand)&.capitalize,
created_at: Time.at(object.created),
currency: object.currency,
discounts: [],
exp_month: payment_method.try(:exp_month).to_s,
exp_year: payment_method.try(:exp_year).to_s,
last4: payment_method.try(:last4).to_s,
line_items: [],
metadata: object.metadata,
payment_intent_id: object.payment_intent,
payment_method_type: object.payment_method_details.type,
stripe_account: pay_customer.stripe_account,
stripe_receipt_url: object.receipt_url,
total_tax_amounts: [],
refunds: refunds.sort_by! { |r| r["created"] }
}
if object.invoice
invoice = (object.invoice.is_a?(::Stripe::Invoice) ? object.invoice : ::Stripe::Invoice.retrieve({id: object.invoice, expand: ["total_discount_amounts.discount", "total_tax_amounts.tax_rate"]}, {stripe_account: stripe_account}.compact))
attrs[:invoice_id] = invoice.id
attrs[:subscription] = pay_customer.subscriptions.find_by(processor_id: invoice.subscription)
attrs[:period_start] = Time.at(invoice.period_start)
attrs[:period_end] = Time.at(invoice.period_end)
attrs[:subtotal] = invoice.subtotal
attrs[:tax] = invoice.tax
attrs[:discounts] = invoice.discounts
attrs[:total_tax_amounts] = invoice.total_tax_amounts.map(&:to_hash)
attrs[:total_discount_amounts] = invoice.total_discount_amounts.map(&:to_hash)
invoice.lines.auto_paging_each do |line_item|
attrs[:line_items] << {
id: line_item.id,
description: line_item.description,
price_id: line_item.price&.id,
quantity: line_item.quantity,
unit_amount: line_item.price&.unit_amount,
amount: line_item.amount,
discounts: line_item.discounts,
tax_amounts: line_item.tax_amounts,
proration: line_item.proration,
period_start: Time.at(line_item.period.start),
period_end: Time.at(line_item.period.end)
}
end
else
attrs[:period_start] = Time.at(object.created)
attrs[:period_end] = Time.at(object.created)
end
if (pay_charge = pay_customer.charges.find_by(processor_id: object.id))
pay_charge.with_lock do
pay_charge.update!(attrs)
end
pay_charge
else
pay_customer.charges.create!(attrs.merge(processor_id: object.id))
end
rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique
try += 1
if try <= retries
sleep 0.1
retry
else
raise
end
end
|