Warnung: file_put_contents(/home/www/web1/html/php_dev/test.txt) [function.file-put-contents]: failed to open stream: Permission denied in /home/www/web1/html/php_dev/sys/lib.activity.php (Zeile 58)
Paypal unzulässige Zahlung via IPN [Archiv] - PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr

- Ad -
php-resource




Archiv verlassen und diese Seite im Standarddesign anzeigen :
Paypal unzulässige Zahlung via IPN


 
bloodyorchid
30-04-2010, 13:14 
 
Servus,
ich bin dabei PayPal auf einer Seite einzubinden. In der Sandbox funktioniert alles soweit. Was mir bis jetzt noch Kopfschmerzen bereitet ist folgendes:

Ich nutze ExpressCheckOut von PayPal
Ich habe eine notify_url angegeben und nutze das PHP Script von PayPal

Da die Daten über ein Formular abgesendet werden kann man die leicht via Firebug o.ä. verändern. Das Problem ist: Wie mach ich PayPal klar das die Zahlung falsch ist?

hier das Script ( hab schon soweit versucht zu ändern )



<?php




/////////////////////////////////////////////////
/////////////Begin Script below./////////////////
/////////////////////////////////////////////////

// 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";

// If testing on Sandbox use:
//$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);






// assign posted variables to local variables
$item_name = $_POST['item_name'];
$business = $_POST['business'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$mc_gross = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$receiver_id = $_POST['receiver_id'];
$quantity = $_POST['quantity'];
$num_cart_items = $_POST['num_cart_items'];
$payment_date = $_POST['payment_date'];
$first_name = $_POST['first_name'];
$last_name = $_POST['last_name'];
$payment_type = $_POST['payment_type'];
$payment_status = $_POST['payment_status'];
$payment_gross = $_POST['payment_gross'];
$payment_fee = $_POST['payment_fee'];
$settle_amount = $_POST['settle_amount'];
$memo = $_POST['memo'];
$payer_email = $_POST['payer_email'];
$txn_type = $_POST['txn_type'];
$payer_status = $_POST['payer_status'];
$address_street = $_POST['address_street'];
$address_city = $_POST['address_city'];
$address_state = $_POST['address_state'];
$address_zip = $_POST['address_zip'];
$address_country = $_POST['address_country'];
$address_status = $_POST['address_status'];
$item_number = $_POST['item_number'];
$tax = $_POST['tax'];
$option_name1 = $_POST['option_name1'];
$option_selection1 = $_POST['option_selection1'];
$option_name2 = $_POST['option_name2'];
$option_selection2 = $_POST['option_selection2'];
$for_auction = $_POST['for_auction'];
$invoice = $_POST['invoice'];
$custom = $_POST['custom'];
$notify_version = $_POST['notify_version'];
$verify_sign = $_POST['verify_sign'];
$payer_business_name = $_POST['payer_business_name'];
$payer_id =$_POST['payer_id'];
$mc_currency = $_POST['mc_currency'];
$mc_fee = $_POST['mc_fee'];
$exchange_rate = $_POST['exchange_rate'];
$settle_currency = $_POST['settle_currency'];
$parent_txn_id = $_POST['parent_txn_id'];
$pending_reason = $_POST['pending_reason'];
$reason_code = $_POST['reason_code'];
$user_hash = $_REQUEST['hash'];


// subscription specific vars

$subscr_id = $_POST['subscr_id'];
$subscr_date = $_POST['subscr_date'];
$subscr_effective = $_POST['subscr_effective'];
$period1 = $_POST['period1'];
$period2 = $_POST['period2'];
$period3 = $_POST['period3'];
$amount1 = $_POST['amount1'];
$amount2 = $_POST['amount2'];
$amount3 = $_POST['amount3'];
$mc_amount1 = $_POST['mc_amount1'];
$mc_amount2 = $_POST['mc_amount2'];
$mc_amount3 = $_POST['mcamount3'];
$recurring = $_POST['recurring'];
$reattempt = $_POST['reattempt'];
$retry_at = $_POST['retry_at'];
$recur_times = $_POST['recur_times'];
$username = $_POST['username'];
$password = $_POST['password'];

//auction specific vars

$for_auction = $_POST['for_auction'];
$auction_closing_date = $_POST['auction_closing_date'];
$auction_multi_item = $_POST['auction_multi_item'];
$auction_buyer_id = $_POST['auction_buyer_id'];



//DB connect creds and email
$notify_email = "***"; //email address to which debug emails are sent to
$DB_Server = "***"; //your MySQL Server
$DB_Username = "***"; //your MySQL User Name
$DB_Password = "***"; //your MySQL Password
$DB_DBName = "***"; //your MySQL Database Name


if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {



$fecha = date("m")."/".date("d")."/".date("Y");
$fecha = date("Y").date("m").date("d");

//check if transaction ID has been processed before
$checkquery = "select txnid from paypal_payment_info where txnid='".$txn_id."'";
$sihay = mysql_query($checkquery) or die(mysql_error());
$nm = mysql_num_rows($sihay);

$preis = '***'; // preisabfrage aus der DB

if ($nm == 0 && $preis == $mc_gross){

//execute query



if ($txn_type == "cart"){
//$strQuery
$result = mysql_query($strQuery);
for ($i = 1; $i <= $num_cart_items; $i++) {
$itemname = "item_name".$i;
$itemnumber = "item_number".$i;
$on0 = "option_name1_".$i;
$os0 = "option_selection1_".$i;
$on1 = "option_name2_".$i;
$os1 = "option_selection2_".$i;
$quantity = "quantity".$i;

//$struery
$result = mysql_query($struery);

}
}



else{
//$strQuery
//$result
}


// send an email in any case
echo "Verified";
}
else {

}

//subscription handling branch
if ( $txn_type == "subscr_signup" || $txn_type == "subscr_payment" ) {

// insert subscriber payment info into paypal_payment_info table
//$strQuery
//$result


// insert subscriber info into paypal_subscription_info table
//$strQuery2
//$result


}
}

// if the IPN POST was 'INVALID'...do this


else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation

//mail($notify_email, "INVALID IPN", "$res\n $req");
}
}
fclose ($fp);
}
?>




hab den Code soweit - hoffentlich genügend - umgebrochen und die Querys rausgenommen da sie funktionieren und im Forum nur Platz verschwenden.

Die Frage war folgende: Wie mach ich PayPal klar das wenn $preis != $mc_gross ist das die Zahlung invalid ist?

 
AmicaNoctis
30-04-2010, 13:29 
 
Hallo,

warum überprüfst du das nicht selbst in deinem Skript? Die Kommunikation mit PayPal machst du doch nur serverseitig, also kannst du dort ja auch die Manipulation erkennen und zwar oben in der foreach-Schleife: Dort musst du nur $key und $value prüfen, bevor du es in die PayPal-Anfrage übernimmst.

Gruß,

Amica

 
bloodyorchid
30-04-2010, 13:33 
 
atm stellt sich mir die Frage: Wo poste ich das?
Vielleicht mag ich blind sein aber ich denk mal an PayPal zurückposten funktioniert via PHP nur mit cURL?

überprüfen tu ich es ja schon - nur scheinbar falsch...
siehe
if ($nm == 0 && $preis == $mc_gross){}

 
AmicaNoctis
30-04-2010, 13:36 
 
Wo poste ich das?

Ziemlich weit oben, dort wo der Kommentar "post back to PayPal system to validate" steht. In diesem Falle passiert das nicht über cURL, sondern direkt per Socketverbindung.

überprüfen tu ich es ja schon - nur scheinbar falsch...

Du prüfst es viel zu spät, da ist es ja schon an PayPal gesendet worden. Wie bereits gesagt: Oben in der foreach-Schleife musst du es prüfen, noch vor dem o. g. Kommentar.

 
bloodyorchid
30-04-2010, 13:38 
 
oh man bin ich deppert. Okay Wald viele Bäume und so ... Dank dir :)

 
AmicaNoctis
30-04-2010, 13:44 
 
Im Übrigen würde ich an deiner Stelle auf die ganzen hidden-Felder verzichten und die unveränderlichen Variablen direkt im PHP-Skript festlegen.

 
bloodyorchid
30-04-2010, 13:46 
 
ich bin ehrlich, was paypal angeht steh ich wie der ochse vorm scheunentor :/

 
AmicaNoctis
30-04-2010, 13:49 
 
Falls du damit den letzten Tipp meinst, der hat weniger mit PayPal zu tun. Ich meine damit, dass es einfacher, sicherer und besser ist

$someVar = "someValue";

zu verwenden, als


$someVar = $_POST["someVar"];
...
<input type="hidden" name="someVar" value="someValue" />

 
bloodyorchid
30-04-2010, 13:53 
 
$someVar = $_POST["someVar"];
...
<input type="hidden" name="someVar" value="someValue" />

postet der das an die nächste seite mit? ist mir neu

 
AmicaNoctis
30-04-2010, 13:54 
 
postet der das an die nächste seite mit? ist mir neu

Was meinst du damit? Jetzt hab ich dich nicht verstanden.

 
bloodyorchid
30-04-2010, 14:01 
 
ich hab dein beispiel iwie nich wirklich verstanden

 
AmicaNoctis
30-04-2010, 14:13 
 
hidden-Felder mit festem Wert sind sinnlos. Die Variablen, die damit übergeben werden sollen, kann man auch im verarbeitenden Skript direkt festlegen. Das wollte ich damit sagen.

Ich hab zwar den Formularcode nicht gesehen, aber lt. dem Skript-Code liest du alles über POST aus dem Formular aus. Daher nehme ich an, dass du die ganzen PayPal-Variablen (zumindest die, die sich nicht ändern) als hidden-Felder dort reingeschrieben hast. Das ist sinnlos, zumal du Manipulationen daran sowieso nur erkennen kannst, wenn du den richtigen Wert im Skript hast, um es zu vergleichen.

Daher: Feste Werte gleich ins Skript, hidden-Felder raus!

Jetzt klar?

 
bloodyorchid
30-04-2010, 14:16 
 
Ja das ist schon klar... Problem ist allerdings ein anderes

Man bindet das Formular für Paypal auf seiner Seite ein...
Nach dem Abschicken wird man auf Paypal weiter geleitet...
Dort loggt man sich ein... bestätigt die Zahlung und kommt auf einer gewissen url wieder raus...

Danach oder während dessen greift Paypal auf das Skript oben zu und überprüft die gesendeten Formular daten mit den Daten die ich habe... Das oben ist quasi nur das Double Check Script

 
AmicaNoctis
30-04-2010, 14:37 
 
Achso, das ist nur das Skript das von PayPal aufgerufen wird, nicht das, mit dem du die Daten vom Benutzer bekommst. Das wusste ich nicht.

 
bloodyorchid
30-04-2010, 14:46 
 
genau das ist es :)

es gibt sicherlich auch bessere methoden als ein Formular... Aber für den Einstieg reicht es erst einmal... Später kann ich mir immernoch um die anderen Lösungen von PayPal gedanken machen ;)

 
AmicaNoctis
30-04-2010, 14:55 
 
Dann muss ich jetzt erstmal noch verstehen, was genau du vorhast. Wo kommt $preis her? Willst du praktisch ausschließen, dass der Käufer weniger bei PayPal bezahlt als es kosten soll? In diesem Falle hilft es dir auch nicht, die Transaktion abzubrechen, dann hat er gar nichts gezahlt. Ich denke mal, an diesem Punkt kommt deine eigene DB ins Spiel, in der du die Verkäufe verwaltest und solange als offen betrachtest, bis der Betrag vollständig angekommen ist. Also ein Teilzahlungsprinzip.

 
bloodyorchid
30-04-2010, 15:01 
 
Wie gesagt, es ist nur das Doublecheck Script was die Daten von PayPal mit den Daten aus meiner DB vergleicht... Hab es nun schon soweit hinbekommen...
Ich hab vor dem zurück posten an PayPal den Preis aus meiner DB gelesen und in der foreach schleife den dementsprechenden wert mit meinem überschrieben...



foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
if($key == 'mc_gross'){ $value = urlencode($preis); }
$req .= "&$key=$value";
}


mc_gross ist der Keyname von PayPal für die Preisvariable

 
AmicaNoctis
30-04-2010, 15:04 
 
Hm, ob das so funktioniert? Lt. PayPal müssen die POST-Daten unverändert zurückgegeben werden. Aber vielleicht bringst du damit ja die Transaktion zum Scheitern, dass du das gerade nicht machst.

Ich gebe mich geschlagen: Ich kann dir nicht helfen und entschuldige mich für die Verwirrung, die ich hier aufgrund meines Missverständnisses verursacht habe ;)

 
bloodyorchid
30-04-2010, 15:06 
 
Lt. PayPal müssen die POST-Daten unverändert zurückgegeben werden.

Genau das passiert ja auch wenn der Preis aus meiner DB gleich dem Preis von PayPal ist... Anderer seits müsste PayPal es als Invalid betrachten..

Oder seh ich das nun falsch?

 
AmicaNoctis
30-04-2010, 15:36 
 
Oder seh ich das nun falsch?

Das musst du ausprobieren. Ich verstehe das zwar auch so, aber PayPal äußert sich dazu nicht definitiv.

 
goth
01-05-2010, 21:15 
 
Dient IPN nicht eigentlich lediglich der asyncronen automatisierten Information über einen Zahlungseingang?

Also PayPal schickt dir die Information das Deinem Konto (für eine Transaktion) ein Betrag gutgeschrieben wurde ... und das der Status der Transaktion auf Complete gesetzt wurde.

Der Wert in mc_gross ist der Brutto Betrag minus PayPal gebühren.

Meines Wissens Interessiert sich PayPal an dieser Stelle nicht für Deine Meinung ... IPN ist lediglich eine Meldung, die Du zur Verifizierung also zur Prüfung ob Die Meldung von PayPal kommt vollständig als POST Request an PayPal zurückschickst ... und von denen dann einen VERIFIED oder INVALID Status zurückbekommst ... alles andere an Kommunikation erfolgt über die SOAP- respektive NVP-API ...


Alle Zeitangaben in WEZ +2. Es ist jetzt 17:21 Uhr.