Bug report
Extension name: firestore-stripe-payments
Describe the bug
The insertInvoiceRecord function in utils.ts uses .set(invoice) without { merge: true }, which overwrites any custom fields added to invoice documents. This is the same bug that was fixed for products/prices in PR #170 (resolving #169), but was not applied to invoices.
Affected code
https://github.com/invertase/stripe-firebase-extensions/blob/next/firestore-stripe-payments/functions/src/utils.ts#L322-L332
// Current code (line ~327):
await customersSnap.docs[0].ref
.collection('subscriptions')
.doc(invoice.subscription as string)
.collection('invoices')
.doc(invoice.id)
.set(invoice); // ❌ Missing { merge: true }
Inconsistency with other functions
Other functions in the same file correctly use { merge: true }:
| Function |
Code |
Status |
createProductRecord |
.set(productData, { merge: true }) |
✅ Fixed in #170 |
insertPriceRecord |
.set(priceData, { merge: true }) |
✅ Fixed in #170 |
insertPaymentRecord |
.set(payment, { merge: true }) |
✅ Correct |
insertInvoiceRecord |
.set(invoice) |
❌ Missing |
manageSubscriptionStatusChange |
.set(subscriptionData) |
❌ Also missing |
To reproduce
- Set up an Eventarc trigger on invoice document writes
- In your handler, add a custom field to the invoice document (e.g.,
mac_status: "processed")
- Wait for Stripe to send another webhook for the same invoice (e.g.,
invoice.paid followed by invoice.payment_succeeded)
- Observe that your custom field is erased
Expected behavior
Custom fields added to invoice documents should be preserved when the extension updates the document with new Stripe data (same behavior as products/prices after #170 fix).
Actual behavior
The entire invoice document is overwritten, erasing any custom fields. This is particularly problematic because Stripe sends multiple webhook events for the same invoice (invoice.paid, invoice.payment_succeeded, invoice.payment_action_required, etc.), each triggering a full overwrite.
Impact
This makes it impossible to use the invoice document itself to track processing state, forcing users to maintain separate collections for idempotency tracking.
Suggested fix
- .set(invoice);
+ .set(invoice, { merge: true });
Also consider applying the same fix to manageSubscriptionStatusChange for consistency.
Related
Bug report
Extension name:
firestore-stripe-paymentsDescribe the bug
The
insertInvoiceRecordfunction inutils.tsuses.set(invoice)without{ merge: true }, which overwrites any custom fields added to invoice documents. This is the same bug that was fixed for products/prices in PR #170 (resolving #169), but was not applied to invoices.Affected code
https://github.com/invertase/stripe-firebase-extensions/blob/next/firestore-stripe-payments/functions/src/utils.ts#L322-L332
Inconsistency with other functions
Other functions in the same file correctly use
{ merge: true }:createProductRecord.set(productData, { merge: true })insertPriceRecord.set(priceData, { merge: true })insertPaymentRecord.set(payment, { merge: true })insertInvoiceRecord.set(invoice)manageSubscriptionStatusChange.set(subscriptionData)To reproduce
mac_status: "processed")invoice.paidfollowed byinvoice.payment_succeeded)Expected behavior
Custom fields added to invoice documents should be preserved when the extension updates the document with new Stripe data (same behavior as products/prices after #170 fix).
Actual behavior
The entire invoice document is overwritten, erasing any custom fields. This is particularly problematic because Stripe sends multiple webhook events for the same invoice (
invoice.paid,invoice.payment_succeeded,invoice.payment_action_required, etc.), each triggering a full overwrite.Impact
This makes it impossible to use the invoice document itself to track processing state, forcing users to maintain separate collections for idempotency tracking.
Suggested fix
Also consider applying the same fix to
manageSubscriptionStatusChangefor consistency.Related