基本Django Stripe Subscriptionsを参考にする。
Contents
model設定で以下のエラーが出た場合
ERRORS:
subscriptions.StripeCustomer.user: (fields.E301) Field defines a relation with the model ‘auth.User’, which has been swapped out.
HINT: Update the relation to point at ‘settings.AUTH_USER_MODEL’.
参照サイトではDjango modelの仕様を前提としているのでエラーが出る
UserModelを使用する場合models.pyの記述方法を調整する必要がある。
subscriptions/models.pyに以下を記述する。
1 2 3 4 5 6 7 8 9 10 11 |
from django.conf import settings from django.db import models class StripeCustomer(models.Model): user = models.OneToOneField(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE) stripeCustomerId = models.CharField(max_length=255) stripeSubscriptionId = models.CharField(max_length=255) def __str__(self): return self.user.username |
支払い完了画面に移行しない場合
参照サイトではホームページ自体がStripeペイメントのページなので、
別のURLを設定する場合subscriptions/view.pyのurlを確認する
例えば以下の場合
success_url=domain_url + ‘success?session_id=
cancel_url=domain_url + ‘cancel/’,
以下に変更する
success_url=domain_url + ‘subscriptions/success?session_id=
cancel_url=domain_url + ‘subscriptions/cancel/’,
subscriptions_stripecustomerが無いというエラー
Stripe用のモデル(データベース)が設定されていない可能性がある。
python manage.py makemigrations subscriptions
python manage.py migrate subscriptions
を行う
stripe_webhookエラー
参照サイトではDjango modelの仕様を前提としているので
webhookでuser名の取得ができない。
user = User.objects.get(id=client_reference_id)にエラーが出る
カスタムユーザーモデルの場合上記のコードが動かないので
以下のモジュールをインポートしてコード内容をget_user_model()に変更する
from django.contrib.auth import get_user_model #インポートする
user = get_user_model().objects.get(id=client_reference_id)
ソース
NameError: name ‘request’ is not defined
ListViewにおいてStripeで支払った人にのみList内容を見せる場合で、
ListViewクラスの関数の引数がselfとなっている場合
stripe_customer = StripeCustomer.objects.get(user=request.user)で
上記エラーが出る。
その為”self.request.user”にする必要がある
stripe_customer = StripeCustomer.objects.get(user=self.request.user)
キャンセル処理
subscriptions/view.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
@login_required def cancel_subscription(request): if request.user.is_authenticated: stripe_customer = StripeCustomer.objects.get(user=request.user) stripe.api_key = settings.STRIPE_SECRET_KEY sub_id = stripe.Subscription.retrieve(stripe_customer.stripeSubscriptionId) print(sub_id) print(sub_id.id) user=request.user print("user is") print(user) try: #delete from stripeapi stripe.Subscription.delete(sub_id) #delete from StripeCustomer model StripeCustomer.objects.filter(stripeSubscriptionId=sub_id.id).delete() print('unsubscribed') except Exception as e: import traceback traceback.print_exc() return JsonResponse({'error': (e.args[0])}, status =403) return render(request, 'home.html') |
メールアドレスの取得
1 2 3 4 5 |
session = event['data']['object'] stripe_customer_id = session.get('customer') retrieve = stripe.Customer.retrieve(stripe_customer_id) print(retrieve['email']) |
登録者にお礼のメール
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#メールアドレスの取得(その他名前などの追加情報も取得可) retrieve = stripe.Customer.retrieve(stripe_customer_id) print(retrieve['email']) customer_email = retrieve['email'] subject = "Thank you for your subscription." message = "Here is your products" from_email = 'kawazoe@customslegaloffice.com' admin_email = ['kawazoe@customslegaloffice.com',customer_email ] print("send") try: send_mail(subject ,message, from_email, admin_email) except: import traceback traceback.print_exc() |
StripeAPIから取得できるデータ一覧
event取得
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
stripe.api_key = settings.STRIPE_SECRET_KEY endpoint_secret = settings.STRIPE_ENDPOINT_SECRET payload = request.body sig_header = request.META['HTTP_STRIPE_SIGNATURE'] event = None try: event = stripe.Webhook.construct_event( payload, sig_header, endpoint_secret ) print(event) #以下取得できるデータ一覧 { "api_version": "2020-08-27", "created": 1623290218, "data": { "object": { "allow_promotion_codes": null, "amount_subtotal": 4, "amount_total": 4, "billing_address_collection": null, "cancel_url": "http://3.129.28.xxx/subscriptions/cancel/", "client_reference_id": "1", "currency": "jpy", "customer": "cus_Jduyyr093qeu2V", "customer_details": { "email": null, "tax_exempt": "none", "tax_ids": [] }, "customer_email": null, "id": "cs_test_a1eysaqK9Evwz4U85W30sPUo9COWcG96Akw5f3CnSKgmfT7qqVwijZixxx", "livemode": false, "locale": null, "metadata": {}, "mode": "subscription", "object": "checkout.session", "payment_intent": null, "payment_method_options": {}, "payment_method_types": [ "card" ], "payment_status": "paid", "setup_intent": "seti_1J0d8eJvSJBZN02Kwwzupxxx", "shipping": null, "shipping_address_collection": null, "submit_type": null, "subscription": "sub_JduyaYhZ5UrRn1", "success_url": "http://3.129.28.xxx/subscriptions/success?session_id={CHECKOUT_SESSION_ID}", "total_details": { "amount_discount": 0, "amount_shipping": 0, "amount_tax": 0 } } }, "id": "evt_1J0d8gJvSJBZN02KkHPwAxxx", "livemode": false, "object": "event", "pending_webhooks": 3, "request": { "id": null, "idempotency_key": null }, "type": "checkout.session.completed" } |
例:event取得後各種IDを取得
client_reference_id,customer,subscriptionの3つのデータが欲しい場合
1 2 3 4 5 6 |
session = event['data']['object'] # Fetch all the required data from session client_reference_id = session.get('client_reference_id') stripe_customer_id = session.get('customer') stripe_subscription_id = session.get('subscription') |
顧客データ詳細を取得
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
session = event['data']['object'] stripe_customer_id = session.get('customer') retrieve = stripe.Customer.retrieve(stripe_customer_id) #以下取得できるデータ一覧 { "address": { "city": null, "country": "JP", "line1": null, "line2": null, "postal_code": null, "state": null }, "balance": 4, "created": 1623314935, "currency": "jpy", "default_source": null, "delinquent": false, "description": null, "discount": null, "email": "xxxxxxxx@gmail.com", "id": "cus_Je1cRQy1VsbQrb", "invoice_prefix": "77146EAE", "invoice_settings": { "custom_fields": null, "default_payment_method": null, "footer": null }, "livemode": false, "metadata": {}, "name": "xxxxxx KAWAZOE", "next_invoice_sequence": 2, "object": "customer", "phone": null, "preferred_locales": [], "shipping": null, "tax_exempt": "none" } |
例:顧客データ詳細取得後各種情報を取得
1 2 3 4 5 6 |
#メールアドレスを取得したい場合 customer_email = retrieve['email'] #価格の取得 currency = retrieve['currency'] amount = retrieve['balance'] |
更に顧客データ詳細を表示
※但しview内にて取得する方法は不明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
stripe_customer = StripeCustomer.objects.get(user=request.user) stripe.api_key = settings.STRIPE_SECRET_KEY sub_id = stripe.Subscription.retrieve(stripe_customer.stripeSubscriptionId) print(sub_id) #以下取得できるデータ一覧 { "application_fee_percent": null, "billing_cycle_anchor": 1623372697, "billing_thresholds": null, "cancel_at": null, "cancel_at_period_end": false, "canceled_at": null, "collection_method": "charge_automatically", "created": 1623372697, "current_period_end": 1625964697, "current_period_start": 1623372697, "customer": "cus_JeH97oQYVT2Ehd", "days_until_due": null, "default_payment_method": "pm_1J0yaxJvSJBZN02Kb7nL7O37", "default_source": null, "default_tax_rates": [], "discount": null, "ended_at": null, "id": "sub_JeH9mHHGs3SrM2", "items": { "data": [ { "billing_thresholds": null, "created": 1623372697, "id": "si_JeH9r5JrZtzGZS", "metadata": {}, "object": "subscription_item", "plan": { "active": true, "aggregate_usage": null, "amount": 4, "amount_decimal": "4", "billing_scheme": "per_unit", "created": 1623289653, "currency": "jpy", "id": "price_1J0czZJvSJBZN02KVdyeJljf", "interval": "month", "interval_count": 1, "livemode": false, "metadata": {}, "nickname": null, "object": "plan", "product": "prod_Jb1LklwtRAVkQB", "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "price": { "active": true, "billing_scheme": "per_unit", "created": 1623289653, "currency": "jpy", "id": "price_1J0czZJvSJBZN02KVdyeJljf", "livemode": false, "lookup_key": null, "metadata": {}, "nickname": null, "object": "price", "product": "prod_Jb1LklwtRAVkQB", "recurring": { "aggregate_usage": null, "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed" }, "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 4, "unit_amount_decimal": "4" }, "quantity": 1, "subscription": "sub_JeH9mHHGs3SrM2", "tax_rates": [] } ], "has_more": false, "object": "list", "total_count": 1, "url": "/v1/subscription_items?subscription=sub_JeH9mHHGs3SrM2" }, "latest_invoice": "in_1J0yazJvSJBZN02K4zKW5kTn", "livemode": false, "metadata": {}, "next_pending_invoice_item_invoice": null, "object": "subscription", "pause_collection": null, "pending_invoice_item_interval": null, "pending_setup_intent": null, "pending_update": null, "plan": { "active": true, "aggregate_usage": null, "amount": 4, "amount_decimal": "4", "billing_scheme": "per_unit", "created": 1623289653, "currency": "jpy", "id": "price_1J0czZJvSJBZN02KVdyeJljf", "interval": "month", "interval_count": 1, "livemode": false, "metadata": {}, "nickname": null, "object": "plan", "product": "prod_Jb1LklwtRAVkQB", "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "quantity": 1, "schedule": null, "start_date": 1623372697, "status": "active", "transfer_data": null, "trial_end": null, "trial_start": null } |
HTMLにて上記データを表示
view.py
1 2 3 4 5 6 7 8 |
stripe_customer = StripeCustomer.objects.get(user=request.user) stripe.api_key = settings.STRIPE_SECRET_KEY subscription = stripe.Subscription.retrieve(stripe_customer.stripeSubscriptionId) return render(request, 'home.html',{ 'subscription': subscription, 'product': product, }) |
html
1 2 |
ProductDescription:{ product.description} Price:{ subscription.plan.currency}} {{ subscription.plan.amount}} |
ローカルでStripe CLI でwebhookをテスト
exeファイルをクリックしてもThis is a command line tool.
You need to open cmd.exe and run it from there.と出て消えてしまうので
exeファイルをShiftを押しながら右クリックする事で開く事ができる。
↓コツはカーソルをstripeから離れた白地の部分でShiftを押しながら
右クリックする事。
Stripeを選んだまま右クリックしてもPowershellウィンドウを開く事は
できない
windowsの場合ログインのコマンドは以下の通り。(stripe loginだけではだめ)
1 |
./stripe login |
1 |
./stripe listen --forward-to localhost:8000/subscriptions/webhook/ |
コメントを残す