ReactでStripeの決済フォームを試す
React SPAでStripeの決済フォームを組み込む方法について整理してみました。 準備 めんどうなので、create-react-appでざっと立てます。 とりあえずこれでReact SPAが簡単につくれます。 r […]
目次
React SPAでStripeの決済フォームを組み込む方法について整理してみました。
準備
めんどうなので、create-react-appでざっと立てます。
$ create-react-app stripe-test
$ cd stripe-test
$ yarn start
とりあえずこれでReact SPAが簡単につくれます。
react-stripe-elements を試す
Stripeのカード情報入力フォームは、react-stripe-elementsを使います。stripe-elementを組み込んだライブラリなので、自力で作る手間が大幅に省けます。
$ yarn add react-stripe-elements
/public/index.htmlでスクリプトを読み込む
Stripeのライブラリを使用するため、/public/index.htmlに以下のコードを追加します。
<script src="https://js.stripe.com/v3/"></script>
/src/App.js
Providerが必要になるので、設定します。プロパティとして、Stripeの公開キーを設定しましょう。
import React, { Component } from 'react';
import {StripeProvider} from 'react-stripe-elements';
import CardForm from './CardForm';
import logo from './logo.svg';
import './App.css';
class App extends Component {
  render() {
    return (
      <StripeProvider apiKey="pk_test_XXXXXXX">
        <div className="App">
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <h1 className="App-title">Welcome to React</h1>
          </header>
          <CardForm />
        </div>
      </StripeProvider>
    );
  }
}
export default App;
/src/CardForm.jsx
カード情報入力フォームを設定します。formを作るコンポーネントをinjectStripeすることで、コンポーネントがthis.props.stripeからstripe-jsのメソッドを利用することができるようになります。
import React from 'react';
import {Elements, injectStripe, CardElement} from 'react-stripe-elements';
// フォーム要素のスタイルなどを定義する
const createOptions = (fontSize: string) => {
  return {
    hidePostalCode: false,
    style: {
      base: {
        fontSize,
        color: '#424770',
        letterSpacing: '0.025em',
        fontFamily: 'Source Code Pro, monospace',
        '::placeholder': {
          color: '#aab7c4',
        },
      },
      invalid: {
        color: '#9e2146',
      },
    },
  };
};
// Cardフォームの要素を定義するコンポーネント
class CardSection extends React.Component {
  render() {
    return (
      <label>
        Card details
        <CardElement
          {...createOptions()}
        />
      </label>
    );
  }
};
// Formの定義と、submit時のアクションを定義するコンポーネント
class CheckoutForm extends React.Component {
  handleSubmit = (ev) => {
    ev.preventDefault();
    this.props.stripe.createToken({name: 'Jenny Rosen'}).then(({token}) => {
      console.log('Received Stripe token:', token);
    });
  }
  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <CardSection />
        <button>Confirm order</button>
      </form>
    );
  }
}
// ここでCheckoutFormがstripe-jsにアクセスできるようにしている
const InjectedCheckoutForm = injectStripe(CheckoutForm);
// Elementsでラップする
class MyStoreCheckout extends React.Component {
  render() {
    return (
      <Elements>
        <InjectedCheckoutForm />
      </Elements>
    );
  }
}
export default MyStoreCheckout;
完成系
上記の編集が完了すると、以下のようにStripeのカードフォームが表示されます。

テスト用のカード番号を入力して[Confirm order]すると、tok_xxxxのような値を含むデータがconsoleに出力されます。
tokenでカスタマーを作成する
先ほどのスクリプトで作成されたtokenを使うことでStripeへのカード情報登録ができます。本来はAPIを作ってそこにリクエストするやり方ですが、めんどうなので今回はcurlで横着します。
curl https://api.stripe.com/v1/customers \
   -u sk_test_xxxxxxx: \
   -d description="Customer for [email protected]" \
   -d email="[email protected]" \
   -d source="tok_xxxxxxx"
実行すると、Stripeのダッシュボードにデータが登録されています。

stripe-jsとreact-stripe-elementsを使うメリット
- カード情報を自分が管理しているサーバーに一切残さずに済む
 - いい感じのカードフォーム(4桁区切り・オートフォーカスなど)が使える
 - カスタマイズ性が高いので、自社サービスへの組み込みがしやすい
 
具体的なカスタマイズなどはまた追い追い紹介します。