【初心者向け】Stripeを使用したクレジットカード登録・決済・削除の実装方法【Python, Go, Javascript】
Spiral.AI Tech Blog は、Stripe を用いたクレジットカード決済機能(登録・課金・削除)の実装手順を Python と Go で解説し、独自実装のリスクと Stripe の利点を比較している。
キーポイント
独自決済実装のリスクと Stripe の必要性
PCI DSS 対応やセキュリティ要件を満たすための独自実装はコストが高く、情報漏洩リスクがあるため、中小企業や個人開発には Stripe の利用が推奨される。
Stripe の主要機能と選定基準
Checkout, Elements, Subscriptions 等多様な機能があるが、現場ではユースケースに合わせて最小限の機能(登録・課金・削除)から学習・実装することが推奨される。
基本フローの実装アプローチ
ユーザーに一度カードを登録させ、以降は登録済みカードで決済を行う形式を採用し、CVR 低下を防ぐための設計思想が示されている。
顧客作成とカード紐付けの役割分担
顧客IDはバックエンドで生成し、クレジットカード情報はフロントエンドからStripeに直接送信して取得する必要がある。
フロントエンドでのカード登録フロー
Stripe Elementsを使用してカード情報を収集し、createPaymentMethod でトークンを取得後、バックエンドへ送付して紐付ける。
セキュリティと認証情報の連携
カードIDをサーバーに送信する際、同時にログインユーザーの認証トークンなどを併せて送り、DB上のユーザーと正しく紐付ける必要がある。
セキュリティを考慮したカード登録フロー
クレジットカード情報はバックエンドを経由せずフロントエンドと Stripe の間で完結し、ログへの情報漏洩リスクを防ぐ設計が推奨されています。
影響分析・編集コメントを表示
影響分析
この記事は AI や最先端技術の進展を報じるものではなく、Web サービス開発における決済インフラの実践的なガイドラインを提供しています。特にスタートアップや個人開発者が、セキュリティリスクを回避しつつ収益化モデルを構築するための具体的なステップを示しており、実務レベルの参考価値が高いです。
編集コメント
本記事は AI 技術の最新動向ではなく、Web サービス開発における決済実装の実践ガイドです。AI 関連ニュースというよりは、エンジニア向けの技術解説記事として評価すべき内容です。
Go
JavaScript
Python
Stripe tech こんにちは、わいけいです。今回の記事ではStripeを使ってクレジットカード決済を実装します。
開発規模の大小を問わず、実装したプロダクトで収益を得るにはユーザーからお金を払ってもらう必要があります。しかし、決済の仕組みを自分たちで実装するのは色々な困難が伴います。
キャッシュレス決済といえばクレジットカードですが、クレカ決済の実装には例えば下記のような課題があります。
実装ミスなどで、ユーザーのクレカ情報が流出すると大事故になる
PCI DSSというセキュリティ要件を守り、決済ブランドの審査に通過するには莫大なコストがかかる
結論として、個人や小規模な企業がクレカ決済を独自実装するのはあまり現実的ではないと私は思っています。こうした問題のソリューションとなるのがStripeです。
まずは そもそもStripeとはなんぞや?というところから見ていきましょう(既に知っている方は読み飛ばしてください)。
ユーザーのカード情報をStripe上の安全な環境に保存しておける
カード決済時に必要なセキュリティ要件がクリアされているので、Stripeを通じて安全にユーザーに対して請求を行える
StripeのAPIと連携して、自分たちのサービスに柔軟に決済機能を組み込める
手数料が完全従量課金(初期費用0)で、手数料も3.6%(2024年5月時点)とリーズナブル
といったメリットを備えたグローバルなサービスです。(特に手数料率3.6%は魅力的ですね。)
さて、以上のようにStripeはとても便利です。しかし、出来ることが多い分その全容を理解するのはかなり大変です。
まるっと提供されている機能だけでも、例えば以下のようなものがあります。
Stripe Checkout
カスタマイズ可能な支払いページを提供し、ウェブサイトに簡単に組み込める。
Stripe Elements
カスタマイズ可能なUIコンポーネントで、フォームを通じて決済情報を安全に収集。
サブスクリプションや繰り返し課金を管理するためのツール。
マーケットプレイスやプラットフォームの支払いを容易にする。
金融不正取引防止ツールで、異常な取引を検出しリスクを管理する。
スタートアップがアメリカで会社を設立し、銀行口座を開設するサポートを提供。
企業が自社のクレジットカードやデビットカードを発行できるサービス。
Stripe Treasury
企業が顧客に銀行のような金融サービスを提供するためのAPI。
Stripe Terminal
実店舗での支払いを処理するための POS デバイスと SDK。
ぱっと見、よく分からないものも多いと思います。実際の現場では、これらのサービス全てを理解するのはコスパが良いとは言えません。それよりは、ユースケースに合わせて動くものを作りながら学んでいった方がいいでしょう。
そこで、今回は一つのサンプルとして、下記のような機能を備えたアプリを実装してみます。
ユーザーがクレジットカードを登録する
そのクレジットカードに対して課金する
ユーザーのクレジットカードを必要に応じて削除する
クレカ決済を導入する際の最も基本的なフロー(というか最小単位)ですね。
純粋にクレカ決済をするだけならば、今回紹介する内容よりも簡単なやり方はあります。しかし、その場合決済のたびにユーザーがクレカ情報を入力する必要があったりと、何かと不便な点があったりまします。サービスを運用していく上ではユーザーに何度もクレカ情報を入力させるのは CVR の低下を招くことが強く懸念されます。
そのため、今回は一度ユーザーにクレカを登録させ、以降の支払いは既に登録済みのクレカに対して行う形式でいきます。
stripe には既に登録しており、API の公開キー&シークレットキーを発行済み
簡素化のため、webhook を利用しない
SPA 形式のサービスへの組み込みを想定する(他の形式の場合でも大元のコードは流用可です)
バックエンドのコードは stripe を扱う主要部分のみを実装する(Web API の体裁にするのは各自の実装に委ねる)
という前提のもとやっていきたいと思います。なお、フロントエンドは javascript, バックエンドは Python と Go の 2 種類の実装を提示します。
※Stripe の API キーについてはこちら を参照してください。API キーは、アカウント作成後ダッシュボードの開発者用画面をポチポチすれば作れます。
また、単純化のためにエラーハンドリングをやっていなかったり、秘匿情報をコードにそのまま書いていたりしますが実運用時はこの辺もしっかりやる必要があるので注意してください。
Stripe へのユーザー登録とカードの紐付け
まず、Stripe 上にユーザーデータを登録し、そのユーザーにカードを紐付けていきましょう。
まず Stripe 上のユーザーを作成する部分です。stripe にユーザーが作成されると同時に、stripe 上での user_id
また、Stripe へユーザー登録するタイミングはアプリ要件によって色々ありますが、多くの場合は
アプリにユーザーが登録した時に必ず Stripe にも登録する
ユーザーが課金することが確定した段階で Stripe に登録する
の 2 パターンになりそうです。要件に合わせて適切な実装を行ってください。
package main
import (
"github.com/stripe/stripe-go"
"github.com/stripe/stripe-go/customer"
)
func main() {
// Stripe のシークレットキーを設定する
stripe.Key = "your secret key"
stripe_cus_id, err := createStripeCustomer()
if err != nil {
panic(err)
}
println(*stripe_cus_id)
}
func createStripeCustomer() (*string, error) {
params := &stripe.CustomerParams{
Name: stripe.String("Jenny Rosen from Go code"),
Email: stripe.String("jennyrosen@example.com"),
}
result, err := customer.New(params)
if err != nil {
return nil, err
}
return &result.ID, nil
}
from stripe import StripeClient
from stripe import Customer
api_key = "your secret key"
client = StripeClient(api_key=api_key)
customer: Customer = client.customers.create(
params={
"email": "hoge@example.com",
"name": "John Doe from python code",
},
)
print(customer.id)
これらのコードを実行後、Stripe のダッシュボードを見てみると顧客データが増えていることが確認できると思います。繰り返しになりますが、実際にはここで取得した Stripe の customer_id(顧客 ID)は、登録したユーザーへクレジットカードを紐付けるために使用します。
登録したユーザーへクレジットカードを紐付け
次にこのユーザーにクレカ情報を紐付ける部分です。概要としては以下のようになります。
・フロントエンドから Stripe に直接カード登録リクエストを投げる
・バックエンドで Stripe 上のカードとユーザーを紐付ける
図にすると以下のようになります。

まず、カード自体を登録するフロント側のサンプルです。
Payment
Submit Payment
※このままテストをする場合は、この html ファイルが置いてあるディレクトリで python3 -m http.server 8000 と実行してください。
ここで、クレジットカードの登録フローはフロントエンドと Stripe のやり取りで完結していることに注意しましょう。(後で提示するように、登録したカードとユーザーの紐付け部分にはバックエンドが絡みます。が、あくまで紐付け部分だけです。)
これは、セキュリティ面を考慮してこの仕様が推奨されているものと思われます。バックエンドにユーザーのカード情報が一度でも流されると、情報が思わぬところで保存されてしまうリスクがあります。例えば、意図せざるログが出てしまってそれが残留してしまう等ですね。恐ろしや。
バックエンドが介在せずに処理を行っているので、必然的にクレカ登録工程(PaymentMethod
さて、次はバックエンドでフロントから paymentmethod_id
package main import ( "github.com/stripe/stripe-go" "github.com/stripe/stripe-go/paymentmethod" ) func main() { // Stripe のシークレットキーを設定 stripe.Key = "your secret key" //実際には多くの場合フロントから送られた認証トークンなどを基に user_id を特定し、 //それを使って DB から検索して取得することになるはず stripe_customer_id := "cus_xxxxxxxx" stripe_paymentmethod_id := "pm_xxxxxxxxxxxxxxxx" //実際にはフロントから受け取る想定 err := attachCardToCustomer(stripe_customer_id, stripe_paymentmethod_id) if err != nil { panic(err) } println("Success") } func attachCardToCustomer(stripe_customer_id string, stripe_paymentmethod_id string) error { // PaymentMethod を Customer に紐付ける _, err := paymentmethod.Attach( stripe_paymentmethod_id, &stripe.PaymentMethodAttachParams{ Customer: stripe.String(stripe_customer_id), }, ) if err != nil { return err } return nil }
from stripe import StripeClient from stripe import PaymentMethod api_key = "your secret key" # 実際には多くの場合フロントから送られた認証トークンなどを基に user_id を特定し、それを使って DB から検索して取得することになるはず stripe_customer_id = "cus_xxxxxxxxx" # 実際にはフロントから受け取る想定 stripe_payment_method_id = "pm_xxxxxxxx" client = StripeClient(api_key=api_key) pm: PaymentMethod = client.payment_methods.attach( payment_method=stripe_payment_method_id, params={ "customer": stripe_customer_id, }, ) print("success!")
このコードが実行されると、ダッシュボード上で顧客データに paymentMethod
次に、ユーザーと紐付けられたクレジットカードに対して請求する部分を実装していきましょう。
全体の流れとしては、以下のようなフローになります。
フロントエンドからバックエンドへ user_id と PaymentMethod ID を送信し、
バックエンド側で Stripe 上で指定した PaymentMethod を使用します。
図にすると以下のようになります。 
いくつか補足しますと、ステップ 2 では Stripe 上で 1 つの customer に紐付けられたクレジットカードの中から、
どういった条件を満たすクレジットカードを使うかはアプリケーションの要件によって異なります。
今回は単純化のために、そもそも 1 枚しかクレジットカードを登録できない仕様のアプリケーションを作っていると想定しましょう。
この場合は機械的にリストの一番始めのクレジットカードに対して課金すれば OK です。
次にステップ 3 についてです。PaymentIntent を作成する際、
ただ、ここではクレジットカードによる即時払いのみに対応したアプリケーションを作っていると想定しているので、一旦この辺の事情は忘れてしまっても問題ありません。
クレカで即時支払いをする場合、PaymentIntent のステータスが requires_action になることがあります。
問題はクレジットカードによっては 3D 認証などのさらなる認証ステップを挟まなければいけないケースがあることです。例えば(最近ではもう非推奨になっている規格ですが)3D セキュア 1 の場合はカードごとに指定された URL にユーザーをリダイレクトしなければなりません。そのケースの場合は、作成された PaymentIntent オブジェクトの中に next_action.redirect_to_url.url が含まれています。
追加の認証が完了すると PaymentIntent は処理されます。
全体として、Stripe での課金処理はカードの登録処理とはまた違った複雑さがあります。カード登録とは違い、バックエンドと Stripe で大体の処理が完結しているのは嬉しい点です。一方で PaymentIntent のステータス管理や、認証が必要な場合のリダイレクト処理など、考慮すべき点も多々あります。
フロントからはユーザーが識別できる情報を渡すだけなので、今回はバックエンドのサンプルコードのみを示します。
必ず JSON 形式で返してください。translation フィールドのみ。他のフィールド (technical_terms 等) は一切追加しないこと — 余計なフィールドを書こうとして本文翻訳がトークン上限で打ち切られる事故を防ぐため:
{"translation": "次に、ユーザーと紐付けられたクレジットカードに対して請求する部分を実装していきましょう。\n\n全体の流れとしては、以下のようなフローになります。\n\nフロントエンドからバックエンドへ user_id と PaymentMethod ID を送信し、\nバックエンド側で Stripe 上で指定した PaymentMethod を使用します。\n\n図にすると以下のようになります。
\n\nいくつか補足しますと、ステップ 2 では Stripe 上で 1 つの customer に紐付けられたクレジットカードの中から、\nどういった条件を満たすクレジットカードを使うかはアプリケーションの要件によって異なります。\n今回は単純化のために、そもそも 1 枚しかクレジットカードを登録できない仕様のアプリケーションを作っていると想定しましょう。\n\nこの場合は機械的にリストの一番始めのクレジットカードに対して課金すれば OK です。\n\n次にステップ 3 についてです。PaymentIntent を作成する際、\nただ、ここではクレジットカードによる即時払いのみに対応したアプリケーションを作っていると想定しているので、一旦この辺の事情は忘れてしまっても問題ありません。\n\nクレカで即時支払いをする場合、PaymentIntent のステータスが requires_action になることがあります。\n問題はクレジットカードによっては 3D 認証などのさらなる認証ステップを挟まなければいけないケースがあることです。例えば(最近ではもう非推奨になっている規格ですが)3D セキュア 1 の場合はカードごとに指定された URL にユーザーをリダイレクトしなければなりません。そのケースの場合は、作成された PaymentIntent オブジェクトの中に next_action.redirect_to_url.url が含まれています。\n\n追加の認証が完了すると PaymentIntent は処理されます。\n\n全体として、Stripe での課金処理はカードの登録処理とはまた違った複雑さがあります。カード登録とは違い、バックエンドと Stripe で大体の処理が完結しているのは嬉しい点です。一方で PaymentIntent のステータス管理や、認証が必要な場合のリダイレクト処理など、考慮すべき点も多々あります。\n\nフロントからはユーザーが識別できる情報を渡すだけなので、今回はバックエンドのサンプルコードのみを示します。"}
package main
import (
"github.com/stripe/stripe-go"
"github.com/stripe/stripe-go/paymentintent"
"github.com/stripe/stripe-go/paymentmethod"
)
func main() {
// Stripe のシークレットキーを設定する
stripe.Key = "your secret key"
// 実際には多くの場合、フロントエンドから送られた認証トークンなどを基に user_id を特定し、
// それを使ってデータベース(DB)から検索して取得することになるはず
stripe_customer_id := "cus_xxxxxxxxx"
amount := 1000 // 課金額
// 顧客の PaymentMethod リストを取得する
paymentMethodListParams := &stripe.PaymentMethodListParams{
Customer: stripe.String(stripe_customer_id),
Type: stripe.String("card"),
}
paymentMethods := paymentmethod.List(paymentMethodListParams)
// 最初のカードを取得する
var firstPaymentMethod *stripe.PaymentMethod
for paymentMethods.Next() {
pm := paymentMethods.PaymentMethod()
firstPaymentMethod = pm
break
}
if firstPaymentMethod == nil {
panic("No payment method found")
}
// PaymentIntent を作成して課金する
params := &stripe.PaymentIntentParams{
Amount: stripe.Int64(int64(amount)),
Currency: stripe.String(string(stripe.CurrencyJPY)),
PaymentMethod: stripe.String(firstPaymentMethod.ID),
Confirm: stripe.Bool(true),
Customer: stripe.String(stripe_customer_id),
}
pi, err := paymentintent.New(params)
if err != nil {
panic(err)
}
// PaymentIntent の主要な情報を表示する
println("PaymentIntent ID: " + pi.ID)
println("PaymentIntent Status: " + string(pi.Status))
println("PaymentIntent Amount: " + string(pi.Amount))
println("PaymentIntent Currency: " + string(pi.Currency))
println("PaymentIntent PaymentMethod: " + string(pi.PaymentMethod.ID))
println("PaymentIntent ConfirmationMethod: " + string(pi.ConfirmationMethod))
// フロントエンドに必要な情報を返す
}
from stripe import StripeClient
from stripe import PaymentMethod, ListObject
api_key = "your secret key" # 実際には多くの場合フロントから送られた認証トークンなどを基にuser_idを特定し、それを使ってDBから検索して取得することになるはず
stripe_customer_id = "cus_xxxxxxx" # 実際にはフロントから受け取る想定
stripe_payment_method_id = "pm_xxxxxxxx" # 課金額
amount = 20000
client = StripeClient(api_key=api_key)
payment_methods: ListObject[PaymentMethod] = client.customers.payment_methods.list(
customer=stripe_customer_id,
params={"type": "card"}
)
pm_id = payment_methods.data[0]["id"] # paymentIntentを作成して即時支払い
payment_intent = client.payment_intents.create(
params={
"amount": amount,
"currency": "jpy",
"payment_method": pm_id,
"customer": stripe_customer_id,
"confirm": True, # 3Dセキュアなどのリダイレクト設定を省略するために下記を設定
"automatic_payment_methods": {"enabled": True, "allow_redirects": "never"},
},
)
print("success!")
このコードの実行が成功すると、Stripeのダッシュボードで売上が増えているのが確認できるはずです!本番環境でもこれだけ簡単に売上が増えればいいのに、、、、、、。
最後に、クレジットカードを削除していきましょう。全体のフローとしては、下記のような流れになります。
フロントから該当ユーザーを特定できる情報をバックエンドに送信
バックエンドからStripeにリクエストし、そのユーザーに紐付いているPaymentMethodリストの最初のPaymentMethod
今回は決済手段として各ユーザー毎に一枚のクレカのみを登録可能な仕様を想定しています。そのため、削除するクレカは単純にPaymentMethod
フローを図にすると下記のようになります。

さて、削除についてもサンプルコードを書いてみます。例によってバックエンドとstripeのやりとりのみを掲載します。
package main
import (
"github.com/stripe/stripe-go"
"github.com/stripe/stripe-go/paymentmethod"
)
func main() {
// Stripe のシークレットキーを設定する
stripe.Key = "your secret key"
// 実際には多くの場合、フロントエンドから送られた認証トークンなどを基に user_id を特定し、
// それを使ってデータベース(DB)から検索して取得することになるはず
stripe_customer_id := "cus_xxxxxxxx"
// 顧客の PaymentMethod をリスト取得する
paymentMethodListParams := &stripe.PaymentMethodListParams{
Customer: stripe.String(stripe_customer_id),
Type: stripe.String("card"),
}
paymentMethods := paymentmethod.List(paymentMethodListParams)
// 最初の PaymentMethod を削除する
var pmIDToDelete string
if paymentMethods.Next() {
pm := paymentMethods.PaymentMethod()
pmIDToDelete = pm.ID
}
if pmIDToDelete == "" {
panic("No payment methods found for the customer")
}
// PaymentMethod を削除する
_, err := paymentmethod.Detach(pmIDToDelete, nil)
if err != nil {
panic(err)
}
println("PaymentMethod deleted")
}
from stripe import StripeClient
from stripe import PaymentMethod, ListObject
api_
原文を表示
Go
JavaScript
Python
Stripe techこんにちは、わいけいです。 今回の記事ではStripeを使ってクレジットカード決済を実装します。
開発規模の大小を問わず、実装したプロダクトで収益を得るにはユーザーからお金を払ってもらう必要があります。 しかし、決済の仕組みを自分たちで実装するのは色々な困難が伴います。
キャッシュレス決済といえばクレジットカードですが、クレカ決済の実装には例えば下記のような課題があります。
実装ミスなどで、ユーザーのクレカ情報が流出すると大事故になる
PCI DSSというセキュリティ要件を守り、決済ブランドの審査に通過するには莫大なコストがかかる
結論として、個人や小規模な企業がクレカ決済を独自実装するのはあまり現実的ではないと私は思っています。 こういった問題のソリューションとなるのがStripeです。
まずは そもそもStripeとはなんぞや? というところから見ていきましょう(既に知っている方は読み飛ばしてください)。
ユーザーのカード情報をStripe上の安全な環境に保存しておける
カード決済時に必要なセキュリティ要件がクリアされているので、Stripeを通じて安全にユーザーに対して請求を行える
StripeのAPIと連携して、自分たちのサービスに柔軟に決済機能を組み込める
手数料が完全従量課金(初期費用0)で、手数料も3.6%(2024年5月時点)とリーズナブル
といったメリットを備えたグローバルなサービスです。 (特に手数料率3.6%は魅力的ですね。)
さて、以上のようにStripeはとても便利です。 しかし、出来ることが多い分その全容を理解するのはかなり大変です。
まるっと提供されている機能だけでも、例えば以下のようなものがあります。
Stripe Checkout
カスタマイズ可能な支払いページを提供し、ウェブサイトに簡単に組み込める。
Stripe Elements
カスタマイズ可能なUIコンポーネントで、フォームを通じて決済情報を安全に収集。
サブスクリプションや繰り返し課金を管理するためのツール。
マーケットプレイスやプラットフォームの支払いを容易にする。
金融不正取引防止ツールで、異常な取引を検出しリスクを管理する。
スタートアップがアメリカで会社を設立し、銀行口座を開設するサポートを提供。
企業が自社のクレジットカードやデビットカードを発行できるサービス。
Stripe Treasury
企業が顧客に銀行のような金融サービスを提供するためのAPI。
Stripe Terminal
実店舗での支払いを処理するためのPOSデバイスとSDK。
ぱっと見、よく分からないものも多いと思います。 実際の現場では、これらのサービス全てを理解するのはコスパが良いとは言えません。 それよりは、ユースケースに合わせて動くものを作りながら学んでいった方がいいでしょう。
そこで、今回は一つのサンプルとして、下記のような機能を備えたアプリを実装してみます。
ユーザーがクレジットカードを登録する
そのクレジットカードに対して課金する
ユーザーのクレジットカードを必要に応じて削除する
クレカ決済を導入する際の最も基本的なフロー(というか最小単位)ですね。
純粋にクレカ決済をするだけならば、今回紹介する内容よりも簡単なやり方はあります。 しかし、その場合決済のたびにユーザーがクレカ情報を入力する必要があったりと、何かと不便な点があったりまします。 サービスを運用していく上ではユーザーに何度もクレカ情報を入力させるのはCVRの低下を招くことが強く懸念されます。
そのため、今回は一度ユーザーにクレカを登録させ、以降の支払いは既に登録済みのクレカに対して行う形式でいきます。
stripeには既に登録しており、APIの公開キー&シークレットキーを発行済み
簡素化のため、webhookを利用しない
SPA形式のサービスへの組み込みを想定する(他の形式の場合でも大元のコードは流用可です)
バックエンドのコードはstripeを扱う主要部分のみを実装する(Web APIの体裁にするのは各自の実装に委ねる)
という前提のもとやっていきたいと思います。 なお、フロントエンドはjavascript,バックエンドはPythonとGoの2種類の実装を提示します。
※StripeのAPIキーについてはこちら を参照してください。APIキーは、アカウント作成後ダッシュボードの開発者用画面をポチポチすれば作れます。
また、単純化のためにエラーハンドリングをやっていなかったり、秘匿情報をコードにそのまま書いていたりしますが実運用時はこの辺もしっかりやる必要があるので注意してください。
Stripeへのユーザー登録とカードの紐付け
まず、Stripe上にユーザーデータを登録し、そのユーザーにカードを紐付けていきましょう。
まずStripe上のユーザーを作成する部分です。 stripeにユーザーが作成されると同時に、stripe上でのuser_id
また、Stripeへユーザー登録するタイミングはアプリ要件によって色々ありますが、多くの場合は
アプリにユーザーが登録した時に必ずStripeにも登録する
ユーザーが課金することが確定した段階でStripeに登録する
の2パターンになりそうです。 要件に合わせて適切な実装を行ってください。
package main import ( "github.com/stripe/stripe-go" "github.com/stripe/stripe-go/customer" ) func main() { // Stripeのシークレットキーを設定 stripe.Key = "your secret key" stripe_cus_id, err := createStripeCustomer() if err != nil { panic(err) } println(*stripe_cus_id) } func createStripeCustomer() (*string, error) { params := &stripe.CustomerParams{ Name: stripe.String("Jenny Rosen from Go code"), Email: stripe.String("jennyrosen@example.com"), } result, err := customer.New(params) if err != nil { return nil, err } return &result.ID, nil }
from stripe import StripeClient from stripe import Customer api_key = "your secret key" client = StripeClient(api_key=api_key) customer: Customer = client.customers.create( params={ "email": "hoge@example.com", "name": "John Doe from python code", }, ) print(customer.id)
これらのコードを実行後、Stripeのダッシュボードを見てみると顧客データが増えていることが確認できると思います。 繰り返しになりますが、実際にはここで取得したstripeのcustomer_id
登録したユーザーへクレジットカードを紐付け
次にこのユーザーにクレカ情報を紐付ける部分です。 概要としては
・フロントエンドからstripeに直接カード登録リクエストを投げる ・バックエンドでstripe上のカードとユーザーを紐付ける
図にすると以下のようになります。

まず、カード自体を登録するフロント側のサンプルです。
Payment
Submit Payment
※このままテストをする場合は、このhtmlファイルが置いてあるディレクトリで python3 -m http.server 8000
ここで、クレジットカードの登録フローはフロントエンドとStripeのやり取りで完結していることに注意しましょう。 (後で提示するように、登録したカードとユーザーの紐付け部分にはバックエンドが絡みます。が、あくまで紐付け部分だけです。)
これは、セキュリティ面を考慮してこの仕様が推奨されているものと思われます。 バックエンドにユーザーのカード情報が一度でも流されると、情報が思わぬところで保存されてしまうリスクがあります。 例えば、意図せざるログが出てしまってそれが残留してしまう等ですね。恐ろしや。
バックエンドが介在せずに処理を行っているので、必然的にクレカ登録工程(PaymentMethod
さて、次はバックエンドでフロントからpaymentmethod_id
package main import ( "github.com/stripe/stripe-go" "github.com/stripe/stripe-go/paymentmethod" ) func main() { // Stripeのシークレットキーを設定 stripe.Key = "your secret key" //実際には多くの場合フロントから送られた認証トークンなどを基にuser_idを特定し、 //それを使ってDBから検索して取得することになるはず stripe_customer_id := "cus_xxxxxxxx" stripe_paymentmethod_id := "pm_xxxxxxxxxxxxxxxx" //実際にはフロントから受け取る想定 err := attachCardToCustomer(stripe_customer_id, stripe_paymentmethod_id) if err != nil { panic(err) } println("Success") } func attachCardToCustomer(stripe_customer_id string, stripe_paymentmethod_id string) error { // PaymentMethodをCustomerに紐付ける _, err := paymentmethod.Attach( stripe_paymentmethod_id, &stripe.PaymentMethodAttachParams{ Customer: stripe.String(stripe_customer_id), }, ) if err != nil { return err } return nil }
from stripe import StripeClient from stripe import PaymentMethod api_key = "your secret key" # 実際には多くの場合フロントから送られた認証トークンなどを基にuser_idを特定し、それを使ってDBから検索して取得することになるはず stripe_customer_id = "cus_xxxxxxxxx" # 実際にはフロントから受け取る想定 stripe_payment_method_id = "pm_xxxxxxxx" client = StripeClient(api_key=api_key) pm: PaymentMethod = client.payment_methods.attach( payment_method=stripe_payment_method_id, params={ "customer": stripe_customer_id, }, ) print("success!")
このコードが実行されると、ダッシュボード上で顧客データにpaymentMethod
次にユーザーと紐付けられたクレジットカードに対して請求する部分を作っていきましょう。
全体の流れとしては以下のようなフローになります。
フロントエンドからバックエンドにuser_id
PaymentMethod ID
バックエンドからstripe上で指定したPaymentMethod
図にすると以下のようになります。 
いくつか補足します。 ステップ2では、Stripe上で1つのcustomer
どういった条件を満たすクレジットカードを使うかは アプリケーションの要件によって異なります。 今回は単純化のために、そもそも1枚しかクレジットカードを登録できない仕様のアプリケーションを作っていると想定しましょう。
この場合は機械的にリストの一番始めのクレジットカードに対して課金すればOKです。
次にステップ3についてです。 PaymentIntent
ただ、ここではクレジットカードによる即時払いのみに対応したアプリケーションを作っていると想定しているので、一旦この辺の事情は忘れてしまっても問題ありません。
クレカで即時支払いをする場合、PaymentIntent
問題はクレジットカードによっては3D認証などのさらなる認証ステップを挟まなければいけないケースがあることです。 例えば(最近ではもう非推奨になっている規格ですが)3Dセキュア1の場合はカードごとに指定された URL にユーザーをリダイレクトしなければなりません。 そのケースの場合は、作成されたPaymentIntentオブジェクトの中にnext_action
redirect_to_url.url
追加の認証が完了するとPaymentIntent
全体として、stripeでの課金処理はカードの登録処理とはまた違った複雑さがあります。 カード登録とは違い、バックエンドとStripeで大体の処理が完結しているのは嬉しい点です。 一方でPaymentIntent
フロントからはユーザーが識別できる情報を渡すだけなので、今回はバックエンドのサンプルコードのみを示します。
package main import ( "github.com/stripe/stripe-go" "github.com/stripe/stripe-go/paymentintent" "github.com/stripe/stripe-go/paymentmethod" ) func main() { // Stripeのシークレットキーを設定 stripe.Key = "your secret key" //実際には多くの場合フロントから送られた認証トークンなどを基にuser_idを特定し、 //それを使ってDBから検索して取得することになるはず stripe_customer_id := "cus_xxxxxxxxx" amount := 1000 //課金額 // 顧客のPaymentMethodリストを取得 paymentMethodListParams := &stripe.PaymentMethodListParams{ Customer: stripe.String(stripe_customer_id), Type: stripe.String("card"), } paymentMethods := paymentmethod.List(paymentMethodListParams) // 最初のカードを取得 var firstPaymentMethod *stripe.PaymentMethod for paymentMethods.Next() { pm := paymentMethods.PaymentMethod() firstPaymentMethod = pm break } if firstPaymentMethod == nil { panic("No payment method found") } // PaymentIntentを作成して課金 params := &stripe.PaymentIntentParams{ Amount: stripe.Int64(int64(amount)), Currency: stripe.String(string(stripe.CurrencyJPY)), PaymentMethod: stripe.String(firstPaymentMethod.ID), Confirm: stripe.Bool(true), Customer: stripe.String(stripe_customer_id), } pi, err := paymentintent.New(params) if err != nil { panic(err) } //paymentIntentの主要な情報を表示 println("PaymentIntent ID: " + pi.ID) println("PaymentIntent Status: " + string(pi.Status)) println("PaymentIntent Amount: " + string(pi.Amount)) println("PaymentIntent Currency: " + string(pi.Currency)) println("PaymentIntent PaymentMethod: " + string(pi.PaymentMethod.ID)) println("PaymentIntent ConfirmationMethod: " + string(pi.ConfirmationMethod)) //フロントに必要な情報を返す }
from stripe import StripeClient from stripe import PaymentMethod, ListObject api_key = "your secret key" # 実際には多くの場合フロントから送られた認証トークンなどを基にuser_idを特定し、それを使ってDBから検索して取得することになるはず stripe_customer_id = "cus_xxxxxxx" # 実際にはフロントから受け取る想定 stripe_payment_method_id = "pm_xxxxxxxx" # 課金額 amount = 20000 client = StripeClient(api_key=api_key) payment_methods: ListObject[PaymentMethod] = client.customers.payment_methods.list( customer=stripe_customer_id, params={"type": "card"} ) pm_id = payment_methods.data[0]["id"] # paymentIntentを作成して即時支払い payment_intent = client.payment_intents.create( params={ "amount": amount, "currency": "jpy", "payment_method": pm_id, "customer": stripe_customer_id, "confirm": True, # 3Dセキュアなどのリダイレクト設定を省略するために下記を設定 "automatic_payment_methods": {"enabled": True, "allow_redirects": "never"}, }, ) print("success!")
このコードの実行が成功すると、Stripeのダッシュボードで売上が増えているのが確認できるはずです! 本番環境でもこれだけ簡単に売上が増えればいいのに、、、、、、。
最後に、クレジットカードを削除していきましょう。 全体のフローとしては、下記のような流れになります。
フロントから該当ユーザーを特定できる情報をバックエンドに送信
バックエンドからStripeにリクエストし、そのユーザーに紐付いているPaymentMethod
リストの最初のPaymentMethod
今回は決済手段として各ユーザー毎に一枚のクレカのみを登録可能な仕様を想定しています。 そのため、削除するクレカは単純にPaymentMethod
フローを図にすると下記のようになります。

さて、削除についてもサンプルコードを書いてみます。 例によってバックエンドとstripeのやりとりのみを掲載します。
package main import ( "github.com/stripe/stripe-go" "github.com/stripe/stripe-go/paymentmethod" ) func main() { // Stripeのシークレットキーを設定 stripe.Key = "your secret key" //実際には多くの場合フロントから送られた認証トークンなどを基にuser_idを特定し、 //それを使ってDBから検索して取得することになるはず stripe_customer_id := "cus_xxxxxxxx" // 顧客のPaymentMethodをリスト取得 paymentMethodListParams := &stripe.PaymentMethodListParams{ Customer: stripe.String(stripe_customer_id), Type: stripe.String("card"), } paymentMethods := paymentmethod.List(paymentMethodListParams) // 最初のPaymentMethodを削除 var pmIDToDelete string if paymentMethods.Next() { pm := paymentMethods.PaymentMethod() pmIDToDelete = pm.ID } if pmIDToDelete == "" { panic("No payment methods found for the customer") } // PaymentMethodを削除 _, err := paymentmethod.Detach(pmIDToDelete, nil) if err != nil { panic(err) } println("PaymentMethod deleted") }
from stripe import StripeClient from stripe import PaymentMethod, ListObject api_
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み