Node.jsでPayPalの商品購入の通知(Webhook)を受け取る
PayPalライトユーザーなので簡単な通知受け取りやってみます。
PayPalのAPIは正直分かりにくいので自分用にまとめます。APIのドキュメントページは以前よりは良くなったけど、昔から存在する分、調べていると過去の情報と混同しがちです。なので2018年2月バージョンです。適宜読み替え必須。
別途ちゃんと記事にまとめたい
かんたん決済ボタン
で会社の商品(Nefry BT)販売しています
PayPalにはかんたん決済ボタン
というツールがあります。たぶん通称がPayPalボタン
で、製品名がウェブペイメントスタンダード
。呼び方いっぱいありますね苦笑
https://www.paypal.com/jp/webapps/mpp/merchant/solutions/paypal-button
HTMLソースを貼り付けるだけで商品購入機能を追加でき、すごく簡単に作れて助かっています。
例えばNefry BTの購入ページからたどると、こんな画面になります。
かんたん決済ボタン(PayPalボタン)の購入通知をNode.jsで受け取りたい
この、商品が購入されたことを知りたいときに使う仕組みがInstant Payment Notification (IPN)
と呼ぶそうです。認識間違ってるかもしれないけど僕はそう理解しておきます。
ちなみに、毎回購入してテストするのも大変なので、購入があったときに通知をシミュレーション出来るツールもあります。
Instant Payment Notification (IPN) Simulator
らしいです。
今回は手元のMacでNode.jsのサーバーを立ててngrokを経由してPayPalからのWebhookを受け取ります。
Expressを使ってPOSTリクエストを受け取るので、expressとbody-parserをインストールします。
ちなみにNode.jsはv9.5.0です。
$ npm init -y
$ npm i --save express body-parser
$ touch app.js
'use strict';
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({extended: false}));
app.use(express.static(__dirname+'/'));
const PORT = process.env.PORT || 3000;
app.post('/', async (req, res) => {
console.log(req.body); //PayPalから送られて来る情報の確認
const response = {
message: 'Success!'
};
res.end(JSON.stringify(response));
});
app.listen(PORT);
console.log(`listening on *:${PORT}`);
起動
$ node app.js
listening on *:3000
これで3000番ポートでサーバーが起動します。
このままだと、PayPal側からのWebhookを手元のPCで立てただけのサーバーでは受け取れないのでngrokを使ってトンネリングをします。
まずインストールです。npm経由でインストールできます。
$ npm i -g ngrok
先ほどNode.jsで3000番ポートでサーバーを立てたので、3000番ポートにリダイレクトするトンネリングサーバーを起動します。ターミナルの別タブなどで起動しましょう。
$ ngrok http 3000
起動するとこんな感じでURLが発行されます。
ngrok by @inconshreveable (Ctrl+C to quit)
Session Status online
Account n0bisuke (Plan: Free)
Version 2.2.8
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://2c0f263e.ngrok.io -> localhost:3000
Forwarding https://2c0f263e.ngrok.io -> localhost:3000
Connections ttl opn rt1 rt5 p50 p90
8 0 0.00 0.00 0.21 5.61
この場合だとhttps://2c0f263e.ngrok.io
がトンネリングサーバーのURLです。
このURLはグローバル公開されているので、このURLに対してPayPalはPOSTリクエストを送ることが出来ます。
このトンネリングサーバーにPOSTリクエストがあると、手元のNode.jsで立てたサーバーにもPOSTリクエストがそのまま送られます。
ちなみにngrokのURLはngrokを再起動するたびに再発行されるので注意しましょう。
Instant Payment Notification (IPN) Simulatorで試してみる
こちらのURLにアクセスし、IPN handler URL
の箇所に、ngrokで作成したトンネリングサーバーのURL(今回だとhttps://2c0f263e.ngrok.io
)を設定します。Transaction type
はあんまりよく分かってないけどExpress Checkout
にしました。(教えて下さい)
この状態でページ下部のSend IPN
を押しましょう。
これで購入があったときのようなPOSTリクエストがPayPalから送られてきて、手元で確認できます。
$ node app.js
listening on *:3000
{ payment_type: 'instant',
payment_date: 'Mon Feb 12 2018 19:27:32 GMT+0900 (JST)',
payment_status: 'Pending',
address_status: 'confirmed',
payer_status: 'verified',
first_name: 'John',
last_name: 'Smith',
payer_email: '[email protected]',
payer_id: 'TESTBUYERID01',
address_name: 'John Smith',
address_country: 'United States',
address_country_code: 'US',
address_zip: '95131',
address_state: 'CA',
address_city: 'San Jose',
address_street: '123 any street',
business: '[email protected]',
receiver_email: '[email protected]',
receiver_id: '[email protected]',
residence_country: 'US',
item_name: 'something',
item_number: 'AK-1234',
quantity: '1',
shipping: '3.04',
tax: '2.02',
mc_currency: 'USD',
mc_fee: '0.44',
mc_gross: '12.34',
mc_gross_1: '9.34',
txn_type: 'web_accept',
txn_id: '507675401',
notify_version: '2.1',
custom: 'xyz123',
invoice: 'abc1234',
test_ipn: '1',
verify_sign: 'AV5g.RRvzcNMaeOO73JJ-F3fudM2ApaAE0NwEVMxteL8ElyK913tPoLn' }
ターミナルにこんな感じのログが表示されればOKです。
実際のかんたん決済ボタン(PayPalボタン)
で試してみる
ボタンの設定画面でステップ 3: 高度な機能をカスタマイズする(オプション)
を選択し、その中の高度な変数を追加する
の項目にnotify_url=(Webhookを受け取るサーバーのURL)
という形式で記述します。
今回の場合はnotify_url=https://2c0f263e.ngrok.io
を記述しました。
この状態で実際に購入してみると手元のNode.jsのサーバーに情報が送られてきます。
{ mc_gross: '1',
protection_eligibility: 'Eligible',
address_status: 'confirmed',
payer_id: 'YKQ5X3VAHDSR8',
address_street: '����2-17-11\r\n�N���G�C�^�[�Y�V�F�A�n�E�X �g���u��',
payment_date: '12:19:52 Feb 17, 2018 PST',
payment_status: 'Completed',
charset: 'Shift_JIS',
address_zip: '111-0025',
first_name: '�ɉ�',
mc_fee: '1',
address_country_code: 'JP',
address_name: '���� �ɉ�',
notify_version: '3.9',
custom: '',
payer_status: 'verified',
business: '[email protected]',
address_country: 'Japan',
address_city: '�䓌��',
quantity: '1',
verify_sign: 'AXK39wE-yxGXy8w.5f-Q92oLUMrXAgw1pM3bgPNM5AJYP8TnyyiCUzHc',
payer_email: '[email protected]',
txn_id: '8TW04018NT010421T',
payment_type: 'instant',
last_name: '����',
address_state: '�����s',
receiver_email: '[email protected]',
payment_fee: '',
receiver_id: 'R9B4DK8ZQGJ7U',
txn_type: 'web_accept',
item_name: '[�w��]�T���v���{�^��',
mc_currency: 'JPY',
item_number: '',
residence_country: 'JP',
transaction_subject: '',
payment_gross: '',
ipn_track_id: '4a2e2f679688c' }
送られて来たけど文字化けしてますね...
文字化け対応
送られてきた情報をのcharset: 'Shift_JIS'
が怪しいです。調べるとUTF8に設定できるらしい。
設定画面からPayPalボタンの言語コード化
を選択します。
言語のエンコード画面になります。
詳細オプション
を選択します。エンコード方式
が確認出来ますが、確かにShif_JIS
になってますねぇ。。。
UTF-8
に変更しましょう。
これでやっととれました。PayPalに登録している住所やメールアドレス、どの商品を買ったかなどの情報がNode.jsで文字化けせずに受け取れました。プログラム側でエンコードしてもいいですけど、UTF-8にしておいた方が何かと便利です。
{ mc_gross: '2',
protection_eligibility: 'Eligible',
address_status: 'confirmed',
payer_id: 'YKQ5X3VAHDSR8',
address_street: 'xxxx2-17-11\r\nXXXXXXシェアハウス XXXXX',
payment_date: '14:31:07 Feb 17, 2018 PST',
payment_status: 'Completed',
charset: 'UTF-8',
address_zip: '111-xxxx',
first_name: '遼介',
mc_fee: '2',
address_country_code: 'JP',
address_name: '菅原 遼介',
notify_version: '3.9',
custom: '',
payer_status: 'verified',
business: '[email protected]',
address_country: 'Japan',
address_city: '台東区',
quantity: '1',
verify_sign: 'XXXXXXXXXX59viv6mMh95wQVtgejAmdhHhoJEWKLm9oesHOJkWqMK-8G',
payer_email: '[email protected]',
txn_id: '9XX216775X972960X',
payment_type: 'instant',
last_name: '菅原',
address_state: '東京都',
receiver_email: '[email protected]',
payment_fee: '',
receiver_id: 'XXXXDK8ZQGJ7U',
txn_type: 'web_accept',
item_name: '[購入]サンプルボタン',
mc_currency: 'JPY',
item_number: '44',
residence_country: 'JP',
transaction_subject: '',
payment_gross: '',
ipn_track_id: 'xxxxf023bdc2a' }
所感
昔よりは分かりやすいけどまだまだ分かりにくい印象なので今回のメモもいつまで使えるのかなぁという感じです苦笑
PayPalボタンと同様のIPNシミュレータの使い方を知りたいですけど、よくわからなかったので実際試すときは1円とか2円のPayPalボタンを作って購入テストしてみました。笑
もっとスマートなデバッグしたい気持ち。
Author And Source
この問題について(Node.jsでPayPalの商品購入の通知(Webhook)を受け取る), 我々は、より多くの情報をここで見つけました https://qiita.com/n0bisuke/items/8484777c3b41448eddc3著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .