All Projects → Subscribie → subscribie

Subscribie / subscribie

Licence: MPL-2.0 license
Collect recurring payments online - subscription payments collection automation

Programming Languages

HTML
75241 projects
python
139335 projects - #7 most used programming language
CSS
56736 projects
javascript
184084 projects - #8 most used programming language
shell
77523 projects
typescript
32286 projects

Projects that are alternatives of or similar to subscribie

drf-stripe-subscription
An out-of-box Django REST framework solution for payment and subscription management using Stripe.
Stars: ✭ 42 (+16.67%)
Mutual labels:  subscription, stripe, payments, billing
Stripe
A comprehensive PHP Library for the Stripe.
Stars: ✭ 256 (+611.11%)
Mutual labels:  subscription, stripe, billing
Gringotts
A complete payment library for Elixir and Phoenix Framework
Stars: ✭ 396 (+1000%)
Mutual labels:  stripe, payments, billing
cashier-register
Cashier Register is a simple quota feature usage tracker for Laravel Cashier subscriptions.
Stars: ✭ 93 (+158.33%)
Mutual labels:  subscription, stripe, saas
recurly
A Recurly API client written in golang. Actively maintained and unit tested. No external dependencies.
Stars: ✭ 40 (+11.11%)
Mutual labels:  subscription, saas, billing
Chip
A drop-in subscription billing UI for Laravel
Stars: ✭ 91 (+152.78%)
Mutual labels:  subscription, stripe, billing
pinax-stripe-light
a payments Django app for Stripe
Stars: ✭ 670 (+1761.11%)
Mutual labels:  stripe, payments, saas
Pinax Stripe
a payments Django app for Stripe
Stars: ✭ 650 (+1705.56%)
Mutual labels:  stripe, payments, saas
Dj Stripe
Django + Stripe Made Easy
Stars: ✭ 1,022 (+2738.89%)
Mutual labels:  stripe, payments, billing
Stripe Billing Typographic
⚡️Typographic is a webfont service (and demo) built with Stripe Billing.
Stars: ✭ 186 (+416.67%)
Mutual labels:  stripe, payments, billing
Memberprism2
open source alternative to memberstack / memberspace , but with both front and backend member-only content protection
Stars: ✭ 171 (+375%)
Mutual labels:  subscription, stripe, saas
wave
Wave - The Software as a Service Starter Kit, designed to help you build the SAAS of your dreams 🚀 💰
Stars: ✭ 3,646 (+10027.78%)
Mutual labels:  subscription, saas
simple-subscribe
Collect emails with a subscription box you can add to any page and build your own independent subscriber base.
Stars: ✭ 67 (+86.11%)
Mutual labels:  subscription, subscription-manager
Google-IAP
Android Library for easing Google Play Billing to your apps with support for Subscriptions, In-App Purchases and Consumables with a beautiful sample app.
Stars: ✭ 129 (+258.33%)
Mutual labels:  subscription, billing
direct-stripe
Stripe payment button for WordPress websites
Stars: ✭ 12 (-66.67%)
Mutual labels:  subscription, stripe
Plans
Laravel Plans is a package for SaaS apps that need management over plans, features, subscriptions, events for plans or limited, countable features.
Stars: ✭ 326 (+805.56%)
Mutual labels:  subscription, saas
Pay
Payments for Ruby on Rails apps
Stars: ✭ 759 (+2008.33%)
Mutual labels:  subscription, stripe
In App Purchase
A Node.js module for in-App-Purchase for iOS, Android, Amazon and Windows.
Stars: ✭ 868 (+2311.11%)
Mutual labels:  subscription, billing
Vue Stripe
Stripe Checkout & Elements for Vue.js
Stars: ✭ 669 (+1758.33%)
Mutual labels:  subscription, stripe
laravel-sibs-payments
Laravel library to communicate with SIBS - Open Payment Platform. The library includes payments: MBWAY, VISA, MASTER, AMEX, VPAY, MAESTRO, VISADEBIT, VISAELECTRON.
Stars: ✭ 30 (-16.67%)
Mutual labels:  payments, sepa

Gitter Recording demo videos Update All Sites Update Onboarding Site testing stripe prod and test webhooks Verify Prod Onbording Login Emails Sending Release

Subscribie - Collect recurring payments easily

Subscribie helps you automatically collect money from your customers, clients and members, without the hassle of manual payments. Save time by having people signup themselves, and easily track payments.

You don't need to be technical, and can integrate it with your existing business by creating your account.

subscribie-intro-video.mp4

Open Source subscription billing and management

Demo

https://footballclub.subscriby.shop/

Video Demos 📹 😎

View video demos

subscriber-Ordering-recurring-plan

-293-subscriber-Ordering-recurring-plan.mp4

What does this project do?

Use Subscribie to collect recurring payments online.

Quickly build a subscription based website, taking weekly/monthly/yearly payments- including one-off charges.

  • You have subscription service(s) to sell (plans)
  • Each of your plans have unique selling points (USPs)
  • Each have a different recurring price, and/or an up-front charge

Demo & Hosting

Don't want/know how to code? Pay for the hosted service.

https://subscribie.co.uk

Developer Quickstart

Quickly run Subscribie from a container:

If you use podman:

podman run -p 8082:80 ghcr.io/subscribie/subscribie/subscribie:latest

Or, if you prefer Docker:

docker run -p 8082:80 ghcr.io/subscribie/subscribie/subscribie:latest

Then visit: http://127.0.0.1:8082/auth/login

Username: [email protected]

Password: password

More about containers.

Why is this project useful?

A lot of the hard work has been done for you. If you're a devloper, you can impress your clients quickly, if you're a small business owner, you might want to try the subscription website hosting service but you can always host it yourself too.

  • Low risk (not very expensive)
  • No coding required
  • Simple: Just enter your plans & prices
  • Upload a picture
  • Uses Stripe for subscriptions & one-off payments

Contributing & Help finding things: Where do I find x? Where is file y?

See CONTRIBUTING.md and quickstart below.

Quickstart (without Docker)

git clone https://github.com/Subscribie/subscribie.git
cd subscribie
cp .env.example .env # Copy default .env settings (read it)
# Read the .env file so you're familiar with the env variables

(Optional) Set database path. Edit .env and set DB_FULL_PATH and SQLALCHEMY_DATABASE_URI. (optional but recommended- do not store data.db in /tmp).

Notice that sqlite:/// starts with three forward slashes. So, if you want to store the database in /home/sam/data.db then, you should put sqlite:////home/sam/data.db (note four /'s)

# Open the .env file, and change the database path to store somewhere else (e.g. your `/home/Documents/data.db` folder):

DB_FULL_PATH="/tmp/data.db"
SQLALCHEMY_DATABASE_URI="sqlite:////tmp/data.db"

Create python environment and run flask:

python3 -m venv venv # Create a python3.x virtual environment
. venv/bin/activate # Activate the virtualenv
pip install -r requirements.txt # Install requirements
export FLASK_APP=subscribie
export FLASK_DEBUG=1
flask db upgrade
flask initdb # (recommended- gives you some example data)

The database file is called data.db. Note, flask initdb inserts pretend data into your database for testing.

Set Stripe API key

You need a Stripe api key.

  1. Create a stripe account
  2. Go to api keys https://dashboard.stripe.com/test/apikeys (test mode)
  3. Copy Publishable key and Secret key
  4. Paste the keys into your .env file:

Edit your .env file

STRIPE_TEST_PUBLISHABLE_KEY=pk_test_<your-Publishable-key>
STRIPE_TEST_SECRET_KEY=sk_test_<your-Secret-key>

Start Subscribie

export FLASK_APP=subscribie
export FLASK_DEBUG=1
flask run

Now visit http://127.0.0.1:5000

Quickstart (with Docker)

If you like to use docker-compose workflow for local development:

git clone https://github.com/Subscribie/subscribie.git
cd subscribie
cp .env.example .env
export COMPOSE_DOCKER_CLI_BUILD=1
export DOCKER_BUILDKIT=1

# Start the container
docker-compose up

# Wait for it to build...

Then visit http://127.0.0.1:5000

To go inside the container, you can do: docker-compose exec web /bin/bash from the project root directory.

Logging & Debugging - How to change the logLevel

Quick: edit your .env file and set PYTHON_LOG_LEVEL=DEBUG.

E.g. to reduce the amount of logs, to WARNING or CRITICAL.

The default log level is DEBUG which means show as much logging information as possible.

The possible values are DEBUG, INFO, WARNING, ERROR, CRITICAL See https://docs.python.org/3/howto/logging.html

Flask does need to be restarted for the log level to change.

How to change theme (theme development)

How to change from the default jesmond theme to the builder theme.

  1. Edit your .env file

Change:

  • THEME_NAME="jesmond" to THEME_NAME="builder"
  • (optional) change TEMPLATE_BASE_DIR if you want to store themes in a different directory.
  1. Stop & start subscribie

  2. Complete. The other theme will now load

Create a new theme

If you're creating a new theme, then change TEMPLATE_BASE_DIR to a directory outside of subscribie root project.

API based authentication with jwt token

Locally

Locally you'll need to create public/private keys for secure jwt authentication.

  1. Generate public/private keys automatically
# Use the commands below to automaticaly create 'private.pem' file and key
openssl genrsa -out private.pem 2048
# Use this command to automatically generate your public.pem
openssl rsa -in private.pem -pubout > public.pem
  1. Update .env file with PRIVATE_KEY and PUBLIC_KEY
PRIVATE_KEY="/path/to/private.pem"
PUBLIC_KEY="/path/to/public.pem"

Logging in via jwt or basic auth

Provide the username & password in a POST request, and a jwt token is returned for use in further requests.

API Basics

Oauth style login:

curl -v -d "[email protected]" -d "password=password" http://127.0.0.1:5000/auth/jwt-login

Http Basic auth login:

curl -v --user "fred:password" http://127.0.0.1:5000/auth/jwt-login

Then use the bearer token in a request to a protect path. e.g.

curl -v -H "Authorization: Bearer <token>" http://127.0.0.1:5000/auth/protected

Get all plans

curl -v -H "Content-Type: application/json" -H "Authorization: Bearer <token> " http://127.0.0.1:5000/api/plans

Create Plan

Example POST request:

    curl -v -H "Content-Type: application/json" 
    -H "Authorization: Bearer <token>" -d '
    {
      "interval_unit": "monthly",
      "interval_amount": "599",
      "sell_price": 0,
      "title": "My title",
      "requirements": {
        "instant_payment": false,
        "subscription": true,
        "note_to_seller_required": false
      },
      "selling_points": [
        {"point":"Quality"}
      ]
    }' http://127.0.0.1:5000/api/plan

Update Plan

Example PUT request:

    curl -v -H 'Content-Type: application/json' -X PUT 
    -d '
    {
      "title":"Coffee", 
      "interval_unit": "monthly", 
      "selling_points": [
        {"point":"Quality"}, 
        {"point": "Unique blend"}
      ], 
      "interval_amount":888, 
      "requirements": {
        "instant_payment": false, 
        "subscription": true, 
        "note_to_seller_required": false}
    }' 
    http://127.0.0.1:5000/api/plan/229

Delete Plan

Example DELETE request:

curl -v -X DELETE -H "Authorization: Bearer <token>" http://127.0.0.1:5000/api/plan/229

How new shops are created

  1. New shop owner submits a form to create a new shop which hits /start-building endpoint
  2. Shop is created and a new shop is started (Shop owner sees "Please wait")
  3. New Shop is ready
  4. Shop owner is automatically redirected to the new shop, loged in using automated one-time login

Saas Deployment

Architecture

Subscribie shop

Every shop owner gets a deployed flask application, with its own database.

stripe-connect-account-announcer

If a Subscribie shop connects to Stripe (it does not have to), then the shop will announce it's Stripe connect id to the stripe-connect-account-announcer.

The stripe-connect-account-announcer stores the Stripe connect id, so that when Stripe webhook events arrive, the stripe-connect-webhook-endpoint-router knows which shop to send the events to.

stripe-connect-webhook-endpoint-router

A Stripe webhook endpoint. Receives Stripe webhook events, which,

  1. Inspects the Stripe connect id from the webhook request
  2. Looks up the Stripe connect id (which has been stored by the stripe-connect-account-announcer)
  3. Forwards the webhook event (e.g. checkout-session-completed) to the correct Subscribie shop
  4. The shop verifies the webhook from Stripe, and processes the event.

Note, in previous implementations there was one webhook endpoint per shop- this isn't compatible with Stripe when using Stripe Connect because there's a limmit on the number of webhooks, and connect events need to be routed based on their Stripe connect id anyway, hence the stripe-connect-webhook-endpoint-router performs this role.

Failure modes:

If the stripe-connect-account-announcer suffers an outage, this means new shops can't announce their Stripe account to stripe-connect-webhook-endpoint-router meaning, when a new Stripe event arrives from Stripe, then, Subscribie's stripe-connect-webhook-endpoint-router would not know which shop to send it to. Stripe automatically retries the delivery of events which allows time for the system to recover in an outage.

Application server: uwsgi

uWSGI is used to run the application services.

Subscribie Saas uses the following key compoent of uwsgi: Emperor mode.

uWSGI Emperor mode starts and manages all running Subscribie shops as uWSGI vassals.

"If the emperor dies, all the vassals die."
-Emperor mode


uWSGI - Emperor - When a new shop is created, the emperor notices a new shop, and starts it as a vassal. - Every Subscribie shop is a vassal of the emperor
uWSGI - vassal-template - A vassal template is injected into every new shop by the emporor. - This avoids having to copy and paste the same config for every new shop. - It also means vassal config is in one place.


Systemd services

subscribie The uWSGI emperor and the vassals it sawns is defined as a single systemd service called `subscribie`.
subscribie-deployer Responsible for listening for new Shop requests, and creating the Shop config which uWSGI needs to spawn a new Shop (aka uwsgi vassal).


Optimisation

Problem: Every shop uses ~45mb of RAM. With lots of Shops the RAM usage can be high. Since shops are not receiving web traffic all the time we can stop them to reduce RAM usage.

Solution: uWSGI vassals are configured to be OnDemandVassals see OnDemandVassals and also socket-activated (note that's two different things):

Result: A reduction of > 17Gb of ram observed on a busy node.

  • OnDemandVassals: The application is not started until the first request is received.
  • Socket-activation: If running idle with no requests after x secconds, the shop is stoped- but is re-activated when a request comes in for the shop

Socker activation is enabled by using the uWSGI feature emperor-on-demand-extension = .socket in the emperor.ini config.

OnDemandVassals is enable by using the following config in the injected vassal config for every shop:

# idle time in seconds
idle = 60
# kill the application after idle time is reached
die-on-idle = true

See: Combining on demand vassals with --idle and --die-on-idle

Subscribie Saas other services

Needed components / services. Check the .env.example for each of them.

Checklist

  • A Redis hostname is set
  • Redis is configured with password authentication
  • Iptables are configured for redis
  • Hostname is setup for stripe-connect-webhook-endpoint-router
  • Hostname is setup for stripe-connect-account-announcer (listening on port 8001 by default)

Where can I get more help, if I need it?

  • Read through all these docs
  • Submit a detailed issue

Docker help

How do I rebuild the container?

Sometimes you need to rebuild the container if you've made changes to the Dockerfile.

docker-compose up --build --force-recreate
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].