Repository: Ionic Github Repository
Software Requirements:
Visual Studio Code(Or any preferred code editor),
A Stripe account
What you will learn:
In this tutorial you would learning about payment processing using stripe. I would be covering these major concepts
- How to add your secret key to your application
- How to use your stripe token to process a stripe payment
- How to use firestore to carry out this processes
Difficulty: Intermediate
Tutorial
In the last tutorial we learnt how to generate tokens from stripe with two methods. This tutorial would be explaining how we could actually process the payments with the generated tokens we got from the first tutorial. Note that this can only be done on a secure back-end which firebase makes easy for us.
To do this we would be using functions that we would create and upload to our backend to carry out these processes for us.
To get started, we would need to initialize our application as a firebase app. To do this run this command in your terminal while in your project directory
firebase init
This would initialize this project as a firebase project and add all the files we would need to deploy our functions.
In your projects directory you should have a folder called functions. Navigate into this folder and run this command to install stripe to the firebase project
npm install stripe --save
This should include it in your package.json
which should now look like this
{
"name": "functions",
"description": "cloud functions for firebase",
"dependencies": {
"firebase-admin": "4.1.2",
"firebase-functions":"0.5",
"stripe": "^4.23.1"//This signifies that firebase has been added
},
"private": true
}
How to add your secret key
To get your secret key, you must have a stripe account which was required in the part one of this tutorial. If you dont know how to find it click Here and login to see your own personal stripe secret key. Every transaction made with your stripe account would require the key and so it is advisable that you keep your key a secret.
When you go to the link above and get your secret key, you would need to add it as a setting. This can be done in two ways but the better way is to use this command
firebase:config:set stripe.testkey = "Your secret key goes here"
And the alternative method would be used in the next step below
Using firestore to process payments
We would be using firestore to process payments whenever a new token is loaded on our firestore database. This means that our function would be triggered whenever a new token is written on our database and this payment would be processed. Firebase has a way of doing this and the code is stated and explained below
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase);
const stripe = require('stripe')('Your test key');
exports.stripeCharge = functions.firestore
.document('/payments/{userId}/mypayments/{paymentId}')
.onCreate((snap,event) => {
const payment = snap.data()
const userId = event.params.userId
const paymentId = event.params.paymentId
console.log(payment);
// checks if payment exists or if it has already been charged
if (!payment || payment.charge) return null;
return admin.firestore()
.doc(`/users/${userId}`)
.get()
.then(snapshot => {
return snapshot
})
.then(customer => {
const amount = payment.amount // amount must be in cents
const idempotency_key = paymentId // prevent duplicate charges
const source = payment.token.source.id;
const currency = 'usd'
const charge = {amount, currency, source}
console.log(charge);
return stripe.charges.create(charge, { idempotency_key })
})
.then((charge) => {
admin.firestore()
.collection('/payments').doc(userId).collection('mypayments').doc(paymentId)
.set({
charge: charge
}, { merge: true })
.catch(er=>{
console.log(er);
return er
}
)
if(charge.status === 'succeeded'){
if(payment.amount === 3000){
const validTill = Date.now() + 12 * 30 * 24 * 60 * 60;
admin.firestore()
.collection('store'+userId).doc('subscriptionValidtill')
.set({
validTill
})
.catch(er=>{
console.log(er);
return er;
})
}
}
})
The first thing i did was import the firebase functionalities which we would be using like this
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
After this i initialized the app and added the test key which is the alternative method to the method stated above
admin.initializeApp(functions.config().firebase);
const stripe = require('stripe')('sk_test_4ZvAeCMGrH85ySuFNZRDxvg9');
I then started building the function which was going to be used on the server. To do this, i stated it as an export and made it to be triggered whenever a new token is written under payments in the firestore database.
I then made collected the payment details from the data that was written
exports.stripeCharge = functions.firestore
.document('/payments/{userId}/mypayments/{paymentId}')
.onCreate((snap,event) => {
const payment = snap.data()
const userId = event.params.userId
const paymentId = event.params.paymentId
console.log(payment);
// checks if payment exists or if it has already been charged
if (!payment || payment.charge) return null;
return admin.firestore()
.doc(`/users/${userId}`)
.get()
.then(snapshot => {
return snapshot
})
.then(customer => {
const amount = payment.amount // amount must be in cents
const idempotency_key = paymentId // prevent duplicate charges
const source = payment.token.source.id;
const currency = 'usd'
const charge = {amount, currency, source}
console.log(charge);
And then used the data i got to process the payment
return stripe.charges.create(charge, { idempotency_key })
Note: The idempotency key is to prevent duplicate charges
If this payment was successful, i then wrote this payment under the users database for future reference
if(charge.status === 'succeeded'){
if(payment.amount === 3000){
const validTill = Date.now() + 12 * 30 * 24 * 60 * 60;
admin.firestore()
.collection('store'+userId).doc('subscriptionValidtill')
.set({
validTill
})
.catch(er=>{
console.log(er);
return er;
})
}
Now that you have the function in place, you would need to deploy it. To do this run this command
firebase deploy --only functions//Specify functions so it would only deploy functions
You can then run the process from the first tutorial and this process would also be run.
Note: You should use your stripe test keys for development purposes and not use the live keys unless the application is ready for production.
You can find the code for this tutorial in my github repo
Here