私は今24時間それを続けており、髪を引き抜こうとしています. Web 全体と Stackoverflow 内をチェックしましたが、役立つものは何も見つかりません。Paypal IPN Sandbox からの応答がありませんなどの以前の投稿も確認しましたが、応答が機能していません。おそらく、私に役立つ投稿を見逃してしまったのでしょう。もしそうなら、同じ質問を繰り返してすみませんが、この問題はかなり緊急であり、私はロープの終わりにいます.
とにかく、問題はこれです:
私は PHP カートを使用しており、クライアントを Paypal に送信しています。すべてが完璧に機能しています。すべてのコードを Paypal に送信する際は、Paypal の指示に従って作成しました。すべて問題ありませんが、最後のステップでは、POST
Paypal からサーバーに戻り、すべて問題がないことを確認します。そこでも、Paypal コード全体をそのままコピーし、すべての一致をチェックする関数を追加しました。しかし、私はそれを機能させることができません。結果を DB に送信しようとしましたが、何も起こりません。Mail
そのため、すべて問題なくメールが届かない場合に最後のアクションを実行する必要がある場所にPHP コマンドを配置しました。私はこの同じMail
コマンドを他のほぼすべての場所に配置して、何を見つけようとしましたか '
まず、 Paypal がサーバーに送り返すはずの変数を電子メールに印刷するように呼び出すと、空白になる と をitem_name
除くすべての変数を含む電子メールが届きます。item_number
これまでのところ、Paypal Sandbox は私が購入していると思われるすべての製品を表示していたので、これは奇妙です。少なくともその時点では、Paypal が変数に値を投稿していないという事実に照らして、PHP コードのこれらの変数に固定値を与えてみました。これら 2 つの値がないことがエラーの原因かどうかを確認したかったのです。ただし、設定値を使用してもエラーは持続しました。
2 つ目while
は、Paypal コードにループがあるため (上記のリンクの応答で に置き換える必要があるというループですが、$res=stream_get_contents($fp, 1024);
これも機能しませんでした)、Mail
そこにコマンドを配置して内容を確認しました戻った。$res
var と theを印刷するように依頼したpayment_status
ところ、予想どおり、いくつかの電子メールが届きました。収集された結果は次のとおりです。
payment_status = Pending
$res = HTTP/1.0 302 Found
Location: https://www.sandbox.paypal.com
Server: BigIP
Connection: close
Content-Length: 0
したがって、この時点でエラーが発生していると思います。何かが起こっている (または起こっていない) のは、コードがチェックを続行するために探しているCompleted
ステータスを返さないだけでなく、応答を返すことさえありません。そのため、応答がなく、すべてが問題ないかどうかを示すものは何もありません。そして、奇妙でさらに悪いことに、どこかにエラーがあり、プロセスが実行されていないことは明らかであるにもかかわらず、Sandbox はこれらの支払い試行のたびに私に偽の請求を行っているという事実です. (もちろん、これは別のジレンマを引き起こします: これがすべて解決された後、ある時点で X の理由でサーバー エラーが発生した場合、Paypal は引き続き私のクライアントに請求し、私は請求しません。payment_status
INVALID
さて、この件について説明できるのはこれくらいだと思います。この時点で、どこが間違っていたのかわかりません。コードはこれを非常に簡単なものにするはずです。ですから、コピーと貼り付けを台無しにする方法が本当にわかりません。元のコードに付属していない限り、少なくともエラーは発生しないはずです。さらに、その時点までの他のすべては 100% 正常に動作しているため、このエラーが発生する唯一の場所は、ユーザーが支払いプロセスを完了した後に Paypal が呼び出す必要があるこの PHP ファイル内です。
この問題に関する任意のアイデアは、非常に高く評価されます!
ここにコードが入ります。
PHP コード:
include('../inc/db_fns.inc'); //<--All my DB work is in here.
include('../inc/shipping.inc');
$paypal_email = "seller_1360198925_biz@hotmail.com";
$paypal_currency = 'USD';
//Here begin the functions I'm using to check everything and pass data to DB.
function no_paypal_trans_id($trans_id) {
$connection = db_connect();
$query = sprintf("SELECT id FROM orders WHERE paypal_trans_id = '%s'", mysql_real_escape_string($trans_id));
$result = mysql_query($query);
$num_results = mysql_num_rows($result);
if($num_results == 0) {
return true;
}
return false;
}
function payment_amount_correct($shipping, $params) {
$amount = 0.00;
for ($i=1; $i <= $params['num_cart_items']; $i++) {
$query = sprintf("SELECT precio FROM products WHERE id='%s'", mysql_real_escape_string($params["item_number{$i}"]));
$result = mysql_query($query);
if($result) {
$item_price = mysql_result($result, 0, 'precio');
$amount += $item_price * $params["quantity{$i}"];
}
}
if(($amount+$shipping) == $params['mc_gross']) {
return true;
} else {
return false;
}
}
function create_order($params) {
db_connect();
$query = sprintf("INSERT INTO orders set orders.firstname = '%s', orders.lastname = '%s', orders.email = '%s', orders.country = '%s', orders.address = '%s', orders.city = '%s', orders.zip_code = '%s', orders.state = '%s', orders.status = '%s', orders.amount = '%s', orders.paypal_trans_id = '%s', created_at = NOW()", mysql_real_escape_string($params['first_name']), mysql_real_escape_string($params['last_name']), mysql_real_escape_string($params['payer_email']), mysql_real_escape_string($params['address_country']), mysql_real_escape_string($params['address_street']), mysql_real_escape_string($params['address_city']), mysql_real_escape_string($params['address_zip']), mysql_real_escape_string($params['address_state']), mysql_real_escape_string($params['payment_status']), mysql_real_escape_string($params['mc_gross']), mysql_real_escape_string($params['txn_id']));
$result = mysql_query($query);
if(!$result) {
return false;
}
$order_id = mysql_insert_id();
for ($i=1; $i <= $params['num_cart_items'] ; $i++) {
$product = find_product($params["item_number{$i}"]);
$query = sprintf("INSERT INTO items set order_id = '%s', product_id = '%s', title = '%s', price = '%s', qty = '%s'", mysql_real_escape_string($order_id), mysql_real_escape_string($product['id']), mysql_real_escape_string($product['title']), mysql_real_escape_string($product['price']), mysql_real_escape_string($params["quantity{$i}"]));
$result = mysql_query($query);
if(!$result) {
return false;
}
}
return true;
}
//Here begins the Paypal code as is
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.sandbox.paypal.com', 80, $errno, $errstr, 30); //<--Here I also tried out the other response to the question linked above and it actually returned a 'Invalid host' into he $res var-
// assign posted variables to local variables
$item_name = $_POST['item_name']; //<--These are the two vars for which
$item_number = $_POST['item_number'];// Paypal Sandbox posts no value.
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
if ($_POST['payment_status'] == 'Completed' && no_paypal_trans_id($_POST['txn_id']) && $paypal_email == $_POST['receiver_email'] && $paypal_currency == $_POST['mc_currency'] && payment_amount_correct($shipping, $_POST)) {
// process payment
create_order($_POST);
}
} else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
}
}
fclose ($fp);
}
編集 1: もう一度やり直してください: 運が悪い!
オリジナルのそのままの Paypal コードを試してみました。これをコピーしてこの PHP に貼り付け、Sandbox 購入を実行しました。同じ結果です。応答がなく、テーブルにデータが挿入されず、誰かが実際に私のカートから何かを購入したことを知る方法もありませんが、Paypal は購入に対して偽の請求を行っています。これは、エラーが元のコードで発生し、追加した関数とは何の関係もないという私の疑いを裏付けています。誰かがすぐにこれを理解できることを願っています。その人に事前に千の感謝を!
編集2:次の最初の応答。
返信を削除した親切なユーザーは、親切にも最初に試してみました。彼/彼女は、Paypal のドキュメントhttps://www.sandbox.paypal.com/cgi-bin/webscr
に私がどこに を持っているかを記載することを勧めましたhttp://www.sandbox.paypal.com
。おそらく古いバージョンのコードを持っているので、彼/彼女の推奨事項を試しました。今、私は何が起こったのかコメントします:
まず第一に、あなたの応答に感謝します。残念ながら、うまくいきません。1 つのアドレスを別のアドレスに置き換えた後、プロセスはループに到達せずwhile
、 で停止しますfsockopen
。そのコマンドに含まれるandMail
を出力するコマンドを配置しました。置換すると、ソケットトランスポート「https」が見つかりません-PHPを構成したときに有効にするのを忘れましたか? そこで、「https://」を削除して、もう一度試しました。今、私はphp_network_getaddresses: getaddrinfo failed: Name or service not knownを取得します。何か案は?$errno
$errstr
https://www.sandbox.paypal.com/cgi-bin/webscr
http://www.sandbox.paypal.com
編集3:コメントセクションで@hexacyanideとの会話に続いて:
$req = cmd=_notify-validate&test_ipn=1&payment_type=instant&payment_date=20%3A55%3A22+Feb+08%2C+2013+PST&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&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%2C+any+street&receiver_email=seller%40paypalsandbox.com&receiver_id=TESTSELLERID1&residence_country=US&item_name1=something&item_number1=AK-1234&quantity1=1&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross_1=9.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=2229455¬ify_version=2.4&custom=xyz123&invoice=abc1234&charset=windows-1252&verify_sign=AsdNkKD2ktCz.aUB.9WYWy-g8MHoAa-TsvSjUgGstseJVdUhQTq3aCwW
申し訳ありませんが、 var$req
ではなく でした。var はループによって返され$res
ます。そこにコマンドを配置すると、値が記載されたいくつかの電子メールが届きます。これらは:$res
while
mail
$res
X-Frame-Options: SAMEORIGIN
HTTP/1.0 200 OK
Strict-Transport-Security: max-age=14400
INVALID
Content-Type: text/html; charset=UTF-8
Date: Sat, 09 Feb 2013 05:44:33 GMT
Connection: close
Content-Length: 7
編集 4: 絶対に唖然: Paypal 開発者の Web サイトから直接、Paypal 開発者の Web サイトでテストされた単純な Paypal IPN コードでさえありません。IPN テスターは動作します...
- ここにある Paypal IPN スクリプト ジェネレーターを使用しました。
- 私は、VALID または INVALID の応答をメールで返すスクリプトを生成することにしました。
- 全体をコピーして、サーバーに保存した PHP ファイルに貼り付けました。
- コードの一部が残っていないことを確認して再確認しました。
- ここにある IPN シミュレーターからサーバー上のこの PHP ファイルをターゲットにしました。
- シミュレーターにチェックが表示され、「IPN が正常に送信されました」と表示されます。
- 私は自分のメールをチェックして、それが有効か無効かを問わず、どのような応答が得られたかを確認します...まったく応答がありませんでした。そのため、ある時点で IPN が PHP の購入に到達すると、プロセスが中断され、VALID/INVALID 関数にさえ到達しなくなります。ただし、これはまさに Paypal が提供するコードであり、Paypal が設計したまさにその sim でテストされています。どうしたの?
このオデッセイの 2 日目
OK 言うまでもなく、まだ運がありません。しかし、私は今、PHP コードと Paypal に送信されるすべてのものを徹底的に追跡することにしました。アイデアは、VALID
このコードが Paypal に挿入された初期値を、まったく同じ順序で Paypal に送り返すときに、 の応答が発生するというものです (これは Paypal のドキュメントによると)。
最初の問題は、コードからまったく応答がないことです。そのため、コードは最初から失敗していたと推測されます。最初の問題は、サンドボックス リンクが機能しないことでした。(@hexacyanide の助けを借りてこの点にたどり着きました。@hexacyanide は、昨日、私の進捗状況または進捗状況の欠如について非常に親切にフォローしてくれました。彼/彼女の反応を積極的にマークするのに十分な評判を得たときはいつでもそうします。)sandbox.
そして、ほら、それは応答を返していましたが、今の応答はINVALID
.
その時から今では、IPN は売り手側のトランザクション チェックとデータ ログのためだけのものであることがわかりました。Paypal は IPN の結果を気にしません。したがって、私のカートは 100% 動作しています。ユーザーが何かを購入すると、Paypal がユーザーに請求します。IPN は、購入情報が実際に Paypal から来ているかどうかのみを確認し、すべてが適切であり、(スクリプトで) このすべての情報を DB に送信して、サービスの側面を実現できるようにします。したがって、たとえ IPN なしでトランザクションが正常に行われたとしても、IPN は販売プロセス全体を促進するための非常に貴重なメカニズムとなります。しかし、この最後の情報はすべて、私のカートのコードはすべて問題なく、問題はこのコード、または Paypal の処理方法のみにあるという私の疑いを解決します。(Paypal の「バージン」コードが Paypal を通過したという事実'
したがって、この PHP に出入りするすべてのログです。Mail
チェックポイントを作成するために、コード内のすべての重要なポイントにコマンドを配置しました。コマンド内に、foreach()
受信する POSTED データのリストを並べ替えるために、インクリメンタル変数を含めました。これが得られたものです。
これは、Paypal によってコードにポストされているデータです (ポストされている順序で)
test_ipn=1
payment_type=instant
payment_date=08%3A42%3A23+Feb+09%2C+2013+PST
payment_status=Completed
payer_status=verified
first_name=John
last_name=Smith
payer_email=buyer%40paypalsandbox.com
payer_id=TESTBUYERID01
business=seller%40paypalsandbox.com
receiver_email=seller%40paypalsandbox.com
receiver_id=TESTSELLERID1
residence_country=US
item_name1=something
item_number1=AK-1234
quantity1=1
tax=2.02
mc_currency=USD
mc_fee=0.44
mc_gross=15.34
mc_gross_1=12.34
mc_handling=2.06
mc_handling1=1.67
mc_shipping=3.02
mc_shipping1=1.02
txn_type=cart
txn_id=23291642
notify_version=2.4
custom=xyz123
invoice=abc1234
charset=windows-1252
一見すると、必要なすべてのデータを Paypal から取得しているように見えます。そして、これは PP が送信する順序です。したがって、このデータをこの順序で送り返し、PP が実際にこの同じ順序をチェックする場合、理論的にはVALID
応答が得られるはずです。
したがって、コードが行うことは、唯一の追加である「cmd=_notify-validate」を追加し (PP のドキュメントでは、これが必要であり、追加が必要であることを明確にしています)、このすべてのデータを次の$req
ように呼び出される var に渡します: A=X&B=Y&C=Z...
.
foreach()
コマンドが終了した直後に追加された、次のチェックポイントからのメッセージを次に示します。
$req = cmd=_notify-validate&test_ipn=1&payment_type=instant&payment_date=08%3A42%3A23+Feb+09%2C+2013+PST&payment_status=Completed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=TESTSELLERID1&residence_country=US&item_name1=something&item_number1=AK-1234&quantity1=1&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=15.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=23291642¬ify_version=2.4&custom=xyz123&invoice=abc1234&charset=windows-1252&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31ACyRxUQ6LVDwUz.i78mjQLsN9aKb
verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31ACyRxUQ6LVDwUz.i78mjQLsN9aKb
末尾に注意してください。foreach()
ループ中に電子メールの形で吐き出されなかったので、そのデータを説明することはできません。それで、それはどこから来たのですか?INVALID
これは、応答を返す犯人のデータでしょうか? 質問を開きます。しかし、この時点では、このすべてのデータが「DATA COMING IN」チェックポイントでコードによって渡されます。したがって、このデータが入ってきて、私のコードがそれを送り返す場合、すべてがうまくいくはずです。
したがって、次のチェックポイントは「DATA COMING OUT 」になります。fputs ($fp, $header . $req);
このチェックポイントは、PPに書き$req
戻すコードの直前に配置しました。そして、これはコードから出てくるものです:
$req = cmd=_notify-validate&test_ipn=1&payment_type=instant&payment_date=08%3A42%3A23+Feb+09%2C+2013+PST&payment_status=Completed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=TESTSELLERID1&residence_country=US&item_name1=something&item_number1=AK-1234&quantity1=1&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=15.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=23291642¬ify_version=2.4&custom=xyz123&invoice=abc1234&charset=windows-1252&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31ACyRxUQ6LVDwUz.i78mjQLsN9aKb
ハム!何か不足していますか?私の目は、このコードの旅を作る最も小さなしゃっくりをスキップしていますか? 出力は入力とまったく同じようです。PP がコードを正常に処理し、POSTED データが PP が期待する方法で文字列に変換され、したがってチェックされると仮定しましょう...これらすべてを想定すると、何が間違っているのでしょうか?
見てみましょう... もう一度: 未解決の質問:
- ヘッダーの問題でしょうか?ドキュメントによると、これは使用すべきヘッダーです...したがって、これをオフにしない限り、正常に機能するはずです。
- 指定された URL に問題がある可能性はありますか? OK、これは実際には問題であり、ある時点で問題でした。インターネット上では、機能するはずの URL と機能しない URL が少なくとも 6 つまたは 7 つ存在します。一部の人には機能し、他の人には機能しない人もいれば、まったく機能しない人もいます. 明らかなことは、
sandbox.
URL を使用しても何も返されないということです。これらが壊れていると考えてください。 - 文字セットの問題でしょうか?互換性がない可能性はありますか?これは、データが 16 進コードで出入りするのを見ているときに思い浮かびました。問題は、これで互換性が得られるはずですよね?しかし、昨日、
while()
ループで何が起こっているのかをチェックしていて、PP から var に返された情報をキャッチしていたので、この証$res
のさらに上にあるように、16 進コードを取得していませんでした。
次のチェックポイントは、if()
VALID とif()
INVALID の古典的なものです。そしてもちろん、すべてが無効になったことを示すメッセージが再び表示されます。
私が提供するこの詳細な情報が、誰かの電球を明るく輝かせることを願っています! 私としては、今でも呆然としています。
前もって感謝します!
ご回答いただきありがとうございます。
私は 2 番目のものを試したことはありませんが、かなり理にかなっているように聞こえます。PayPal から入手した元のコードに問題があったようです。試してコードが機能するかどうかを確認する時間があれば、ここにフィードバックを投稿します。うまくいけば、誰かがこれがすべて役立つと思うでしょう。
頭を壁にぶつけて 1 週間頭を悩ませ、頭の中の問題を冷やすために少し休んだ後、2 日前にようやく Web のどこかで問題を解決する別の方法を見つけました。ヘキサシアニドの応答の一部。この文字列をフォローしている人のために、以下に投稿します。ただし、PayPal コードにはかなりのバグがあると言わざるを得ません。少なくとも私が受け取ったもの。それ以来、回避策で解決しなければならない他のいくつかの問題がありました。最悪の部分は、PayPal がまったくサポートしていないことです。私は 3 回も電話をかけました。その後、彼らはウイルスの問題である可能性があると私に言いました (何が起こっているのか本当にわからないときの典型的な反応です)。
とにかく、両方の回答を評価できればいいのですが、それには +15 ポイント以上が必要なので、ここで口頭で称賛します。Hexacynide の応答コードをそのまま試してみましたが、うまくいかなかったので、チェックマークを付けることができません。将来、他の方法を試す時間があり、それが機能する場合は、正しいとマークします。
それまでは、CURL を使用してコードを更新します。
$ch = curl_init('https://www.paypal.com/pe/cgi-bin/webscr');
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
if( !($res = curl_exec($ch)) ) {
// error_log("Got " . curl_error($ch) . " when processing IPN data");
curl_close($ch);
exit;
}
curl_close($ch);
注:ここでは、現在稼働中であるため、実際のものを対象としていますが、これを使用しても同様にsandbox.
機能します。