StripeにPayPayを組み込んでみよう

こんにちは。Stripeのパートナーソリューションエンジニア池田です。

普段はStripeのパートナー様の技術支援的なお仕事をしています。

今回はQiitaにて、Stripeの **EPM (External Payment Methods)** という機能と、それを使ってPayPayのような外部決済手段をStripeに組み込む方法についてお伝えしようと思います。

簡単に言うと、StripeにPayPayを組み込んでみよう！ ということです。

# EPMとは
EPMとはExternal Payment Methodsの略称で、Stripeでは包括契約をサポートしていない決済手段（外部決済手段）を、StripeのPaymentElementというUIの中に組み込んでUXを高めることができるという機能のことです。

詳細については[公式のドキュメント](https://stripe.com/docs/payments/external-payment-methods)もぜひご確認ください。実装手順や免責事項も記載されています。

さて、このEPMですが、リダイレクト型なら国内外問わずかなりの数の決済手段に対応しています。（[こちらのページ](https://stripe.com/jp/payments/payment-methods)で外部と記載のあるものが該当します）

PayPayも例外ではありません。


## PayPayをEPMとして組み込んでみよう！

### PayPay for Developersに会員登録
まずはPayPay for Developersへ登録して、開発アカウントとAPIキー等々を取得しましょう。

下記のページから登録ができます。

https://developer.paypay.ne.jp/account/signup

無事登録が完了すると、数分〜数時間後にテスト環境とダッシュボードへのアクセスが可能になります。そこでは次の画像のように、APIキー、シークレット、およびテストユーザーの情報等にアクセスできるようになります。

![Screenshot 2023-12-14 at 16.01.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6116/0cb7f767-8880-f994-fe62-38de754067ca.png)


### PayPayのAPIキーを取得
ダッシュボードからAPIキーとシークレット、および加盟店ID（マーチャントID）を取得し、どこかにメモを取っておきます。

準備ができたらStripeのアカウントの用意と、サンプルコードの取得を行います。

### PaymentElementのコードを取得
Stripeの下記のドキュメントページで、PaymentElementを使った簡単なコードサンプル一式を取得できます。なお、Stripeアカウントがまだない方は先にアカウント取得をするのを忘れずに。

https://stripe.com/docs/payments/quickstart

今回のこの記事ではフロントエンドをWeb/HTML、バックエンドをNodeで実装を行っていきますので、コードサンプルもNodeとHTMLで取得しておくとよいでしょう。

ここからEPMのコードを追加していきます。途中までは[公式のドキュメント](https://stripe.com/docs/payments/external-payment-methods)の記載内容とほぼ同じです。

### externalPaymentMethodTyepsを設定
フロントエンドのcheckout.jsに対して、下記のコードを追記し、EPMにPayPayを追加することを宣言します。

```javascript:checkout.js
elements = stripe.elements({

    clientSecret: clientSecret,

    externalPaymentMethodTypes: ['external_paypay']

});
```

`'external_paypay'`という文字列がどこから来たか？ 当然疑問を持たれると思います。ここで指定できる文字列は[ここ](https://stripe.com/docs/payments/external-payment-methods#%E5%88%A9%E7%94%A8%E5%8F%AF%E8%83%BD%E3%81%AA%E5%A4%96%E9%83%A8%E3%81%AE%E6%B1%BA%E6%B8%88%E6%89%8B%E6%AE%B5)から探せます。

### 外部決済手段へのリダイレクト実装
EPMにおいて、外部決済手段へのリダイレクトの方法は2種類あって、ボタンそのものを置き換えるか、アクションを置き換えるかです。ここではアクションを置き換えます。

下記のコードを追加し、ユーザーが決済手段を変更したときの値を格納しておきます。

```javascript:checkout.js
paymentElement.mount("#payment-element");

// 選択された決済手段を格納しておく
let selectedPaymentMethod;

paymentElement.on('change', (event) => {

  selectedPaymentMethod = event?.value?.type;

});
```

そしてhandleSubmit関数の中で下記のように分岐を作ります。なお、handlesubmitはサンプルコードの中でsubmitイベントのリスナーにバインドされています。

```javascript:checkout.js
if (selectedPaymentMethod === 'external_paypay') {
  // Redirect customer to the PayPay checkout page to complete the transaction
  const paypayRedirectUrl = "<< fill the Divido redirect URL here >>";
  window.location.href = paypayRedirectUrl;
} else {
  const { error } = await stripe.confirmPayment({
  ...略...
}
```

最後にelements作成時のコードを次のように書き換え、PayPayが二番目に来るようにします。

```javascript:checkout.js
const paymentElement = elements.create("payment", {
  paymentMethodOrder: ['card', 'external_paypay']
});
```
ここまでフロントエンドを実装したら `npm start` して表示が変わるかどうか確認しましょう。

うまく行っていれば次のように、PaymentElementにPayPayのUIが出現します。

![Screenshot 2023-12-14 at 15.59.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6116/c327cb31-f27f-b8b5-b9d5-3cfc7966836c.png)

人によってはコンビニ決済やAlipay, WechatPayは出ていないかもしれません。こちらは[別途ダッシュボード](https://dashboard.stripe.com/test/settings/payment_methods)で有効にしておく必要があります。必要なければ特に気にしなくとも構いません。PayPayが出現しているかどうかがここでは重要です。

### バックエンド呼び出しコードの追加
ここまでできたら、PayPay呼び出しのコードを書き、UIから呼び出すだけです。

サーバサイドのコードは後ほど書くとして、ひとまずクライアントサイドのhandlesubmitを次のように書き換えておきましょう。

```javascript:checkout.js
if(selectedPaymentMethod === 'external_paypay') {
    const response = await fetch("/create-paypay", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: null,
    });
    const { url } = await response.json();

    const paypayRedirectUrl =  url;
    window.location.href = paypayRedirectUrl;
```

### バックエンドの実装
さて、それではバックエンドの処理を書きます。


まずPayPayライブラリを次のようにインストールします。uuidも必要になるのでここで一緒にインストールしています。

```bash
npm install --save @paypayopa/paypayopa-sdk-node uuid
```

ライブラリをインストールしたら、`server.js` に次のようなコードを書き、PayPayの設定を行います。

```javascript:server.js
const PAYPAY = require('@paypayopa/paypayopa-sdk-node');
PAYPAY.Configure({
  clientId: "PayPayのAPIキー",
  clientSecret: "PayPayのシークレット",
  merchantId: "PayPayの加盟店ID",
  productionMode: false
});
const uuid = require('uuid'); //これも後で使います
```

前もって用意しておいたPayPayのテスト環境のAPIキー、APIシークレット、加盟店IDをここで利用します。

APIキーとシークレット、マーチャントIDの部分は `.env` などを使って環境変数経由で取得するように書いたほうがいいですが、ここでは省略しています。


次に、下記のようなコードを書き、クライアントからPOSTでPayPayのリクエストを受け取れるようにします。

```javascript:server.js
app.post('/create-paypay', async (req, res) => {
    const paymentId = uuid.v4();
    const payload = {
        merchantPaymentId: paymentId,
        amount: { "amount":3000, "currency": "JPY" },
        codeType: 'ORDER_QR',
        orderItems: null,
        redirectUrl: 'http://localhost:4242/checkout.html',
        redirectType: 'WEB_LINK',
    };
    console.log(payload);
  
    PAYPAY.QRCodeCreate(payload, (ppResonse) => {
      const body = ppResonse.BODY;
      res.send({ url: body.data.url});
    });


});
```

コードを簡単にするためにamountパラメータをここでは固定値で入れていますが、実際にはクライアントから値を受け取って処理するといいでしょう。

その他のパラメータについては他にもバリエーションはありますので、詳しくは[PayPayのドキュメント](https://developer.paypay.ne.jp/products/docs/webpayment)を参照してください。

実装としてはこれだけで終わりです。簡単ですよね。


### 動作イメージ
全てうまくいくと、次のように動作します。確認してみてください。

![paypay_qiita3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6116/a6cf3731-ed97-32a9-e4bf-0fa007e5039b.gif)


## サンプルコード
コード一式は下記から取得してください。

https://github.com/ikeike-stripe/SampleForQiita