async processWebhookEventToFirestore()

in packages/fxa-auth-server/lib/payments/stripe.ts [3474:3535]


  async processWebhookEventToFirestore(event: Stripe.Event) {
    const { type } = event;

    // Stripe does not include the card_automatically_updated event
    // despite this being a valid event for Stripe webhook registration
    type StripeEnabledEvent =
      | Stripe.WebhookEndpointUpdateParams.EnabledEvent
      | 'payment_method.card_automatically_updated';

    // Note that we must insert before any event handled by the general
    // webhook code to ensure the object is up to date in Firestore before
    // our code handles the event.
    let handled = true;
    try {
      switch (type as StripeEnabledEvent) {
        case 'invoice.created':
        case 'invoice.finalized':
        case 'invoice.paid':
        case 'invoice.payment_failed':
        case 'invoice.updated':
        case 'invoice.deleted':
          await this.processInvoiceEventToFirestore(event);
          break;
        case 'customer.created':
        case 'customer.updated':
        case 'customer.deleted':
          await this.processCustomerEventToFirestore(event);
          break;
        case 'customer.subscription.created':
        case 'customer.subscription.updated':
        case 'customer.subscription.deleted':
          await this.processSubscriptionEventToFirestore(event);
          break;
        case 'payment_method.attached':
        case 'payment_method.card_automatically_updated':
        case 'payment_method.updated':
          await this.processPaymentMethodEventToFirestore(event);
          break;
        case 'payment_method.detached':
          await this.processPaymentMethodDetachedEventToFirestore(event);
          break;
        default: {
          handled = false;
          break;
        }
      }
    } catch (err) {
      if (
        [
          FirestoreStripeError.STRIPE_CUSTOMER_DELETED,
          FirestoreStripeError.FIRESTORE_CUSTOMER_NOT_FOUND,
        ].includes(err.name)
      ) {
        // We cannot back-fill Firestore with records for deleted customers
        // as they're missing necessary metadata for us to know which user
        // the customer belongs to.
        return handled;
      }
      throw err;
    }
    return handled;
  }