(Django + Stripeの組み合わせでECサイトを開発中です。備忘録を兼ねてこの記事を更新していきます。作成途中なため、順序が不適切であったり、修正箇所が網羅されていなかったりします。)
Stripeでは2020年5月現在、PaymentIntentを用いたコーディングが推奨されています。Stripeの公式ドキュメントではFlaskが採用されていてDjangoについての記載がありません。加えて、インターネットでStripeのDjangoへの適用例を調べるとChargeAPIを使用しているものがほとんどでPaymentIntentの使用例は見つかりません。
そこで、本記事ではDjango+Stripeの組み合わせでPaymentIntentを使用した決済システムの構築に向けて、公式ドキュメントでは足りないところを補います。
ベースとするコード
下記の公式ドキュメントをベースに編集していきます。Platform:Web,Frontend:HTML/JS,Backend:Pythonを選択してください。
429 Too Many Requests - stripe.com |
CSRF対策
ご存知の通り、DjangoではformをPOSTするときには{%CSRF_TOKEN%}を使ってcsrf_tokenを送ります。ベースコードそのままではscarf_tokenが送られないので、fetchのheaderにcsrf_tokenを追加する必要があります。csrf_tokenはCookieに含まれています。まず、Cookieを取得するための関数をclient.jsの先頭に定義します。
// client.js function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie !== '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; }
fetich処理
Djangoの場合はjQueryのAjaxを使用する方が相性が良いという話もありますが、今回は公式ドキュメントに近いコードにするためにそのままfetchを使用することにします。
ポイントは2点あり、「前述のcsrf_tokenをheadersに追加すること」と「”Content-Type”を”application/x-www-form-urlencoded; charset=utf-8″にすること」です。
//client.js // Disable the button until we have Stripe set up on the page document.querySelector("#submit").disabled = true; csrf_token = getCookie('csrftoken'); // 先頭で定義した関数を使ってcsrf_tokenを取得 fetch("/create-payment-intent", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded; charset=utf-8", "X-CSRFToken":csrf_token, 'X-Requested-With':'XMLHttpRequest', }, body: JSON.stringify(purchase), })