SaaS App Example with Stripe using AWS CloudFormation

This project is an example SaaS app which allows you to register users and monitor their usage using credits and take payments (including subscriptions) using Stripe. The infrastruture is written using CloudFormation.

  • The blog post can/will be found here.
  • Live demo can/will be found here.

How it works

Architecture Overview

architecture

User Management State Machine

Screenshots

Home Page User Page Prices Page

Step By Step Instructions

  1. This project assumes the existence of a domain hosted on Route53 and with SSL certificates for both the region of your service and US-EAST-1.
    1. Get a domain on AWS
    2. Create a hosted zone on Route53
    3. Create two HTTPS Certificates
      • One for your region e.g. eu-west-1
      • One for cloudfront which must be us-east-1
  2. Deploy 00-infra.yml to create code bucket, certificate, and email alerts.
    •   aws cloudformation deploy --template-file ./00-infra.yml --stack-name infra --region=eu-west-1  --capabilities CAPABILITY_NAMED_IAM --parameter-overrides 
        RootDomain=t3chflicks.org 
        RegionalCertArn=arn:aws:acm:eu-west-1:855097409413:certificate/73255636-c96a-4170-b86d-10261b5e3c0a 
        HostedZoneId=ZFRPCPYMXP38T 
        CloudFrontCertArn=arn:aws:acm:us-east-1:855097409413:certificate/196cda25-d956-415e-b4b6-423342b9657d
      
  3. Deploy 01-vpc.yml to create vpc
    •   aws cloudformation deploy --template-file ./01-vpc.yml --stack-name vpc
      
  4. Deploy 02-tables.yml to create user and product tables
    • aws cloudformation deploy --template-file ./02-tables.yml --stack-name tables
      
  5. Deploy 03-user-manager.yml and use your own Stripe parameters to create a State Machine
    • Package AddPlan lambda and upload to bucket - the bucket name should be ~ s3://infra-codebucket-...
    •   aws cloudformation deploy --template-file ./03-user-manager.yml --stack-name user-manager --region=eu-west-1  --capabilities CAPABILITY_NAMED_IAM
      
  6. Create Stripe Account
    • get test API keys
  7. Create Stripe products using extra/StripeScripts/syncProducts.py
    • using new secret test key
    • using product table name exported from previous step.
  8. Deploy 04-congito.yml to create the user pool and post confirmation functions using Stripe params
    •   aws cloudformation deploy --template-file ./04-cognito.yml --stack-name cognito --region=eu-west-1  --capabilities CAPABILITY_NAMED_IAM --parameter-overrides 
        StripeSecretKey=sk_test_51HKlevJAV1tclqKuuFvkoHoOoygiavnUNDet2HXnyXd2bsNVCzvxkW2bNAA8HivobXs5idcpa5VCzK0b90wub2h100rsOtHlun
      
  9. Deploy 05-user-api.yml to create the user api and create functions
    •   aws cloudformation deploy --template-file ./05-user-api.yml --stack-name user-api --region=eu-west-1  --capabilities CAPABILITY_NAMED_IAM --parameter-overrides 
        StripeSecretKey=sk_test_51HKlevJAV1tclqKuuFvkoHoOoygiavnUNDet2HXnyXd2bsNVCzvxkW2bNAA8HivobXs5idcpa5VCzK0b90wub2h100rsOtHlun
      
  10. Create Stripe web hook using extra/StripeScripts/createWebHook.py
    • use WebHookAPIUrl + endpoint
  11. Deploy 06-stripe-api.yml to create webhook api
    • add Stripe Secret key
    • add Stripe web hook Secret
    •   aws cloudformation deploy --template-file ./06-stripe-api.yml --stack-name stripe-api --region=eu-west-1  --capabilities CAPABILITY_NAMED_IAM --parameter-overrides 
        StripeSecretKey=sk_test_51HKlevJAV1tclqKuuFvkoHoOoygiavnUNDet2HXnyXd2bsNVCzvxkW2bNAA8HivobXs5idcpa5VCzK0b90wub2h100rsOtHlun  
        StripeWebHookSecret=whsec_GJx2kmziA8JG3Cjs3EVVcRZzYaD5nsmz
      
  12. Deploy 07-test-service.yml as an example service running on the load balancer which verifies the user request
    •   aws cloudformation deploy --template-file ./07-test-api.yml --stack-name test-api --region=eu-west-1  --capabilities CAPABILITY_NAMED_IAM
      
  13. Deploy 08-site.yml
    •   aws cloudformation deploy --template-file ./08-site.yml --stack-name site --region=eu-west-1  --capabilities CAPABILITY_NAMED_IAM      
      
  14. Add parameters to frontend/src/main.js
    • Root Domain
    • Region
    • UserApiUrl
    • TestApiUrl
    • CognitoUserPoolId
    • CognitoUserPoolClientId
  15. Add parameter to frontend/src/views/Pricing.png
    • publishableKey from Stripe
  16. Build
    • npm run build
  17. Deploy to S3 bucket
    •   aws s3 cp ./dist s3://saas-app.YOUR_DOMAIN --recursive
      

Extra Info