-
Verben konjugieren - mit Coniuno spielend leicht gelernt
Verben konjugieren - mit Coniuno spielend leicht gelernt
Verben konjugieren mit Coniuno
Verben konjugieren in Deutsch, Niederländisch, Englisch, Französisch, Italienisch, Spanisch, Portugiesisch und Latein
Verben konjugieren in Deutsch, Niederländisch, Englisch, Französisch, Italienisch, Spanisch, Portugiesisch und Latein
-


PayPal – Automatische eMail Kaufbestätigung an den Kunden mit IPN


IPN – Instant Payment Notification


Zurück zur Übersicht

II. Ein vollständiger IPN Listener (mit PayPal Handling, MySQL Update und eMail Versand)


Bitte legt zunächst eine leere Datei "ipn-listener.php" an, dann könnt ihr den kommenden Code gleich testen und für eure Seite verwenden.


1.: IPN Nachricht von PayPal empfangen

Wenn PayPal eine IPN Message an unseren IPN Listener schickt, sind allen Daten des aktuellen Kaufs als _POST-Daten enthalten.

In der PayPal Dokumentation steht, dass der IPN Listener zunächst ein "HTTP/1.1 200 OK" zurück schicken soll.
Hierfür ist aber kein eigener Code erforderlich - siehe hierzu auch, Workarounds ("http/1.1 200 OK")

Der nachfolgende Code macht nichts anderes, als die Daten der IPN Nachricht auszulesen und in einen einzigen, langen String zu schreiben.
Dem Vorangestellt wird ein zusätzliches Kommando (cmd=notify-validate), welches bewirkt, dass PayPal die Nachricht gegen das Original verifiziert.
Hierbei ist es wichtig, dass die Nachricht inhaltlich unverändert der Nachricht entspricht, die von PayPal zuvor gesendet wurde.
Die einzig notwenige Änderung ist eine URL-Enkodierung der Value-Daten.



<?php $req = 'cmd=_notify-validate'; foreach ($_POST as $key =>; $value) { $value = urlencode($value); $req .= "&" . $key . "=" . $value; }

2.: Socket zu PayPal öffnen, um die IPN Notification zur Validierung zurück zu schicken

Um mit PayPal zu kommunizieren, müssen wir eine Socket Verbindung zu PayPal aufbauen (cURL geht natürlich auch, hab ich aber hier nicht verwendet).
Hierbei muss zwischen Live System und Sandbox / Simulator unterschieden werden.
(siehe hierzu auch Workarounds "Socket Open für Sandbox geht nicht" und "HTTP/1.1 200 OK")


DEFINE("USE_SANDBOX", 1); // set to 1 for Sandbox / Simulator, else 0 for Live Environment // Festlegen der URL (live system oder Sandbox / Simulator) if (USE_SANDBOX) { $paypal_url = "ipnpb.sandbox.paypal.com"; $port = "443"; } else { $paypal_url = "ipnpb.paypal.com"; $port = "443"; } // try to open the socket to PayPal (identical for sandbox / simulator and live) $fp = fsockopen ('ssl://'.$paypal_url, $port, $errno, $errstr, 30); // if socket cannot be opened, request PayPal to resend the IPN if (!$fp) { header( "HTTP/1.1 400 Bad Request" ); return false; }
3.: Zurück schicken der IPN Notification an PayPal

Die empfangene Nachricht, plus vorangestelltem cmd=notify-validate, ist als ein langer String in der Variablen $req gespeichert (siehe 1.).
Diese wird nun über die Socket-Verbindung an PayPal (siehe Variable $fp) mittels fputs Befehl gesendet.
Bitte beachtet hier, dass neben der PayPal_url (ipnpb.paypal.com oder ipnpb.sandbox.paypal.com) auch der Port angegeben ist (443), sowie das Verzeichnis auf dem PayPal Server in $paypal_path = /cgi-bin/webscr.


Unmittelbar nach Senden von $req, prüfen wir auf das Verifikations-Ergebnis von PayPal, welches ebenfalls über die geöffnete Socket-Verbindung kommt.
Das Ergebnis ist entweder "VERIFIED" oder "INVALID" und eigentlich reicht es hier auf VERIFIED zu prüfen (alles andere ist dann automatisch INVALID).
Abschließend wird die Socket-Verbindung geschlossen und für PayPal ist der Fall erledigt.


// send the IPN message back to PayPal $paypal_path = "/cgi-bin/webscr"; fputs($fp, "POST " . $paypal_path . " HTTP/1.1\r\n"); fputs($fp, "Host: " . $paypal_url . ":".$port."\r\n"); fputs($fp, "Content-Type: application/x-www-form-urlencoded\r\n"); fputs($fp, "Content-Length: " . strlen($req) . "\r\n"); fputs($fp, "Connection: close\r\n\r\n"); fputs($fp, $req); // check for VERIFIED response $valid = false; while(!feof($fp)) // PayPal sends VERIFIED or INVALID { $res = fgets ($fp, 1024); if (strcmp(strtoupper(trim($res)), "VERIFIED") == 0) $valid = true; } // close the socket to PayPal fclose ($fp); if (!$valid) { // IPN verification failed, ignore message return false; // optional: implement error notification } // to yourself (e.g. send email) // next comes the private code for successful IPN notification handling // e.g. enter user data in database, and eventually send eMail to the // new customer

4.: Auslesen der Daten aus der IPN Notification

Jetzt wo wir wissen, dass die IPN Notification gültig ist, können wir noch die Daten aus dem zu Beginn erhaltenen POST auslesen.

Hinweis: eigentlich ist es ziemlich egal wann man das macht, es geht auch früher, wenn man gewisse Daten verwenden möchte, um Fehler zu debuggen oder Hinweis-Nachrichten an seine eigene eMail zu schicken, wenn etwas schief gegangen ist.


Also zum Beispiel:

$buy_email = isset($_POST['payer_email']) ? $_POST['payer_email'] : '-'; $buy_firstname = isset($_POST['first_name']) ? $_POST['first_name'] : '-'; $buy_lastname = isset($_POST['last_name']) ? $_POST['last_name'] : '-'; $buy_paytype = isset($_POST['payment_type']) ? $_POST['payment_type'] : '-'; $buy_paystatus = isset($_POST['payment_status']) ? $_POST['payment_status'] : '-'; $buy_mcgross = isset($_POST['mc_gross']) ? $_POST['mc_gross'] : '-'; $buy_mccurrency = isset($_POST['mc_currency']) ? $_POST['mc_currency'] : '-'; $buy_itemnumber = isset($_POST['item_number']) ? $_POST['item_number'] : '-';


Hinweis: weitere Felder, die in den POST Daten stehen können, bekommt ihr am besten raus, wenn ihr euch mal die key=value Kombinationen der empfangenen Daten aus Punkt 1. weiter oben zum Debuggen mit ausgeben lasst - oder mal die PayPal Dokumentation durchstöbern.
(siehe auch Kapitel iii, Hinweise zum Debuggen).


An dieser Stelle jetzt haben wir die IPN Notification empfangen, mit PayPal gegengecheckt und sind sicher, dass die enthaltenen Daten gültig sind.
Jetzt kommen noch zwei weitere Schritte: zum einen tragen wir die eMail Adresse des neuen Kunden in eine MySQL Datenbank ein, zum zweiten schicken wir eine "Danke-Mail" an den neuen Kunden.



5.: Eintragen der eMail Adresse in eine MySQL Datenbank

Die Routine funktioniert so:

Im Beispiel hier handelt es sich um eine einfache SQL Tabelle mit einer einzigen Spalte "email". Ihr könnt diese über die Datenbankverwaltung eures Web Providers (z.B. Strato) anlegen.


$errLevel = 0; // init: before db activities // connect to mySql server $link = mysqli_connect($mySqlServer, $mySqlUser, $mySqlPass); if ($link) $errLevel = 1; // if successful, raise level // connect to database if (($errLevel == 1) && (mysqli_select_db($link, $mySqlDB))) $errLevel = 2; // check if buyer is already registered if ($errLevel == 2) { if ($gUser = mysqli_query($link, "SELECT * FROM users WHERE email='".$buy_email."'")) { $errLevel = 3; } } if ($errLevel == 3) { // check if 0 or 1 entry $verify = mysqli_num_rows($gUser); // if 0 entries, then add if ($verify == 0) $errLevel = 4; // new user to database } if ($errLevel == 4) { // user not registered yet if (mysqli_query($link, "INSERT INTO users (email) VALUES ('".$buy_email."')")) { $errLevel = 5; // add user to database } } if ($errLevel >= 1) mysqli_close($link); // above level 1, close connection // evaluate error level if ($errLevel == 3) { // user already registered $errText = 'user already registered'; } else if ($errLevel == 5) { // new user successfully registered $errText = 'new user registered'; } else // else, something went wrong { $errText = 'ErrLevel: '.$errLevel.' Error: '; switch ($errLevel) // write debug information { case 0: $errText .= 'couldn\'t connect to MySQL Server' . mysql_error(); break; case 1: $errText .= 'couldn\'t set default database' . mysql_error(); break; case 2: $errText .= 'couldn\'t fetch data from database' . mysql_error(); break; case 4: $errText .= 'couldn\'t insert user to database' . mysql_error(); break; default: break; } return false; }

6.: Schicken der eMail an den Kunden

Das Beispiel hier verwendet den Standard PHP Mail Handler, keine nachträgliche Installation von Dritt-Software ist notwendig.

Die Mail wird in HTML und UTF-8 Codierung geschickt.


require_once "Mail.php"; // standard PHP Mail $mimeVer = '1.0'; $contType = 'text/html; charset=UTF-8'; // send mail in HTML format and UTF-8 $from = 'Your Webpage <support@your_webpage.de>'; $to = <'.$buy_email.'>'; $subject = 'Kaufbestätigung'; $body = ' <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> </head> <body> <div style="font-family:Verdana; font-size:10pt"> Sehr geehrte(r) Frau/Herr '.$buyLastName.',<br> <br> vielen Dank, dass Sie unser Produkt gekauft haben.<br> … <br> <br> vielen Dank und viele Grüße<br> Name <br> <br> </div> </body> </html> '; // end of mail body $headers['From'] = $from; $headers['To'] = $to; $headers['Subject'] = $subject; $headers['MIME-Version'] = $mimeVer; $headers['Content-type'] = $contType; $params['sendmail_path'] = '/usr/lib/sendmail'; $mail_object =& Mail::factory('sendmail', $params); $mail_object->send($to, $headers, $body); if (PEAR::isError($mail)) return $mail->getMessage(); else return true; ?> // end of IPN Listener

7.: Fazit

Der IPN Listener ist vom Prinzip her voll einsatzfähig.

Ihr müsst nur eure eigenen Daten für eMail Adressen, Mail Account Daten (Passwort, Provider) und die MySQL Datenbank eintragen und dann könnt ihr mit dem Testen und Debuggen loslegen.






Support:
Webmaster:
support@coniuno.de
webmaster@coniuno.de
Copyright © Helmut Bischoff 2005-2018. All rights reserved
 
Copyright H.Bischoff 2005-2018. All rights reserved