Grab and show the next amount to pay from Stripe

This commit is contained in:
Jorge Manrubia
2025-12-15 18:26:42 +01:00
parent 8dd31e3635
commit 3395b8d6ed
6 changed files with 30 additions and 5 deletions
@@ -48,7 +48,8 @@ class Stripe::WebhooksController < ApplicationController
stripe_subscription_id: stripe_subscription.id,
status: stripe_subscription.status,
current_period_end: current_period_end_for(stripe_subscription),
cancel_at: stripe_subscription.cancel_at ? Time.at(stripe_subscription.cancel_at) : nil
cancel_at: stripe_subscription.cancel_at ? Time.at(stripe_subscription.cancel_at) : nil,
next_amount_due_in_cents: next_amount_due_for(stripe_subscription)
}
yield subscription_properties if block_given?
@@ -66,4 +67,13 @@ class Stripe::WebhooksController < ApplicationController
timestamp = stripe_subscription.items.data.first&.current_period_end
Time.at(timestamp) if timestamp
end
def next_amount_due_for(stripe_subscription)
return nil if stripe_subscription.status == "canceled"
preview = Stripe::Invoice.create_preview(customer: stripe_subscription.customer, subscription: stripe_subscription.id)
preview.amount_due
rescue Stripe::InvalidRequestError
nil
end
end
+1 -1
View File
@@ -5,7 +5,7 @@ module SubscriptionsHelper
elsif subscription.canceled?
"Your Fizzy subscription ended on"
else
"Your next payment of <b>$#{ subscription.plan.price }</b> will be billed on".html_safe
"Your next payment of <b>#{ number_to_currency(subscription.next_amount_due) }</b> will be billed on".html_safe
end
end
end
+4
View File
@@ -14,4 +14,8 @@ class Account::Subscription < SaasRecord
def to_be_canceled?
active? && cancel_at.present?
end
def next_amount_due
next_amount_due_in_cents ? next_amount_due_in_cents / 100.0 : plan.price
end
end
@@ -0,0 +1,5 @@
class AddNextAmountDueInCentsToAccountSubscriptions < ActiveRecord::Migration[8.2]
def change
add_column :account_subscriptions, :next_amount_due_in_cents, :integer
end
end
+2 -1
View File
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.2].define(version: 2025_12_15_160000) do
ActiveRecord::Schema[8.2].define(version: 2025_12_15_170000) do
create_table "account_billing_waivers", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.datetime "created_at", null: false
@@ -31,6 +31,7 @@ ActiveRecord::Schema[8.2].define(version: 2025_12_15_160000) do
t.datetime "cancel_at"
t.datetime "created_at", null: false
t.datetime "current_period_end"
t.integer "next_amount_due_in_cents"
t.string "plan_key"
t.string "status"
t.string "stripe_customer_id", null: false
@@ -29,6 +29,7 @@ class Stripe::WebhooksControllerTest < ActionDispatch::IntegrationTest
Stripe::Webhook.stubs(:construct_event).returns(event)
Stripe::Subscription.stubs(:retrieve).returns(stripe_sub)
Stripe::Invoice.stubs(:create_preview).returns(OpenStruct.new(amount_due: 1999))
post stripe_webhooks_path
@@ -38,7 +39,7 @@ class Stripe::WebhooksControllerTest < ActionDispatch::IntegrationTest
assert_equal "active", @subscription.status
end
test "subscription updated changes status" do
test "subscription updated changes status and syncs next amount due" do
@subscription.update!(stripe_subscription_id: "sub_123", status: "active")
stripe_sub = OpenStruct.new(
@@ -53,11 +54,14 @@ class Stripe::WebhooksControllerTest < ActionDispatch::IntegrationTest
Stripe::Webhook.stubs(:construct_event).returns(event)
Stripe::Subscription.stubs(:retrieve).returns(stripe_sub)
Stripe::Invoice.stubs(:create_preview).returns(OpenStruct.new(amount_due: 1999))
post stripe_webhooks_path
assert_response :ok
assert_equal "past_due", @subscription.reload.status
@subscription.reload
assert_equal "past_due", @subscription.status
assert_equal 1999, @subscription.next_amount_due_in_cents
end
test "subscription deleted cancels subscription" do
@@ -82,6 +86,7 @@ class Stripe::WebhooksControllerTest < ActionDispatch::IntegrationTest
@subscription.reload
assert_equal "canceled", @subscription.status
assert_nil @subscription.stripe_subscription_id
assert_nil @subscription.next_amount_due_in_cents
end
private