Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(firestore-stripe-payments): allow to be specify trial period days #605

Merged
merged 5 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion firestore-stripe-payments/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,38 +37,47 @@
[feat] - Add `setup_future_usage` parameter for one-time payment flows

## 0.3.5 - 2023-08-14

[chore] Updated naming and upgraded to node18

[fix] Updated icons

[fix] updated appinfo versioning

## 0.3.4 - 2023-08-14

This extension has been formally transferred to Invertase. See the updated README for more details.

## Version 0.3.3 - 2023-03-20

[fix] Address issue where `insertInvoiceRecord` function fails. [#511]

## Version 0.3.2 - 2022-11-30

[chore] Added support for `us-west1` as a deployable region for Firebase functions. [#464]

## Version 0.3.1 - 2022-08-24

[chore] Added `package-lock.json` to version control to prevent installation issues. [#426]

## Version 0.3.0 - 2022-08-23

[feat] Allow configurable minimum instances for `createCheckoutSession` function. [#375]

[feat] Throw an `unauthenticated` Firebase error from `creatPortalLink` function. [#420]

[feat] Add Price object IDs from invoice line items for subscription payments to payments Firestore collection. [#393]

## Version 0.2.7 - 2022-05-10

[chore] Updated package-lock.json that was causing install errors.

## Version 0.2.6 - 2022-05-10

[feat] Added Stripe extension events. This extension emits events, which allows you to listen to and run custom logic at different trigger points during the functioning of the extension. For example you can listen to events when a product has been added via the `product.created` event, or whenever a payment has succeeded through the `invoice.payment_succeeded` event. (#386)

## Version 0.2.5 - 2022-04-20

[feat] Add parameter to enable phone number collection. (#371)

[feat] Add parameters to enable expired Checkout Session recovery. (#350)
Expand Down Expand Up @@ -334,7 +343,7 @@ db.collection("products")

Previously, only subscriptions created via Stripe Checkout were synced to Cloud Firestore. By additionally listening to the `customer.subscription.created` event, the extension now also captures subscriptions created via the Stripe Dashboard or directly via the API. For this to work, Firebase Authentication users need to be synced with Stripe customer objects and the customers collection in Cloud Firestore (new configuration added in version `0.1.7`).

- Add snippet on importing Stripe.js as an ES module when using a build toolchain for your client application (e.g. Angular, React, TypeScript, etc.) to `POSTINSTALL.md`. (#74)
- Add snippet on importing Stripe.js as an ES module when using a build toolchain for your client application (e.g. Angular, React, TypeScript, etc.) to `POSTINSTALL.md`. (#74)

## Version 0.1.6 - 2020-09-10

Expand Down
110 changes: 57 additions & 53 deletions firestore-stripe-payments/POSTINSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,15 +175,15 @@ The quickest way to sign-up new users is by using the [FirebaseUI library](https
Products and pricing information are normal collections and docs in your Cloud Firestore and can be queried as such:

```js
db.collection('${param:PRODUCTS_COLLECTION}')
.where('active', '==', true)
db.collection("${param:PRODUCTS_COLLECTION}")
.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();
console.log(doc.id, " => ", doc.data());
const priceSnap = await doc.ref.collection("prices").get();
priceSnap.docs.forEach((doc) => {
console.log(doc.id, ' => ', doc.data());
console.log(doc.id, " => ", doc.data());
});
});
});
Expand All @@ -197,7 +197,7 @@ To create a Checkout Session ID for a one-time payment, pass `mode: 'payment` to

```js
const docRef = await db
.collection('${param:CUSTOMERS_COLLECTION}')
.collection("${param:CUSTOMERS_COLLECTION}")
.doc(currentUser.uid)
.collection("checkout_sessions")
.add({
Expand Down Expand Up @@ -238,11 +238,11 @@ To subscribe the user to a specific pricing plan, create a new doc in the `check

```js
const docRef = await db
.collection('${param:CUSTOMERS_COLLECTION}')
.collection("${param:CUSTOMERS_COLLECTION}")
.doc(currentUser.uid)
.collection('checkout_sessions')
.collection("checkout_sessions")
.add({
price: 'price_1GqIC8HYgolSBA35zoTTN2Zl',
price: "price_1GqIC8HYgolSBA35zoTTN2Zl",
success_url: window.location.origin,
cancel_url: window.location.origin,
});
Expand All @@ -263,7 +263,7 @@ docRef.onSnapshot((snap) => {

#### Handling trials

By default, the trial period days that you've specified on the pricing plan will be applied to the checkout session. Should you wish to not offer the trial for a certain user (e.g. they've previously had a subscription with a trial that they canceled and are now signing up again), you can specify `trial_from_plan: false` when creating the checkout session doc:
You can specify subscription trial period when creating the checkout session by using the `trial_period_days` parameter. Refer to the [docs](https://stripe.com/docs/payments/checkout/free-trials) for a detailed guide on free trials and how to set them up.

```js
const docRef = await db
Expand All @@ -272,7 +272,7 @@ const docRef = await db
.collection("checkout_sessions")
.add({
price: "price_1GqIC8HYgolSBA35zoTTN2Zl",
trial_from_plan: false,
trial_period_days: 7,
success_url: window.location.origin,
cancel_url: window.location.origin,
});
Expand All @@ -286,11 +286,11 @@ In order for the promotion code redemption box to show up on the checkout page,

```js
const docRef = await db
.collection('${param:CUSTOMERS_COLLECTION}')
.collection("${param:CUSTOMERS_COLLECTION}")
.doc(currentUser)
.collection('checkout_sessions')
.collection("checkout_sessions")
.add({
price: 'price_1GqIC8HYgolSBA35zoTTN2Zl',
price: "price_1GqIC8HYgolSBA35zoTTN2Zl",
allow_promotion_codes: true,
success_url: window.location.origin,
cancel_url: window.location.origin,
Expand All @@ -305,7 +305,7 @@ You can set a [promotion code](https://stripe.com/docs/billing/subscriptions/dis

```js
const docRef = await db
.collection('${param:CUSTOMERS_COLLECTION}')
.collection("${param:CUSTOMERS_COLLECTION}")
.doc(currentUser.uid)
.collection("checkout_sessions")
.add({
Expand All @@ -326,7 +326,7 @@ Stripe Tax lets you calculate and collect sales tax, VAT, and GST. Know where to

```js
const docRef = await db
.collection('${param:CUSTOMERS_COLLECTION}')
.collection("${param:CUSTOMERS_COLLECTION}")
.doc(currentUser.uid)
.collection("checkout_sessions")
.add({
Expand All @@ -340,19 +340,23 @@ const docRef = await db

#### Applying tax rates dynamically

Stripe Checkout supports applying the correct tax rate for customers in US, GB, AU, and all countries in the EU. With [dynamic tax rates](https://stripe.com/docs/billing/subscriptions/taxes#adding-tax-rates-to-checkout), you create tax rates for different regions (e.g., a 20% VAT tax rate for customers in the UK and a 7.25% sales tax rate for customers in California, US) and Stripe attempts to match your customer’s location to one of those tax rates.
Stripe Checkout supports applying the correct tax rate for customers in US, GB, AU, and all countries in the EU. With [dynamic tax rates](https://stripe.com/docs/billing/subscriptions/taxes#adding-tax-rates-to-checkout), you create tax rates for different regions (e.g., a 20% VAT tax rate for customers in the UK and a 7.25% sales tax rate for customers in California, US) and Stripe attempts to match your customer’s location to one of those tax rates.

```js
const docRef = await db
.collection('${param:CUSTOMERS_COLLECTION}')
.collection("${param:CUSTOMERS_COLLECTION}")
.doc(currentUser)
.collection("checkout_sessions")
.add({
line_items: [
{
price: "price_1HCUD4HYgolSBA35icTHEXd5",
quantity: 1,
dynamic_tax_rates: ["txr_1IJJtvHYgolSBA35ITTBOaew", "txr_1Hlsk0HYgolSBA35rlraUVWO", "txr_1HCshzHYgolSBA35WkPjzOOi"],
dynamic_tax_rates: [
"txr_1IJJtvHYgolSBA35ITTBOaew",
"txr_1Hlsk0HYgolSBA35rlraUVWO",
"txr_1HCshzHYgolSBA35WkPjzOOi",
],
},
],
success_url: window.location.origin,
Expand All @@ -366,12 +370,12 @@ You can collect and report taxes with [Tax Rates](https://stripe.com/docs/billin

```js
const docRef = await db
.collection('${param:CUSTOMERS_COLLECTION}')
.collection("${param:CUSTOMERS_COLLECTION}")
.doc(currentUser)
.collection('checkout_sessions')
.collection("checkout_sessions")
.add({
price: 'price_1GqIC8HYgolSBA35zoTTN2Zl',
tax_rates: ['txr_1HCjzTHYgolSBA35m0e1tJN5'],
price: "price_1GqIC8HYgolSBA35zoTTN2Zl",
tax_rates: ["txr_1HCjzTHYgolSBA35m0e1tJN5"],
success_url: window.location.origin,
cancel_url: window.location.origin,
});
Expand All @@ -385,7 +389,7 @@ Secondly, you need to add `collect_shipping_address: true` to the Checkout Sessi

```js
const docRef = await db
.collection('${param:CUSTOMERS_COLLECTION}')
.collection("${param:CUSTOMERS_COLLECTION}")
.doc(currentUser.uid)
.collection("checkout_sessions")
.add({
Expand All @@ -402,15 +406,15 @@ You can optionally set a metadata object with key-value pairs when creating the

```js
const docRef = await db
.collection('${param:CUSTOMERS_COLLECTION}')
.collection("${param:CUSTOMERS_COLLECTION}")
.doc(currentUser)
.collection('checkout_sessions')
.collection("checkout_sessions")
.add({
price: 'price_1GqIC8HYgolSBA35zoTTN2Zl',
price: "price_1GqIC8HYgolSBA35zoTTN2Zl",
success_url: window.location.origin,
cancel_url: window.location.origin,
metadata: {
item: 'item001',
item: "item001",
},
});
```
Expand All @@ -421,25 +425,25 @@ In addition to recurring prices, you can add one-time prices. These will only be

```js
const docRef = await db
.collection('${param:CUSTOMERS_COLLECTION}')
.doc(currentUser)
.collection('checkout_sessions')
.add({
line_items: [
{
price: 'price_1HCUD4HYgolSBA35icTHEXd5', // RECURRING_PRICE_ID
quantity: 1,
tax_rates: ['txr_1HCjzTHYgolSBA35m0e1tJN5'],
},
{
price: 'price_1HEtgDHYgolSBA35LMkO3ExX', // ONE_TIME_PRICE_ID
quantity: 1,
tax_rates: ['txr_1HCjzTHYgolSBA35m0e1tJN5'],
},
],
success_url: window.location.origin,
cancel_url: window.location.origin,
});
.collection("${param:CUSTOMERS_COLLECTION}")
.doc(currentUser)
.collection("checkout_sessions")
.add({
line_items: [
{
price: "price_1HCUD4HYgolSBA35icTHEXd5", // RECURRING_PRICE_ID
quantity: 1,
tax_rates: ["txr_1HCjzTHYgolSBA35m0e1tJN5"],
},
{
price: "price_1HEtgDHYgolSBA35LMkO3ExX", // ONE_TIME_PRICE_ID
quantity: 1,
tax_rates: ["txr_1HCjzTHYgolSBA35m0e1tJN5"],
},
],
success_url: window.location.origin,
cancel_url: window.location.origin,
});
```

**_NOTE_**: If you specify more than one recurring price in the `line_items` array, the subscription object in Cloud Firestore will list all recurring prices in the `prices` array. The `price` attribute on the subscription in Cloud Firestore will be equal to the first item in the `prices` array: `price === prices[0]`.
Expand All @@ -457,14 +461,14 @@ In order for this to work, Firebase Authentication users need to be synced with
Subscription details are synced to the `subscriptions` sub-collection in the user's corresponding customer doc.

```js
db.collection('${param:CUSTOMERS_COLLECTION}')
db.collection("${param:CUSTOMERS_COLLECTION}")
.doc(currentUser.uid)
.collection('subscriptions')
.where('status', 'in', ['trialing', 'active'])
.collection("subscriptions")
.where("status", "in", ["trialing", "active"])
.onSnapshot(async (snapshot) => {
// In this implementation we only expect one active or trialing subscription to exist.
const doc = snapshot.docs[0];
console.log(doc.id, ' => ', doc.data());
console.log(doc.id, " => ", doc.data());
});
```

Expand All @@ -475,8 +479,8 @@ Once a customer is subscribed you should show them a button to access the custom
```js
const functionRef = firebase
.app()
.functions('${param:LOCATION}')
.httpsCallable('${function:createPortalLink.name}');
.functions("${param:LOCATION}")
.httpsCallable("${function:createPortalLink.name}");
const { data } = await functionRef({
returnUrl: window.location.origin,
locale: "auto", // Optional, defaults to "auto"
Expand Down
6 changes: 3 additions & 3 deletions firestore-stripe-payments/PREINSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ The design for Stripe Checkout and the customer portal can be customized in your

#### Recommended usage

If you're building on the web platform, you can use this extension for any of your payment use cases.
If you're building on the web platform, you can use this extension for any of your payment use cases.

If you're developing native mobile applications and you're selling digital products or services within your app, (e.g. subscriptions, in-game currencies, game levels, access to premium content, or unlocking a full version), you must use the app store's in-app purchase APIs. See [Apple's](https://developer.apple.com/app-store/review/guidelines/#payments) and [Google's](https://support.google.com/googleplay/android-developer/answer/9858738?hl=en&ref_topic=9857752) guidelines for more information.
If you're developing native mobile applications and you're selling digital products or services within your app, (e.g. subscriptions, in-game currencies, game levels, access to premium content, or unlocking a full version), you must use the app store's in-app purchase APIs. See [Apple's](https://developer.apple.com/app-store/review/guidelines/#payments) and [Google's](https://support.google.com/googleplay/android-developer/answer/9858738?hl=en&ref_topic=9857752) guidelines for more information.

For all other scenarios you can use the [stripe-android](https://github.com/stripe/stripe-android), [stripe-ios](https://github.com/stripe/stripe-ios), [stripe-react-native](https://github.com/stripe/stripe-react-native), or [flutter_stripe](https://github.com/flutter-stripe/flutter_stripe) SDKs.

Expand Down Expand Up @@ -73,4 +73,4 @@ You are responsible for any costs associated with your use of these services.

To install this extension, your Firebase project must be on the Blaze (pay-as-you-go) plan. You will only be charged for the resources you use. Most Firebase services offer a free tier for low-volume use. [Learn more about Firebase billing.](https://firebase.google.com/pricing)

Starting August 17 2020, you will be billed a small amount (typically less than $0.10) when you install or reconfigure this extension. See the [Cloud Functions for Firebase billing FAQ](https://firebase.google.com/support/faq#expandable-15) for a detailed explanation.
Starting August 17 2020, you will be billed a small amount (typically less than $0.10) when you install or reconfigure this extension. See the [Cloud Functions for Firebase billing FAQ](https://firebase.google.com/support/faq#expandable-15) for a detailed explanation.
Loading
Loading