WordPressでStripe決済フォームを配置するカスタムブロックを作成する方法

この記事では、WordPressで構築されたサイトに決済フォームを組み込むために、カスタムブロックを作成する方法を紹介します。　WordPressのブロック作成支援ツールと、Stripe SDKを利用したブロック実装方法の紹介と、実際のウェブサイトに導入する際の注意点をステップバイステップで紹介します。

## Step1: カスタムブロックのプロジェクトを新しく作成する

まず、新しいWordPressのカスタムブロックプロジェクトを作成します。ここではカスタムブロックを作成するためのCLIツールである[create-block](https://ja.wordpress.org/team/handbook/block-editor/getting-started/devenv/get-started-with-create-block/)を利用します。

```bash
$ npx @wordpress/create-block@latest example-wp-stripe
$ cd example-wp-stripe
```

## Step2: 開発・テスト環境の準備

開発をスムーズに進めるため、ローカルテスト環境を設定します。ローカルでの開発には、[wp-now](https://wordpress.org/playground/development-environments/)を利用します。これを利用することで、Dockerなどを利用せず、簡単にローカルテスト環境を用意できます。

```bash
$ npm i -D @wp-now/wp-now
$ npx wp-now start
```

このコマンドを実行すると、以下のようにローカルテスト環境のURLなどが表示されます。このURLにアクセスすると、WordPressサイトが表示されます。

```
Starting the server......
directory: /Users/sandbox/wordpress/example-wp-stripe
mode: plugin
php: 8.0
wp: latest
WordPress latest folder already exists. Skipping download.
SQLite folder already exists. Skipping download.
Server running at http://localhost:8881
```

### Stripe SDK(JS)のインストール

Stripeの決済フォームを埋め込むため、JavaScript SDKをインストールしましょう。Stripe APIはWordPressが提供する関数（`wp_remote_request`）から呼び出すため、PHP SDKのインストールは行いません。

```bash
$ npm i @stripe/stripe-js
```


## Step3: 編集画面の処理を実装する

カスタムブロック開発の準備ができましたので、実装を始めましょう。まずは`Edit.jsx`ファイルを編集して、注文ボタンのテキストをカスタマイズできるようにします。

`block.json`ファイルに新しい属性を追加します：

```json
{
  "attributes": {
    "button-label": {
      "type": "string",
      "default": "注文する"
    }
  }
}
```

次に、`Edit.jsx`を以下のように更新します：

```jsx
import { Button } from '@wordpress/components';
import { RichText, useBlockProps } from '@wordpress/block-editor';

export default function Edit({attributes, setAttributes}) {
  const blockProps = useBlockProps()
  return (
    <div { ...blockProps }>
      <Button variant="secondary">
        <RichText
          {...blockProps}
          onChange={text => {
            setAttributes({
              'button-label': text,
            })
          }}
          value={attributes['button-label']}
        />
      </Button>
    </div>
  );
}
```

この変更により、エディタ上でボタンのラベルを編集できるようになります。

![編集画面のスクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/3c23c7c2-c3c3-fd98-671c-79bff38b0b0a.png)

## Step4: 決済フォームのHTMLを実装する

続いてウェブサイトに決済フォームを表示するための処理を実装しましょう。今回はPHPの処理も実行するため、[ダイナミックブロック](https://ja.wordpress.org/team/handbook/block-editor/how-to-guides/block-tutorial/creating-dynamic-blocks/)として実装します。`block.json`に以下の行を追加しましょう：

```json
{
  "render": "file:./render.php"
}
```

`render.php`ファイルを作成し、以下のコードを追加します：

```php
<?php
  $block_wrapper_attributes = get_block_wrapper_attributes();
  $parsed_args = wp_parse_args( [
    "method" => "POST",
    "headers" => [
      "Authorization" => "Bearer sk_testからはじまるシークレットAPIキー",
    ],
    "body" => [
      "amount" => 100,
      "currency" => "jpy"
    ],
  ] );
  $response = wp_remote_request(
    "https://api.stripe.com/v1/payment_intents",
    $parsed_args
  );
  if ( is_wp_error( $response ) || $response['response']['code'] > 399 ) {
?>
  <div <?php echo $block_wrapper_attributes; ?>>
      <p>支払い情報の作成に失敗しました。</p>
  </div>
<?php
  } else {
  $body = json_decode( wp_remote_retrieve_body( $response ), true );
?>
  <form <?php echo $block_wrapper_attributes;?> id="payment-form">
    <div id="payment-element" data-client-secret="<?php echo $body['client_secret']; ?>"></div>
    <button type="submit">
      <?php echo esc_html( $attributes["button-label"] );?>
    </button>
  </form>
<?php } ?>
```

このコードは、Stripe APIを使用して支払い情報を作成し、フォームを表示します。エラーが発生した場合はエラーメッセージを表示します。

###フロントエンドのJavaScript実装

続いて決済フォームを埋め込むためのJavaScriptコードを追加します。`view.js`ファイルを作成し、以下のコードを追加しましょう：

```javascript
import { loadStripe } from "@stripe/stripe-js";

window.onload = async () => {
  try {
    const mountTargetElement = document.getElementById("payment-element");
    const clientSecret = mountTargetElement.getAttribute('data-client-secret');
    const stripe = await loadStripe('pk_test_からはじまる公開可能キー');
    const elements = stripe.elements({
      clientSecret,
      appearance: {
        theme: "stripe"
      }
    });
    const paymentElement = elements.create("payment", {
      layout: {
        type: 'tabs'
      }
    });
    paymentElement.mount("#payment-element");

    const formElement = document.getElementById("payment-form");
    formElement.addEventListener("submit", async e => {
      e.preventDefault();
      const { error } = await stripe.confirmPayment({
        elements,
        redirect: 'if_required'
      });
      if (error) {
        alert("支払いに失敗しました");
      } else {
        alert("支払いに成功しました");
      }
    });
  } catch (e) {
    console.log(e)
  }
}
```

このコードは、Stripe Elements を使用して決済フォームを表示し、フォーム送信時に決済処理を行います。

## 実運用時の注意点

### Stripe APIキーの管理

セキュリティのため、公開可能キーとシークレットAPIキーは環境変数やSettings APIを使用して安全に管理しましょう。

### ブロックの複数配置制限

決済フォームを1つの記事に複数配置することは通常ありません。`block.json`に以下の設定を追加して、ブロックの複数配置を制限できます：

```json
{
  "supports": {
    "multiple": false
  }
}
```

## まとめ

この記事では、WordPressのブロックエディタを使用してStripe決済フォームを実装する方法を説明しました。カスタムブロックの作成からStripe SDKの統合、フロントエンド処理の実装まで、段階的に解説しました。

実際のプロジェクトに適用する際は、セキュリティに十分注意し、APIキーの管理や適切なエラーハンドリングを行ってください。また、Stripeの開発者ドキュメントを参照し、最新のベストプラクティスに従うことをお勧めします。

## 参考ドキュメント

https://ja.wordpress.org/team/handbook/block-editor/how-to-guides/block-tutorial/creating-dynamic-blocks/

https://docs.stripe.com/api

https://docs.stripe.com/get-started/development-environment

https://docs.stripe.com/get-started/checklist/go-live