aldeed:plans-stripe
Stripe service add-on for aldeed:plans package.
STATUS: USE AT YOUR OWN RISK. STILL IN DEVELOPMENT
Installation
In your Meteor app directory:
$ meteor add aldeed:plans-stripe
If you have a mobile-config
file for Cordova, add this:
1App.accessRule("https://*.stripe.com/*");
Example
Let's imagine a case where your app has three plan levels: bronze, silver, and gold. All new users are assigned to the free bronze plan when they register. They may upgrade and downgrade at will.
In our example, our users always have exactly one plan (which includes the features of other plans), so we use the get
and set
methods rather than add
and remove
.
Step 1: Create the plans in Stripe
First we will create the plans in stripe, setting the price. We won't create a Stripe plan for "bronze" because it does not require payment, but we'll create one plan with ID "silver" and one with ID "gold".
Tip: Create test and live plans with the same IDs and make sure all the plan details match.
Step 2: Define the plans in your app
In the app, we simply need to define each plan, indicating which Stripe plan it is linked with.
In common code:
1AppPlans.define('bronze'); 2 3AppPlans.define('silver', { 4 services: [ 5 { 6 name: 'stripe', // External plan is on Stripe 7 planName: 'silver', // External plan ID is "silver" 8 // Options for the Stripe Checkout flow on the client 9 payOptions: { 10 name: 'Silver Plan', 11 description: 'Only $5.00/month', 12 amount: 500 13 } 14 } 15 ], 16 includedPlans: ['bronze'] 17}); 18 19AppPlans.define('gold', { 20 services: [ 21 { 22 name: 'stripe', // External plan is on Stripe 23 planName: 'gold', // External plan ID is "silver" 24 // Options for the Stripe Checkout flow on the client 25 payOptions: { 26 name: 'Gold Plan', 27 description: 'Only $10.00/month', 28 amount: 1000 29 } 30 } 31 ], 32 includedPlans: ['bronze, silver'] 33});
The full list of possible payOptions
for Stripe is:
1{ 2 name: String, 3 description: String, 4 amount: Number, 5 email: Match.Optional(String), 6 currency: Match.Optional(String), 7 panelLabel: Match.Optional(String), 8 zipCode: Match.Optional(Boolean), 9 bitcoin: Match.Optional(Boolean) 10}
If you want a "Remember Me" check box on the Stripe Checkout form, set Meteor.settings.public.Stripe.rememberMe
to true
.
Step 3: Add Stripe credentials to your app
In order to call the Stripe API, this package needs your credentials. Set these in Meteor.settings:
{ "public" : { "Stripe" : { "publicKey" : "pk_test_5AqRfe1NSDIFUETngWikN3ODm", } }, "Stripe" : { "secretKey" : "sk_test_LnDJKqZY87FDIOBTmbratiz3M" } }
NOTE: Example keys above are fake. Find your real keys by logging into your Stripe account. Be sure to use your test keys when testing.
Step 4: Assign the default plan for new users
In server code:
1Accounts.onLogin(function (info) { 2 var userId = info.user._id; 3 var plan = AppPlans.get({userId: userId}); 4 if (!plan) { 5 AppPlans.set('bronze', {userId: userId}); 6 } 7});
No token, customer, or payment info is needed when calling AppPlans.set('bronze')
because we haven't linked that plan with a Stripe plan.
NOTE: We use onLogin
because there is not a hook that runs after user creation.
Step 5: Add a plans page where users can change their plans
We'll now add a page with buttons to change your plan. We can use {{AppPlans.listDefined}}
to get the list of all our plans and {{AppPlans.get}}
(reactive) to see which plan the user currently has. {{#if AppPlans.hasAccess 'silver'}}
(reactive) will tell us whether the current user has a plan that includes the features of the "silver" plan (i.e., either the "silver" plan or the "gold" plan).
When the user clicks a button to choose a plan, we set the plan in the click handler:
1AppPlans.set('silver', function (error) { 2 if (error) { 3 console.log(error); 4 alert('Sorry, there was a problem signing you up for this plan.'); 5 } 6});
When the button is clicked, the plans package will check to see whether we already have a Stripe customer ID with stored payment information for the current user. If so, the app plan and the corresponding Stripe subscription will be changed automatically. If not, the Stripe Checkout payment flow will be shown, allowing the user to enter their credit card information. Once we have a valid payment authorization, the user's app plan and Stripe subscription will be updated.
Note that you can pass override pay options when calling AppPlans.set
:
1AppPlans.set('silver', {payOptions: myOverrideOptions});
Step 6: Ensure our plan stays in sync with the Stripe subscription
Since the credit card could be declined or someone could manually cancel the subscription in Stripe, we will periodically check with Stripe to confirm what plan each user should have. We can do this as often as we want, but in our example, we'll just add it to our onLogin
hook:
In server code:
1Accounts.onLogin(function (info) { 2 var userId = info.user._id; 3 4 AppPlans.sync({userId: userId}); 5 6 var plan = AppPlans.get({userId: userId}); 7 if (!plan) { 8 AppPlans.set('bronze', {userId: userId}); 9 } 10});