Skip to content

Commit

Permalink
feat: Sync Stripe Credit Balance to Pay::Customer (#825)
Browse files Browse the repository at this point in the history
* feat: Sync Stripe Credit Balance to Pay::Customer

* add invoice credit balance to customer updated webhook

* rename payment_customer to stripe_customer

Renaming variable to better reflect the actual underlying object being used in the code.

* test(vcr): add updated vcr cassettes

* refactor to check presence directly on hash instead of keys

* Store entire stripe invoice_credit_balance

* Add comment for invoice_credit_balance

---------

Co-authored-by: cjilbert504 <54157657+cjilbert504@users.noreply.github.com>
Co-authored-by: Chris Oliver <excid3@gmail.com>
  • Loading branch information
3 people committed Jul 18, 2023
1 parent 213cac1 commit 275d512
Show file tree
Hide file tree
Showing 7 changed files with 1,028 additions and 1,004 deletions.
4 changes: 4 additions & 0 deletions app/models/pay/customer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class Customer < Pay::ApplicationRecord
store_accessor :data, :stripe_account
store_accessor :data, :braintree_account

# Stripe invoice credit balance is a Hash-like object { "usd" => 1234 }
store_accessor :data, :invoice_credit_balance
store_accessor :data, :currency

delegate :email, to: :owner
delegate_missing_to :pay_processor

Expand Down
2 changes: 1 addition & 1 deletion lib/pay/stripe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def self.configure_webhooks
# When a customers subscription trial period is 3 days from ending or ended immediately this event is fired
events.subscribe "stripe.customer.subscription.trial_will_end", Pay::Stripe::Webhooks::SubscriptionTrialWillEnd.new

# Monitor changes for customer's default card changing
# Monitor changes for customer's default card changing and invoice credit updates
events.subscribe "stripe.customer.updated", Pay::Stripe::Webhooks::CustomerUpdated.new

# If a customer was deleted in Stripe, their subscriptions should be cancelled
Expand Down
2 changes: 1 addition & 1 deletion lib/pay/stripe/billable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def customer_attributes
# Returns a Stripe::Customer object
def customer
stripe_customer = if processor_id?
::Stripe::Customer.retrieve({id: processor_id, expand: ["tax"]}, stripe_options)
::Stripe::Customer.retrieve({id: processor_id, expand: ["tax", "invoice_credit_balance"]}, stripe_options)
else
sc = ::Stripe::Customer.create(customer_attributes.merge(expand: ["tax"]), stripe_options)
pay_customer.update!(processor_id: sc.id, stripe_account: stripe_account)
Expand Down
12 changes: 11 additions & 1 deletion lib/pay/stripe/webhooks/customer_updated.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,24 @@ def call(event)
# Couldn't find user, we can skip
return unless pay_customer.present?

stripe_customer = pay_customer.customer

# Sync default card
if (payment_method_id = pay_customer.customer.invoice_settings.default_payment_method)
if (payment_method_id = stripe_customer.invoice_settings.default_payment_method)
Pay::Stripe::PaymentMethod.sync(payment_method_id, stripe_account: event.try(:account))

else
# No default payment method set
pay_customer.payment_methods.update_all(default: false)
end

# Sync invoice credit balance and currency
if stripe_customer.invoice_credit_balance.present?
pay_customer.update(
invoice_credit_balance: stripe_customer.invoice_credit_balance,
currency: stripe_customer.currency
)
end
end
end
end
Expand Down
9 changes: 9 additions & 0 deletions test/pay/stripe/webhooks/customer_updated_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,13 @@ class Pay::Stripe::Webhooks::CustomerUpdatedTest < ActiveSupport::TestCase
Pay::Stripe::Billable.any_instance.expects(:sync_payment_method_from_stripe).never
Pay::Stripe::Webhooks::CustomerUpdated.new.call(event)
end

test "stripe invoice credit balance is updated" do
event = stripe_event("customer.updated")
Pay::Stripe::Billable.any_instance.expects(:customer).returns(OpenStruct.new(invoice_credit_balance: Stripe::Util.convert_to_stripe_object(usd: 12345), invoice_settings: OpenStruct.new(default_payment_method: nil), currency: "usd"))
Pay::Stripe::Webhooks::CustomerUpdated.new.call(event)
@pay_customer.reload
assert_equal "usd", @pay_customer.currency
assert_equal 12345, @pay_customer.invoice_credit_balance["usd"]
end
end
Loading

0 comments on commit 275d512

Please sign in to comment.