Como crear una pasarela de pago con PayPal


Escrito por fernando! | 14-02-2010 23:42

Ultimamente he estado implicado en un proyecto que requería hacer una pasarela de pago con PayPal de modo que me puse a buscar información al respecto y me he dado cuenta que resulta complicado obtener ejemplos funcionales por lo que he decidido hacer esta pequeña entrada para aquellos que se encuentren en mi misma situación lo tengan un poco más fácil.

Existen muchas forma de realizar un pago mediante paypal : Pago express , carro de la compra , pago estándar ... Dentro de cada uno de estos formatos existen muchos otras formas de realizar el pago. El más tradicional y el cual seguramente muchos de vosotros habréis usado es el pago estándar ya sea para pagar algún producto de una tienda online o para realizar una donación en los muchos sitios web que piden donaciones , de modo que este va a ser nuestro caso de estudio.

Pero antes de nada para aquellos que todavía no sepan que es Paypal os añado la definición propia de wikipedia :

PayPal es una empresa estadounidense perteneciente al sector del comercio electrónico por Internet que permite la transferencia de dinero entre usuarios que tengan correo electrónico, una alternativa al tradicional método en papel como los cheques o giros postales. PayPal también procesa peticiones de pago en comercio electrónico y otros servicios webs, por los que cobra un porcentaje. La mayor parte de su clientela proviene del sitio de subastas en línea eBay.

Primero hay que entender como funciona el flujo de datos en este tipo de transacciones para ello no hay nada mejor que una imagen procedente de PayPal : 

En la imagen podemos observar como partiendo de nuestro sitio web mediante un formulario que tendrá una serie de campos ocultos podemos acceder a paypal donde se realizará el pago , una vez se realiza el pago PayPal envía una notificación mediante su protocolo IPN (Instant Payment Notification o notificación instantánea de pago) a través de ella conoceremos el estado que ha tenido la transacción así como una serie de datos añadidos que permitirán que podemos tener un control absoluto sobre el estado del pago.

Ya que no puedo concentrar todas las posibilidades que tiene este método de pago voy a explicarlo a través de un pequeño código de ejemplo para que podáis tener más información de la que aparece en la documentación de paypal.

Algo que tenéis que tener en cuenta a la hora de desarrollar una pasarela de pago con PayPal es que debéis conocer el sandbox o entorno de prueba (https://www.sandbox.paypal.com/) , para poder utilizar la DEMO o modificar/usar estos scripts tenéis que daros de alta y crear compradores y vendedores ficticios.

Formulario.html

#GALLETAS5 ; Nombre: Galletas ; Valor : 5.00 , Cantidad : 2 #PIRULETAS3 ; Nombre: Piruletas ; Valor : 3.00 , Cantidad : 5

Como podréis observar el campo action del formulario nos lleva al sandbox de PayPal , es decir , al sitio de pruebas donde podremos testear nuestro script , en caso de querer realizar el testeo directamente con PayPal deberemos de eleminar el subdominio sandbox dejándolo como : https://www.paypal.com/cgi-bin/webscr.

Repecto a los demás campos:

  • cmd > indica el tipo de fichero que va a recoger PayPal 
    _cart : varios items
    _donations : donaciones
    _xclick : boton de compra
  • business > indica el identificador del negocio registrado en paypal. Ejemplo : buyer_1265883185_biz@gmail.com
  • shopping_url > la dirección de nuestra tienda online . Ejemplo : http://www.fernandosalom.es
  • currency_code > el tipo de moneda (USD , EUR ...)
  • return > sera el enlace de vuelta a nuestro negocio que ofrece paypal
  • notify_url > en esta pagina es donde recogeremos el estado del pago y un gran numeros de variables con informacion adicional en nuestro caso lo hemos llamado paypal_ipn.php
  • rm > Indica el método que se va a utilizar para enviar la información de vuelta a nuestro sitio. RM=1 información enviada por GET , RM=2 información enviada por POST (En este caso usamos este método porque es un script php el que recoge los datos) . (Gracias Miguel)
  • item_number_X > identificador del producto
  • item_name_X > nombre del producto
  • amount_X > precio del producto
  • quantity_X > cantidad del producto

Paypal_ipn.php

 
<\?php

//Leer POST del sistema de PayPal y añadir 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
//header para el sistema de paypal
$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";
//header para el correo
$headers = 'From: webmaster@ejemplo.com' . "\r\n" .
           'Reply-To: webmaster@ejemplo.com' . "\r\n" .
           'X-Mailer: PHP/' . phpversion();
//Si estamos usando el testeo de paypal:
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
//En caso de querer usar PayPal oficialmente:
//$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
if (!$fp) {
// ERROR DE HTTP
}else{
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {

//Almacenamos todos los valores recibidos por $_POST.
foreach($_POST as $key => $value){
        $recibido.= $key." = ". $value."\r\n";
}
//Enviamos por correo todos los datos , esto es solo para que veáis como funciona
//En un caso real accederíamos a una BBDD y almacenaríamos los datos.
// > Comprobando que payment_status es Completed
// > Comprobando que txn_id no ha sido previamente procesado
// > Comprobando que receiver_email es tu email primario de paypal
// > Comprobando que payment_amount/payment_currency son procesos de pago correctos

mail("micorreo", "NOTIFICACION DE PAGO", $recibido , $headers);
}else if (strcmp ($res, "INVALID") == 0) {
mail("micorreo", "NOTIFICACION DE PAGO INVALIDA", "invalido",$headers);
}
}fclose ($fp);
}
?>

Este script no se visualiza ya que no hacemos un acceso directo a él sino que es PayPal el que lo ejecuta para notificarnos los datos de la transacción , es por ello que en este script he hecho que nos envíe un correo con los datos de la operación si han sido válidos o no. Para ello lo único que debemos modificar es el texto micorreo por nuestro correo electrónico.

Este no es el procedimiento adecuado para recoger estos datos ya que lo que deberíamos de hacer es crear un script con su correspondiente BBDD que comprobará los datos y los insertará para tener un registro de todas las transacciones.

Si deseáis preguntar algo comentarlo y lo contestaré conforme tenga tiempo , a continuación os dejo una serie de enlaces de interés sobre este tema.

> DEMO de este ejemplo en funcionamiento Recordar que debéis de daros de alta en el SANDBOX y crear un comprador ficticio para que os funcione

> Documentación para pagos estándares


Iván dice :
15-02-2010 12:58
Es muy buen artículo, me ha gustado. Y también el blog está muy bien
Adrian dice :
05-03-2010 08:44
Con este tutorial (que es excelente, sobre todo por el ejemplo), es posible recibir el ID del usuario, a fin de saber quien fue el usuario que me compro, que fue lo que compro. Agradezco tu respuesta. Saludos
Fernando! dice :
14-03-2010 16:15
Hola Adrian , no se que tipo de compra estas desarrollando pero una forma que se me ocurre de poder hacer lo que dices es hacer el formulario con php y de esa forma puedas modificar dinámicamente el campo notify_url de modo que cuando se realice la compra puedas obtener valores por GET por ejemplo : http://mipagina.com/paypal_ipn.php?idusuario=10 y almacenar la cesta que ha seleccionado el usuario en la bbdd de modo que con id de usuario puedas obtener los datos que necesitas , esto es una explicacion rapida , pero espero que te valga la idea ;)
Miguel dice :
15-03-2010 13:16
Gracias por este magnifico manual, era justo lo que necesitaba para aclararme algunas dudas.
Miguel dice :
15-03-2010 13:43
Por cierto una cosa que si me ha resultado dudosa es la variable rm dices que es el numero de items, pero en la página de PayPal hablan sobre:
rm=2:" El método POST redirige el navegador del pagador a la URL de devolución y también se envían todas las variables de transacción."
cuando se refieren a la variable rm.
Fernando! dice :
15-03-2010 17:51
Hola Miguel , tienes razón fue un error por hacer las cosas rápidas - como puedes ver en https://www.x.com/docs/DOC-1552

la variable rm hace referencia al método que se va a utilizar para enviar la información a devolver , en nuestro caso al ser un script el que recogerá la información vamos a utilizar rm=2 ya que la información se enviará por POST , rm=1 lo utilizaríamos en caso de querer enviar la información por GET . Voy a cambiarlo en el post.

Muchas gracias;)
Adrian dice :
21-03-2010 19:36
Gracias Fernando por la respuesta, ya estoy realizando algunas cosas, mas que nada pruebas, al final si no surgen mas dudas, posteare el link a la pagina en donde lo implemente. Saludos.
Jose L. Guerrero dice :
29-04-2010 19:22
Muchas gracias por tus explicaciones, lo cierto es que llevaba mucho tiempo intentando encontar una explicacion documentada y sencilla como la que propones.
Y puedes estar seguro de que al menos a mi me has ayudado muchisimo.
Un saludo y muchas gracias.
09-06-2010 11:20
Muy bueno el articulo, solo que si añadieras unas capturas estaria mejor
18-06-2010 11:17
Hola Fernando, como sería para añadir campos de información opcionales??

Lo he intentado buscar en la
Sara dice :
24-06-2010 16:39
Hola Fernando, muy buen artículo. Sólo tengo un problema, que a mí no me funciona.
No sé donde tengo que activar el ipn.
Si me identifico en Sandbox con mi usuario y contraseña y voy a "Test Tools" me aparece lo de ipn y relleno los siguientes campos con los datos:
IPN handler URL: http://localhost/prueba/paypal_ipn.php
Transaction type: Web accept
No sé si están bien los valores.

Por favor, una ayudita.

Muchas Gracias
Fernando dice :
28-06-2010 11:00
Hola Sara , perdona por el retraso. No estoy muy seguro de lo que te pasa pero creo que por lo que me has puesto el problema es el IPN handler URL ya que estas usando una dirección local para recibir la petición y el sandbox de paypal no te puede hacer llegar los datos.

Deberías de tener un dominio en internet para que tu dirección sea visible por el sandbox , por ejemplo : http://www.mipaginaweb.com/prueba/paypal_ipn.php , no te sirve hacerlo en local.

Espero que te sea de ayuda
Sara dice :
29-06-2010 11:40
Gracias Fernando por tu respuesta, ya lo conseguí hacer funcionar.
Ahora tengo otro problema, y es que cuando paso a sandbox y me tienen que mostrar los artículos que he comprado, me aparece un "Error detectado: Ha escrito caracteres no admitidos en este cuadro. Los tipos de caracteres actualmente disponibles son: europeo, chino, coreano, japonés y tailandés. Inténtelo de nuevo."

Muchísimas gracias por contestar.

Un saludo.
dayer dice :
09-07-2010 03:10
¡Gran explicación! Ya no creía posible el hecho de transferir el típico carrito de la compra hecho en PHP a PayPal para que quedara más serio que el cobrar una cantidad por un único producto a ojos de PayPal.

Un saludo.
carlos dice :
12-07-2010 17:11
Gracias Fernando, cuando tuve que ponerme con el carrito de Paypal pensé que sería más sencillo al haber hecho ya el de Servired, pero no me imaginaba que iba a ser tan complicado y que iba a haber tan poca documentación (y tan poco clara) sobre el tema.
Luego apareciste tú... y se hizo la luz ;)
Lo dicho: 1000 GRACIAS :)
Fernando dice :
13-07-2010 21:08
Comentarios como los vuestros hacen que uno tenga ganas de seguir escribiendo este tipo de artículos , gracias ;)
Jose francisco dice :
14-07-2010 14:30
Buenas Fernando, excelente información la que nos has plasmado alli. Me pasa igual que a Sara, al tratar de pagar en PayPal me aparece el mensaje: Ha escrito caracteres no admitidos en este cuadro. Los tipos de caracteres actualmente disponibles son: europeo, chino, coreano, japonés y tailandés. Inténtelo de nuevo. ¿A que se debe o como lo soluciono?
Gracias Fernando.

Añade tu comentario


Me reservo el derecho de eliminar y/o modificar aquellos comentarios que se salgan de esta temática , así como los promocionales (spam), susceptibles de afectar a derechos de terceros o de vulnerar las leyes.
Lenguaje HTML permitido : strong , em , a , ul , li , i , u

* :
* : * (no será publicado) : :