From 9041ecd2063923d304ca66d2d297a1005a1211eb Mon Sep 17 00:00:00 2001 From: Artur Borecki Date: Wed, 6 May 2026 19:27:00 +0200 Subject: [PATCH] feat: first stripe imp --- home/templates/home/course_page.html | 5 +++- kursy/urls.py | 2 +- purchase/stripe_client.py | 37 ++++++++++++++++++++++++++++ purchase/templates/success.html | 12 +++++++++ purchase/urls.py | 2 ++ purchase/views.py | 11 +++++++++ pyproject.toml | 1 + uv.lock | 15 +++++++++++ 8 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 purchase/stripe_client.py create mode 100644 purchase/templates/success.html diff --git a/home/templates/home/course_page.html b/home/templates/home/course_page.html index b54619c..13b7fe6 100644 --- a/home/templates/home/course_page.html +++ b/home/templates/home/course_page.html @@ -52,7 +52,10 @@ {% else %}

{% trans "You don't have access to this course. Please purchase it to view the modules." %}

- {% trans "Purchase Course" %} +
+ {% csrf_token %} + +
{% endif %} {% endblock content %} diff --git a/kursy/urls.py b/kursy/urls.py index 7c560df..453b43d 100644 --- a/kursy/urls.py +++ b/kursy/urls.py @@ -22,7 +22,7 @@ urlpatterns = [ path("i18n/", include("django.conf.urls.i18n")), path("oauth2/", include("oauth2_provider.urls", namespace="oauth2_provider")), path("", include("home.urls")), - path("", include("purchase.urls")), + path("purchase/", include("purchase.urls")), path("calendar/", views.calendar, name="calendar"), # TODO: move occurrence related urls to home app path( diff --git a/purchase/stripe_client.py b/purchase/stripe_client.py new file mode 100644 index 0000000..1edcc3f --- /dev/null +++ b/purchase/stripe_client.py @@ -0,0 +1,37 @@ +import os + +import stripe +from django.conf import settings +from django.http import HttpResponse, request +from django.shortcuts import redirect +from django.urls import reverse + + +class StripeClient: + def __init__(self, api_key: str): + self.api_key = api_key + + self.stripe = stripe.StripeClient(api_key=self.api_key) + + def create_checkout_session(self, price_id: str): + try: + checkout_session = self.stripe.v1.checkout.sessions.create( + params={ + "line_items": [ + { + "price": price_id, + "quantity": 1, + }, + ], + "mode": "payment", + # "success_url": f"http://{Site.objects.get_current().domain}{reverse('purchase_success')}", + "success_url": f"http://localhost:8000{reverse('purchase_success')}", + } + ) + except Exception as e: + return HttpResponse(str(e)) + + return redirect(checkout_session.url, code=303) + + +stripe_client = StripeClient(api_key=os.getenv("STRIPE_SECRET_KEY")) diff --git a/purchase/templates/success.html b/purchase/templates/success.html new file mode 100644 index 0000000..f06df5d --- /dev/null +++ b/purchase/templates/success.html @@ -0,0 +1,12 @@ +{% extends 'base.html' %} + +{% block content %} +
+
+
+

BRAWO KURWA!!!!

+

WYDAŁEŚ PIENIĄDZE NA JAKIEŚ TOTALNE GÓWNO!!!!

+
+
+
+{% endblock %} diff --git a/purchase/urls.py b/purchase/urls.py index 275378c..46d030b 100644 --- a/purchase/urls.py +++ b/purchase/urls.py @@ -13,4 +13,6 @@ urlpatterns = [ views.mock_refund_purchase, name="mock_refund_purchase", ), + path("test-purchase/", views.test_purchase, name="test_purchase"), + path("success/", views.purchase_success, name="purchase_success"), ] diff --git a/purchase/views.py b/purchase/views.py index 51402c6..df68136 100644 --- a/purchase/views.py +++ b/purchase/views.py @@ -1,7 +1,9 @@ from django.shortcuts import redirect, render from django.urls import reverse +from django.views.decorators.http import require_POST from home.models import CoursePage +from purchase.stripe_client import stripe_client from purchase.models import CoursePurchase @@ -19,3 +21,12 @@ def mock_refund_purchase(request, purchase_id): purchase.mock_refund() return redirect(purchase.course.url) + + +@require_POST +def test_purchase(request): + return stripe_client.create_checkout_session("price_1TU8ZqK3lJAo3tbKX3T1jsBg") + + +def purchase_success(request): + return render(request, "success.html") diff --git a/pyproject.toml b/pyproject.toml index 777f08d..c5f999f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ dependencies = [ "gunicorn>=25.3.0", "python-dotenv>=1.2.2", "slippers>=0.6.2", + "stripe>=15.1.0", "uvicorn>=0.42.0", "uvicorn-worker>=0.4.0", "wagtail==7.3rc1", diff --git a/uv.lock b/uv.lock index 6db8cfd..7d795f5 100644 --- a/uv.lock +++ b/uv.lock @@ -537,6 +537,7 @@ dependencies = [ { name = "gunicorn" }, { name = "python-dotenv" }, { name = "slippers" }, + { name = "stripe" }, { name = "uvicorn" }, { name = "uvicorn-worker" }, { name = "wagtail" }, @@ -557,6 +558,7 @@ requires-dist = [ { name = "gunicorn", specifier = ">=25.3.0" }, { name = "python-dotenv", specifier = ">=1.2.2" }, { name = "slippers", specifier = ">=0.6.2" }, + { name = "stripe", specifier = ">=15.1.0" }, { name = "uvicorn", specifier = ">=0.42.0" }, { name = "uvicorn-worker", specifier = ">=0.4.0" }, { name = "wagtail", specifier = "==7.3rc1" }, @@ -898,6 +900,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/49/4b/359f28a903c13438ef59ebeee215fb25da53066db67b305c125f1c6d2a25/sqlparse-0.5.5-py3-none-any.whl", hash = "sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba", size = 46138, upload-time = "2025-12-19T07:17:46.573Z" }, ] +[[package]] +name = "stripe" +version = "15.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "requests" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/45/26/5d6f5f5beae6f1ff78213e2e6f4fbd431518dcd98733cdd39fb4ba0d01d3/stripe-15.1.0.tar.gz", hash = "sha256:24bd3b6bd0969a4841bd4d7681556a9e35e46c414a07c8590a225fbd5a878450", size = 1501673, upload-time = "2026-04-24T00:18:58.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d8/4e/fd9cb74ddf1e61fb6241e2f6799a81ef99bf6cf2e94f8812ee1cd5458e5d/stripe-15.1.0-py3-none-any.whl", hash = "sha256:bdfb556be08662a41833e6403607ebf12e0062cae4f9b93e2b89b6ba926d7c82", size = 2143199, upload-time = "2026-04-24T00:18:56.027Z" }, +] + [[package]] name = "telepath" version = "0.3.1"