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
|
# File 'lib/pay/stripe/subscription.rb', line 26
def self.sync(subscription_id, object: nil, name: nil, stripe_account: nil, try: 0, retries: 1)
object ||= ::Stripe::Subscription.retrieve({id: subscription_id}.merge(expand_options), {stripe_account: stripe_account}.compact)
pay_customer = Pay::Customer.find_by(processor: :stripe, processor_id: object.customer)
return unless pay_customer
attributes = {
application_fee_percent: object.application_fee_percent,
processor_plan: object.items.first.price.id,
quantity: object.items.first.try(:quantity) || 0,
status: object.status,
stripe_account: pay_customer.stripe_account,
metadata: object.metadata,
subscription_items: [],
metered: false,
pause_behavior: object.pause_collection&.behavior,
pause_resumes_at: (object.pause_collection&.resumes_at ? Time.at(object.pause_collection&.resumes_at) : nil)
}
if object.trial_end
attributes[:trial_ends_at] = Time.at(object.ended_at || object.trial_end)
end
object.items.auto_paging_each do |subscription_item|
if !attributes[:metered] && (subscription_item.to_hash.dig(:price, :recurring, :usage_type) == "metered")
attributes[:metered] = true
end
attributes[:subscription_items] << subscription_item.to_hash.slice(:id, :price, :metadata, :quantity)
end
attributes[:ends_at] = if object.ended_at
Time.at(object.ended_at)
elsif object.cancel_at
Time.at(object.cancel_at)
elsif object.cancel_at_period_end
Time.at(object.current_period_end)
end
pay_subscription = pay_customer.subscriptions.find_by(processor_id: object.id)
if pay_subscription
pay_subscription.with_lock { pay_subscription.update!(attributes) }
else
name ||= object.metadata["pay_name"] || Pay.default_product_name
pay_subscription = pay_customer.subscriptions.create!(attributes.merge(name: name, processor_id: object.id))
end
pay_subscription.stripe_subscription = object
if (charge = object.try(:latest_invoice).try(:charge)) && charge.try(:status) == "succeeded"
Pay::Stripe::Charge.sync(charge.id, stripe_account: pay_subscription.stripe_account)
end
pay_subscription
rescue ActiveRecord::RecordInvalid
try += 1
if try <= retries
sleep 0.1
retry
else
raise
end
end
|