iachat/enterprise/app
Tanmay Deep Sharma 04acc16609
fix: skip pay call if invoice already paid after finalize (#13924)
## 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
2026-03-30 10:37:28 +05:30
..
builders fix: restrict existing user sign-in to account members (#13793) 2026-03-13 12:22:25 +05:30
controllers feat: support bulk select and delete for documents (#13907) 2026-03-26 19:48:12 +05:30
dispatchers/enterprise feat(ee): Add Captain features (#10665) 2025-01-14 16:15:47 -08:00
drops feat: Add push/email notification support for SLA (#9140) 2024-03-29 20:27:21 +11:00
fields fix: Render all account limit fields (#13435) 2026-02-04 20:21:07 +05:30
finders/enterprise feat: Conversation API to return applied_sla and sla_events (#9174) 2024-04-01 23:30:07 +05:30
helpers feat: allow captain to access contact attributes (#13850) 2026-03-20 16:15:06 +05:30
jobs fix: handoff only if conversation pending (#13882) 2026-03-23 17:09:58 +05:30
listeners feat: Add support for realtime-events in copilot-threads and copilot-messages (#11557) 2025-05-22 22:25:05 -07:00
mailers/enterprise/agent_notifications chore: fix sla email notifications (#9192) 2024-04-04 21:16:49 +05:30
models fix: resolve V2 capacity bypass in team assignment (#13904) 2026-03-27 15:38:17 +05:30
policies feat(help-center): enable drag-and-drop category reordering (#13706) 2026-03-05 12:53:38 +05:30
presenters/enterprise/conversations feat: UI to show the SLA threshold in chat screen (#9146) 2024-04-04 15:46:46 +05:30
services fix: skip pay call if invoice already paid after finalize (#13924) 2026-03-30 10:37:28 +05:30
views feat: Backend - Companies API endpoint with pagination and search (#12840) 2025-11-18 14:28:56 +05:30