なぜこれが必要なのですか?
このプロジェクトは、便利な支払いシステムの接続を主張しました。 はい、ウェブマネーはありますが、まったくありません。 はい、カードのマネーブッカーはいますが、官僚的なプロセスは長すぎます。
QIWIを介して支払いを受け入れることが決定されました。まず、マシンがほぼどこにでもあるためです(2つ目は、大きな秘密です!)。
さて、昨日、支払いシステムからレジストリを手動で要求し、経理部とサイトにデータを入力するために-昨日、SOAPプロトコルを使用した完全自動接続オプションが選択されました。
すぐに言ってやった!
完全に普通のVDSがサイトに採用され、その上に完全に普通のサーバーセットが構築されました-前にnginx、後ろにApache。
私はすでに、特定のCMSの形で基盤を持っていました。これには、個人ユーザーアカウントのモジュールと、支払いシステムのプラグインモジュールも実装されていました。
SOAPを使用する最も簡単な方法は、GoogleコードからnuSOAPクラス( http://code.google.com/p/nusoap-for-php5/ )を取得することです。
次に、2つのことを行う必要があります。
- QIWIサーバーへの支払い試行情報の送信
- QIWIからサーバーに、支払いステータスの変更に関する情報を含むパッケージを受け取ります。
ドキュメントは、あまり詳細ではないのが残念です。https : //ishop.qiwi.ru/docs/OnlineStores_Protocols_SOAP.pdf
私は自分のコードを持ってきて、誰でもそれを基礎として取ることができます
$client = new nusoap_client("https://mobw.ru/services/ishop", false); // QIWI
$error = $client->getError();
if ( !empty($error) ) {
TPAccount::cancelTransaction($transaction); //
echo -1;
exit();
}
$client->useHTTPPersistentConnection();
// :
// ID QIWI
//
//
//
// ,
//
//
//
// 0 – QIWI, 1 –
$params = array(
'login' => $payment->getVar('id'),
'password' => $payment->getVar('password'),
'user' => $phone,
'amount' => $transaction['amount'],
'comment' => ' ',
'txn' => $transaction['id'],
'lifetime' => date("dmY H:i:s", strtotime("+2 weeks")),
'alarm' => 1,
'create' => 1
);
// :
$result = $client->call('createBill', $params, "http://server.ishop.mw.ru/");
if ($client->fault) {
TPAccount::cancelTransaction($transaction);
echo -1;
exit();
} else {
$err = $client->getError();
if ($err) {
TPAccount::cancelTransaction($transaction);
echo -1;
exit();
} else {
echo $result;
exit();
}
}
このスクリプトはAJAX経由で呼び出され、コードからわかるように、完了コードを返します。-1-エラー、その他の値-QIWIサーバーの応答。
もう少し複雑なのは、支払いシステムからステータスの変更に関する情報を受け取るためのコードです(最終フォームですぐに引用しています)。
$server = new nusoap_server;
$server->register('updateBill');
$server->service($HTTP_RAW_POST_DATA);
function updateBill($login, $password, $txn, $status) {
// qiwiPayment
$paymentclass = "qiwi" . "Payment";
$payment = new $paymentclass;
//
if ( $login != $payment->getVar('id') )
return 150;
if ( !empty($password) && $password != md5($payment->getVar('password')) )
return 150;
//
$transaction = TPTransactions::getTransactionByID(intval($txn));
if ( empty($transaction) )
return 300;
switch ( intval($status) ) {
case 50:
// Bill created
return 0;
break;
case 60:
// –
TPAccount::proceedTransaction($transaction);
return 0;
break;
default:
// - , ,
TPAccount::cancelTransaction($transaction);
return 0;
break;
}
return 300;
}
最初の驚き。 nuSOAP。
コードはローカルサーバーで作成され、テストされているようです。今度はQIWIの高貴なJAVAにPHPを紹介します。
最初の驚きはすぐに起こります-テスト支払いを作成する最初の試みで、nuSOAPは「テキスト/ xml以外の応答」というメッセージでパズルを解きます。 はい、nuSOAPの作成者は、あるロシアの支払いシステムがSOAPを「アプリケーション/石鹸+ xml」と決定することを期待していませんでした。 それらを修正します-nuSOAPコード内の対応するチェックを見つけてコメントアウトするのは簡単です。
そして、ここに勝利があります-テスト支払いが作成され、QIWIで見ることができます、それは彼から成功した支払いについての答えを受け入れる時です。
私は機械に行きます...
nginxの構成。 エラー411。
しかし、不愉快な驚きが私を待っています。 ストアのWebサービスの動作を確認しようとすると、サーバーが予期せず「411-長さが必要です」というエラーで応答します。
QIWIサポートの回答により、すべてが明確になりました。
こんにちは。 このサービスは、コンテンツの長さを指定せずにチャンクされたリクエストを送信します。 Webサーバーには、そのようなリクエストを処理するための設定が必要だと思います。」
私にとって、それはQIWIがまだContent-lengthを指定することを妨げる謎のままでしたが、今では多くが理解されています。 nginxは、切り捨てられたリクエストを受け入れず、すぐにエラーで応答します...
サーバーに行って仕事に行きます!
NginxHttpChunkinModuleモジュールをダウンロードし、たとえば/ root / chunkinに展開して配置します。 こちらで入手できます: http : //wiki.nginx.org/NginxHttpChunkinModule 、インストール手順もあります
インストールに複雑なことは何もありません。FreeBSDとnginx 0.7.64を例として使用して説明します
#cd /usr/ports/www/nginx
# cd ./work/nginx-0.7.64
# ./configure --add-module=/root/chunkin
# cd ../../
#make rmconfig && make config && make deinstall && make install
次に、httpセクションのnginx config(通常、これは/usr/local/etc/nginx/nginx.conf)にパラメーターを入れます
chunkin on;
nginxを再起動します
別の驚きはエラー501です
そして、あなたはどう思いますか? 動作しますか? いいえ、もちろんです。
次の不幸はエラー501 Method Not Implementedでした。 サーバーログを調べることで、その理由を十分に迅速に特定することができました。 QIWIインターフェースにWebサービス/account/result/qiwi.htmlのアドレスを登録したという事実にもかかわらず、QIWIクライアントは頑固に密室で戦いました-彼は存在しないアドレス/アカウント/結果/ qiwi /
この動作の原因を見つけることはできませんでしたが、1つのmod_rewriteルールが状況を保存しました。 必要なアドレスにリクエストが届き始めました。 そして、QIWIサポートはこの問題をすぐに解決しました。
最後で最も恐ろしい驚き
さて、今、すべてが準備ができているように見えるとき、QIWIは私のために別の驚きを用意しました。 QIWIインターフェースからストアのWebサービスをテストしようとすると、「リクエスト中にエラーが発生しました:メッセージ解析中のエラー:xmlが空で、解析できませんでした!」というメッセージを常に受け取りました。
実際、これは良い兆候です-これは、nuSOAPが機能していることを意味し、QIWIの観点からは、要求に対するSOAP応答を正しく提供することさえできます。 しかし、彼はQIWIからのデータを見ません...
デバッグにより、$ _POST配列が空であり、QIWIからデータが送信されていないことが示されました。
ここで私は完全なst迷に陥った。 この動作の明確な理由はありませんが、存在します!
--with-debugオプションを使用したnginxアセンブリ、2日間のログ分析、nginxスペシャリストとの相談(MiksIrの同志に感謝します)は、かなりい画像を示しました。 チャンキンモジュールがインストールされたNginxは、切り捨てられたデータを本当に良心的に1つの全体に収集し、正しいContent-lengthヘッダーを持つリクエストをさらにApacheに転送する準備をしました。 ただし、Transfer-encoding:chunckedヘッダーを元のリクエストから完全に削除する代わりに、chunkinモジュールはその値のみを切り捨て、「Transfer-encoding:」をほぼこの形式のままにします。 Apacheはそのような不名誉を論理的に誓った。
問題が速かったとは言えません。 しかし、彼女はまだ決めました。 だから:
NginxHttpChunkinModuleモジュールのソースであるngx_http_chunckin_filter_module.cファイルに移動し、次の行にコメントします。
r->headers_in.transfer_encoding->value.len = 0;
r->headers_in.transfer_encoding->value.data = (u_char*) "";
ngx_http_chunkin_clear_transfer_encoding(r);
コードを深く理解する時間はなかったので、失礼ながら効果的なハックと見なすことができます。
再びnginxを再構築し、出来上がり!
最後の驚き
自分でトランザクションを作成します。その番号が表示されます。 QIWIの個人アカウントに移動し、「支払済み」のステータスを手動で設定しようとしています。 QIWIテストスクリプトは忠実に0(ゼロ)を表示しますが、何も起こりません...
このグリッチの検索プロセスの説明で読者を退屈させません。 サーバーからの応答に関係なく、テストスクリプトは常にゼロを返します。これは「QIWIのシステムサポートの機能 」 ですが、何らかの理由でJavaで記述された支払いシステムのクライアント部分が送信義務を考慮するという事実を考慮することです大文字のパスワードのハッシュ-必須。
結果。
すべてが機能し、サイトが稼働し、非常に貴重な体験が得られました。それをhabrausersと共有できることを嬉しく思います( ところで、ようこそ-これがHabréの最初の投稿です! )そしてhabrachiteli。
事前に感謝します、私の記事が誰かが少なくとも数分の貴重な時間を節約するのを助けることを願っています!
PS私はプロジェクトへのリンクを与えることができました-しかし、私はhabraeffectが怖いです。 おそらく、対応するブログで、サーバーが生き残ると確信しているとき...
UPD。 ブログ「Payment Systems」に移動しました