Payment Request APIで簡単に決済機能を提供する

Payment Request APIとは

Payment Request APIは支払い情報・配送先住所などを入力するUIを提供するAPIです。このAPIでは、ブラウザなどに記録されているクレジットカード情報や住所を、UIからユーザが選択することもできるので、支払いなどでのユーザの負担を軽減することができます。

このAPIは入力されたデータをJavaScriptでPAY.JPやStripeなどの外部決済サービスに送信し、レスポンスを受け取って決済の結果を画面に表示する機能のみです。実際に使用するためには、サービスと事前に連携させる必要があります。

Payment Request APIを使用した場合のフロー

Payment Request APIを使用した場合のフローは以下のようになるかと思います。

・Webサイト上で購入する商品を選択
・購入ボタンをクリック
・Payment Requestの表示
・支払い方法の選択
・支払いボタンのクリック
・(決済処理)
・決済処理の結果に応じた画面表示

実際の使用方法

このAPI自体は決済処理を行わないため、決済サービスと連携させて使用することになります。今回はPAY.JPと連携させたサンプルnodeアプリを作成しました。このアプリの作成には以下のページを参考にしました。

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const payjp = require('payjp')('sk_test_key);

app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended: true}));

app.get('/', function (req, res) {
   res.render('index');
});

app.post('/pay', function (req, res) {
   Promise.resolve(payjp.charges.create({
           card: req.body.token,
           amount: req.body.amount,
           currency: 'jpy'
       })
   )
       .then((r) => {
           res.sendStatus(200);
       }, (err) => {
           res.sendStatus(500);
       })
});

app.listen(3000, function () {
   console.log('sample app listening on port 3000!');
});
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8">
   <title>Payment Request API Demo</title>
</head>
<body>
<a id="buy" href="#">buy</a>
<script type="text/javascript" src="https://js.pay.jp/"></script>
<script>
   Payjp.setPublicKey("pk_test_key");

   function onBuyClicked() {
       if (!window.PaymentRequest) {
           console.log("Payment Request APIに対応していません");
           return
       }

       // サポートする支払い方法
       const supportedInstruments = [{
           supportedMethods: ['basic-card'],
           data: {
               supportedNetworks: [
                   'visa', 'mastercard', 'jcb'
               ]
           }
       }];

       // 支払う商品
       const details = {
           displayItems: [{
               label: 'りんご',
               amount: {currency: 'JPY', value: '100'}
           }],
           total: {
               label: '合計',
               amount: {currency: 'JPY', value: '100'}
           }
       };

       const request = new PaymentRequest(supportedInstruments, details);
       const xhr = new XMLHttpRequest();
       
       // `.show()` を呼び出して、ネイティブ UI を表示する
       request.show()
           .then(result => {
               const card = {
                   number: result.details.cardNumber,
                   exp_month: result.details.expiryMonth,
                   exp_year: result.details.expiryYear,
                   cvc: result.details.cardSecurityCode,
               };
               Payjp.createToken(card, function (status, response) {
                   if (status === 200) {
                       xhr.addEventListener('loadend', function () {
                           if (xhr.status === 200) {
                               return result.complete('success');
                           } else {
                               return result.complete('fail');
                           }
                       });
                       xhr.open('POST', 'http://localhost:3000/pay');
                       xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                       xhr.send('token=' + response.id + '&amount=' + details.total.amount.value);
                   } else {
                       return result.complete('fail');
                   }
               });
           });
   }

   document.querySelector('#buy').addEventListener('click', onBuyClicked);
</script>
</body>
</html>

このサンプルアプリを試す際には、PAY.JPに登録しAPIキーを取得してコードのsk_test_key、pk_test_keyを置き換えてください。また、サンプルアプリのため、エラー処理などを簡単にしているので注意してください。
実際にPayment Request APIを使用する際には、サーバに送信されたトークンの検証や支払いの状態をDBに記録するといった処理が追加で必要になるかと思います。

ブラウザ対応状況

最後に各ブラウザの対応状況ですが、この記事の執筆時点では以下のようになっています。各ブラウザの対応状況を確認の上使用してください。

IE 非対応Edge Edge 15 から対応
Firefox 対応しているが、デフォルトでは無効
Chrome for desktop release 61 から対応
Chrome for Android release 53 から対応
Chrome for iOS release 62 から対応
Safari 11.1 から対応iOS Safari 11.3 から対応


この記事が気に入ったら、サポートをしてみませんか?気軽にクリエイターを支援できます。

15

smasato

#エンジニア 系記事まとめ

noteに投稿されたエンジニア系の記事のまとめ。コーディングTIPSよりは、考察や意見などを中心に。
コメントを投稿するには、 ログイン または 会員登録 をする必要があります。