PHP(WordPress)でStripeを使ってみたのでまとめてみました。

# 背景

とある業務にて、WordPressのプラグイン上にStripeの決済を実装することになったので、その時のメモを共有しておきます。  
なおこの記事は、[Stripe Advent Calendar 2017](https://adventar.org/calendars/2339)  の12月14日としても投稿しています。

# テスト環境

Stripeのダッシュボードにログインすると、テストデータと本番データをいい感じで切り替えるボタンが出てきます。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/125488/f02bc05c-0d21-56cf-fb8f-6384b5835da0.png)

APIの公開キーと、シークレットキーもこのダッシュボードから取得可能です。

# 準備
PHPもしっかりとSDKが用意されているため、まずはそれをダウンロードします。

https://github.com/stripe/stripe-php
  
今回Wordpressのプラグインに組み込むので、wp-content/plugins/myPlugin/vendor/stripe-php として配置してみました。

# 呼び出し

SDKのrequireは非常に簡単です。

``` myPlugin.php
        require_once(dirname(__FILE__) . '/'. 'vendor/stripe-php/init.php');
        \Stripe\Stripe::setApiKey(get_option('stripe_api_key'));
```

Stripeのキー情報は、WordPressの設定として保存しておきます。こうすることで、APIキーを切り替えるだけで運用環境とテスト環境を切り替えることができます。get_optionの使い方は、WordPressのドキュメントをご参照ください。

# カード登録

カスタマーカードの登録も、超簡単です。基本的には、公式のドキュメントにあるソースをコピペするだけでOKです。

https://stripe.com/docs/stripe-js/elements/quickstart

ですが、ここでもAPI公開キーをテスト用と本番用で切り分ける必要があるため少しだけ修正を加えてます。  
PHP側でWordPressの設定値として保存した公開キーを取得して、inputタグのattributeとして設定しておきます。

``` create_card.php
<script src="https://js.stripe.com/v3/"></script>
<div class="form-row">
    <div id="card-element"></div>
    <div id="card-errors" role="alert"></div>
</div>
<input type="submit" name="update" id="stripe_payment_button" data-stripe-public-key="<?= get_option('stripe_api_public') ?>" value="作成">
```

設定しておいたattributeからキーを取得する動作にしています。その他はサンプルコードのままで動きます。

``` create_card.js
// Create a Stripe client
const b = document.getElementById('stripe_payment_button'); 
const pk = b.getAttribute('data-stripe-public-key');
const stripe = Stripe(pk);
```

# POSTで受け取ったカードを使って更新

さて、ここからが少しサンプルと違うところです。StripeのSDKはカードエラーを例外として投げてきます。なので、サンプルコードをそのまま使った場合、不正なカードが来た時に500エラーになります。カードの作成、サブスクリプション、決済、などいくつか必要な処理があるので、実際には、エラーをハンドリングするクラスを作ってラップするのが良いと思います。

※ ちなみに不正なカードのテストデータはこちら。
https://stripe.com/docs/testing

``` create_card.php
        $response = array(
            'body' => null,
            'message' => ''
        );
        try {
            $token = $_POST['stripeToken'];
            $body = array('source' => $token);
            if (isset($email)) {
                $body['email'] = $email;
            }
            $response['body'] = \Stripe\Customer::create($body);
            $response['message'] = 'カード処理に成功しました。';
        } catch(\Stripe\Error\Card $e) {
            $body = $e->getJsonBody();
            $err  = $body['error'];
            switch ($err['code']) {
                case 'invalid_number':
                    // エラーごとの処理
                    break;
                case 'incorrect_number':
                    // エラーごとの処理
                    break;
                case 'invalid_expiry_month':
                    // エラーごとの処理
                    break;
                case 'invalid_expiry_year':
                    // エラーごとの処理
                    break;
                case 'expired_card':
                    // エラーごとの処理
                    break;
                case 'invalid_cvc':
                    // エラーごとの処理
                    break;
                case 'incorrect_cvc':
                    // エラーごとの処理
                    break;
                case 'invalid_swipe_data':
                    // エラーごとの処理
                    break;
                case 'incorrect_zip':
                    // エラーごとの処理
                    break;
                case 'card_declined':
                    // エラーごとの処理
                    break;
                default:
                    break;
            }
        } catch(Exception $e) {
            $response['message'] = 'カード処理の実行中にプログラムエラーが発生しました。';
        }
        return $response;
```

エラーの内容は、ドキュメントを参照してください。
https://stripe.com/docs/api#errors

# まとめ

すごく簡単に実装できます。  
実際のカードに関するところは、たったこれだけですからね！

``` cool.php
\Stripe\Customer::create($body)
```