Introducción a PayPal e IPN para programadores


Mi buzón de entrada está lleno de spam que intenta que solicite una cuenta de vendedor para que mi sitio web pueda aceptar pagos con tarjeta de crédito. ¿Quién necesita eso si tiene PayPal?

Si su sitio web necesita aceptar pagos electrónicos, PayPal es la mejor opción. No necesita ponerse en contacto con ningún vendedor de PayPal, y no necesita instalar ni comprar software alguno. Solo necesita una cuenta PayPal y habilidades básicas en HTML y secuencias de comandos. Puede utilizar PayPal como solución de pago y dejar que se encargue de todo el complejo procesamiento de pagos.

Cualquier sitio web puede empezar a cobrar pagos con los Servicios para vendedores de PayPal. Basta con rellenar un simple formulario web y PayPal le proporcionará un botón que puede colocar en su sitio web para empezar a cobrar dinero. No es necesaria ninguna programación. Este componente de los Servicios para vendedores de PayPal se denomina Aceptación mediante web.

Asistente de Aceptación mediante web de PayPal

Aceptación mediante web funciona bien de manera autónoma, pero es incluso más potente si se combina con otro componente de los Servicios para vendedores de PayPal denominado Notificación de pago instantánea (IPN). Con IPN, su sitio web cobra dinero a través de PayPal, y se comunican a su servidor todos los pagos en cuanto se realizan. Mediante una sencilla interfaz CGI, PayPal envía a su servidor todos los detalles de pago que necesita para registrar, procesar y entregar transacciones.

Notificación de pago instantánea de PayPal

Con la combinación de Aceptación mediante web y Notificación de pago instantánea, PayPal realmente funciona como un servicio web valioso y fácil de usar. Los pagos de sus usuarios se depositan directamente en su cuenta PayPal. El dinero no pasa por un intermediario en ningún momento. PayPal recopila la información de envío por usted, si es necesario. Y usted puede variar el nivel en que su organización automatiza su gestión de pagos. Puede comenzar por un proceso sencillo de pagos e ir integrando y automatizando gradualmente más funciones y servicios de PayPal a medida que su empresa crece.

La forma más sencilla de comenzar es con el asistente de Aceptación mediante web de PayPal y copiar el HTML que genera. Después, modifique el HTML, ya sea manualmente o mediante programación, para ajustarlo a las necesidades de su sitio. El siguiente ejemplo ilustra el proceso. Nota: En este ejemplo, se asume que ya tengo un sitio web activo y en marcha y que ya tengo una cuenta PayPal.

Supongamos que produzco chismes, y que quiero empezar a vender chismes desde mi sitio web personal utilizando PayPal. Comienzo por utilizar el formulario de Aceptación mediante web de PayPal para rellenar los detalles de mi producto y PayPal me devuelve lo siguiente para mi sitio web:

<!-- Begin PayPal Logo -->
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="alanb@alanb.com">
<input type="hidden" name="undefined_quantity" value="1">
<input type="hidden" name="item_name" value="doodad from alanb.com">
<input type="hidden" name="item_number" value="dd01">
<input type="hidden" name="amount" value="4.99">
<input type="hidden" name="return" value="http://alanb.com/doodads/thanks.html">
<input type="hidden" name="cancel_return" value="http://alanb.com/doodads/canceled.html">
<input type="image" border="0" name="submit" src="http://images.paypal.com/images/x-click-but5.gif" alt="Realice pagos con PayPal: es rápido, gratis y seguro.">
</form>
<!-- End PayPal Logo -->

Observe que la variable de empresa (business) apunta a mi dirección de correo electrónico, que también representa mi cuenta PayPal. Puedo editar el nombre de artículo, el número de artículo y el importe como necesite.

El formulario también contiene dos URL, denominadas return y cancel_return. Se utilizan para enviar al usuario de nuevo a mi sitio web una vez completada o cancelada la transacción con PayPal. He creado dos sencillas páginas web denominadas thanks.html y canceled.html para este ejemplo.

Podría dejarlo aquí mismo, poner ese HTML en una página web y empezar a aceptar pedidos de chismes. Cada vez que alguien haga clic en PayPal y compre un chisme, PayPal me enviará por correo electrónico los detalles de la transacción y la información de contacto del cliente. Pero supongamos que quiero introducir los datos de ese cliente y de la transacción en mi propia base de datos. Puedo ampliar fácilmente el bloque anterior de HTML para que comunique a mi servidor web todas las transacciones a medida que se produzcan. Basta con añadir un campo de entrada oculto más al formulario HTML:

<input type="hidden" name="notify_url" value="http://alanb.com/doodads/notify.cgi">

Ahora, los servidores de PayPal llamarán a mi secuencia de comandos CGI, notify.cgi, con los detalles de cada pedido de un chisme en cuanto se produzca. Esto es la notificación de pago instantánea. PayPal utiliza el método HTTP POST para enviar detalles de transacción a notify.cgi. Entonces, notify.cgi devuelve los datos de esa transacción a PayPal para confirmar la validez del pago. Para este sencillo ejemplo, notify.cgi registra a continuación los detalles del pago en un archivo de registro. PayPal no requiere un código de respuesta especial de notify.cgi, así que pongo la palabra "foo" para terminar la comunicación HTTP.

Este es mi botón HTML de PayPal, modificado para que utilice la notificación instantánea de PayPal, junto con un par de retoques más:

<!-- Begin PayPal Button -->
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="alanb@alanb.com">
<input type="hidden" name="undefined_quantity" value="1">
<input type="hidden" name="item_name" value="doodad from alanb.com">
<input type="hidden" name="item_number" value="dd01">
<input type="hidden" name="amount" value="1.99">
<input type="hidden" name="return">
value="http://alanb.com/doodads/thanks.cgi">
<input type="hidden" name="cancel_return">
value="http://alanb.com/doodads/canceled.html">
<input type="hidden" name="notify_url" value="http://alanb.com/doodads/notify.cgi">
<input type="image" border="0" name="submit" src="http://images.paypal.com/images/x-click-but5.gif" alt="Compre lo que sea con PayPal">
</form>
<!-- End PayPal Button -->

And here is a simple Python script, notify.cgi:

#!/usr/local/bin/python

# notify.cgi -- CGI script that receives PayPal instant payment notifications
# Alan Braverman
# 27/11/2001

import sys, time, urllib

def confirmPayment():
"Ask PayPal to confirm this payment, return status and detail strings"
paymentDetails = sys.stdin.read() # formatted as a CGI query
confirmPostData = paymentDetails + '&cmd=_notify-validate'
confirmPostRequest = urllib.urlopen(
'http://www.paypal.com/cgi-bin/webscr', confirmPostData)
paymentStatus = confirmPostRequest.read() # either VERIFIED or INVALID
return paymentStatus, paymentDetails

def logPayment(paymentStatus, paymentDetails):
"Write payment status and details to a log file"
logFile = open('payments.log', 'a')
logFile.write('%s %s %s\n' % (
time.ctime(time.time()), paymentStatus, paymentDetails))
logFile.close()

def sendResponse():
"Send a simple HTTP response back to PayPal"
print 'Content-type: text/plain\n\nfoo'

def main(argc, argv):
"Process PayPal Instant Payment Notification CGI call"
paymentStatus, paymentDetails = confirmPayment()
logPayment(paymentStatus, paymentDetails)
sendResponse()

if __name__ == "__main__":
main(len(sys.argv), sys.argv)

Ni que decir tiene que podría extender este proceso de miles de formas además de volcar un archivo de registro, desde escribir en una base de datos hasta procesar automáticamente el pedido y entregar un producto o un servicio. Recomiendo que las rutinas de la interfaz de PayPal se mantengan sencillas y que otro proceso se encargue de atender y cumplimentar el pedido. Si su secuencia de comandos CGI tiene errores, podría perder una transacción. Sin embargo, hasta que su secuencia de comandos confirme cada pago, PayPal seguirá intentando comunicárselo. Puede probar con un ejemplo sencillo y verá cómo PayPal informa a sus registros de acceso. Del mismo modo, se recuperará de los errores con más facilidad si su secuencia de comandos distingue las transacciones únicas de las repetidas.

Cuando un usuario completa una transacción, PayPal envía los detalles de la transacción a mi URL de retorno. Así que he sustituido thanks.html por una secuencia de comandos thanks.cgi. En este ejemplo, thanks.cgi se limita a redirigir al usuario a thanks.html. Podría extender esto para utilizar los detalles del pedido en la página "thanks", para generar un recibo o una información por Internet.

He aquí otra sencilla secuencia de comandos Python, thanks.cgi:

#!/usr/local/bin/python

def main():
print 'Content-type: text/plain'
print 'Status: 302'
print 'Location: http://alanb.com/doodads/thanks.html'
print

if __name__ == "__main__":
main()

No voy a profundizar en detalles de datos de transacción en este artículo. Consulte la tabla de variables de notificación de pago instantánea en el sitio web de PayPal.

Cuando PayPal le comunique que se ha completado o cancelado un pago, sabrá cómo gestionarlo desde su lado. Pero a veces PayPal le comunicará que el estado de un pago está "pendiente". Los pagos pendientes son algo más difíciles de gestionar y la ayuda de PayPal es limitada en estos casos. De acuerdo con la documentación de IPN de PayPal en lo relativo a pagos pendientes, cuando se inicie un pago se le comunicará a su servidor y una segunda vez cuando el pago haya cambiado de "pendiente" a "completado".

Los programadores Web con experiencia ya saben que las secuencias de comandos CGI pueden resultar difíciles de depurar. Lamentablemente, PayPal no le permite pagarse a sí mismo. Necesitaría crear artículos de prueba y depurarlos con un amigo para probar el flujo del producto de un extremo a otro. Busque a otro programador con el que juntarse para probar PayPal.

Mi ejemplo de los chismes está operativo en http://alanb.com/doodads, así que anímese a comprarme un chisme si quiere ver cómo funciona esto desde el punto de vista del comprador. No voy a enviarle nada, por supuesto, pero mis chismes tienen un precio razonable :-).


RENUNCIA DE RESPONSABILIDAD: Los contenidos siguientes han sido proporcionados por los autores de cada artículo y no por PayPal, Inc. o ninguna de sus subsidiarias o empresas afiliadas. Estos artículos pueden contener errores, y PayPal no apoya ni se responsabiliza de su contenido. PayPal le recomienda que se ponga en contacto con los autores de dichos artículos si desea obtener más información sobre asistencia técnica, garantías o licencias, si es necesaria. Si decide confiar en el contenido de cualquiera de estos artículos, lo hará por su cuenta y riesgo. PayPal no será responsable de errores, daños o perjuicios que puedan surgir como resultado de la confianza puesta en estos contenidos, incluyendo cualquier tipo de daño incidental, especial, indirecto o consecuencial. PayPal RENUNCIA EXPRESAMENTE A TODA GARANTÍA relativa a dichos contenidos y al uso de los mismos.