アクトインディ開発者ブログ

子供とお出かけ情報「いこーよ」を運営する、アクトインディ株式会社の開発者ブログです

Stripeを使った決済処理を調べてみた。

morishitaです。

今回はStripeについて調べてみたのでそのことを書きます。

Stripeとは

Stripeは決済処理を代行してくれるサービスです。
サービス内でなにか販売をしようとするとユーザーから代金をいただく決済の仕組みを用意する必要があります。

ネットサービスだとまずはクレジットカード決済のサポートが必須となると思います。
通常は、各クレジッドカードブランドと直接やり取りすることはなく、代行処理サービスを使います。 Stripeもそんな代行処理サービスのひとつです。

決済機能はクレジットカード番号というセンシティブな情報を扱うため、代行処理サービスを使ってもやり取りが複雑になりがちです。
私自は過去に国内の同様のサービスを使ってクレジットカード決済を実装したことありましたが、 今回Stripeを使ってみてその実装の容易さに感動しました。

Rails のアプリケーションに組み込む前提で調査したのでご紹介します。

最初の一歩

Stripe: Registerでアカウントを作って開発用のAPIキーを取得したら、ざっくり決済をどうやって実装するのか感じを掴むために次のドキュメントをやってみることをおすすめします。

stripe.com

掲載されているコードのコピー&ペーストで下のようにRails上で決済できるところまで実装できます。

rails newからで所要15-30分くらいです。 ローカルマシン上で動かせます(rails sを使います)。

出来上がると次の様にCheckout.jsというStripe社が用意するJSライブラリで作られたクレジットカードフォームを使って決済を行えます。

f:id:HeRo:20190525151945g:plain
Stripeデモ

クレジットカード情報はRailsに送信されません。 Checkout.jsが直接StripeのAPIサーバに送信して、stripeTokenを取得します。

RailsにはこのstripeTokenを送信して、決済処理に利用します。

f:id:HeRo:20190525151906p:plain
シーケンス

こうしてクレジットカード情報というセンシティブな情報を自社で運用するサーバには一切送らずに決済処理ができるというわけです。

決済処理を行うために必要最低限のRails側のコードは次の通りです1

def create
  charge = Stripe::Charge.create({
    source: params[:stripeToken],
    amount: 500, # 決済金額
    currency: 'jpy',
  })
  # 〜決済結果を保存する処理など〜
end

とてもシンプルな実装で決済処理を実現できます。

Checkout.js

クレジットカード情報はCheckout.jsでハンドリングすると前述しましたが、そちら側の実装も簡単です。

上のGIFアニメのフォームを表示するには次の様に実装するだけです。

  <script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
          data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
          data-description="A month's subscription"
          data-amount="500"
          data-locale="auto"></script>

data-属性で言語や通貨の指定や請求先住所の入力欄の追加などが簡単にできるようになっています。

Stripe.js と Elements

Checkout.jsを利用するとほぼ実装なしと言えるくらい簡単ですが、実際には自社のサービスに合わせたデザインにしたいでしょう。

そのためにStripe.jsというJavaScriptライブラリの中にプリミティブなUIコンポーネントであるElementsが用意されています。実装量は増えるものの、こちらを使えば自由にデザイン可能です。

使いやすいと思ったところ

実際に試してみていいと思ったところ、よく考えられているなと思ったところを紹介します。

カード情報を保存できる。複数カードも可能

StripeではCustomerを登録することでお客様情報を管理できます。
そしてCustomerに対してカード情報を登録し管理できます。
これにより、リピーターとなってくれたお客様が毎回カード番号を入力する手間から解放できます。
複数カードの登録も可能なので複数のカードを使い分けたいというニーズにも対応できます。

クレジットカード番号の追加時も自社サーバにはカード情報は送信しません。やはりJavaScriptで実装したフォームから直接Stripeへ送信して得られたトークンでCustomerに紐づけます。カード情報の一部、ブランド、有効期限といったお客様がカードを選択するのに必要な情報はAPIで取得できるのでそれを示して選択してもらいます。
また、決済に使用するデフォルトカードも設定可能なので、「いつものカードで決済」といったショートカットも用意できます。

部分払い戻しが可能

1回の決済で複数の物品を購入し、その一部をキャンセルしたい場合があります。
その様なユースケースにも対応できます。

1つの決済を何回にも分けて払い戻すことが可能です。 当たり前ですが決済額を超えて払い戻そうとするとエラーが発生します。

冪等なリクエストが可能

UIのレスポンスや通信の遅れで購入確定のボタンを複数回押してしまうことがあります。また、世の中には基本ボタンは連打する人もいます。
リクエスト回数だけ処理するのがサーバとしては普通なのですが、ユーザ視点に立つと意図しない購入、請求に繋がります。

なので決済処理ではサーバサイドで2度めのリクエストは無視するなどの処理が必要になりますが、Stripeはこれにも対応しています。

次の様にidempotency_key(冪等キー)をStripe APIへのリクエストに付加してやることで、冪等にリクエストが処理されます。 つまり、同じリスクエストを2回送ってしまっても2回目以降は同じレスポンスが帰って来て、Stripe側では1つしか決済が作られません。

charge = Stripe::Charge.create({
  amount: 2000,
  currency: "jpy",
  source: @stripe_token,
  description: "何らかのお支払"
}, {
  idempotency_key: @unique_key
})

自社サービス側も冪等に実装しておくことにより、ユーザが意図しない決済が発生することを防げます。

メタデータを保存可能

Stripeに登録する決済(Charge)、カスタマー(Customer)、払い戻し(Refund)などのリソースには、メタデータとして自由にキー:バリューなデータを保存できます。

自社システム側で振り出したIDなどを保存しておけば、システム間でのデータの突き合わせに役立ったりします。
保存したデータはWebコンソールで参照できます。

開発環境が整っている

開発用のAPIキー発行は管理コンソールから簡単にできます。 また、いくつでも発行できます。

実際に請求はされませんが、決済処理を行いそのデータも管理コンソールですぐに確認可能です。

テスト時の決済に使える各種ブランドのカード番号も用意されています。

stripe.com

エラーが発生して決済できない番号も用意されているので様々な挙動を確認することができます。

各種言語用のクライアントライブラリも用意されており、ドキュメントも揃っています。

Stripe API Reference

webhookもある

Stripeで決済Chargeを登録する。払い戻しRefundするといったイベントごとにWebhookにリクエストを送ることも可能となっています。

次の様な用途に利用できるでしょう。

  • お客様サポートのために決済エラーを監視する
  • お客様の購買行動からKPIをリアルタイムで把握する

まとめ

  • クレジットカード情報を一切自社サービスシステムに送らず決済可能
  • 一部払い戻し、ユーザの複数カードの管理など柔軟な決済機能が実装可能
  • 開発環境も整っており実装しやすい

Stripeのサブスクリプションについて調べたことは次のエントリに書いたのでこちらもどうぞ!

tech.actindi.net

最後に

どうしてStripeについて調査したのかというと先日リリースしたいこーよでのチケット販売サービス「すぐいこ」のためです。

「すぐいこ」は実現したいことのまだ一部しかできてません。 アクトインディでは一緒に「すぐいこ」を開発してくれるエンジニアを募集しています。


  1. Rails Checkout Guideの例から更に削って本当の必要最小限のコードとなっています。