Skip to content

Conversation

Copilot
Copy link

@Copilot Copilot AI commented Jul 24, 2025

Problem

The invoice.upcoming webhook event was failing with the error:

Value for argument "documentPath" is not a valid resource path. Path must be a non-empty string.

This occurred because upcoming invoices from Stripe don't have an id field, causing the Firestore document path to be invalid when trying to create the invoice document.

Root Cause

In the insertInvoiceRecord function in utils.ts, the code was attempting to use invoice.id directly as the Firestore document ID:

await customersSnap.docs[0].ref
  .collection('subscriptions')
  .doc(invoice.subscription as string)
  .collection('invoices')
  .doc(invoice.id)  // ❌ This is null/undefined for upcoming invoices
  .set(invoice);

For invoice.upcoming events, Stripe doesn't provide an id field since these are preview/draft invoices that haven't been finalized yet.

Solution

The fix generates a unique document ID for upcoming invoices when invoice.id is null/undefined:

// For upcoming invoices, generate a unique document ID since they don't have an id
const invoiceDocId = invoice.id || `upcoming_${invoice.subscription}_${Date.now()}`;

await customersSnap.docs[0].ref
  .collection('subscriptions')
  .doc(invoice.subscription as string)
  .collection('invoices')
  .doc(invoiceDocId)  // ✅ Always a valid string
  .set(invoice);

Additionally, the fix prevents creating unnecessary payment records for upcoming invoices when they don't have a payment intent, since upcoming invoices are previews and don't represent actual payments:

// Only create payment records for invoices that have a payment_intent or id
// Upcoming invoices are previews and don't represent actual payments
const recordId: string = (invoice.payment_intent as string) ?? invoice.id;
if (recordId) {
  // Create payment record only if recordId exists
  await customersSnap.docs[0].ref
    .collection('payments')
    .doc(recordId)
    .set({ prices }, { merge: true });
}

Impact

  • ✅ Fixes webhook processing for invoice.upcoming events
  • ✅ Preserves existing behavior for regular invoices with IDs
  • ✅ Prevents unnecessary payment records for preview invoices
  • ✅ Maintains unique document IDs using subscription + timestamp
  • ✅ No breaking changes to existing functionality

Test Cases Handled

  1. Regular invoice with ID: Uses original ID as document ID, creates payment record
  2. Upcoming invoice without ID: Generates unique ID (upcoming_{subscription}_{timestamp}), skips payment record if no payment_intent
  3. Invoice without ID but with payment_intent: Generates unique ID, creates payment record using payment_intent

Fixes #616


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@Copilot Copilot AI changed the title [WIP] Can you investigte issue 616 and provide a fix Fix invoice.upcoming webhook handler failure - generate unique document ID for invoices without id Jul 24, 2025
@Copilot Copilot AI requested a review from Ehesp July 24, 2025 15:30
Copilot finished work on behalf of Ehesp July 24, 2025 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

invoice.upcoming failed: Value for argument "documentPath" is not a valid resource path. Path must be a non-empty string.
3 participants