Code Monkey home page Code Monkey logo

stripe-firebase-extensions's Introduction

UPDATE 2023-10-08:

This project has now being officailly transferred to Invertase, who will maintain this extension going forward. Please see this issue for more details. It is now reccomended to uninstall the stripe/firestore-stripe-payments extension and install invertase/firestore-stripe-payments from the Firebase Extension Hub.

Alternativley, you can also use the following link to convert your current installation to the Invertase version

https://console.firebase.google.com/project/_/extensions/install?instanceId=STRIPE_EXTENSION_INSTANCE_ID&ref=invertase%[email protected]

Stripe Firebase Extensions

This repository contains the source code for Firebase Extensions that enable payment functionality. Created and tested by Stripe, these official Stripe Firebase extensions are reliable and secure. To learn more about Firebase Extensions, including how to install them in your Firebase projects, visit the Firebase documentation.

Each directory in this repo contains the source code for the extension and a README to explain how the extension works, including information about the enabled APIs, resources created, and the access granted to the extension.

Extension Directory

This repository includes the source code for the following extensions:

  1. Stripe backend for web, mobile, and subscription payments
  2. Send invoices using Stripe

stripe-firebase-extensions's People

Contributors

abierbaum avatar ashtonthomas avatar chetbox avatar christiangenco avatar cjavilla-stripe avatar dackers86 avatar davidgaroro avatar feiyang1 avatar hiranya911 avatar jauntybrain avatar jhuleatt avatar joehan avatar joshdance avatar jsteele-stripe avatar kazuooooo avatar ktole18 avatar laander avatar lahirumaramba avatar lemuel-stripe avatar luc122c avatar michaelangeloio avatar paulasjes-stripe avatar pr-mais avatar remilefort avatar salakar avatar stanbar avatar thatfiredev avatar thorsten-stripe avatar willbattel avatar ynnoj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stripe-firebase-extensions's Issues

one-time setup fee for a subscription

Feature request

  • Extension name: firestore-stripe-subscriptions

Is your feature request related to a problem? Please describe.

A clear and concise description of what you want and what your use case is.

Describe the solution you'd like

  1. I would love to be able to add a one-time setup fee to the subscription.
  2. Setting up a limited time discounted trial period (instead of totally free) would be amazing as well.

Thanks!

stripe.redirectToCheckout does not exist on type stripe

please how do i fix this issue.
import { AngularFirestore } from '@angular/fire/firestore';
import { ServicesClass } from './../services/service';
import { Component, OnInit } from '@angular/core';
import Stripe from 'stripe';

@component({
selector: 'app-plans',
templateUrl: './plans.component.html',
styleUrls: ['./plans.component.css'],
})
export class PlansComponent implements OnInit {
plans;
constructor(private afs: AngularFirestore, public service: ServicesClass) {
this.afs
.collection('products')
.ref.where('active', '==', true)
.get()
.then(function (querySnapshot) {
querySnapshot.forEach(async function (doc) {
console.log(doc.id, ' => ', doc.data());
// const priceSnap = await doc.ref.collection('prices').get();
// priceSnap.docs.forEach((doc) => {
// console.log(doc.id, ' => ', doc.data());
// });
});
});
}

async subscribe() {
const docRef = await this.afs
.collection('users')
.doc(this.service.userData.uid)
.collection('checkout_sessions')
.add({
price: 'price_1GqIC8HYgolSBA35zoTTN2Zl',
success_url: window.location.origin,
cancel_url: window.location.origin,
});
// Wait for the CheckoutSession to get attached by the extension
docRef.onSnapshot((snap) => {
const { sessionId } = snap.data();
if (sessionId) {
// We have a session, let's redirect to Checkout
// Init Stripe

    // const stripe = Stripe('pk_test_*****************');

    const stripe = new Stripe(
      'pk_********************',
      {
        apiVersion: '2020-08-27',
        typescript: true,
      }
    );
     stripe.redirectToCheckout({ sessionId });
  }
});

}

ngOnInit(): void {}
}

Store: price.nickname in firestore

Feature request

firestore-stripe-subscriptions

Is your feature request related to a problem? Please describe.

Price data stored in firestore should include the price's description as well. This use case is useful using the description to name different pricing tiers to display to customers.

Describe the solution you'd like

Update the insertPriceRecord handler for price.create and price.update to also store price.nickname

Describe alternatives you've considered

An alternative is to look at price.interval and display "Monthly" or "Annually" to customers depending on what price.interval is

Additional context

N/A

Webhooks repeatedly failing

Bug report

  • Extension name: firestore-stripe-subscriptions

Describe the bug

The webhook associated with this extension is failing repeatedly when dealing with customer or checkout events. Both price and product creates/updates fire successfully. I can't find any way to review logs on the failing webhooks so I'm not sure how to debug this.
*Fair warning that I'm new to this extension/Stripe in general.

To Reproduce

This is a private repo so can't share much.

Expected behavior

I need the webhook to run successfully.

Screenshots

Screen Shot 2020-08-16 at 5 58 13 PM

System information

  • OS: macOS
  • Browser (if applies) Chrome

Additional context

Feel free to get at me with any questions or clarifications.

UX: On smaller screen sizes, applying promo code requires users to select "View Details" first

Feature request

Should the field for entering the promo code be on the main redirect checkout screen instead of requiring to select "View Details" in order to see it?

Is your feature request related to a problem? Please describe.

Users would need to know to select "View Details" in order to apply a promo code:

view-details-promocode

Describe the solution you'd like

Add the field to the main screen which has the CC info, etc?

Describe alternatives you've considered

Pointing out to users that they can find to promo code field under "View Details" if it isn't visible.

Add any other context or screenshots about the feature request here.

Support quantity and unit_amount instead of just amount

Feature request

  • Extension name: firestore-stripe-invoices

Is your feature request related to a problem? Please describe.

I'd like to be able to pass 'quantity' and 'unit_amount' instead of 'amount'. Not every item quantity = 1.

Describe the solution you'd like

OrderItems should use quantity and unit_amount instead of just amount

Describe alternatives you've considered

implementing my own solution.

Additional context

image

Adding Subscription to User in Dashboard not updating Firestore

Bug report

  • Extension name: [e.g. firestore-stripe-subscriptions]

Describe the bug

Creating a Subscription in Stripe for a user does not send it back to Firestore

To Reproduce

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

  1. User Sign up in Firebase
  2. User is created as Customer in Firebase and as a Customer in Stripe
  3. Add a Subscription to the user in Stripe Dashboard
  4. Subscription is not added to the user in Firebase

Expected behavior

Subscription should be added to the user's Firebase Document

Webhook is failing on checkout.session.completed and customer.subscription.updates

Bug report

  • firestore-stripe-subscriptions

Describe the bug

The webhook is failing on checkout.session.completed and customer.subscription.updates.

To Reproduce

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

  1. Setup the stripe firebase extension: extensions/instances/firestore-stripe-subscriptions?tab=config
  2. Create the account and initiate the checkout portal on stripe, e.g. : https://checkout.stripe.com/pay/cs_test_12345*****
  3. Complete the payment process
  4. Check the webhook logs in Stripe: https://dashboard.stripe.com/test/webhooks/we_12345*****
  5. customer.subscription.updated and checkout.session.completed events fail with the message:
	Webhook URL: https://****************.cloudfunctions.net/ext-firestore-stripe-subscriptions-handleWebhookEvents
	HTTP status code - 400 (Bad Request)
	Response Webhook handler failed. View logs.
  1. In the firebase console logs I see this:
    [Error]: Webhook handler for Stripe event [evt_1234567890******] of type [customer.subscription.updated] failed: The provided key 'rk_test_51*********************************************************************************************frB0' does not have the required permissions for this endpoint on account 'acct_1234567890******'. Having the 'rak_subscription_read' permission would allow this request to continue.

Expected behavior

The expected behavior is that the webhook succeeds and that the data appears in the connected firestore

System information

The frontend web application is a ReactJS app

Additional context

The error in firebase look very descriptive but I'm not sure how or where to set the rak_subscription_read permission.

Code Snippet

Here are some JS code snippets used along with import { loadStripe } from '@stripe/stripe-js'; for creating the user in firebase and starting the Stripe subscription checkout


startSubscriptionCheckout = async (stripe, userId, priceId) => {
  console.log('startSubscriptionCheckout', stripe, userId, priceId);
  const docRef = await db
    .collection('customers')
    .doc(userId)
    .collection('checkout_sessions')
    .add({
      price: priceId,
      success_url: window.location.origin,
      cancel_url: window.location.origin,
    });

  // Wait for the CheckoutSession to get attached by the extension
  docRef.onSnapshot((snap) => {
    const { sessionId } = snap.data();
    if (sessionId) {
      // We have a session, let's redirect to Checkout
      // Init Stripe
      stripe.redirectToCheckout({ sessionId });
    }
  });
};

// Create the user in firebase and return it
const user = auth.createUserWithEmailAndPassword(email, password)
  .then((userCredential) => {
    userCredential.user.updateProfile({
      displayName: name,
    }).then((result) => {
      // Update successful.
      console.log('user updated', result);
    }, (error) => {
      // An error happened.
      console.log('user update error', error);
    });
    return userCredential.user;
  }, (error) => {
    const errorCode = error.code;
    const errorMessage = error.message;
    if (errorCode === 'auth/weak-password') {
      console.log('The password is too weak.');
    } else {
      console.error(error);
    }

    return error;
  });

// pass in the stripe instance
startSubscriptionCheckout(stripe, user.uid, 'price_1234567890******');

Thanks!

StripeRole remove 'role' from custom claims

Bug report
firestore-stripe-subscriptions

To Reproduce

  1. Create user in firestore app and set custom user claims like: admin.auth().setCustomUserClaims(user.uid, { role: 'admin' });
  2. Use stripe to make a subscription for a product with firebaseRole metadata
  3. If success => sign out and sign in again
  4. Check user.getIdTokenResult() - 'role' will be removed
  5. If you set 'role' again, it will remove stripeRole from custom claims

Expected behavior
'StripeRole' shouldn't replace/delete other custom claims.

As can I see (https://firebase.google.com/docs/auth/admin/custom-claims#set_and_validate_custom_user_claims_via_the_admin_sdk) this is expected behavior.

It means this extension is unusable if you need to use other custom claims (you need to choose between custom claims created by firebase or stripe). I need both (stripeRole to match the subscribed plan with appropriate document in firebase collection where I defined specific limits for that plan).

Remove 'stripeRole' when deleting a user subscription

Feature request

firestore-stripe-subscriptions

Is your feature request related to a problem? Please describe.

When deleting a user subscription in the customers collection (to cancel it) (directly from Firebase admin panel), it does not change the custom claim role stripeRole on the user token.

Edit: when deleting the subscriptions from Stripe dashboard, it also remove the stripeRole custom role.

Describe the solution you'd like

When deleting a user subscription in the customers collection, delete the custom claim role stripeRole.

Describe alternatives you've considered

Create manually a cloud function to delete the subscription in the customers collection and in the same time, removing the stripeRole custom claim role, or use stripe api to cancel the subscription.

Should we move the prices subcollection into the original product document?

Feature request

  • Extension name: firestore-stripe-subscriptions

Hi, Stripe Engineers! So I noticed that when we create a new subscription product with a set of pricing options in Stripe, those pricing options get added to a "prices" subcollection for the individual product. While that seems logical, it means that when you want to get a list of products and their prices, you have to query both the products collection, and then go back and query every individual prices subcollection for every product. This leads to longer load times, more complex code, and more reads charged to the developer.

So I'm wondering if it would make sense to take all of those pricing documents and simply merge them into the original product document, probably as a map field. It might look something like this:

prod_abcdefg:
   active: true
   description: "Foo"
   images: ["http://..."]
   name: "Bar"
   prices: {
    price_123: {active: true, currency: "usd", description: "...", interval: "month", // etc.}
    price_456: {active: true, currency: "usd", description: "...", interval: "week", // etc.}
    price_789: {active: true, currency: "usd", description: "...", interval: "year", // etc.}
   }
   role: "Premium"

This would mean that as a developer, you can much more easily query for a list of products and all of their prices with a single database call.

The potential drawbacks to this approach are that a) There would be no server-side filtering of prices. (That is, a client would retrieve all pricing options, and if there were inactive ones or other pricing options you wanted to keep hidden from the client, that wouldn't be possible), b) You would always retrieve all pricing options even if you didn't need or want them. (Maybe there are situations where you only want to display products and not show pricing information, so we'd be downloading some unnecessary info), c) If you had a lot of pricing options, you could run up against the 1mb / document limit (but that would be pretty unusual), and d) It's a non-backwards-compatible change.

Since I don't have enough familiarly with the Stripe user base or their typical workflows, I don't know if any of these drawbacks are legitimate concerns, but I just thought I should bring this idea up in case you hadn't considered it.

sales tax(consumption tax) cannot specified default_tax_rates

Bug report

  • Extension name: firestore-stripe-subscriptions

Describe the bug

sales tax (consumption tax 10% in Japan) can not be specified with this extention.

To Reproduce

Just use this extention. Stripe Checkout charges without tax.

Expected behavior

Strip API reference
default_tax_rates with specific TAX_RATE_ID should be able to specify on either FIrebase Stripe Extention console or within createCheckoutSession function. Or, it should be able to specify with the client function.

Checkout without internationalization option

Feature request

  • enable you to inform the location and internal checkout of the stripe to work with this

Is your feature request related to a problem? Please describe.

  • Is your feature request related to a problem? Please describe.

Describe the solution you'd like

  • When inserting the session creation document, enable the creation of the checkout session with internationalization

Describe alternatives you've considered

Do not use the extension

Support multiple line items

Feature request

  • Extension name: firestore-stripe-subscriptions

Is your feature request related to a problem? Please describe.

Currently the CheckoutSession creation only allows passing in one price ID, but there will likely be use cases where one wants to provide multiple pricing plans or add a one-time setup fee.

Describe the solution you'd like

To support this, we should allow to optionally pass in the whole line_items array, instead of just a price ID.

Bug Report: Inconsistency in how Webhook function handles one-time pricing

Bug report

firestore-stripe-subscriptions

Describe the bug

The webhook function will consume a product.create or product.update request but disregards any prices marked as one-time because the interval is set to null. Yet will send a 400 response for any price.create or price.update requests.

This creates unpriced products in the firestore database with no way to reconcile them with the Stripe catalog.

To Reproduce

Case 1

  1. Go to the Stripe Dashboard
  2. Create a product with a one-time price
  3. Go to Firestore dashboard
  4. See that product was created without a price sub-document

Case 2

  1. Go to the Stripe Dashboard
  2. Create or update a price on a product to be a one-time price
  3. Go to Stripe Webhook Monitor
  4. See that the request failed

Expected behavior

Consistency in how the extension handles one-time prices on products. EIther it should create and update the price document in Firestore, or it should refuse product requests that contain only one-time prices.

Firestore Customers table not updating using firebase.auth().createUserWithEmailAndPassword(email, password)

Bug report

  • Extension name: [e.g. firestore-stripe-subscriptions] Version 0.1.4

Describe the bug

Documentation under https://console.firebase.google.com/u/1/project/clowte-prototype/extensions/instances/firestore-stripe-subscriptions?tab=config

Sign-up users with Firebase Authentication
The quickest way to sign-up new users is by using the FirebaseUI library. Follow the steps outlined in the official docs. The extension listens to new users signing up and then automatically creates a Stripe customer object and a customer record in your Cloud Firestore.

Unfortunately, the extension is not properly listening for new user sign ups and the firestore Customers table not updating when using firebase.auth().createUserWithEmailAndPassword(email, password)

I know the sign up process is working though, because the Firebase Console > Authentication table shows them signed up.

Is there a manual config / process to ensure Firebase Auth matches up with the Customers table for the Stripe extension integration?

To Reproduce

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

  1. Go to '…'
  2. Click on '…'
  3. Scroll down to '…'
  4. See error

Expected behavior

A clear and concise description of what you expected to happen.

Screenshots

If applicable, add screenshots to help explain your problem.

System information

  • OS: [e.g. macOS, Windows]
  • Browser (if applies) [e.g. Chrome, Safari]

Additional context

Add any other context about the problem here.

createCheckoutSession function very slow

Bug report

  • firestore-stripe-subscriptions

Describe the bug

When clicking on the button in my app that should take the user to the Stripe checkout page, it takes anywhere from 500-5000 ms to redirect the user. Most of the time it takes for the user to be redirected is from the time it takes the createCheckoutSession to run. As well, the function can have up to 6 seconds of latency according to Firebase logger.

Expected behavior

I wish the program ran way faster.

Screenshots

Screenshot 2020-09-22 113131
Screenshot 2020-09-22 113018
Screenshot 2020-09-22 113258

System information

  • OS: Windows 10
  • Browser: Microsoft Edge (tested on all browsers)

[FAQ] Products and prices not syncing with Cloud Firestore

Bug report

  • Extension name: [e.g. firestore-stripe-subscriptions]

Describe the bug

FireStore collections not being created / updated upon reconfiguring customers / products in Extension config.

To Reproduce

When you are in the Firebase Dev Console and click on Extensions > Stripe Extension Manage Button > Extension Configuration

I deleted my previous collections and renamed them as follows in bold:

Products and pricing plans collection
Description: What is the path to the Cloud Firestore collection where the extension should store Stripe pricing plans?

products

Customer details and subscriptions collection
Description: What is the path to the Cloud Firestore collection where the extension should store Stripe customer details?

customers

Expected behavior

I would expect the FireStore collections to be created and/or updated upon clicking Save and reconfiguration completes.

Screenshots

If applicable, add screenshots to help explain your problem.

System information

  • OS: [e.g. macOS, Windows]
  • Browser (if applies) [e.g. Chrome, Safari]

Additional context

Add any other context about the problem here.

Add automated integration tests

Feature request

  • Extension name: all

Describe the solution you'd like

The Firebase emulators have an exec command that starts the emulators, runs a script, and then stops the emulators. For extensions, this looks like: firebase ext:dev:emulators:exec \"mocha --timeout=10000\" --test-params=../test-params.env --test-config=../firebase.json

Since the Stripe CLI is really useful for simulating Stripe events, I wonder if the Stripe CLI + Firebase emulators exec command could be used together to set up automated integration tests for the repo.

Support collection of shipping address details

Feature request

  • Extension name: firestore-stripe-subscriptions

Is your feature request related to a problem? Please describe.

Some subscription business models ship physical goods. We should support collection of shipping address details for those.

Describe the solution you'd like

Support https://site-admin.stripe.com/docs/payments/checkout/customization#shipping-address-collection

We need to figure out whether to

  1. Set allowed_countries via the client side (not ideal as it could be modified by customer via browser dev console)
  2. Set allowed_countries as metadata on the product? (need to figure out if the 500 character limit would be a problem)
  3. Read allowed_countries from a location in Firestore?

Support subscription_data.coupon in createCheckoutSession

Feature request

  • Extension name: firestore-stripe-subscriptions

Is your feature request related to a problem? Please describe.

Would be nice to be able to support coupons.

Describe the solution you'd like

  1. Add the coupon value when creating a checkout session:
  const docRef = await db
    .collection('customers')
    .doc(currentUser)
    .collection('checkout_sessions')
    .add({
      price: formData.get('price'),
      success_url: window.location.origin,
      cancel_url: window.location.origin,
      subscription_data: { coupon: "MYVALUABLECOUPON" }
    });
  1. In src/functions exports.createCheckoutSession, add the coupon to the parameters for checkout.sessions.create .

Would be nice to have (... assuming this approach works....?).

Best regards,

Robert

One-time trial

Feature request

firestore-stripe-subscriptions

Is your feature request related to a problem? Please describe.

Users who have used the trial once do not want to give the trial again.

  1. I canceled a new subscription during the trial period.
  2. If I purchase the subscription again after the trial period ends, the trial will start.
  3. Therefore, if I set a trial period, you can repeatedly subscribe for free.

Describe the solution you'd like

Do not give a trial to customers who have /customers/{uid}/subscriptions.

Describe alternatives you've considered

I thought it was possible with line_items, but it was a different feature.

Thanks.

Trial period is not set on customer creation

Bug report

  • Extension name: firestore-stripe-subscriptions

Describe the bug

When customer entity is created in Stripe, the subscription (for selected product / price) doesn't have trial period set. It also results in "active" status of subscription object put in firestore and not "trialing". If you add trial days in created subscription from Stripe dashboard, status is getting changed correctly to "trialing".

To Reproduce

  1. In Stripe dashboard create a Product, which has price with Trial days more than 0.
  2. In your firebase-stripe integrated application initialize checkout.
  3. Check your firestore for created customer entity in "customers" collection and see that subscription has "active" status without trial information set.

Expected behavior

"trialing" status correctly set like in description above.

The checkout form has the wrong email when user changes his email before

Bug report

  • Extension name: [e.g. firestore-stripe-subscriptions]

Describe the bug

Wrong/bad user email when he changes his email address before subscribing to some plan. The checkout form has the wrong email then.

To Reproduce

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

  1. Sign up a new user in service which uses Firebase
  2. New customer (stripe) is created - with an email address which user put in the register form
  3. User doesn't subscribe to a plan yet but changes his email address in service which uses Firebase
  4. User subscribe to a plan, with old/bad email

Expected behavior

Users can change his email address, it's typical behavior. So the checkout form should have access to his updated (last used) email address.

Support for customers without email addresses

Feature request

Add support for webapps not using email authentication.

Is your feature request related to a problem? Please describe.

Reliance on email address stops webapps/websites from utilizing firebase's phone authentication feature. The email is (as far as I can tell) not needed for stripe's customer or portal API. Attempting to register a user without an email results in:

ext-firestore-stripe-subscriptions-createCustomer ❗️[Error]: User does not have an email!

This is by design within the function. However, the customer is still created within Stripe. The only real missing piece is retrieving the StripeID and stripeLink fields to store within the customer's individual collection (record? I'm forgetting my noSQL terms here). Doing this manually (copy/pasting IDs) then allows the portal to function normally (the customer would just need to fill in an email address during checkout)

Describe the solution you'd like

Use the firebaseUID as the matching identifier if possible. Another solution is to use the phone number itself in lieu of an email address.

I'm not sure if the above is possible. Like I mentioned above, I see specific error handling for this within createCustomer. My attempts of playing around with it haven't yielded much success. This is my only hiccup with the extension so far - otherwise it's perfect.

[FAQ] CORS error when calling function

I'm running through a very annoying issue when calling createPortalLink function.

I always get the following error : "Access to fetch at 'https://name-of-my-project.cloudfunctions.net/createPortalLink' from origin 'https://my-app.firebaseapp.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request"

This happens only when I try to call a function from this extension, not my own.

It is not only happening when I test on localhost, but also when it is deployed on firebase hosting.

Any idea on how I could solve it ?

Thanks for your help.

Stripe One-Time Payment Extension

Feature request

Describe the solution you'd like

I love the ease of use and functionality of the Stripe Subscriptions extension. I was hoping for the creation of another extension that allows for easier one-time payment processing. I love the design of https://github.com/stripe/stripe-payments-demo, but wish it would work with Firebase.

Describe alternatives you've considered

https://github.com/firebase/functions-samples/tree/master/stripe Also works, but it requires you to use Cloud Functions, rather than an extension; also, it uses the Stripe portal for checkout rather than the Stripe Card Element.

Additional context

Keep up the amazing work! I understand if this feature is too much to ask.

[FAQ] Write your own Cloud Functions for Firebase

For anyone trying to use the source and customize these functions, FYI I found that there appears to be an issue which causes deployment to fail using the latest firebase CLI/tools.

Issue manifests as error during firebase deploy --only functions

HTTP Error: 400, Invalid JSON payload received. Unknown name "children" at 'function': Cannot find field.
Invalid JSON payload received. Unknown name "exit" at 'function': Cannot find field.
Invalid JSON payload received. Unknown name "message" at 'function': Cannot find field.

The root cause appears to be that the trigger for the function is missing (details available by running above with --debug)

The resolution for me was the following change:

functions.handler.https.onRequest
should be replaced with

functions.https.onRequest

Seat-based subscription plan

Feature request

  • Extension name: firestore-stripe-subscriptions

Is your feature request related to a problem? Please describe.

We're a software company. We have monthly subscription plans at a fixed rate for our customers. We have already built a fixed price subscription system on Firebase with PayPal ourselves.

However, we would like to do more B2B and we'd like to allow companies' administrators to manage the subscriptions of all the companies' employees. To do so, we'd need to handle seat-based subscriptions so that administrators can easily add/remove seats for the companies' employees.

Describe the solution you'd like

We'd like to be able to change the number of seats for a fixed-price subscription on-the-go, based on administrators inputs.

We will also need to manage the claims :

  • admin claim to manage the number of seats and to assign the seats to the employees
  • employee claim to know whether the user has a valid licence to access our software

Managing claims within Stripe extension might be out of scope though ?

Describe alternatives you've considered

Use the subscriptions APIs offered by PayPal (since we're using this payment gateway at the moment) or Stripe which both have seat-based features.

The management of licences will likely be done within cloud functions / firestore but we didn't think about the exact implementation yet.

Maybe a workaround with this extension in this current state would be to create many products for 5, 10, 25, 50, 100, ... seats and allow the administrators to update their subscriptions ?

Additional context

We have limited development resources (manpower/time) to implement this new feature. If this extension could help us achieve our goal more easily, we will likely switch from PayPal to Stripe.

ERROR Error: Uncaught (in promise): FirebaseError: Firebase: No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp() (app/no-app).

This is the error i get when i try to click on customer portal function i created in Angular
Below is the code.

async createPortalLink() {
const functionRef = firebase
.app()
.functions('us-east4')
.httpsCallable('ext-firestore-stripe-subscriptions-createPortalLink');
const { data } = await functionRef({ returnUrl: window.location.origin });
window.location.assign(data.url);
}

please help.

Hardcode price for Stripe Subscription

Feature request

  • firestore-stripe-subscriptions

Is your feature request related to a problem? Please describe.

When running the code shown below, it throws an error because formData.get('price') is not setup for my website. How could I hardcode in the price for the product. Let's say that the price is $5.00 USD, how do I set that.

const docRef = await db .collection('customers') .doc(currentUser.uid) .collection('checkout_sessions') .add({ price: formData.get('price'), success_url: window.location.origin, cancel_url: window.location.origin, }); // Wait for the CheckoutSession to get attached by the extension docRef.onSnapshot((snap) => { const { sessionId } = snap.data(); if (sessionId) { // We have a session, let's redirect to Checkout // Init Stripe const stripe = Stripe('pk_test_1234'); stripe.redirectToCheckout({ sessionId }); } });

Describe the solution you'd like

I want to hard code in the price of the product that I'm purchasing.

Additional context

This is the error thrown when I type 500 as my price.
❗️[Error]: Checkout session creation failed for doc [aiBdCNtUt0uIKuLpOuVk]: No such price: 500

P.S. thank you so much for your delete customer feature. It is a game changer. Keep up the fantastic work!

Sync metadata object from the Stripe subscription object to Cloud Firestore

Feature request

  • firestore-stripe-subscriptions`

Is your feature request related to a problem? Please describe.

Stripe API Subscription object has a metadata object to store custom key-value pairs informations. Metadata data object is currently not synced to firestore subscription object.

Describe the solution you'd like

Add the abilty to attach a metadata object from the beginning of the subscrption process (checkout session) to finally save it to newly created firestore subscrption object.

Additional context

In my situation, a customer may create multiple items. For each item, customer needs a subscrption in order to activate the service. Metadata allows me to link item and subscritpion for a given customer.

Can not sync up user id with stripe user id.

Feature request

  • Extension name: [e.g. firestore-stripe-subscriptions, or leave empty if suggesting a new extension]

Is your feature request related to a problem? Please describe.

Can not sync up user id with stripe user id. What if I want the user Id to be the same as stripe userid? and also I can't add names to the thing as well.

Describe the solution you'd like

Using same firebase userid as stripe user id

Describe alternatives you've considered

rewrite the entire thing

Additional context

I also can't add display name to the stripe users. This is a big problem for syncing up stripe, android and iOS payment. There is always more steps to check whether user have paid through one way or another (in app purchase or stripe over the web), if it's just using one set of userId we can sync this up much more easier.

Client can't know if there was a problem in attaching a session id

Bug report

  • Extension name: [e.g. firestore-stripe-subscriptions]

Describe the bug

when there is a problem in createCheckoutSession (which can happen because of many reasons --network failure or validation error from stripe), there is no way to know from the client why sessionid wasn't created.
In case of a valid error may be you should create something like "error" so that client can monitor both sessionid as well as "error" and can appropriately handle the situation.

To Reproduce

Create a customer and make a successful subscription in one currency .Let's say USD.

When the same customer tries to make another subscription in a different currency ,we get the following error from the function "createCheckoutSession" .
"Checkout session creation failed for doc [xyz]: Customer with currency usd cannot subscribe to price of different currency (inr)."

While this issue can be handled on the client side by checking customer subscription ,the general nature of the problem remains same .Client has to keep waiting for a sessionid in case of an error which may never come.

Expected behavior

Client should be informed that there was a problem in attaching a session.

Screenshots

System information

Additional context

Add any other context about the problem here.

Typescript Extension Documentation

Feature request

  • Extension name: firestore-stripe-subscriptions

Is your feature request related to a problem? Please describe.

The documentation does not cover the Typescript implementation.

Describe the solution you'd like

The Javascript documentation includes the following:

docRef.onSnapshot((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 occured: ${error.message}`);
  }
  if (sessionId) {
    // We have a session, let's redirect to Checkout
    // Init Stripe
    const stripe = Stripe('pk_test_1234');
    stripe.redirectToCheckout({ sessionId });
  }

The documentation does not include how to include install the Stripe TS definition. A snippet in the documentation as to how to install the right package and use it to redirect to checkout would be great. An example of the solution is here: #69 (comment)

import {loadStripe} from '@stripe/stripe-js';

const stripe = await loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx');
stripe.redirectToCheckout({ sessionId });

Describe alternatives you've considered

N/A, the solution is listed above.

Additional context

N/A

How do I disable a function that I do not want to use from the extension

Bug report

  • Extension name: [e.g. firestore-stripe-subscriptions]

Describe the bug

I have two different set of users and I do not need to create customers always .I have looked at extension and wrote a conditional customer creation function that is working as expected .I have commented out the code inside function create customer. The question I have is when I upgrade the extension it will override the commented code .If I delete the unwanted function will it help? If not ,is there a way to select what function to deploy during upgrade.

Without these options I always have to manually delete/comment the function and deploy and unwanted things can happen during the same window.

Appreciate any suggestion you may have.

adding firestoreRole to products doesn't add userCustomClaims stripeRole

Bug report

  • Extension name: [e.g. firestore-stripe-subscriptions]

Describe the bug

Not really sure where to report/ask this, so I figured here would be a good place.

If a product has a firestoreRole value in Stripe, and there's a customer subscription, that user should have the same value on the user claim key stripeRole... right? That's my understanding. If I'm wrong, can someone clear this up for me? If I'm correct in that assumption, something may be up with the extension

To Reproduce

Here's my setup:

  • I have a freshly installed extension, pre-existing products in Stripe: Basic, Pro, Premium.
  • each product has a firestoreRole value: basic, pro, premium

Retrieving the customClaims on a front-end next.js app with this:

export async function getCustomClaimRole() {
  await firebase.auth().currentUser.getIdToken(true);
  const decodedToken = await firebase.auth().currentUser.getIdTokenResult();
  console.log("decodedToken", decodedToken.claims.stripeRole); // output is undefined, stripeRole doesn't exist :( more on that below
  return decodedToken.claims.stripeRole;
}

Expected behavior

stripeRole should exist on user custom claims if firebaseRole exists on products.
Not really sure why the claim isn't there.

Screenshots

Here's the entire decodedToken object consoled I mentioned above:

decoded

Here's the metadata firebaseRole on a product in stripe:

Screen Shot 2020-08-15 at 4 50 58 PM

Happy to provide any further details to help debug this. I've been wracking my brain on this one 😅 hope all of this makes sense

Using a path like stripe/customers while installing breaks installation due to onCustomerDataDeleted regex error

Bug report

  • Extension name: [e.g. firestore-stripe-subscriptions]
    firestore-stripe-subscriptions

Describe the bug

When you install the extension and provide a path like "stripe/customers" installation will result in an error due to the path not matching the regex in onCustomerDataDeleted. Seems like every other function works

A clear and concise description of what the bug is.

To Reproduce

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

  1. Click install extension
  2. Installation wizard will ask you about config settings
  3. Use stripe/products for products path and stripe/customers for customer path
  4. See error

Expected behavior

Path should be allowed

[firestore-stripe-subscriptions] Create Stripe customer for pre-existing Firebase users

Feature request

  • firestore-stripe-subscriptions

Is your feature request related to a problem? Please describe.

I'm using this extension with a pre-existing Firebase project which has ~1,000 users. When using the extension, a Stripe customer is created for these pre-existing Firebase users. However the email address of the Firebase user is not passed to the Stripe customer.

Describe the solution you'd like

I'd like for the email address of the pre-existing Firebase user to be passed to the created Stripe customer. This will make identifying customers in Stripe a lot easier going forward.

Describe alternatives you've considered

N/A

Additional context

N/A

403 Webhook Error on multiple events

Bug report

  • Extension name: [e.g. firestore-stripe-subscriptions]

Describe the bug

Getting 403 Error from Stripe Dashboard for the following events:

price.created
product.created

Expected behavior

Would write products and prices to firestore

This message is what the webhook is getting back in response from firestore.

Status code is 403

<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>403 Forbidden</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Forbidden</h1>
<h2>Your client does not have permission to get URL <code>/ext-firestore-stripe-subscriptions-handleWebhookEvents</code> from this server.</h2>
<h2></h2>
</body></html>

Sample security rules should make subscriptions read-only

Bug report

  • Extension name: firestore-stripe-subscriptions

Describe the bug

The sample security rules in the documentation has the customers/{uid}/subscription/{id} documents readable and writable by the client.

Unless there's something I'm overlooking, I don't think there's any reason for the client to be writing to their /subscriptions/ document. We should make it read only, so that it's only written to by the Cloud Function.

To Reproduce

Open up the firestore-stripe-extensions/POSTINSTALL.md file. You'll see there's the following sample security rules:

    match /${param:CUSTOMERS_COLLECTION}/{uid} {
      allow read, write: if request.auth.uid == uid;

      match /checkout_sessions/{id} {
        allow read, write: if request.auth.uid == uid;
      }
      match /subscriptions/{id} {
        allow read, write: if request.auth.uid == uid;
      }
    }

Which would mean that any client could go ahead and update their subscriptions document. I'm assuming we don't want that to happen?

Expected behavior

I believe that /subscriptions/{id} block should be:

      match /subscriptions/{id} {
        allow read: if request.auth.uid == uid;
        allow write: if false;
      }

Make create stripe customer action configurable for use with document creation other than auth user.

Feature request

firestore-stripe-subscriptions

Is your feature request related to a problem? Please describe.

Currently, this extension will create a stripe customer for every firebase auth user associated with an app. In my case, not every app user is expected to be a paying user - and specifically, I already have the notion of an explicit 'customers' collection, which is a sub-set of auth users.

Describe the solution you'd like

While defaulting to triggering on auth user creation is fine, it would be great if, perhaps during initial configuration, users of the extension could specify which collection should have it's doc create trigger associated with creating the stripe customer.

Describe alternatives you've considered

Seems like the only real alternative for me here is to clone the bits of the webhooks etc, uninstall the extension, and rely on my own customer collection as the basis for my stripe integration.

Additional context

Just wanted to say thanks - just starting out with stripe and this is an awesome resource, even if it's not a perfect fit for my use case just yet.

createPortalLink() failed for return_url like 'chrome-extension://wtrfdnfleobejgjajmgkfahnafphfooa'

Bug report

  • Extension name: firestore-stripe-subscriptions

Describe the bug

createPortalLink() failed when used with return_url like this: 'chrome-extension://wtrfdnfleobejgjajmgkfahnafphfooa'.

I try to integrate the checkout process into the Chome extension and I get:

Request URL: https://********.cloudfunctions.net/ext-firestore-stripe-subscriptions-createPortalLink
Request Method: POST
Status Code: 500 

Response:
{"error":{"message":"Not a valid URL","status":"INTERNAL"}}

To Reproduce

Short: call the code below from the Chrome extension:

		// Call billing portal function
		const functionRef = firebase
			.app()
			.functions(functionLocation)
			.httpsCallable('ext-firestore-stripe-subscriptions-createPortalLink');
		const { data } = await functionRef({ returnUrl: window.location.origin });

Long: use the sample:
https://github.com/stripe-samples/firebase-subscription-payments
inside of the Chrome extension.

Expected behavior

A user accesses the Stripe portal and the return link is like this: 'chrome-extension://wtrfdnfleobejgjajmgkfahnafphfooa/somepage.html'.

I can hardcode the return URL to ANY https://...
const { data } = await functionRef({ returnUrl: 'https://anyurl.com' });
then everything is working fine from the Chrome extension.
It's obvious that returnUrl doesn't play any serious role. It's just used in https://billing.stripe.com/session/*********** to allow a user return to the initial page.

Thanks in advance!

Custom title in the line item of the invoice

Feature request

feature request

My web app has users and teams,. Users can be part of multiple teams.
Then I offer a "Premium Plan" subscription for my users, but the subscription applies to a whole team. When a user buys a subscription for a team, then the whole team gets access to the premium features.
So one user can buy 2 subscriptions for 2 separate teams. Then they don´t know which invoice is for which subscription, as both invoices just state "Premium Plan" in the description of the line item.

Possible solution

Similar to the metadata field in the checkout_sessions collection, I would like to be able to overwrite the description in the line item of the invoice via the checkout_session object.

Current workaround

Right now I use the metadata from the subscription collection (the metadata info is passed via the checkout_session into the subscription object). So I am at least able to display relevant subscription info to the user in the web app.

Stripe Subscription - Before installing this extension... More info needed

Bug report

  • Extension name: [e.g. firestore-stripe-subscriptions]

Describe the bug

Context: https://github.com/stripe/stripe-firebase-extensions/blob/next/firestore-stripe-subscriptions/README.md

From the main README for Stripe Firebase Extension Subscriptions one needs to first:
"Before installing this extension, set up the following Firebase services in your Firebase project:

Cloud Firestore to store customer & subscription details.
Firebase Authentication to enable different sign-up options for your users."

No details are provided on how to properly pre-configure Firestore or Authentication or how to reconfigure them after I did the initial install. I would expect this information to be available after installation in the Cloud Console > Extensions > "How this extension works" page:

https://console.firebase.google.com/u/1/project/clowte-prototype/extensions/instances/firestore-stripe-subscriptions?tab=config

(There is also no information after installation if it was successful [was Firestore / Auth setup for me? Or what to do next?])

Delete Stripe customer by deleting Firestore customer file

Feature request

  • firestore-stripe-subscriptions

Is your feature request related to a problem? Please describe.

Yes. Firebase already has an extension that allows for data (besides the authentication account) to be removed upon account deletion.

Describe the solution you'd like

If removing the customer file within Firestore would send a trigger to delete the customer on the dashboard, that would be the best solution.

Additional context

https://firebase.google.com/products/extensions/delete-user-data

P.S. I'm so thankful for this extension. It really makes my life 400 thousand times easier. Keep up the phenomenal work!

Allow subscription extension to be added to existing database

Feature request

  • Extension name: firestore-stripe-subscriptions

Is your feature request related to a problem? Please describe.

If you already have a Firestore database + Firebase Authentication, it's not possible to adopt this extension without deleting all of your users.

Describe the solution you'd like

Instead of listening for customers on create, we could do createOrRetrieve instead.

Describe alternatives you've considered

Deleting all my users 😢

Additional context

Luckily, I found this in my dev environment so deleting the users wasn't a big deal. I can see how this might bite other people with existing prod databases, though!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.