SDK ではなく REST API で PayPal 決済・認証をする
下記公式ドキュメントで使用されている PayPal の SDK は便利だが、購入ボタンが特定のデザインに固定される。完全にカスタマイズされたボタンで PayPal 決済をする方法を探る。
前提
- Web アプリケーションで商品を購入できるようにしたい
- 購入ボタンはオリジナルのものを作りたい
- 金額は予めわかっている
- ユーザーが承認したら即座に決済を完了し、元の商品ページに戻りたい
Create Order
PayPal REST API で Create Order し、レスポンスで返ってくる決済承認用 URL にユーザーをリダイレクトすればよさそう。
To create an order:
- In your Postman workspace, navigate to your fork of the PayPal collection.
- Select Orders > Create Order > Send. On a successful call, the API returns a 201 order created response code.
- Find the approve link in the response.
- Open the approve link in a browser.
- Log in with your Developer Dashboard sandbox personal account credentials.
Create Order のエンドポイントを叩く際に、リダイレクトから戻ったときの URL やキャンセル時に戻る URL、PayPal-Request-Idリクエストヘッダーなど必要なものはもろもろリクエストに含めておく。
承認されたら即座に決済を完了させたいが、Capture はどうやってやればいいんだろう。
ユーザーがブラウザで承認した後じゃないといけない。
return_url
のクエリパラメータにいろいろ情報を詰めておき、商品ページに戻ってきた時に改めて Capture するのが一つの案。
Create Order 時の return_url
には元の商品ページを指定するイメージでいたが、承認後に行いたい処理を実装した API の URL を指定することでも Capture ができそう。
アプリケーション用の API を用意し、承認後に行いたい処理を特定のエンドポイントに実装する。
このエンドポイントの中で PayPal API の Capture を叩き、成功したら元の商品ページにリダイレクトするレスポンスを返す。
PayPal の Webhook を使う手もありそう。
しかし、購入が完了していたら商品ページで即座に状況を反映したいので、遅延が発生しないように上記の案がよさそう。
エラーハンドリング
PayPalアカウントのカード与信エラーの発生方法:
カードの請求先住所(カードを登録する際に入力)の番地(Line1)に「CCREJECT-REFUSED」といれると、カード与信エラーが常に発生するようになります。このカードを決済時に利用することで、上記の「カード与信エラーが起きた場合のリカバリー」のテストができます。
と書いてあるが、上記記事でリンクされたドキュメントが 404 なのでもう使えないのか...?
リクエストの値をいじってエラーにする方法は下記にあるが、E2E でテストしたいのでアカウント側の設定でやりたいなあ。
これでできそう!
sandbox アカウントでログインして、カード作成時に住所にエラートリガー文字列を入れておくとエラーにできた。(ドキュメントのようにカード名や First Name を設定する欄は見当たらない。)
不正なカードを使って決済しようとすると、capture に失敗して下記のようなエラーメッセージが返ってきた。
{
"name": "UNPROCESSABLE_ENTITY",
"details": [
{
"issue": "INSTRUMENT_DECLINED",
"description": "The instrument presented was either declined by the processor or bank, or it can't be used for this payment."
}
],
"message": "The requested action could not be performed, semantically incorrect, or failed business validation.",
"debug_id": "e416fbb215a2f",
"links": [
{
"href": "https://developer.paypal.com/docs/api/orders/v2/#error-INSTRUMENT_DECLINED",
"rel": "information_link",
"method": "GET"
},
{
"href": "https://www.sandbox.paypal.com/checkoutnow?token=9LC452798Y049805P",
"rel": "redirect",
"method": "GET"
}
]
}
ユーザーが PayPal を使って Web サービス上のコンテンツを購入する実装は上記の流れでできる。
ユーザーの PayPal アカウントに送金するには
逆に、ユーザーが Web サービス上で立てた売上げをサービス側から送金したいときにどうするか。
PayPal に登録されているメールアドレスか携帯電話番号を使う。
PayPalアカウントを使用して資金を受け取るには、PayPalアカウントに登録されている確認済みのメールアドレス、または携帯電話番号に支払いを行うよう、支払い元に依頼してください。
メールアドレスを使うとして、どうやってサービス側から取得するか。下記のドキュメントに書いてある。
個人情報を Web サービス上で管理するのは嫌なので、認証に使っている Firebase Authentication を利用できないか試してみる。PayPal は OpenID Connect 準拠のようなので自前で provider を作れば出来そう。
と思ったが、PayPal sandbox のディスカバリードキュメントがないのでこの方法は無理だ。(live 環境しか使ってないならできるけど)