首頁 後端開發 Python教學 將 Stripe 整合到單一產品 Django Python 商店中

將 Stripe 整合到單一產品 Django Python 商店中

Sep 18, 2024 pm 10:52 PM

在本系列的第一部分中,我們使用 htmx 建立了一個 Django 線上商店。

在第二部分中,我們將使用 Stripe 處理訂單。

我們會做什麼

我們將整合 Stripe 以安全地處理付款。這就是我們想要實現的目標:

  1. 在購買視圖中,我們首先建立 Stripe 結帳工作階段並將客戶重新導向到對應的 URL。我們在這裡告訴 Stripe 我們正在銷售的產品、數量以及成功購買後客戶應重定向到的位置(success_url)。
  2. 客戶在 Stripe 結帳頁面填寫付款詳細資料並完成付款。然後,Stripe 向我們網站上的 Webhook 端點發出 POST 請求,我們在其中監聽事件並進行相應的處理。如果付款成功,我們會將訂單保存在資料庫中,並通知客戶(以及我們的員工用戶)有關購買的資訊。
  3. 最後,如果 webhook 傳回帶有​​ 200 OK HTTP 狀態碼的回應,Stripe 會重新導向到第一步驟中建立的 success_url。

為我們的 Django Python 商店設定 Stripe

我們首先需要跳到 Stripe 並執行以下操作:

  1. 建立一個 Stripe 帳戶。
  2. 建立產品(帶有付款 ID)。
  3. 建立一個 webhook。

1:建立 Stripe 帳戶

先建立一個 Stripe 帳戶。目前,您實際上不需要啟動您的帳戶。您可以只在測試模式下工作,這將阻止您在測試時進行真正的付款。前往 API 金鑰頁面並檢索可發布金鑰和秘密金鑰。將它們保存在專案環境變數中(STRIPE_PUBLISHABLE_KEY 和 STRIPE_SECRET_KEY)。我們將使用這些金鑰來驗證您的 Stripe 請求。

2:創建您的產品

在產品頁面上建立新產品。填寫詳細資料並將付款類型設定為一次性。您的產品應如下所示:

Integrating Stripe Into A One-Product Django Python Shop

按下新增產品後,您應該能夠在產品清單中看到您的產品。如果您點擊它並向下捲動到定價部分,您可以找到您建立的價格項目的API ID - 它應該類似於price_3ODP5…。將其保存在環境變數 (STRIPE_PRICE_ID) 中:建立 Stripe 結帳會話時將需要它。

3:創建網路鉤子

我們需要建立一個 Webhook 端點,以便 Stripe 在付款完成時呼叫。在webhooks頁面,選擇在本地環境進行測試。這將允許您將請求轉發到本機 URL,例如 http://127.0.0.1:8000。首先下載 Stripe CLI。然後,您可以:

  1. 登入 Stripe
stripe login
登入後複製
  1. 將事件轉送到您將要建立的 Webhook 端點:
stripe listen --forward-to http://127.0.0.1:8000/webhook
> Ready! Your webhook signing secret is whsec_06531a7ba22363ac038f284ac547906b89e5c939f8d55dfd03a3619f9adc590a (^C to quit)
登入後複製

這可確保一旦進行購買,Stripe 會將 Webhook 呼叫轉發到您的本地端點。該命令將記錄一個 Webhook 簽章金鑰,您也應該將其儲存為專案環境變數 (STRIPE_WEBHOOK_SECRET)。這對於驗證請求確實來自 Stripe 並且您正在處理正確的 Webhook 非常有用。

在本節結束時,您應該有四個 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 來載入環境變數。

拓展視野

我們現在需要透過建立結帳會話、成功購買視圖和 Webhook 視圖來擴展視圖以整合 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})
登入後複製

讓我們分解一下:

  1. We first set the Stripe API key.
  2. 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.
  3. 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.
  4. We create a Stripe checkout session with our price ID (the product identifier) and the quantity the customer wants to purchase.
  5. 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>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:

Integrating Stripe Into A One-Product Django Python Shop

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 等函式庫來管理您的電子郵件範本和佇列。
  • 部署網站後,建立一個實際的 Webhook(不是本機偵聽器)。
  • 查看 Stripe 文檔,以了解我們概述的結帳流程的替代方案,包括嵌入式結帳表單。

總結

在這個由兩部分組成的系列中,我們使用 Django、htmx 和 Stripe 成功建立了一個單一產品的電子商務網站。本指南引導您完成 Django 專案的設定、整合 htmx 以實現無縫用戶交互,以及將安全支付與 Stripe 結合。

我們也介紹如何處理訂單處理,包括將訂單資訊儲存到您的資料庫、通知員工使用者新購買的商品以及向您的客戶發送確認電子郵件。有了這些基礎,您可以進一步客製化和擴展您的電子商務網站以滿足您的特定需求。

編碼愉快!

P.S.如果您想在 Python 文章發布後立即閱讀,請訂閱我們的 Python Wizardry 時事通訊,不錯過任何一篇文章!

以上是將 Stripe 整合到單一產品 Django Python 商店中的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1670
14
CakePHP 教程
1428
52
Laravel 教程
1329
25
PHP教程
1274
29
C# 教程
1256
24
Python與C:學習曲線和易用性 Python與C:學習曲線和易用性 Apr 19, 2025 am 12:20 AM

Python更易學且易用,C 則更強大但複雜。 1.Python語法簡潔,適合初學者,動態類型和自動內存管理使其易用,但可能導致運行時錯誤。 2.C 提供低級控制和高級特性,適合高性能應用,但學習門檻高,需手動管理內存和類型安全。

Python和時間:充分利用您的學習時間 Python和時間:充分利用您的學習時間 Apr 14, 2025 am 12:02 AM

要在有限的時間內最大化學習Python的效率,可以使用Python的datetime、time和schedule模塊。 1.datetime模塊用於記錄和規劃學習時間。 2.time模塊幫助設置學習和休息時間。 3.schedule模塊自動化安排每週學習任務。

Python vs.C:探索性能和效率 Python vs.C:探索性能和效率 Apr 18, 2025 am 12:20 AM

Python在開發效率上優於C ,但C 在執行性能上更高。 1.Python的簡潔語法和豐富庫提高開發效率。 2.C 的編譯型特性和硬件控制提升執行性能。選擇時需根據項目需求權衡開發速度與執行效率。

學習Python:2小時的每日學習是否足夠? 學習Python:2小時的每日學習是否足夠? Apr 18, 2025 am 12:22 AM

每天學習Python兩個小時是否足夠?這取決於你的目標和學習方法。 1)制定清晰的學習計劃,2)選擇合適的學習資源和方法,3)動手實踐和復習鞏固,可以在這段時間內逐步掌握Python的基本知識和高級功能。

Python vs. C:了解關鍵差異 Python vs. C:了解關鍵差異 Apr 21, 2025 am 12:18 AM

Python和C 各有優勢,選擇應基於項目需求。 1)Python適合快速開發和數據處理,因其簡潔語法和動態類型。 2)C 適用於高性能和系統編程,因其靜態類型和手動內存管理。

Python標準庫的哪一部分是:列表或數組? Python標準庫的哪一部分是:列表或數組? Apr 27, 2025 am 12:03 AM

pythonlistsarepartofthestAndArdLibrary,herilearRaysarenot.listsarebuilt-In,多功能,和Rused ForStoringCollections,而EasaraySaraySaraySaraysaraySaraySaraysaraySaraysarrayModuleandleandleandlesscommonlyusedDduetolimitedFunctionalityFunctionalityFunctionality。

Python:自動化,腳本和任務管理 Python:自動化,腳本和任務管理 Apr 16, 2025 am 12:14 AM

Python在自動化、腳本編寫和任務管理中表現出色。 1)自動化:通過標準庫如os、shutil實現文件備份。 2)腳本編寫:使用psutil庫監控系統資源。 3)任務管理:利用schedule庫調度任務。 Python的易用性和豐富庫支持使其在這些領域中成為首選工具。

Web開發的Python:關鍵應用程序 Web開發的Python:關鍵應用程序 Apr 18, 2025 am 12:20 AM

Python在Web開發中的關鍵應用包括使用Django和Flask框架、API開發、數據分析與可視化、機器學習與AI、以及性能優化。 1.Django和Flask框架:Django適合快速開發複雜應用,Flask適用於小型或高度自定義項目。 2.API開發:使用Flask或DjangoRESTFramework構建RESTfulAPI。 3.數據分析與可視化:利用Python處理數據並通過Web界面展示。 4.機器學習與AI:Python用於構建智能Web應用。 5.性能優化:通過異步編程、緩存和代碼優

See all articles