Me podrías decir, pués es simple, te avisan por correo.
Pero la cuestión es la siguiente, automatizar el recibo de los avisos para poder generar un informe personalizado o desencadenar acciones en nuestra base de datos y un largo etcétera, las posibilidades son bastante amplias.

Bueno lo primero que tenemos que hacer, es tener una cuenta en PayPal.
Para activar la Notificación de pago instantánea debes acceder a tu cuenta.
Desde el apartado Mi Cuenta accedes al Perfil y bajo la cabecera Preferencias de venta clicamos en Preferencias de Notificación de pago instantánea.
Una vez dentro pulsamos en editar.
Activamos la casilla y asignamos una url, que será el destino de los avisos.
Decir que también se puede activar la Notificación de pago instantánea agregando el campo notify_url=dirección url, pero no creo que sea muy recomendable hacerlo (a menos que tengas varias cuentas de correo asignadas en tu cuenta paypal) puesto que es un campo que puede ser visionado por cualquiera.
Una vez hemos activado el IPN, generamos los botones de donación/pago y los agregamos a nuestro sitio web.
Terminada la “infraestructura de venta visual” solamente nos falta el archivo que hará de receptor de los avisos.
Decir que en la web de PayPal ponen a disposición una serie de scripts de ejemplo para los siguientes lenguajes :
ASP.Net/C#
ASP.Net/VB
ASP/VBScript
Cold Fusion
Java/JSP
PERL
PHP
(Hace falta estar logeado en paypal para poder verlos, para la documentación también)
La documentación así la podéis encontrar en
Si no podéis acceder os la subo a algún sitio.
Yo voy a proseguir a partir del ejemplo de PHP 4.1 que ofrecen en la web, voy a comentarlo y
luego pondré un ejemplo con una base de datos y que cada cual lo adapte a sus necesidades.
Decir que pese a mi esfuerzo por guardar márgenes y demás en los ejemplos para un mejor visionado el muy perrete se ha comido las tabulaciones al publicar el tutorial ¬¬’
PHP 4.1
//comentado por Roberto Herrero para su blog http://blog-indomita.blogspot.com/
// read the post from PayPal system and add 'cmd'
//es la variable señuelo que hay que devolver a PayPal para que compruebe su veracidad
$req = 'cmd=_notify-validate';
//recogemos todos los datos POST que nos envía paypal y los guardamos en el mismo orden
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate
//creamos la petición de llamada para avisar de la recepción
$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";
//en la documentación dice que pongas www.paypal.es pero supongo que es un errata, con .es no funciona así que deja el .com
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
// assign posted variables to local variables
//tomamos los valores del POST anterior
//nombre que hemos asignado al crear el botón
$item_name = $_POST['item_name'];
//número personal que hemos asignado al crear el botón
$item_number = $_POST['item_number'];
//estado del pago la buena noticia es que este en Completed xD
$payment_status = $_POST['payment_status'];
//ojo aquí que el payment_amount es el mc_gross no liarse que al mirar la documentación puede dar a confusiones
//la cantidad del ingreso
$payment_amount = $_POST['mc_gross'];
//igual que antes ojito xD
//la moneda del ingreso
$payment_currency = $_POST['mc_currency'];
//identificador alfanumérico que PayPal le asigna
$txn_id = $_POST['txn_id'];
//cuenta a la que se ha ingresado
$receiver_email = $_POST['receiver_email'];
//emisor del pago
$payer_email = $_POST['payer_email'];
if (!$fp) {
// HTTP ERROR
//no hemos podido conectar con paypal
} else {
//tenemos respuesta de paypal
fputs ($fp, $header . $req);
//leémos los datos recibidos, realmente estamos buscando si los datos que hemos recogido con anterioridad son válidos, ya que algún graciosillo/lamercillo puede estar intentando tomarnos el pelo
while (!feof($fp)) {
$res = fgets ($fp, 1024);
//comprobación verificada
if (strcmp ($res, "VERIFIED") == 0) {
// check the payment_status is Completed
//ahora tenemos que comprobar que el payment_status es Completed, en la documentación pone Completado pero ni caso xD
// check that txn_id has not been previously processed
//comprobamos en nuestra base de datos que no sea una transacción ya procesada, ¿por qué? para evitar malas intenciones de terceros no tiene sentido procesar algo que ya hemos procesado
// check that receiver_email is your Primary PayPal email
//comprobamos si el email de la transacción es el nuestro
// check that payment_amount/payment_currency are correct
//comprobamos que tanto la cantidad como la moneda son las correctas
// process payment
//si todo ha ido bien ya podemos procesar el pago/donación
//la comprobación es incorrecta
}else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
//aquí puedes guardar un log para ir investigando quién esta jugando con tu sistema
}
}
//cerramos
fclose ($fp);
}
Ejemplo con base de datos MySql
Requisitos previos:
* Conocer como crear el conector $link.
Te dejo el tutorial por si te interesa: Tutorial Conexión a MySql desde PHP
* La base de datos debe tener tantos campos como parametros desees guardar, en este caso guardaremos la fecha(datetime) y una cadena(varchar o text) con todos los parámetros, amén del identificador(varchar) único que otorga PayPal para la transacción
//comentado por Roberto Herrero para su blog http://www.miblog.indomita.org/
//recomiendo añadir un parámetro personal a la url que utilizaremos para gestionar los pagos, nuestro señuelo y si esta encriptado pos mejor
//con comprobar si la variable ha sido enviada creo que es suficiente,
pero si eres un paranoico y no te fias de los mamones que navegan por la red
puedes añadir && $_GET["antimamones"]==md5("nointentesjodermequetevasaenterar")
//el parámetro que pases por GET recuerda que tienes que agregarlo en el perfil de url IPN del comienzo de este manual.
if(isset($_GET["antimamones"]))
nuevo_ingreso();
function nuevo_ingreso(){
//esto ya lo he comentado antes así que paso xD
// 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.paypal.com', 80, $errno, $errstr, 30);
// assign posted variables to local variables
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$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'];
//podemos añadir el campo custom en nuestros botones (en el código una vez generados) con la información que deseemos, esto viene bien para identificar al usuario
$custom = $_POST['custom'];
//creamos una conexión a nuestra base de datos
conecta($link);
if (!$fp) {
// HTTP ERROR
} else {
//recorremos respuesta
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
// check the payment_status is Completed
if(strcmp ($payment_status, "Completed")==0){
//la transacción esta completada
// check that txn_id has not been previously processed
//la función es_idenfiticador_alfanumerico comprueba que no inyecten sentencias SQL (usease antimamoneo) esta definida al final
if(es_identificador_alfanumerico($txn_id)) {
//comprobamos si no la hemos procesado ya
$r=mysql_query("select count(txn_id) as repes from ingresos_recibidos where txn_id='".$txn_id."'",$link);
$f=mysql_fetch_array($r);
$repetida=(int)$f["repes"];
}else{ $repetida=1;}
//en el caso de que no sea válido tendremos valor 1
if($repetida==0){
//no es una transacción repetida
// check that receiver_email is your Primary PayPal email
if(strcmp ($receiver_email, "micorreo@loquesea.com")==0){
//es un correo válido
// check that payment_amount/payment_currency are correct
//ahora pasamos a comprobar que tipo de pago ha realizado tenemos que anidar los diferentes casos de alguna manera, en el ejemplo lo he hecho con 2 casos
//obtengo el usuario que ha hecho el ingreso del campo custom
//supongo que tendrás tu propia clase de acceso y recogida de datos, si no la tienes lo que pongo es funcional
$r=mysql_query("select usuario from tabla_usuarios where usuario=".((int)$custom), $link);
$f=mysql_fetch_array($r);
$usuario=(int)$f["usuario"];
//caso 1: el pago es de 1.99 la moneda el EURO que son los valores que debería de tener el elemento identificador personal 1
if($payment_amount==1.99&&strcmp($payment_currency, "EUR")==0
&&$item_number==1&&$usuario>0){
//aquí van las operaciones de guardado de informe y las que desencadenas al recibir un pago
//ingresamos los datos
$cadena=sprintf("guardando informe
item_name=%s
item_number=%s
custom=%s
payment_status=%s
mc_gross=%s
mc_currency=%s
txn_id=%s
receiver_email=%s
payer_email=%s",
$item_name,$item_number,$custom,$payment_status,$payment_amount,$payment_currency,$txn_id,$receiver_email,$payer_email);
mysql_query("insert into ingresos_recibidos (cadena,txn_id,fecha) values ('".$cadena."'
,'".$txn_id."','".date("Y-m-d H:i:s")."')",$c);
//actualizamos las gracias que le damos al usuario
(mil gracias)
mysql_query("update tabla_usuarios set gracias=gracias+1000 where usuario=".$usuario,$link);
//caso 2: el pago es de 6.99 la moneda el EURO que son los valores que debería de tener el elemento identificador personal 2
}elseif($payment_amount==6.99&&strcmp($payment_currency, "EUR")==0
&&$item_number==2&&$usuario>0){
//aquí van las operaciones de guardado de informe y las que desencadenas al recibir un pago
//lo mismo que antes aunque yo recomiendo hacerse una funcioncita o algo que evite repetir código
//actualizamos las gracias que le damos al usuario
(un millón de gracias)
mysql_query("update tabla_usuarios set gracias=gracias+1000000 where usuario=".$usuario,$link);
}
}
}
}
}elseif (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
}
}
fclose ($fp);
}
}
//funcion antimamoneo, realmente no se el rango total de caractéres raros que envia paypal así que habría que adaptarla xD
function es_identificador_alfanumerico($cadena){
return ereg("^[A-Za-z0-9_]*$",$cadena);
}
No he probado el código y seguramente tenga algun pequeño fallo (falta de paréntesis, ; o alguna } )
Paypal ofrece otros métodos IPN que incluyen conexión https y demás en el servidor.
El código del ejemplo no necesita una conexión segura para llevarse a cabo.
Si alguien ve algun agujero de seguridad le agradecería que me lo comunicase para modificarlo.
Anexo: Realizar pruebas de pagos con PayPal
Espero que a alguien le sirva de ayuda.











» ideone.com – Compilador online de código multitud de lenguajes de programación
» Librería ADOdb Date Time para manejar fechas sin límites

9 Comentarios
gracias por el tuto me esta sirviendo excelentemente, la unica duda es que al momento de q poner q la moneda es EUR, esto es porke el pago lo realiza en EUR??? y si se realiza en DOLARES???, es lo mismo o tengo q ponerle en USD???.
gracias de antemano.
Depende de como quieras tenerlo.
Si deseas aceptar solamente EUR debes especificarlo en el botón de pago y no se si en la cuenta también.
Al pulsar el botón de pago cobrará la cantidad en EUROS y si no tiene euros transforma automáticamente x dólares del “comprador” en euros para ti;
A la hora de verificar debes comprobar que la moneda es la que deseas para evitar que te la intenten jugar pagando en otra moneda más baja al cambio;
Me alegro de que te resulte últil el tutorial
hola indomita tengo un problema con este codigo
ya lo hice todo y esta todo bien
pero no guarda en mi base de datos
y al parecer no paypal tampoco envia los datos, por que le he puesto un pequeño script que me abre una ventana osea , lo he puesto como una laerta si llegan datos o no desde paypal..
cual seria el problema osea por que la url de ipn de mi paypal lo he puesto sin parametros y tiene que ser con parametros… lo he puesto asi
http://forosax.webcindario.com/informe1.php
y sera asi que no me sale o le debo de poder algun partametro y si fuera con algun parametro quisiera saber cual es el parametro de entrada osea asi
http://forosax.webcindario.com/informe1.php?xxx=zzz
entonces mi pregunta es cual seria nombre de la variable de xxx y zzz. por favor amigo necesito que urgente me ayudes con esta respuesta ya que estoy implementando un sistema , y necesito esta informacion urgente. te lo agradecere de ante mano…
y respondme en cuanto tengas la respuesta
mi correo es: ing_joseportilla@hotmail.com
paypal envía los datos por POST no por GET
cuando alguien realiza una donación o paga PayPal realiza una petición por POST a la web que le has dicho, una vez tienes los datos los compruebas realizando una petición a PayPal y todo listo
creo que no habías entendido correctamente el sistema
parece que no me entiendes ya se que envia por post, entonces por que no me envia los datos a mi base de datos de mi hosting
ya he hecho unas pruebas de compras, y la informacion de compras no me llega a la base de datos de mi hosting
no se por que ademas ya la url de mi ipn en mi paypal
lo que yo qyuiero saber es si es la que url de mi ipn de mi paypal es con parametros o no ?
osea si es con este formato
http://mihosting/procesa.php
o es asi
http://mihosting/procesa.php?variable1=variable2
ya que este punto es importante, y nocesito saberlo
y si fuera con variables nocesito saber que el nmombre de los parametros…
por que si no como se que paypal en que paquete me va a enviar toda la informacion…
por eso necesito que me ayudes amigo…
ya he hecho todo, he puesto el codigo. con la url y no me funciona.
las variables personalizadas las llama custom, es recomendable bajarse la guía de paypal.
Si no te lees la guía te va a resultar bastante complicado hacerlo.
En el ejemplo lo explico :
//el parámetro que pases por GET recuerda que tienes que agregarlo en el perfil de url IPN del comienzo de este manual.
Si el dato es variable y estas utilizando la url IPN fija pués no puedes pasar ningún dato extra variable en la url. Se pasan por $_POST con el identificador custom.
TABLA A.2 Variables IPN y PDT: Información avanzada y personalizada :
custom: Valor personalizado transferido por usted, el vendedor. Son unas variables de transferencia que nunca se presentarán a su cliente.
Longitud de caracteres : 255
Hola, no entiendo muy bien como funciona este sistema
¿sera que despues de hacer la compra paypal lo manda a esa pagina y ahi se sabe si la persona pago?
no entiendo bien
eso es lo que hace, cuando una persona paga, paypal envía un aviso con los datos, se comprueban y si coinciden son buenos
Guapissimo tutorial, la verdad que iba buscando algo asi para aclarar algunas dudas y me ha venido fenomenal.
Gracias
Escribir un Comentario