## Description When a customer downgrades from Enterprise to Business, they may retain unused Stripe credit balance. During an AI credits topup, Stripe::Invoice.finalize_invoice auto-applies that credit balance to the invoice. If the credit balance fully covers the invoice amount, Stripe marks it as paid immediately upon finalization. Calling Stripe::Invoice.pay on an already-paid invoice throws an error, breaking the topup flow. This fix retrieves the invoice status after finalization and skips the pay call if Stripe has already settled it via credits. ## Type of change Please delete options that are not relevant. - [ ] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? Tested against Stripe test mode with the following scenarios: - Full credit balance payment: Customer has enough Stripe credit balance to cover the entire invoice. Invoice is marked paid after finalize_invoice — pay is correctly skipped. Credits are fulfilled successfully. - Partial credit balance payment: Customer has some Stripe credit balance but not enough to cover the full amount. Invoice remains open after finalization — pay is called and charges the remaining amount to the default payment method. Credits are fulfilled successfully. - Zero credit balance (normal payment): Customer has no Stripe credit balance. Invoice remains open after finalization — pay charges the full amount. Credits are fulfilled successfully. ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules |
||
|---|---|---|
| .. | ||
| app | ||
| config | ||
| lib | ||
| LICENSE | ||
| tasks_railtie.rb | ||