Apple Pay を Web アプリで利用したいと思い利用方法を調べた結果です。
Apple Pay について
公式に日本語のドキュメントがあるのでそこを見れば大体は理解できると思います。
その中で開発者として気をつけないければならないこととしては、 ペイメントサービスプロバイダと連携する ことが強く推奨されています。
SDKやJS APIに関しては、Apple Payをサポートするペイメントサービスプロバイダが提供するものを使用することが強く推奨されています。別の方法としては、AppやWebサイトからの支払いの受け取り、ペイメントトークンの復号、承認のためのペイメントサービスプロバイダとのやり取りといった、一連のプロセスを実行するためのサーバサイドソリューションをデベロッパ自身で用意することもできます。クレジットやデビットカードによる支払いへの対応は複雑になる場合があります。そのため、専門知識を有しているか、すでにシステムが用意されている場合でない限り、ペイメントサービスプロバイダが提供するApple PayのSDKやJS APIを使用することが、AppやWebサイトにApple Payをサポートする上で最も簡単かつ安全な方法です。詳しくは、ご利用のプラットフォームまたはペイメントサービスプロバイダにお問い合わせください
つまり、「素人は下手に手を出さず、専門の方々がラップしたものを利用してくれ」というとこだと察します。
現時点(2019/09/17)では以下の10社がラッパを提供してくれているようです。
この中から今回は PAY.JP を使用して Apple Pay を実装しようと思います。
準備
- create-nuxt-app のインストール
- Nuxt アプリの雛形を作成してくれるものです。今回はこちらから作成します。
- PAY.JP のアカウント登録
問題
こちらのサンプル にある通り、 pay.jp で Apple Pay を利用するためのモジュールは script タグでロードされることを想定しており、 package.json で管理できません。
なので Vue コンポーネントのヘッダーで外部リソースとして読み込む必要がありますが、これが読み込めず...。
以下自分が試したことですが、全て失敗に終わったのでスキップしていただいて構いません。
ヘッダーで pay.jp のライブラリを外部リソースとして読み込む
こんな実装です。
@Component({
head: function() {
return {
script: [
{ src: 'https://js.pay.jp/' }
]
}
}
})
export default class index extends Vue {
mounted() {
// @ts-ignore
window.Payjp.setPublicKey('xxxxxxxx')
}
}
ページのヘッダーで https://js.pay.jp/
をロードして、 DOM に触ることのできる mounted()
のタイミングで初期化処理をしています。
Payjp
を読み込めないとエラーが表示されるので // @ts-ignore
をしています。本来は declear global
などで Window に Payjp を定義してあげる方法が綺麗かと思いますが、自分の環境ではなぜかエラーが解消されなかったので汚いですが ignore としました。
Window に Payjp を定義してあげる方法はこちらの記事が参考になると思います。
https://qiita.com/moriyuu/items/f0340a9ed22ea43d7b4c
問題点
上記実装で問題なく Payjp モジュールを参照することができたのですが、 ApplePaySession
を参照することができません。
ApplePaySession
は Apple Pay のフォームに成功可否を通知して UI を表示するために使用します。
ApplePaySession.STATUS_SUCCESS
を通知すれば Apple Pay のフォームに成功と表示されて閉じますし、それ以外なら失敗と表示されます。
成功 | 失敗(undefined) |
---|---|
サンプルの例でいうと、buildSession が成功すると 1つ目の result を引数に持つコールバックが呼ばれます。バックエンドで実装した決済 API をコールして成功したら ApplePaySession.STATUS_SUCCESS
を通知してあげます。
result.token.id
は取得できているのに、 ApplePaySession
が undefined なためエラーとなってしまいます。
// @ts-ignore
let session = window.Payjp.applePay.buildSession(req, (result: any) => {
// TODO: ここで result.token.id を使って backend の決済 API をコールする
// @ts-ignore
session.completePayment(window.Payjp.ApplePaySession.STATUS_SUCCESS)
alert(result.token.id)
}, (e: any) => {
alert(e.error.message)
})
session.begin()
以下のパターンで試してみましたが、どれも undefined でした。
- window.ApplePaySession
- window.Payjp.ApplePaySession
- window.Payjp.applePay.ApplePaySession
対応
結果的にサンプルコードを static/ 配下に pay.html として設置して <a href='/pay.html'>
でリンクするという方法に至りました。
これであれば、 ApplePaySession
を参照可能です。
コード全体はこちらです。
所感
- PAY.JP のドキュメントは日本語で内容も充実していると感じた。
- 会員登録前でもドキュメントを参照できるのはすごくありがたい。
- Web コンソールが使いやすい。
- サンプルが充実しているので Nuxt のサンプルもそこに追加してほしい。
以上です。