Making Your First Recurly Subscription with Meteor 1.3
In this tutorial, we are going to create a dead-simple form that will allow you to start implementing subscription features in your app using the Recurly API.
Features:
- Meteor 1.3
- ES2015
- First class support for npm on Meteor
- Future / Fiber
Full repo can be found here
Okay, so let's get started.
Go ahead and install Meteor if you don't have it.
curl https://install.meteor.com/ | sh
Then create a meteor project as follows:
meteor create recurly
cd recurly
This is how our folder structure is going to look like:
NOTE: Meteor 1.3 is still in beta, so you might need to use the --release
flag (at the moment of this write 02/17/2016) the release version is .8
, so just run this.
update --release 1.3-modules-beta.8
For more info, feel free to check this topic at the Meteor forum.
Now with this you can start using npm install
in your project and have all your dependencies like a nodejs app, great right =D!?
Go ahead and create a package.json
inside your app's root directory, which might look like this:
{
"name": "meteor-recurly",
"version": "0.0.1",
"description": "Meteor + Recurly Example",
"author": "ethaan",
"repository": {
"type": "git",
"url": "https://github.com/Ethaan/playground/recurly"
},
"dependencies": {
"recurly-js": "2.1.3"
}
}
And then run
npm install
Now you are ready to go, you should see node_modules
in the root of your project.
NOTE: We are going to use recurly-js which is a fork of the original node-recurly library. Just to let you know, it is NOT an "official" library supported by Recurly.
The Code
I'm pretty sure that you want to start coding, so let's do it.
Let's start setting up the server stuff.
The first thing we need to do is import the two npm libraries that we are going to use.
Yes I'm talking about Future and Recurly.
Go ahead and create a /server folder, and inside of it, create a methods.js file like the following:
//methods.js
// This replaces the old:
//Future = Npm.require('fibers/future');
//Recurly = Meteor.npmRequire('recurly-js'); or if you use meteorhacks:npm
import Future from 'fibers/future';
import Recurly from 'recurly-js';
Now, the next thing you need to do is to go to the Recurly site to signup and get your API_KEY
& subdomain.
Then we are going to create a folder in the root directory named **/settings ** with a development.json file inside, which should look like this.
{
"recurly":{
"API_KEY": "yourkey",
"SUBDOMAIN": "yourdomain-sandbox",
"ENVIRONMENT": "sandbox",
"DEBUG" : true
}
}
You can get your credentials from the left-sidebar:
Now run with Meteor like this (more about meteor settings here):
meteor --settings settings/development.json
After that, go back to methods.js and add this extra line.
const RECURLY_SETTINGS = Meteor.settings.recurly;
Now let's go and jump to the client-side.
For the CSS I'm going to use Less + Materializescss, so first let's add the packages.
meteor add poetic:materialize-scss less
Also, since the npm library is only avaible on the server, we need to call one script in order to make Recurly work on the client-side, so go ahead and create this file main.html and put this line inside of it.
<head>
<title>Recurly + Meteor 1.3</title>
<script src="https://js.recurly.com/v3/recurly.js"></script>
</head>
Now, let's create a client/stylesheets folder. If you wish, you can copy the style from here
In addition, before we start building the form, you need to do a minimal config on the client-side in order to generate a recurly token. To do so, can put this inside your main.js
Meteor.startup(() => {
recurly.configure({
publicKey: Meteor.settings.public.publicRecurlyKey
});
});
After that, go and create a form inside client/views/subscriptionForm/subscriptionForm.html. A good feature about the Recurly API is that you can add a data attribute to your form. For example:
<template name="subscriptionForm">
<div class="container">
<div class="row subscription_form_wrapper">
<form class="col s12">
<input name="fakeusernameremembered" style="display:none" type="text"/> {{! just to avoid chrome autoprefill}}
<input name="fakepasswordremembered" style="display:none" type="password"/>
<div class="row">
<div class="input-field col s12">
<input class="validate" id="first_name" placeholder="Placeholder" type="text" data-recurly="first_name">
<label for="first_name">First Name</label>
</div>
</div>
</form>
</div>
</div>
</template>
Did you see the:
data-recurly="first_name"
The final form should look like this:
This makes your life easier by simply calling querySelectorAll
in your submit event, or even by passing the whole form to the Recurly API, which believe me is the best way.
You can see the full Form here and you can also check the list of supported attr elements here.
Now that we are ready to submit the form, this is how the submit event should look like.
const SUBSCRIPTION_FIXED_PRICE = 1500;
Template.subscriptionForm.events({
"submit #subscription-recurly-test": (event, template) =>{
event.preventDefault();
let formElement = $('#subscription-recurly-test'),
proceed = true;
if(proceed){
//You could add any form validation here
recurly.token(formElement, (error, token) =>{
if(error){
console.log(error);
}else{
Meteor.call('CreateSubscriptionAndAccount',{
subscription: {
plan_code: 'some-plan-thing-here-1',
currency: 'USD',
unit_amount_in_cents: SUBSCRIPTION_FIXED_PRICE,
account: {
account_code: 123456, // you could use Meteor.userId();
username: 'testuser', //you could use Meteor.user().username;
email: 'email', // you could use Meteor.user().emails[0].address
first_name: template.$('#first_name').val(),
last_name: template.$('#last_name').val(),
billing_info: {
token_id: token.id
}
}
}
}, callback);
}
});
};
}
});
Lets try to explain it.
let formElement = $('#subscription-recurly-test')
Here we are grabbing the form element by the ID selector to be passed into
recurly.token(formElement, [callback]);
Which is going to look for all the elements that have "data-recurly" as an attribute to check them and then generate a token.
Finally, we are calling the CreateSubscriptionAndAccount
method to generate the subscription. If the response from the server is good, you can (for example) display a success message, redirect the user, hide the form or do whatever you want. Your callback function could look like the following:
callback = function(error, result){
if(error){
console.log(error); //display the errors
}else{
console.log(result); //do your redirects here
}
};
Now as a final step, let's jump back to the server-side code again into the methods.js file.
Add the following code:
Meteor.methods({
CreateSubscriptionAndAccount: (options) => {
check([options], [Object]);
let recurlyFuture = new Future(),
recurly = new Recurly(RECURLY_SETTINGS);
recurly.subscriptions.create(accountAndSubscriptionObject.subscription,
function(error, subscription) {
if (error) {
return recurlyFuture.return(error.statusCode);
} else {
return recurlyFuture.return(subscription);
}
});
return recurlyFuture.wait();
}
});
The code itself is easy to read.
First we are creating an instance of a Future.
Why future?
You need to know that all Meteor code on the server must run on a "fiber" (for more details, feel free to check out this SO answer. In short, if you want to call 3rd party asynchronous functions, you must wrap them inside a Fiber.
Then, we are creating an instance of the Recurly Class, and then we are creating an account and subscribing it to a plan.
Why create an account and then subscribe to it?
I choose this for the tutorial example, but you can skip the account part and just update the subscription of a user.
And there you go, if you made everything correctly, you should now go to your recurly dashboard page and you should see something like this:
There is still a lot of work to do, so you should dive into the recurly API to flesh out your app!