invertase / stripe-firebase-extensions

Repository of Firebase Extensions built by Stripe.
https://firebase.google.com/products/extensions
Apache License 2.0
437 stars 172 forks source link

Duplicate Customers In Stripe #117

Closed padioca closed 3 years ago

padioca commented 3 years ago

Bug report

Describe the bug

When Stripe checkout is completed at least two customers with the same email address are created in Stripe. When Sync New Users is set to "Do Not Sync", two customers are typically added, although there are instances in which one customer is created and I can't find a discernible reason why. When "Sync" is selected three customers are typically created, but sometimes it is only two.

This is causing issues with the Customer Claims occasionally coming back as null depending on which customer is connected to the Firebase record.

There are also typically two Checkout Sessions stored in Firestore, but again, sometimes there is only one.

From what I can tell from the webhook logs (screenshot below), there are a lot of them that are failing. I would assume this has something to do with it but I'm unsure how to resolve the issue...

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

Here's the code I'm running on submit in the Vue app. Can confirm customer is not created in Stripe until Checkout is complete, then it is created once complete.

await database.collection('users').doc(firebase.auth().currentUser.uid).set({  
   firstName: this.firstName,  
   lastName: this.lastName,  
   address1: this.addressOne,  
   address2: this.addressTwo,  
   city: this.addressCity,  
   addressState: this.addressState,  
   zipCode: this.addressZip,  
   location: new firebase.firestore.GeoPoint(this.latitude, this.longitude),  
   finalFrostDate: firebase.firestore.Timestamp.fromDate(moment(this.finalFrost).toDate()),  
   firstFrostDate: firebase.firestore.Timestamp.fromDate(moment(this.firstFrost).toDate()),  
});  
const docRef = await database.collection('users')
   .doc(firebase.auth().currentUser.uid)
   .collection('checkout_sessions')
   .add({
      price: 'price_1HynyCBbnWnWb7b0SCkuT0vG',
      success_url: window.location.origin,
      cancel_url: window.location.origin,
});

// Wait for the CheckoutSession to get attached by the extension
docRef.onSnapshot(async (snap) => {
   const { error, sessionId } = snap.data();
   if (error) {
      // Show an error to your customer and
      // inspect your Cloud Function logs in the Firebase console.
      alert(`An error occurred: ${error.message}`);
   }
   if (sessionId) {
      // We have a session, let's redirect to Checkout
      // Init Stripe
      const stripe = await loadStripe('pk_test_1234');
      await stripe.redirectToCheckout({sessionId});
   }
});

Expected behavior

I would expect for only one Customer to be created in Stripe. I guess I would only expect for there to be one Checkout Session.

Screenshots

If applicable, add screenshots to help explain your problem.

Duplicate Users in Stripe

Screen Shot 2020-12-21 at 7 11 39 PM

Showing null values for Custom Claims in Firebase Functions Logs

Screen Shot 2020-12-21 at 7 27 10 PM

Product Setup

Untitled

Webhook Logs With Errors

Untitled2

System information

Additional context

I have literally tried everything I can think of over the last 3 days to get this working and I am just out of ideas. Occassionally I will change something in an attempt to fix it (as an example, I realized I didn't have the "Update Subscriptions" set) and when I change that things seem to work for one go around. I am fairly new to all of this and have been stumbling my way through JS & Vue development for about the past year, so I could be totally overlooking something very basic. Any help would be appreciated.

padioca commented 3 years ago

Figured it out. For anyone curious, I was running the entire submit method twice, one on click of the Submit button and one using @submit.prevent.