Class: Pay::Lago::Billable

Inherits:
Object
  • Object
show all
Defined in:
lib/pay/lago/billable.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pay_customer) ⇒ Billable

Returns a new instance of Billable.



15
16
17
# File 'lib/pay/lago/billable.rb', line 15

def initialize(pay_customer)
  @pay_customer = pay_customer
end

Instance Attribute Details

#pay_customerObject (readonly)

Returns the value of attribute pay_customer.



6
7
8
# File 'lib/pay/lago/billable.rb', line 6

def pay_customer
  @pay_customer
end

Instance Method Details

#add_payment_method(provider, provider_id, default: true, sync: true, options: {}) ⇒ Object

Raises:



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/pay/lago/billable.rb', line 125

def add_payment_method(provider, provider_id, default: true, sync: true, options: {})
  raise Pay::Lago::Error.new("Invalid provider!") unless Pay::Lago::PaymentMethod.valid_provider?(provider)

  payment_method = pay_customer.payment_methods.with_provider(provider).where(processor_id: provider_id).first
  payment_method ||= Pay::PaymentMethod.create(
    processor_id: provider_id,
    type: "card",
    customer: pay_customer, data: options.merge(payment_provider: provider, provider_customer_id: provider_id)
  )

  payment_method.make_default! if default
  payment_method.payment_processor.push! if sync && default

  payment_method
end

#charge(amount = nil, addon: nil, options: {}) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/pay/lago/billable.rb', line 74

def charge(amount = nil, addon: nil, options: {})
  lago_customer = customer
  lago_addon = addon.is_a?(String) ? Lago.client.add_ons.get(addon) : pay_default_addon
  amount ||= lago_addon.amount_cents

  attributes = {
    external_customer_id: processor_id,
    currency: options[:currency] || lago_customer.currency,
    fees: [
      {
        add_on_code: lago_addon.code,
        unit_amount_cents: amount
      }.merge(options.except(:amount_cents, :add_on_code, :currency))
    ]
  }

  invoice = Lago.client.invoices.create(attributes)
  Pay::Lago::Charge.sync(invoice.lago_id, object: invoice)
rescue ::Lago::Api::HttpError => e
  raise Pay::Lago::Error, e
end

#clear_payment_method!Object



141
142
143
144
145
146
# File 'lib/pay/lago/billable.rb', line 141

def clear_payment_method!
  data = (pay_customer.data || {}).merge(
    "billing_configuration": {payment_provider: nil, payment_method_id: nil, provider_customer_id: nil, provider_payment_methods: nil}
  )
  update_customer!(data)
end

#customerObject



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/pay/lago/billable.rb', line 40

def customer
  begin
    lago_customer = Lago.client.customers.get(pay_external_id)
  rescue ::Lago::Api::HttpError
    lago_customer = Lago.client.customers.create(customer_attributes(pay_external_id))
  end
  pull!(lago_customer)
  lago_customer
rescue ::Lago::Api::HttpError => e
  raise Pay::Lago::Error, e
end

#customer_attributes(external_id) ⇒ Object

Returns a hash of attributes for the Lago::Customer object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/pay/lago/billable.rb', line 24

def customer_attributes(external_id)
  owner = pay_customer.owner

  attributes = case owner.class.pay_lago_customer_attributes
  when Symbol
    owner.send(owner.class.pay_lago_customer_attributes, pay_customer)
  when Proc
    owner.class.pay_lago_customer_attributes.call(pay_customer)
  end

  # Guard against attributes being returned nil
  attributes ||= {}

  {external_id: external_id, email: email, name: customer_name}.merge(attributes)
end

#get_payment_method(provider, provider_id = nil) ⇒ Object

Raises:



118
119
120
121
122
123
# File 'lib/pay/lago/billable.rb', line 118

def get_payment_method(provider, provider_id = nil)
  raise Pay::Lago::Error.new("Invalid provider!") unless Pay::Lago::PaymentMethod.valid_provider?(provider)
  return Pay::PaymentMethod.find_by_lago_provider_and_id(provider, provider_id) if provider_id.present?
  return pay_customer.default_payment_method if pay_customer.default_payment_method&.provider == provider
  Pay::PaymentMethod.with_provider(provider).first
end

#pay_external_idObject



19
20
21
# File 'lib/pay/lago/billable.rb', line 19

def pay_external_id
  processor_id || pay_customer.to_gid.to_s
end

#processor_subscription(subscription_id, **_options) ⇒ Object



148
149
150
# File 'lib/pay/lago/billable.rb', line 148

def processor_subscription(subscription_id, **_options)
  Pay::Lago.client.subscriptions.get(subscription_id)
end

#pull!(lago_customer = customer, force: false) ⇒ Object



62
63
64
65
66
67
68
# File 'lib/pay/lago/billable.rb', line 62

def pull!(lago_customer = customer, force: false)
  if pay_customer.processor_id.present? && pay_customer.processor_id != lago_customer.external_id && !force
    raise Pay::Lago::Error.new("Error syncing Lago Customer: IDs do not match!")
  end
  new_data = Pay::Lago.openstruct_to_h(lago_customer)
  pay_customer.update!(processor_id: lago_customer.external_id, data: new_data)
end

#push!Object



70
71
72
# File 'lib/pay/lago/billable.rb', line 70

def push!
  update_customer!(pay_customer.data)
end

#subscribe(name: Pay.default_product_name, plan: Pay.default_plan_name, **options) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/pay/lago/billable.rb', line 96

def subscribe(name: Pay.default_product_name, plan: Pay.default_plan_name, **options)
  # Make to generate a processor_id
  lago_customer = customer
  pay_subscription = create_placeholder_subscription(name, plan)
  external_id = pay_subscription.to_gid.to_s

  attributes = options.merge(
    external_customer_id: lago_customer.external_id,
    name: name, external_id: external_id, plan_code: plan
  )

  begin
    subscription = Lago.client.subscriptions.create(attributes)
  rescue ::Lago::Api::HttpError => e
    pay_subscription.destroy!
    raise Pay::Lago::Error, e
  end

  pay_subscription.update!(processor_id: external_id)
  Pay::Lago::Subscription.sync(lago_customer.external_id, external_id, object: subscription)
end

#trial_end_date(subscription) ⇒ Object

Raises:



152
153
154
# File 'lib/pay/lago/billable.rb', line 152

def trial_end_date(subscription)
  raise Pay::Lago::Error.new("Lago subscriptions do not implement trials.")
end

#update_customer!(attributes = {}) ⇒ Object



52
53
54
55
56
57
58
59
60
# File 'lib/pay/lago/billable.rb', line 52

def update_customer!(attributes = {})
  attributes = symbolize_recursive(attributes)
  new_attributes = Lago.openstruct_to_h(customer).except(:lago_id)
  lago_customer = Lago.client.customers.create(
    new_attributes.merge(attributes.except(:external_id))
  )
  pull!(lago_customer)
  lago_customer
end