Pei's Lab

[Django]Stipeを使ってECサイトを作る

(Django + Stripeの組み合わせでECサイトを開発中です。備忘録を兼ねてこの記事を更新していきます。作成途中なため、順序が不適切であったり、修正箇所が網羅されていなかったりします。)

Stripeでは2020年5月現在、PaymentIntentを用いたコーディングが推奨されています。Stripeの公式ドキュメントではFlaskが採用されていてDjangoについての記載がありません。加えて、インターネットでStripeのDjangoへの適用例を調べるとChargeAPIを使用しているものがほとんどでPaymentIntentの使用例は見つかりません。

そこで、本記事ではDjango+Stripeの組み合わせでPaymentIntentを使用した決済システムの構築に向けて、公式ドキュメントでは足りないところを補います。

ベースとするコード

下記の公式ドキュメントをベースに編集していきます。Platform:Web,Frontend:HTML/JS,Backend:Pythonを選択してください。

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),
})