【stripe】webhookでデータ取得【PHP】
webhookで受信したデータから特定の情報を取り出す覚書
PHPでの書き方
//customer_id を使ってメールアドレスを取得
$customer = \Stripe\Customer::retrieve($customer_id);
$customer_email = $customer->email;
PHP
webhookで受信したデータから特定の情報を取り出す覚書
PHPでの書き方
//customer_id を使ってメールアドレスを取得
$customer = \Stripe\Customer::retrieve($customer_id);
$customer_email = $customer->email;
stripeのwebhook設定手順
参考ページ
https://stripe.com/docs/webhooks/setup
https://qiita.com/hirocueki2/items/9dc1eea6836e3f293f47
1.dashboard の「開発者」から webhook の設定をする
エンドポイントの例
https://example.com/stripe_test/webhook_test.php?action=stripehook
2.PHPファイルをサーバーに置く
PHPファイルの例
//////////////////////////////////////////////////////////
<?php
// ダウンロードしたStripeのPHPライブラリのinit.phpを読み込む
//require_once('/home/hoge/stripe-php/init.php'); //手動でダウンロードした場合は init.php になるらしい
require_once('/var/ruigo_stripe_composer/vendor/autoload.php');
// APIのシークレットキー
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
\Stripe\Stripe::setApiKey('秘密キー');
// You can find your endpoint's secret in your webhook settings
$endpoint_secret = 'whsec_~から始まるエンドポイントの秘密キー';
$payload = @file_get_contents('php://input');
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = null;
try {
$event = \Stripe\Webhook::constructEvent(
$payload, $sig_header, $endpoint_secret
);
} catch(\UnexpectedValueException $e) {
// Invalid payload
http_response_code(400);
exit();
} catch(\Stripe\Error\SignatureVerification $e) {
// Invalid signature
http_response_code(400);
exit();
}
//
// $eventに対しての処理を行う
//
$event_json = json_decode($payload);
$event_id = $event_json->id;
//dashboard からのテスト送信だと id が 00000 になるのでエラーが返る
try {
$event = \Stripe\Event::retrieve($event_id);
} catch(\Stripe\Error\InvalidRequest $e) {
// Invalid payload
http_response_code(400);
exit();
} catch(\Stripe\Error $e) {
// Invalid payload
http_response_code(400);
exit();
}
if ($event->type == 'customer.created') {
//ここに自分自身にメール送信やデータベースへの登録などの処理を記述
}
if ($event->type == 'customer.subscription.deleted') {
}
if ($event->type == 'customer.subscription.updated') {
}
if ($event->type == 'invoice.payment_succeeded') {
}
echo "aa"; //このページからのレスポンス。stripe のダッシュボードで確認できる
http_response_code(200);
?>
//////////////////////////////////////////////////////////
stripeでカード情報を更新してデフォルトに設定する
JCBカードは洗い替えに対応していないので更新を促す必要がある。
カード番号更新フォームに作り方。
https://stripe.com/jp/blog/smarter-saved-cards
//カード情報を更新してデフォルト 方法1
//////////////////////////////////////////////////
\Stripe\Customer::update($stripe_cus_id, [
'source' => $token, ← 顧客からフォームを通してカードを番号を入力してもらって取得
]);
//////////////////////////////////////////////////
リファレンス
https://stripe.com/docs/saving-cards
//カード情報を更新してデフォルト 方法2
//すでに登録されているカード情報に追加して、二枚目のカードとして新しいカードを登録する場合
//////////////////////////////////////////////////
//まず登録
$card = \Stripe\Customer::createSource(
$stripe_cus_id,
[
'source' => $token,
]);
//新しいカードをデフォルトに切り替える
$customer = \Stripe\Customer::retrieve($stripe_cus_id);
$customer->default_source=$card['id'];
//$customer->save();
//////////////////////////////////////////////////
1.stripe のダッシュボードで定額商品を作成。ここで作られる プランid がスクリプトで必要になる。
プランid の他にも id がつくられるので間違えやすい。plan_ から始まるものが正解。 prod_ から始まるものは違う。
参考:
Stripe サブスクリプション実装の際に必要なidについて
2.php スクリプトを記述
//購入画面(order.html)
--------------------------------------------------
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>購入画面</title>
<!-- 購入ボタンのCSS -->
<style type="text/css">
.stripe-button-el {
width: 350px;
max-width: 100%;
}
.stripe-button-el span {
font-size: 18px;
padding-top: 15px;
min-height: 60px!important;
}
</style>
</head>
<body>
<form action="charge_subsc.php" method="POST">
<?php //data-key は公開キー ?>
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="公開キー"
data-name="サブスクプラン"
data-description="◯◯◯◯◯◯◯"
data-locale="auto"
data-amount="400"
data-currency="jpy"
data-label="お申し込みする">
</script>
</form>
</body>
</html>
--------------------------------------------------
//購入画面からデータを投げる先(charge_subsc.php)
--------------------------------------------------
<?php
// ダウンロードしたStripeのPHPライブラリのinit.phpを読み込む
//require_once('/home/hoge/stripe-php/init.php'); //手動でダウンロードした場合は init.php になるらしい
require_once('/var/hoge/vendor/autoload.php');
// APIのシークレットキー
\Stripe\Stripe::setApiKey('秘密キー');
try
{
$customer = \Stripe\Customer::create(array(
'email' => $_POST['stripeEmail'],
'source' => $_POST['stripeToken'],
));
$subscription = \Stripe\Subscription::create(array(
'customer' => $customer->id,
'items' => array(array('plan' => '1で作ったプランのid')),
));
//データベース操作など stripe とは関係ない処理
//必要に応じてデータベースに保存する
$customer_id = $customer->id;
$subscription_id = $subscription->id;
$last4 = $customer->sources->data[0]->last4; //カード番号下四桁
$exp_month = $customer->sources->data[0]->exp_month; //カード有効月
$exp_year = $customer->sources->data[0]->exp_year; //カード有効年
$card_exp_date = $exp_month . "/" . $exp_year;
header('Location: thankyou.html');
exit;
}
catch(Exception $e)
{
// header('Location:oops.html');
echo "error:" . $e->getMessage();
error_log("unable to sign up customer:" . $_POST['stripeEmail'].
", error:" . $e->getMessage());
}
// サンキューページへリダイレクト
exit;
?>
--------------------------------------------------
これでできるはず。
ちなみにキャンセルはこれ
--------------------------------------------------
//サブスクリプションをキャンセル
$subscription = \Stripe\Subscription::retrieve($stripe_subsc_id);
$subscription->cancel();
--------------------------------------------------
メインで参考にしたページ
https://teratail.com/questions/118633
前提
php で composer が使える状態である
composer の導入はこちら
1.ComposerでStripeライブラリをインストールする
2.ファイルの設置
メインで参考にしたページ
https://qiita.com/p_s_m_t/items/a69dfbc75804fe86ad9c
ファイル内でライブラリをロードするときの注意点
ComposerでStripeライブラリをインストールした場合
-------------------------------------------------
require_once('/stripe_test/vendor/autoload.php');
-------------------------------------------------
Composerを使わず、手動でStripeライブラリをダウンロードしてサーバーに置いた場合
-------------------------------------------------
require_once('/stripe_test/stripe-php/init.php');
-------------------------------------------------
デフォルトのファイル名が違うので間違えないように
カテゴリー:CentOS, PHP, stripe, さくらインターネット
composer が導入されているか
composer が利用できないことを確認
----------------------------------------
composer --version
-bash: composer: コマンドが見つかりません
----------------------------------------
composer をどこのディレクトリにダウンロードしてどこにインストールするべきか確認した結果、特に決まりはなく任意のディレクトリでよさそうだ。ただ、プロジェクトだけで必要か、システム全体で使えるようにしたいのかでインストールの実行ディレクトリを決めればいいという意見も多くあった。
自分はさくらVPS の環境でグローバルで使えたほうが便利と考えたのでファイルのダウンロード先を ルートディレクトリ(/root)と決めた
root になってホームディレクトリ(/root)でコマンドを実行
-----------------------------------------------------------------------
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
-----------------------------------------------------------------------
すると /root に composer-setup.php がダウンロードされる
次のコマンドでファイルに問題がないか確認
-----------------------------------------------------------------------
php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
-----------------------------------------------------------------------
Installer verified と出たらOK
セットアップを実行
-----------------------------------------------------------------------
php composer-setup.php
-----------------------------------------------------------------------
この状態でカレントディレクトリであるルートディレクトリ(/root)を確認すると composer 関連の二つのファイルが確認できる
-----------------------------------------------------------------------
composer-setup.php composer.phar
-----------------------------------------------------------------------
composer-setup.php はもういらないので削除
-----------------------------------------------------------------------
php -r "unlink('composer-setup.php');"
-----------------------------------------------------------------------
パスを通すために composer.phar を /usr/local/bin/composer に移動
-----------------------------------------------------------------------
mv composer.phar /usr/local/bin/composer
-----------------------------------------------------------------------
composer は root で実行しないように推奨されているのでユーザーを変更。
-----------------------------------------------------------------------
su - ユーザー名
-----------------------------------------------------------------------
参考:rootユーザでcomposerコマンドを実行してはダメな理由
https://akamist.com/blog/archives/261
composer が利用できることを確認
--------------------------------------------------------------------------------
composer
--------------------------------------------------------------------------------
実際に利用するには composer.json ファイルが必要
適当なディレクトに移動、もしくは作る。自分は /var 直下に作った。
カレントディレクトリに composer.json をつくる。
-q で対話形式の入力を行わない
--------------------------------------------------
composer init -q
--------------------------------------------------
インストール参考
https://technoledge.net/composer-install-and-use/
https://laboradian.com/php-composer/
https://qiita.com/inakadegaebal/items/d370bcb1627fce2b5cd1
https://weblabo.oscasierra.net/php-composer-centos-install/
composerディレクトリ構成
http://tadasy.hateblo.jp/entry/2013/10/09/193415
カテゴリー:PHP, さくらインターネット, サーバー設定
php の mb_send_mail 関数で一部のメールが送れない。
yahoo メール宛てには送れるのに、独自メールが送れない。
--------------------------------------------------
環境
送信元:さくらのVPS WEBサーバーより mb_send_mail を利用
--------------------------------------------------
mb_send_mail 関数自体はエラーを吐かず、正常に終了する。
ターミナルでメールエラーを確認
--------------------------------------------------
cd /var/log/maillog
--------------------------------------------------
エラーっぽい箇所の抜粋
--------------------------------------------------
May 29 12:14:51 localhost postfix/smtp[32237]: 70ED82C028C: to=
--------------------------------------------------
検索して見つけた対処法
設定してなかった mb_send_mail 第五引数に "-fプロバイダメールアドレス" を指定。
第五引数はエラーがあった場合にメールを送信するメールアドレス。
これで送信できるようになった。
ちなみに別で契約しているもう一つのさくらVPSでは 第五引数がなくても送信できている。サーバーの設定を変えることでも問題解決できそうだ。
参考
https://okwave.jp/qa/q4822148.html
https://b-risk.jp/blog/2013/01/php_mb_send_mail/
追記
ezweb を使っている方から仮登録メールが届かないという連絡が問い合わせフォームからあった。
SPF の設定が何のが原因か?
----------------------------------------
"v=spf1 +ip4:web公開サーバーのipアドレス +mx ~all"
----------------------------------------
参考
https://qiita.com/ryounagaoka/items/931081c74b5c7a9b2bff
spfの確認
http://mxtoolbox.com/spf.aspx
追記2
gmail 宛てに送ったら迷惑メールに振り分けられたら
gmail から メールヘッダーを確認。
Received-SPF の部分が softfail になっていたらそれが原因。
ip6 対応のサーバーから送信した場合、SPF の設定に ip6 を追加する必要がある。
参考
https://www.nalabo.net/blog/2013/06/18/148
カテゴリー:CentOS, PHP, さくらインターネット, サーバー設定
php の mb_send_mail 関数でメールが送れない。他のサーバーでは送れるのでスクリプトのエラーではない。
ターミナルから送ろうとするとエラーが出た。
こう打つ
--------------------------------------------------------------------
[root@localhost ~]# echo "test" | /usr/sbin/sendmail -t -i ○○@yahoo.co.jp
--------------------------------------------------------------------
//↓出たエラー
--------------------------------------------------------------------
sendmail: fatal: parameter inet_interfaces: no local interface found for ::1
--------------------------------------------------------------------
↓このページのようにしたらできた。
https://qiita.com/cs_sonar/items/706a9204cba1a8e99cb1
postfix はメールを送るためのソフト。
mysql のデータベース内に入っているデータをphpを使ってデータマイニングした際、時間がかかったのでしたこと。
何も対策せずにすると35日ほどかかった。
もう一度する必要でてきたのでそのときにしたこと。
ブラウザを複数立ち上げて同時に処理していった。
このとき同じブラウザ(IE)でやると、それぞれのブラウザで処理が倍になってトータル時間が変わらなかった。
なので、IE、chrome、opera の三つで同時に行った。
単純に三倍速くはならなかったけど、2.5倍ほど早くなったように思う。
iphone で一部のページが読み込めない。PCでは問題なく表示されるページでも iphone では safari も chrome もダメだった。
「ページを開けません。サーバーが応答を停止しています。」と出る。
PCでページの読み込み時間を計測した
FFTBが長すぎ
原因は、サーバーサイド(PHP)の処理に時間がかかりすぎるため。どうも iphone では 60 秒以上データを送信しない PHP ファイルはサーバー停止と同じエラーがブラウザに出るみたい。
対策として PHP の繰り返し処理中に1バイトの送信を繰り返す。するとサーバー停止扱いにはならない。
//半角スペースを出力してファイルが処理中であることを iphone に伝える
-------------------------------------------------
echo " ";
-------------------------------------------------
カテゴリー:PHP