이 시리즈의 첫 번째 부분에서는 htmx를 사용하여 Django 온라인 상점을 만들었습니다.
이번 2부에서는 Stripe를 이용해 주문을 처리해보겠습니다.
우리가 할 일
Stripe를 통합하여 결제를 안전하게 처리할 예정입니다. 이것이 우리가 달성하고자 하는 것입니다:
- 구매 보기에서는 먼저 Stripe 결제 세션을 생성하고 고객을 해당 URL로 리디렉션합니다. 여기에서 Stripe에게 판매하는 제품, 수량, 성공적인 구매 후 고객이 리디렉션되어야 하는 위치(성공 URL)에 대해 알려줍니다.
- 고객이 Stripe 결제 페이지에서 결제 세부정보를 입력하고 결제를 완료합니다. 그런 다음 Stripe는 웹사이트의 웹훅 엔드포인트에 POST 요청을 하고, 여기서 이벤트를 수신하고 이에 따라 처리합니다. 결제가 성공적으로 이루어지면 데이터베이스에 주문을 저장하고 고객(및 직원 사용자)에게 구매 사실을 알립니다.
- 마지막으로 웹훅이 200 OK HTTP 상태 코드로 응답을 반환하면 Stripe는 첫 번째 단계에서 생성된 성공 URL로 리디렉션됩니다.
Django Python Store를 위한 Stripe 설정
먼저 Stripe로 이동하여 다음을 수행해야 합니다.
- 스트라이프 계정을 만드세요.
- (결제 ID로) 제품을 만듭니다.
- 웹훅을 생성하세요.
1: 스트라이프 계정 만들기
Stripe 계정을 만드는 것부터 시작하세요. 지금은 실제로 계정을 활성화할 필요가 없습니다. 테스트 모드에서만 작업할 수 있으며, 이렇게 하면 테스트하는 동안 실제 결제를 할 수 없습니다. API 키 페이지로 이동하여 게시 가능 키와 비밀 키를 검색하세요. 프로젝트 환경 변수(STRIPE_PUBLISHABLE_KEY 및 STRIPE_SECRET_KEY)에 저장하세요. 이 키를 사용하여 Stripe 요청을 인증합니다.
2: 제품 만들기
제품 페이지에서 새 제품을 생성하세요. 세부 사항을 입력하고 결제 유형을 일회성으로 설정하세요. 귀하의 제품은 다음과 같아야 합니다.
상품 추가를 누르면 상품 목록에서 해당 상품을 확인할 수 있습니다. 이를 클릭하고 가격 섹션까지 아래로 스크롤하면 생성한 가격 항목에 대한 API ID를 찾을 수 있습니다. 가격_3ODP5…와 비슷해야 합니다. 환경 변수(STRIPE_PRICE_ID)에 저장하세요. Stripe 체크아웃 세션을 생성할 때 필요합니다.
3: 웹훅 생성
결제가 완료되면 Stripe가 호출할 웹훅 엔드포인트를 생성해야 합니다. Webhooks 페이지에서 로컬 환경에서 테스트하도록 선택합니다. 이렇게 하면 요청을 http://127.0.0.1:8000과 같은 로컬 URL로 전달할 수 있습니다. Stripe CLI를 다운로드하여 시작하세요. 그런 다음 다음을 수행할 수 있습니다.
- Stripe에 로그인
stripe login
- 만들려는 웹훅 엔드포인트로 이벤트를 전달합니다.
stripe listen --forward-to http://127.0.0.1:8000/webhook > Ready! Your webhook signing secret is whsec_06531a7ba22363ac038f284ac547906b89e5c939f8d55dfd03a3619f9adc590a (^C to quit)
이렇게 하면 구매가 완료되면 Stripe가 웹훅 호출을 로컬 엔드포인트로 전달합니다. 이 명령은 웹훅 서명 비밀을 기록하며, 이를 프로젝트 환경 변수(STRIPE_WEBHOOK_SECRET)로도 저장해야 합니다. 이는 요청이 실제로 Stripe에서 왔는지, 올바른 웹훅을 처리하고 있는지 확인하는 데 유용할 것입니다.
이 섹션이 끝나면 4개의 Stripe 환경 변수가 있어야 합니다. 이제 ecommerce_site/settings.py에서 로드할 수 있습니다:
# ecommerce_site/settings.py import os from dotenv import load_dotenv load_dotenv() STRIPE_PUBLISHABLE_KEY = os.environ.get("STRIPE_PUBLISHABLE_KEY") STRIPE_SECRET_KEY = os.environ.get("STRIPE_SECRET_KEY") STRIPE_PRICE_ID = os.environ.get("STRIPE_PRICE_ID") STRIPE_WEBHOOK_SECRET = os.environ.get("STRIPE_WEBHOOK_SECRET")
참고: python-dotenv를 사용하여 환경 변수를 로드하고 있습니다.
뷰 확장
이제 체크아웃 세션, 성공적인 구매 뷰, 웹훅 뷰를 생성하여 Stripe을 통합하기 위한 뷰를 확장해야 합니다.
1: Stripe 체크아웃 세션 생성
구매 보기에서 구매 양식이 유효한 경우 Stripe 결제 세션을 생성합니다.
# ecommerce/views.py from django_htmx import HttpResponseClientRedirect from django.conf import settings import stripe @require_POST def purchase(request): form = OrderForm(request.POST) if form.is_valid(): quantity = form.cleaned_data["quantity"] # replace time.sleep(2) with the following code ⬇️ # 1 - set stripe api key stripe.api_key = settings.STRIPE_SECRET_KEY # 2 - create success url success_url = ( request.build_absolute_uri( reverse("purchase_success") ) + "?session_id={CHECKOUT_SESSION_ID}" ) # 3 - create cancel url cancel_url = request.build_absolute_uri(reverse("home")) # 4 - create checkout session checkout_session = stripe.checkout.Session.create( line_items=[ { "price": settings.STRIPE_PRICE_ID, "quantity": quantity, } ], mode="payment", success_url=success_url, cancel_url=cancel_url ) # 5 - redirect to checkout session url return HttpResponseClientRedirect(checkout_session.url) return render(request, "product.html", {"form": form})
이를 분석해 보겠습니다.
- We first set the Stripe API key.
- We then create a successful purchase URL pointing to the purchase_success view (which we'll create in the next step). Stripe should automatically populate the CHECKOUT_SESSION_ID.
- We create a URL for when a purchase is canceled — for example, when the customer changes their mind. In this case, it’s just the home view.
- We create a Stripe checkout session with our price ID (the product identifier) and the quantity the customer wants to purchase.
- Stripe returns a session object from which we can extract the URL and redirect the customer. Since this request is coming from htmx, we can’t really use the standard Django redirect function. Instead, we use the django-htmx package, which provides this HttpResponseClientRedirect class.
2: Create the Successful Purchase View
After completing the purchase, Stripe will redirect the customer to our specified success_url. Here, we can handle the post-purchase logic:
from django.shortcuts import redirect def purchase_success(request): session_id = request.GET.get("session_id") if session_id is None: return redirect("home") stripe.api_key = settings.STRIPE_SECRET_KEY try: stripe.checkout.Session.retrieve(session_id) except stripe.error.InvalidRequestError: messages.error(request, "There was a problem while buying your product. Please try again.") return redirect("home") return render(request, "purchase_success.html")
In this view, we first check if the session_id query parameter is present. If it is, we retrieve the corresponding session from Stripe using the secret key and the session_id. We then render the successful purchase template, which looks like this:
# ecommerce/templates/purchase_success.html {% extends "base.html" %} {% block content %} <section> <header> <h2 id="Thank-you-for-your-purchase">Thank you for your purchase</h2> <p> Your purchase was successful. You will receive an email with the details of your purchase soon. </p> </header> </section> {% endblock %}
You should also add it to the urlpatterns:
# ecommerce_site/urls.py # ... same imports as before urlpatterns = [ # ... same urls as before path("purchase_success", views.purchase_success, name="purchase_success"), # ⬅️ new ]
3: Create the Webhook View
While the customer is in the purchase process, and before they are redirected to the success view, Stripe will call our webhook endpoint (remember to have the webhook listener running, as explained in the earlier 'Create the Webhook' section of this post):
from django.views.decorators.csrf import csrf_exempt from django.http import HttpResponse @csrf_exempt def webhook(request): stripe.api_key = settings.STRIPE_SECRET_KEY sig_header = request.headers.get('stripe-signature') payload = request.body event = None try: event = stripe.Webhook.construct_event( payload, sig_header, settings.STRIPE_WEBHOOK_SECRET ) except stripe.error.SignatureVerificationError: # Invalid signature return HttpResponse(status=400) # Handle the checkout.session.completed event if event.type == "checkout.session.completed": # TODO: create line orders return HttpResponse(status=200) return HttpResponse(status=400)
Let’s break this down:
- We try to construct a Stripe event from the payload, the signature header, and the webhook secret: the first is used to build the actual event, and the last two variables are relevant to validate the authenticity of the request.
- If the signature verification fails, we return a 400 HTTP response. Remember that Stripe is actually calling this endpoint, not our customer, so Stripe will know what to do in this scenario.
- We check if the event type is checkout.session.completed, i.e., if a customer successfully paid for our product. For now, we don’t do much else here, but we will process the order in the next step.
Note: A Stripe event can have multiple types but we will only handle completed sessions in this post. However, you can (and should) extend a webhook by following the docs.
You should also add this view to urlpatterns:
# ecommerce_site/urls.py # ... same imports as before urlpatterns = [ # ... same urls as before path("webhook", views.webhook, name="webhook"), # ⬅️ new ]
If everything works well, once you click “buy”, you should be redirected to a Stripe payment page. Since we are in test mode, we can fill in the payment details with dummy data, like a 4242 4242 4242 4242 card:
Once you press Pay, Stripe should call the webhook view and redirect you to the purchase_success view. Congratulations, you have successfully processed a payment with Stripe!
Create the Orders and Notify Users
Once a purchase is completed, we need to do a few things in the webhook view:
- Save the order information in our database.
- Notify staff users about the recent purchase.
- Send a confirmation email to the customer.
Let’s create a LineOrder database model in ecommerce/models.py to store some of the order information:
# ecommerce/models.py from django.db import models class LineOrder(models.Model): quantity = models.IntegerField() name = models.CharField(max_length=255, null=True, blank=True) email = models.EmailField(null=True, blank=True) shipping_details = models.TextField(null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return f"Order {self.id} - {self.quantity} units"
Remember to create and run the migrations:
python manage.py makemigrations # ⬅️ creates the migration files python manage.py migrate # ⬅️ applies the migrations in the database
We can now create a function to process the orders and call it from the webhook view:
# ecommerce/views.py @csrf_exempt def webhook(request): # ...same code as before if event.type == "checkout.session.completed": create_line_orders(event.data.object) # ⬅️ new return HttpResponse(status=200) return HttpResponse(status=400) # new ⬇️ def create_line_orders(session: stripe.checkout.Session): line_items = stripe.checkout.Session.list_line_items(session.id) for line_item in line_items.data: LineOrder.objects.create( name=session.customer_details.name, email=session.customer_details.email, shipping_details=session.shipping_details, quantity=line_item.quantity, ) mail.send_mail( "Your order has been placed", f""" Hi {session.customer_details.name}, Your order has been placed. Thank you for shopping with us! You will receive an email with tracking information shortly. Best, The one product e-commerce Team """, "from@example.com", [session.customer_details.email], ) staff_users = User.objects.filter(is_staff=True) mail.send_mail( "You have a new order!", """ Hi team! You have a new order in your shop! go to the admin page to see it. Best, The one product e-commerce Team """, "from@example.com", [user.email for user in staff_users], )
Let’s break this down:
- We first create line order instances from the Stripe session and send a confirmation email to the customer about their purchase.
- We then send an email to all staff users telling them to check the admin panel.
You can now register the LineOrder model in the admin panel, so it’s accessible to staff users:
# ecommerce/admin.py from django.contrib import admin from ecommerce.models import LineOrder # Register your models here. admin.site.register(LineOrder)
When staff users log in to the admin page, they will now be able to check new orders and process them accordingly — in this case, pack and ship mugs to the customer!
Some Tips to Optimize Your Django Store
Here are some tips to further improve on the store you've built:
- 테스트 작성 - GitHub 저장소에서 몇 가지 예를 볼 수 있습니다.
- 판매할 제품이 더 있으면 해당 제품에 대한 데이터베이스 모델을 생성하고 ForeignKey를 통해 LineOrder를 연결하세요.
- Django의 이메일 문서에 따라 이메일 설정을 구성하세요. django-post-office와 같은 라이브러리를 사용하여 이메일 템플릿과 대기열을 관리할 수도 있습니다.
- 웹사이트를 배포한 후 실제 웹훅을 생성합니다(로컬 리스너가 아님).
- 삽입된 체크아웃 양식을 포함하여 우리가 설명한 체크아웃 프로세스에 대한 대안을 보려면 Stripe 문서를 살펴보세요.
마무리
2부로 구성된 이 시리즈에서는 Django, htmx, Stripe을 사용하여 단일 제품 전자상거래 사이트를 성공적으로 구축했습니다. 이 가이드에서는 Django 프로젝트 설정, 원활한 사용자 상호 작용을 위한 htmx 통합, Stripe과 안전한 결제 통합 등을 안내했습니다.
또한 주문 정보를 데이터베이스에 저장하고 직원에게 새로운 구매에 대해 알리고 고객에게 확인 이메일을 보내는 등 주문 처리를 처리하는 방법도 다루었습니다. 이러한 기반을 바탕으로 특정 요구 사항에 맞게 전자상거래 사이트를 더욱 맞춤화하고 확장할 수 있습니다.
즐거운 코딩하세요!
P.S. Python 게시물이 보도되자마자 읽고 싶다면 Python Wizardry 뉴스레터를 구독하고 게시물 하나도 놓치지 마세요!
위 내용은 Stripe를 단일 제품 Django Python Shop에 통합의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

Tomergelistsinpython, youcanusethe operator, extendmethod, listcomprehension, oritertools.chain, 각각은 각각의 지위를 불러 일으킨다

Python 3에서는 다양한 방법을 통해 두 개의 목록을 연결할 수 있습니다. 1) 작은 목록에 적합하지만 큰 목록에는 비효율적입니다. 2) 메모리 효율이 높지만 원래 목록을 수정하는 큰 목록에 적합한 확장 방법을 사용합니다. 3) 원래 목록을 수정하지 않고 여러 목록을 병합하는 데 적합한 * 운영자 사용; 4) 메모리 효율이 높은 대형 데이터 세트에 적합한 itertools.chain을 사용하십시오.

join () 메소드를 사용하는 것은 Python의 목록에서 문자열을 연결하는 가장 효율적인 방법입니다. 1) join () 메소드를 사용하여 효율적이고 읽기 쉽습니다. 2)주기는 큰 목록에 비효율적으로 운영자를 사용합니다. 3) List Comprehension과 Join ()의 조합은 변환이 필요한 시나리오에 적합합니다. 4) READE () 방법은 다른 유형의 감소에 적합하지만 문자열 연결에 비효율적입니다. 완전한 문장은 끝납니다.

pythonexecutionissprocessoftransformingpythoncodeintoExecutableInstructions.1) the -interreadsTheCode, ConvertingItintoByTecode, thethepythonVirtualMachine (pvm)을 실행합니다

Python의 주요 특징은 다음과 같습니다. 1. 구문은 간결하고 이해하기 쉽고 초보자에게 적합합니다. 2. 개발 속도 향상, 동적 유형 시스템; 3. 여러 작업을 지원하는 풍부한 표준 라이브러리; 4. 광범위한 지원을 제공하는 강력한 지역 사회와 생태계; 5. 스크립팅 및 빠른 프로토 타이핑에 적합한 해석; 6. 다양한 프로그래밍 스타일에 적합한 다중-파라 디그 지원.

Python은 해석 된 언어이지만 편집 프로세스도 포함됩니다. 1) 파이썬 코드는 먼저 바이트 코드로 컴파일됩니다. 2) 바이트 코드는 Python Virtual Machine에 의해 해석되고 실행됩니다. 3)이 하이브리드 메커니즘은 파이썬이 유연하고 효율적이지만 완전히 편집 된 언어만큼 빠르지는 않습니다.

USEAFORLOOPHENTERATINGOVERASERASERASPECIFICNUMBEROFTIMES; USEAWHILLOOPWHENTINUTIMONDITINISMET.FORLOOPSAREIDEALFORKNOWNSEDINGENCENCENS, WHILEWHILELOOPSSUITSITUATIONS WITHERMINGEDERITERATIONS.

Pythonloopscanleadtoerrors likeinfiniteloops, modifyinglistsdizeration, off-by-by-byerrors, zero-indexingissues, andnestedloopineficiencies.toavoidthese : 1) aing'i


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

WebStorm Mac 버전
유용한 JavaScript 개발 도구

mPDF
mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

맨티스BT
Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

ZendStudio 13.5.1 맥
강력한 PHP 통합 개발 환경