diff --git a/.vscode/launch.json b/.vscode/launch.json index dd0f9712..310cd2e8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,6 +10,13 @@ "request": "launch", "program": "${workspaceRoot}/launcher.py", "console": "internalConsole" + }, + { + "name": "Run Server", + "type": "python", + "request": "launch", + "program": "${workspaceRoot}/server.py", + "console": "internalConsole" } ] } \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 20c6a803..fbd77981 100644 --- a/poetry.lock +++ b/poetry.lock @@ -173,6 +173,7 @@ version = "1.1.2a0" reference = "2f5fc749cc6edb0fdef81f885d1f2d536616a458" type = "git" url = "https://github.com/poketwo/discord-ext-ipc" + [[package]] category = "main" description = "A Discord.py extension allowing you to pass flags as arguments." @@ -473,6 +474,7 @@ whoosh = ">=2.5,<2.7" reference = "b09929dfb636d2b0337edbfe6761496c7d435965" type = "git" url = "https://github.com/veekun/pokedex.git" + [[package]] category = "main" description = "A pure-Python implementation of the HTTP/2 priority tree" @@ -604,6 +606,17 @@ postgresql_psycopg2binary = ["psycopg2-binary"] postgresql_psycopg2cffi = ["psycopg2cffi"] pymysql = ["pymysql"] +[[package]] +category = "main" +description = "Python bindings for the Stripe API" +name = "stripe" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.51.0" + +[package.dependencies] +requests = {version = ">=2.20", markers = "python_version >= \"3.0\""} + [[package]] category = "main" description = "Simple sunset and sunrise time calculation python library" @@ -732,7 +745,7 @@ idna = ">=2.0" multidict = ">=4.0" [metadata] -content-hash = "fca8fec5b839c52181836312d415598d46997b24f3a2261f535bf63474a2461c" +content-hash = "2c64a8158de9c7ef5e580b764c3979fe2f9e83b091088e7abd77013c6da4d8f9" lock-version = "1.1" python-versions = "^3.8" @@ -1123,6 +1136,10 @@ sqlalchemy = [ {file = "SQLAlchemy-1.3.19-cp38-cp38-win_amd64.whl", hash = "sha256:83469ad15262402b0e0974e612546bc0b05f379b5aa9072ebf66d0f8fef16bea"}, {file = "SQLAlchemy-1.3.19.tar.gz", hash = "sha256:3bba2e9fbedb0511769780fe1d63007081008c5c2d7d715e91858c94dbaa260e"}, ] +stripe = [ + {file = "stripe-2.51.0-py2.py3-none-any.whl", hash = "sha256:67f9887ac80411a43fc0d20680760b10bd06506f03df0b7fade284d97ffa2bcf"}, + {file = "stripe-2.51.0.tar.gz", hash = "sha256:ed0e58eeb2f154c7165225e64059145c7e0bd0a31607112f494db41e51effe7c"}, +] suntime = [ {file = "suntime-1.2.5-py3-none-any.whl", hash = "sha256:d957e9ca786ab3cd80bf624b007fed7d07f07c6fa33f3ccc5ec34c9bb0c380c6"}, {file = "suntime-1.2.5-py3.7.egg", hash = "sha256:ac03cc8bb6e6457c946139e24928300762e60236e8623f3e0e5f4944a582e0dd"}, diff --git a/pyproject.toml b/pyproject.toml index 5ae00f62..8d69a309 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,6 +22,7 @@ humanfriendly = "^8.2" unidecode = "^1.1.1" discord-flags = "^2.1.1" quart = "^0.13.1" +stripe = "^2.51.0" [tool.poetry.dev-dependencies] black = {version = "^20.8b1", allow-prereleases = true} diff --git a/server.py b/server.py index e9023e1d..4e308d7b 100644 --- a/server.py +++ b/server.py @@ -4,15 +4,29 @@ from datetime import datetime, timedelta from functools import wraps +import stripe from discord.ext.ipc import Client from motor.motor_asyncio import AsyncIOMotorClient from quart import Quart, request -loop = asyncio.get_event_loop() +# Constants + +purchase_amounts = { + 500: 500, + 1000: 1100, + 2000: 2420, + 4000: 5324, +} + +# Setup +stripe.api_key = os.getenv("STRIPE_KEY") +endpoint_secret = os.getenv("STRIPE_WEBHOOK_SECRET") app = Quart(__name__) web_ipc = Client(secret_key=os.getenv("SECRET_KEY")) + +loop = asyncio.get_event_loop() db = AsyncIOMotorClient(os.getenv("DATABASE_URI"), io_loop=loop)[ os.getenv("DATABASE_NAME") ] @@ -188,5 +202,31 @@ async def dbl(): return "Success", 200 +@app.route("/purchase", methods=["POST"]) +async def purchase(): + try: + event = stripe.Webhook.construct_event( + await request.get_data(), + request.headers["Stripe-Signature"], + endpoint_secret, + ) + except ValueError as e: + return "Invalid Payload", 400 + except stripe.error.SignatureVerificationError as e: + return "Invalid Signature", 400 + + if event.type != "payment_intent.succeeded": + return "Invalid Event", 400 + + session = event.data.object + uid = int(session["metadata"]["id"]) + amount = session["amount"] + shards = purchase_amounts[amount] + + await db.member.update_one({"_id": uid}, {"$inc": {"premium_balance": shards}}) + + return "Success", 200 + + if __name__ == "__main__": app.run(loop=loop)