Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bill Users for Paid Accounts #61

Merged
merged 7 commits into from Aug 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions .env
Expand Up @@ -10,5 +10,5 @@ SERVER_NAME=localhost:5000
MIN_CALVER=2019.4.18.2
SSH_KEY=~/.ssh/id_rsa.pub
CONFIRM_URL=http://localhost:5000/account/confirm/{0}
STRIPE_KEY="sk_test_123"
STRIPE_PRODUCT_ID="paid"
STRIPE_KEY="sk_test_12345"
STRIPE_ENDPOINT="https://api.stripe.com"
2 changes: 1 addition & 1 deletion .projections.json
Expand Up @@ -13,7 +13,7 @@
},
"app/jobs/*.py": {
"type": "job",
"alternate": "tests/functional/jobs/{dirname}/test_{basename}_job.py"
"alternate": "tests/functional/jobs/{dirname}/test_{basename}.py"
},
"app/__init__.py": {
"type": "init"
Expand Down
5 changes: 4 additions & 1 deletion Pipfile
Expand Up @@ -16,6 +16,8 @@ vcrpy = "*"
pytest-vcr = "*"
ipython = "~=6.5"
factory_boy = "~=2.11"
flask-shell-ipython = "*"
pylint = "*"

[packages]
alembic = "==1.0.0"
Expand All @@ -33,7 +35,6 @@ decorator = "==4.3.0"
docker = "==3.5.0"
docker-pycreds = "==0.3.0"
idna = "==2.5"
inflection = "==0.3.1"
itsdangerous = "==0.24"
jsonschema = "~=3.0"
marshmallow = "*"
Expand Down Expand Up @@ -96,6 +97,8 @@ dnspython = "*"
flask-limiter = "*"
pytest-random-order = "*"
stripe = "*"
inflection = "~=0.3"
mypy-extensions = "*"
flask-redis = "*"

[requires]
Expand Down
89 changes: 89 additions & 0 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Taskfile.yml
Expand Up @@ -92,7 +92,7 @@ tasks:
- sleep 3
- docker-compose exec db createdb -U postgres holepunch_development
- docker-compose exec db createdb -U postgres holepunch_test
- docker-compose run web flask db upgrade
- docker-compose run web python -m flask db upgrade
- docker-compose run web python -m flask plan populate
- docker-compose run web python -m flask redis populate

Expand Down Expand Up @@ -317,3 +317,4 @@ tasks:
ANSIBLE_VAULT_PATH: "{{.ANSIBLE_VAULT_PATH}}"
WORKSPACE: "{{.WORKSPACE}}"
HOOK: "{{.HOOK}} post"

4 changes: 2 additions & 2 deletions app/__init__.py
Expand Up @@ -18,6 +18,8 @@
import rollbar.contrib.flask
import stripe
import logging
import app.settings as settings

from packaging import version

from app.utils.json import JSONSchemaManager, json_api
Expand Down Expand Up @@ -50,8 +52,6 @@ def load_corpus():


def create_app(env: str = "development"):
import app.settings as settings

app = Flask(__name__)
app.config.from_object(settings.app_config[env])

Expand Down
64 changes: 24 additions & 40 deletions app/commands.py
@@ -1,46 +1,15 @@
import stripe
import click
import json
from flask.cli import with_appcontext
from flask import current_app
from app.models import Plan
from app import db, redis_client
from stripe.error import InvalidRequestError

LIMITS = {
"free": {
"tunnel_count": 1,
"bandwidth": 100,
"forwards": 2,
"reserved_subdomains": 0,
"cost": 0,
},
"waiting": {
"tunnel_count": 0,
"bandwidth": 0,
"forwards": 0,
"reserved_subdomains": 0,
"cost": 0,
},
"beta": {
"tunnel_count": 2,
"bandwidth": 1000,
"forwards": 10,
"reserved_subdomains": 1,
"cost": 0,
},
"paid": {
"tunnel_count": 5,
"bandwidth": 100_000,
"forwards": 9999,
"reserved_subdomains": 5,
"cost": 999,
},
"admin": {
"tunnel_count": 5,
"bandwidth": 100_000,
"forwards": 9999,
"reserved_subdomains": 50,
"cost": 0,
},
}

with open("support/plans.json") as plans:
LIMITS = json.load(plans)


@click.group()
Expand All @@ -57,20 +26,34 @@ def create_product_command():

def create_product():
""" Create Stripe Products for Holepunch """

try:
stripe.Product.retrieve("holepunch")
except InvalidRequestError:
stripe.Product.create(name="Holepunch.io", type="service", id="holepunch")

for plan in Plan.query.all():
if plan.cost == 0:
continue

stripe.Product.create(name="Holepunch.io", type="service", id=plan.name)
if plan.stripe_id:
try:
stripe.Plan.retrieve(plan.stripe_id)
current_app.logger.info(
f"Skipping `{plan.name}` as it already exists on Stripe"
)
except InvalidRequestError:
pass # expected for plans not created yet

stripe_plan = stripe.Plan.create(
product=plan.name,
product="holepunch",
nickname=f"Holepunch Service: {plan.name}",
interval="month",
currency="usd",
amount=plan.cost,
)

plan.stripe_id = stripe_plan["product"]
plan.stripe_id = stripe_plan["id"]
db.session.add(plan)

db.session.commit()
Expand All @@ -84,6 +67,7 @@ def populate_command():

def populate():
""" Create DB Entries for Holepunch Plans"""
global LIMITS

for plan_name, plan in LIMITS.items():
p = Plan(**{"name": plan_name}, **plan)
Expand Down