Cobrando por servicios a través de PayPal con PHP

Hace un tiempo necesitábamos crear un sistema de compras a través de PayPal con la particularidad de que teníamos recibir confirmación instantánea del pago para reflejar esas compras al usuario. Esta era la diferencia principal respecto de un carro de compra de una web donde vendes algo físicamente, en este caso no necesitas saber el estado de una compra, cuando el equipo de almacén prepare el pedido ya comprobará si se ha realizado el pago antes de servirlo. Nuestro caso es más complicado. Vendemos servicios que pueden ser suscripciones, créditos de uso en la web, servicios premium, acceso a zonas privadas… todo este tipo de opciones donde el usuario, después de pagar, vuelve a tu web para disfrutar de los servicios que ha comprado.

Al querer cobrar a través de PayPal tienes dos opciones, o creas botones estáticos (Comprar Ahora) desde la web de PayPal o generas los tuyos propios. El problema de crearlos estáticos es que debes crear uno por cada usuario y para cada servicio que necesites vender, algo absurdo para el caso que tratamos ya que estarías ante miles de botones. Al generar los tuyos propios puedes hacerlos normales o seguros, para que no se puedan modificar por el camino. Este es el método que deberías utilizar normalmente ya que, en los normales, un usuario experimentado puede modificar el importe a cobrar, algo que no deseas que ocurra.

Para que el sistema funcionase bien deberíamos recibir en una URL las compras realizadas de alguna manera que nos permitiese identificar al usuario que habia hecho la compra para añadirle los servicios en cuestión. La solución es crear botones firmados online utilizando como identificador de producto de compra el idUsuario de tu base de datos, de esta forma las confirmaciones de compra te indican el usuario al que pertenecen y ya puedas darle los servicios por los que ha pagado. Puedes utilizar combinaciones más elaboradas para reutilizar el sistema para distintos productos, por ejemplo idUsuario-idServicio (12345-3). Al recibirlo, con dividir la cadena por el guión ya tienes todo lo necesario. En nuestro caso había varios tipos de servicio pero se indentificaban por el coste del mismo, con lo cual con el identificador de usuario teníamos suficiente.

Aparentemente es sencillo el proceso, pero se complica ya que la documentación, a pesar de ser extensa, no esta del todo claro. Por un lado no está nada claro cómo configurar tu cuenta de PayPal para tener el sistema completo y por otro es bastante lioso el modo de crear los botones y recibir las confirmaciones. Vamos a explicarlo detalladamente ya que es un interesante ejercicio de programación en PHP.

Configurando la cuenta de PayPal

Lo primero que tienes que hacer es crear un certificado público X.509, único sistema que acepta PayPal.

Las instrucciones detallas las tienes aquí. básicamente necesitas tener openssl funcionando, cualquier sistema Linux lo tendrá instalado y sino tienes versiones para Windows.

openssl genrsa -out my-prvkey.pem 1024
openssl req -new -key my-prvkey.pem -x509 -days 3650 -out my-pubcert.pem

Con esto generamos primero la clave privada y a continuación el certificado público X.509 de esa clave. Es importante el parámetro -days, lo hemos puesto a 10 años para no tener problemas. En mi caso, la primera vez puse 365 días tal como viene en el ejemplo y al año dejó de funcionar sin que te dieses cuenta, fueron los usuarios los que nos avisaron. Guarda los dos archivos, my-prvkey.pem y my-pubcert.pem pues los necesitaremos a continuación.

Ya tenemos nuestro certificado preparado. Ahora debemos subirlo a PayPal para que sepa desencriptar nuestros botones. En tu cuenta de PayPal debes ir a:

Perfil->Configuración de pago codificado

Desde ahí, por un lado descargas el certificado público de PayPal, lo necesitaremos para codificar nuestros botones, y por otro subes tu certificado público que hemos llamado my-pubcert.pem. Obtendrás un ID de certificado, apúntatelo.

Si todo ha ido bien, ahora debemos configurar la cuenta para que PayPal sólamente acepte botones firmados, de manera que nadie pueda suplantar nuestra identidad con botones a otros precios, un detalle muy importante. Vamos entonces a:

Perfil->Preferencias de pago en el sitio Web

Primero activas Transferencia de datos de pago y te copias el Código Personal de Identidad que te indica, lo necesitaremos más adelante. A continuación, en la sección Pagos en el sitio Web codificado activamos la opción Bloquear pago en el sitio Web no codificado. Como véis no estaba tan claro el proceso.

Este paso no es obligatorio, pero haciéndolo conseguimos que el usuario vuelva a tu web una vez haya realizado el pago y, si ha sido correcto, tenga ya sus servicios disponibles. Activa la opción Retroceso automático e indica la URL de devolución, es decir, la URL donde será devuelto tu cliente, por ejemplo: http://www.tudominio.com/index.php?accion=creditos_paypalok

Finalmente activaremos la opción que nos permitirá recibir notificaciones de pagos online. Para ello vamos a:

Perfil->Preferencias de Notificación de pago instantánea

Y activaremos la notificación indicando la URL donde las vamos a recibir, por ejemplo, http://www.tudominio.com/secure/paypal/ipn.php.

Si has llegado a este punto, ya tienes todo lo necesario para comenzar con el código. Como recordatorio, necesitas:

  • Tu clave privada, my-prvkey.pem.
  • Tu certificado público, my-pubcert.pem.
  • Tu ID de certificado en PayPal
  • Tu Código Personal de Identidad
  • Certificado público de Paypal, paypal_cert_pem.txt.

Nos quedan, entonces, tres tareas pendientes:

  • Crear botones de compra
  • Crear el script de recepción de cobros realizados
  • Crear el script de vuelta después de una compra

Creando los botones

Comenzamos con el código. El único requerimiento es que tu instalación de PHP debe tener configurada la extensión openssl imprescindible para trabajar con los certificados. Con esta clase que encontré en su momento (me costó bastante localizar algo sencillo) tienes todo el proceso automatizado, sólo debes preocuparte por indicarle los datos que hemos ido guardando, los certificados y el ID del tu certificado en PayPal, simple ¿no?.

include("Class.PayPalEWP.php");
$paypal = &new PayPalEWP();
$paypal->setTempFileDirectory("/tmp");
$paypal->setCertificate("my-pubcert.pem", "my-prvkey.pem");
$paypal->setCertificateID("XXXXXXXXXX");
$paypal->setPayPalCertificate("paypal_cert_pem.txt");

$paypalParam = array(
    'cmd' => '_xclick',
    'business' => 'info@tudominio.com',
    'item_name' => 'Comprar Servicio X,
    'item_number' => $_SESSION['idUsuario'],
    'amount' => '5',
    'no_shipping' => '1',
    'currency_code' => 'EUR',
    'lc' => 'ES',
);
$form5="<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
            <input type="hidden" name="cmd" value="_s-xclick"/>
            <input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----n".$paypal->encryptButton($paypalParam)."n-----END PKCS7-----"/>
            <input type="image" src="imagenes/comprar_paypal.gif" border="0" name="submit" alt="Realice pagos con PayPal: es rápido, gratis y seguro." style="border:0;">
        </form>";

El código es bastante claro.
Ya lo tenemos, $form5 contiene el código de tu botón.
Los parámetros importantes son:

  • item_name: informativo, para que tu cliente sepa lo que compra. Por ejemplo: compra de suscripción a noticias.
  • item_number: Aquí configuramos el idUsuario de tu cliente en tu base de datos, así sabes quién compra.
  • amount: Precio que le cobras, en este caso 5 euros.

Modifica estos y los demás parámetros para reflejar tus opciones y adecuarlos a tu aplicación. Al sacar el código de $form5 en tu página tienes listo el sistema de compra.

Recibiendo las notificaciones

La recepción de notificaciones es la piedra angular del sistema para estar seguros de que un cliente ha pagado por un servicio. PayPal ha pensado que puedes llegar a tener problamas temporales de conectividad que te impidan reconocer una compra, con lo cual obliga a que le confirmes que has recibido la confirmación reenviándole los mismos parámetros que te ha enviado. Un sistema curioso pero efectivo, no puedes suplantarlo puesto que no sabes los identificadores de operación que te va a enviar, así que sólo el receptor de la confirmación podrá confirmar la recepción. Lo que hacemos es crear una solicitud HTTP POST con todos los parámetros que nos ha enviado y se la devolvemos a PayPal. Si todo ha ido bien recibiremos un VERIFIED y podremos aceptar esa transaccion como válida y hacer el procesado que estimemos oportuno, comenzando por comprobar la duplicidad de la transacción ya que PayPal podría estar reenviándola y terminando por otorgar al usuario el servicio por el que ha pagado.

// 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.0rn";
$header .= "Content-Type: application/x-www-form-urlencodedrn";
$header .= "Content-Length: " . strlen($req) . "rnrn";
$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'];
$transid=$_POST['txn_id'];
$idUsuario=$_POST['item_number'];
$cantidad=$_POST['mc_gross'];
$creditos=100;

if (!$fp) {
    //CONTROL DE ERRORES; NO SE PUEDE CONECTAR CON PAYPAL
    //NO ES GRAVE, COMO NO LE CONFIRMAMOS LA TRANSACCION
    //ELLOS MISMOS LA REINTENTARÁN MÁS ADELANTE
}else{
    fputs ($fp, $header . $req);
    while (!feof($fp)) {
        $res = fgets ($fp, 1024);
        if (strcmp ($res, "VERIFIED") == 0) {
            //compruebo que no se haya procesado ya la transaccion
            $query="select * from paypal where transid='$transid' and estado=1";
            $rs=$conn->Execute($query);
            $sumar=$rs->recordcount();
            if($sumar==0){
                //LOGEAMOS TODA LA TRANSACCION
                $vars="GET: ".serialize($_GET)."rnPOST: ".serialize($_POST)."";
                $query="insert into paypal (transid, fecha, estado, variables)
                    VALUES ('$transid', now(), 1, '$vars')";
                $rs=$conn->Execute($query);

                //aquí debes hacer ahora tus operaciones
                //para conceder el servicio al usuario: $idUsuario
                //incluso comprobar que idUsuario es válido
            }else{
              //TRANSACCION DUPLICADA, NO HACEMOS NADA
            }
        }else if (strcmp ($res, "INVALID") == 0) {
            //CONTROL DE ERRORES
        }
    }
    fclose ($fp);
}

Ya hemos recibido la confirmación de pago de PayPal, la hemos guardado en nuestra base de datos y le hemos dado a nuestro cliente su servicio, este proceso será distinto para cada aplicación así que no lo explicaremos, haz el tuyo como creas oportuno. Lo que sí te recomiendo es guardar una tabla con todas las transacciones recibidas a modo de log, te servirá para buscar errores o reclamaciones de usuarios.

Cabe señalar que PayPal sólamente lanza este proceso con las transacciones correctas, aquellas se que se han cobrado correctamente, nunca con las erróneas (falta de saldo, tarjeta incorrecta, etc.).

Devolviendo al usuario a nuestra web

Una vez que el usuario ha terminado su transacción en PayPal deberíamos enviarlo de nuevo a nuestra web para que comience a utilizar el servicio por el que ha pagado. Para ello PayPal nos provee del método Retroceso automático que mandará al usuario a la URL que le hayamos especificado indicando los parámetros de la transacción, entre ellos si ha sido válida o no. PayPal, además, ha pensado en todo: no puedo devolver a un usuario a la web de origen sin antes haberle comunicado el éxito de la transacción (el paso anterior). Así el mecanismo de PayPal retrasa el reenvío del usuario unos segundos para intentar que tu servidor ya esté informado de esa transacción. Simplemente genial. Ahora utilizaremos tu código personal de identidad que hemos obtenido al configurar la cuenta en PayPal. Es el parámetro que en el código llamamos $auth_token.

El proceso es parecido a la confirmación de transacciones. Debemos comunicar a PayPal que hemos recibido al petición de vuelta del usuario y que somos nosotros quién lo hacemos, sólo así nos dará los datos de la transacción. De nuevo un método curioso. Para hacerlo, nos indica por GET el identificador de la transacción y debemos devolvérselo junto a nuestro código personal de identidad mediante otra llamada HTTP POST, de este modo nos aseguramos de que somos nosotros quienes solicitamos la información. Si todo ha sido correcto PayPal nos devuelve los datos de la transacción como respuesta a esta llamada. Otra vez genial el sistema.

¿Por qué no hacerlo como en el paso anterior? Sencillo, el método IPN es transparence al usuario, es una llamada interna que hacen los sistemas de PayPal a los tuyos, nadie va a saber que datos se envían, con lo cual puedes utilizar esos datos para confirmar la transacción. En el método de retroceso, esta URL llega al usuario, con lo que podría hacer cosas que no deseamos con los datos, con lo que no nos envían nada en la solicitud, simplemente el identificador de la transacción para que internamente nosotros pidamos los datos validándonos con el código personal.

//read the post from PayPal system and add 'cmd'
$tx_token = $_GET['tx'];
$auth_token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
$req = 'cmd=_notify-synch';
$req .= "&tx=$tx_token&at=$auth_token";
$header .= "POST /cgi-bin/webscr HTTP/1.0rn";
$header .= "Content-Type: application/x-www-form-urlencodedrn";
$header .= "Content-Length: " . strlen($req) . "rnrn";

$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
$isError=0;
if(!$fp) {
    $isError=2;//error HTTP
}else{
    fputs ($fp, $header . $req);
    // read the body data
    $res = '';
    $headerdone = false;
    while (!feof($fp)) {
        $line = fgets ($fp, 1024);
        if (strcmp($line, "rn") == 0) {
            // read the header
            $headerdone = true;
        }else if ($headerdone){
            // header has been read. now read the contents
            $res .= $line;
        }
    }    // parse the data
    $lines = explode("n", $res);
    $keyarray = array();
    if (strcmp ($lines[0], "SUCCESS") == 0) {
        for ($i=1; $i<count($lines);$i++){
            list($key,$val) = explode("=", $lines[$i]);
            $keyarray[urldecode($key)] = urldecode($val);
        }

        $isError=0;//no error
        $nombre = $keyarray['first_name']." ".$keyarray['last_name'];
        $producto = $keyarray['item_name'];
        $amount = $keyarray['payment_gross'];
        $idUsuario=$keyarray['item_number'];
        $cantidad=0+$keyarray['mc_gross'];
        $estado=$keyarray['payment_status'];
        $transid=$keyarray['txn_id'];

        //ahora ya puedes evaluar lo que necesites de tu transacción
        //y termina informando al usuario de que todo ha ido bien y ya tiene su servicio
    }else if (strcmp ($lines[0], "FAIL") == 0) {
        $isError=1; //error de transaccion
    }
}
fclose ($fp);

La respuesta que recibimos es una respuesta HTTP estandar, con lo cual debemos ser conscientes de que vamos a recibir primero todas las cabeceras HTTP de la respuesta, después dos saltos de línea y a continuación la respuesta propiamente dicha. En una petición normal esta respuesta sería el código HTML de tu página, pero en este caso recibimos la lista de parámetros de la transacción, uno por línea y del tipo:

parámetro1=valor1
parámetro2=valor2
...

El código tiene esto en cuenta y, al recoger la respuesta, regenera la lista de parámetros/valores recibidos con lo que tenemos los datos necesarios.
La primera línea va a ser SUCESS ó FAIL, está claro el dato, una indica que la transacción ha sido válida y la otra que no. Obviamente debes informar al usuario de que la operación ha sido correcta y que ya tiene su servicio disponible.

Si has entendido bien todo lo explicado hasta ahora, verás que los sistemas de recepción de notificaciones y retroceso automático son muy similares, de hecho puedes utilizar este último para validar las transacciones de igual modo que con el primero y no necesitarías éste. Pero ¿qué ocurriría si sólo implementas el segundo y el usuario cierra la ventana del pago mientras está en esos segundos de espera antes de reenviarlo a tu web? Simplemente que el usuario no tendría su servicio disponible ya que nunca ha llegado a realizar el proceso del Retroceso automático. Para solucionarlo implementamos los dos. Con el primero aseguramos que la mayoría de transacciones válidas son procesadas y los servicios otorgados al cliente, con la segunda, además de informar al cliente del éxito o fracaso se su operación, tenemos un sistema de redundancia por si el primer procedimiento hubiese fallado. Como en ámbos tenemos el identificador de transacción, simplemente debemos comprobar que esa transacción ya existe y no hacer nada o procesarla si no existe.

Y eso es todo amigos. Con esto hemos aprendido a tener un sistema de compras de servicios seguro y dinámico en PayPal. Cómo habéis podido observar, el procedimiento es bastante complejo en cuanto a configuración y desarrollo, pero es muy interesante el estudio del resultado para tener una idea más amplia de como implementar sistemas seguros.

105 comentarios en “Cobrando por servicios a través de PayPal con PHP

  1. Buenas David,

    Encantado de que te haya ayudado el artículo y de que hayas podido solucionar tu problema.

    No entiendo mucho lo que dices de varios productos. ¿Quieres decir que con un solo botón compres un pack de productos? Solo tendrías que poner el precio total y el detalle de la compra.
    ¿Es eso o qué es exactamente lo que quieres hacer?

  2. No. Tengo un catalogo, de ahi se pueden añadir productos a un carrito (add to cart), al ver el carrito tego n productos y el boton “comprar ahora”. Al hacerle clic los n productos que estan en el carro pasan toda la información a paypal. Es como le estoy haciendo por ahora (sin botones encriptados), y te comento que paypal hace la suma del total, yo sole le paso los items mediante este boton.

    Si tienen ideas, compartan. De momento trabajo en esto y les hago saber.

  3. Hola,

    estoy utilizando el tutorial para un proyecto de tienda online y está genial, una vez eliminda toda la basurilla que deja el wordpress en el código de PHP funciona de maravilla.

    Esto me ha ahorrado unas cuantas horas de trabajo.

    Muchas gracias!

  4. Hola yo tengo un problema, con lo que dicen de las comillas, por mas que las cambio de ” a ” (no se si se ve la diferencia pero el punto es que las que salen en el codigo de aqui son las redonditas y en dreamweaber son las rectas cambio todas y aun asi no me sale el boton al hacer echo $form5 y los guines que comentaron que son dos y deben ser 5.

    Si alguien me pudiera ayudar con eso le agradeceria

  5. Otra duda, a los archivos de recibiendo las notificaciones como tengo que guardarlos, porque ya logre hacer funcionar el primer codigo, y todo bien hasta ese momento pero me perdi en como guardo esos php con que nombre vaya!!!

  6. se que no he agradecido por el post se me fue la onda pero es que ando algo desesperado porque necesito que esto me funcione en 3 dias y por mas que busco este post es el mas claro y cercano a lo que necesito.

    mi duda es si los dos codigos de recibiendo las notificaciones y devolviendo al usuario van en el archivo ipn? porque ya hice la prueba y ya me esta haciendo los cargos pero en la seccion de codigo de”recibiendo las notificaciones” en donde esta comentado //ahora ya puedes evaluar lo que necesites de tu transaccion

    Solo necesito hace un update de de un campo de una tabla pero no me lo hace, yo digo que es por mi dudaa de esos dos codigos van en ipn.php porque plos dos tienen el mismo header y la misma variable req y supongo que eso es lo que estoy haciendo mal

    Muchas gracias de antemano a quien me peuda ayudar.

  7. Hola buenos días, gracias por este tutorial es la primera vez que voy a empezar con paypal y mas que todo tengo dudas, controlo algo de php pero las dudas son con respecto a los parámetro que hay que enviar.
    Estuve revisando el apartado para generar el boton encriptado y genere los certificados lo que no encuentro dentro de paypal es Perfil->Configuración de pago codificado (yo tengo una cuenta paypal de estas gratis, es por eso que no funciona??).

    Un saludo

  8. Hola Eduardo, no sabría decirte si por qué no te sale, yo creo que vale para todas las cuentas.
    Te adjunto captura de la opción por si la hubieses pasado por alto:

    paypal

  9. He estado peleándome con la clase Class.PayPalEWP.php y siempre me daba el mismo error “La dirección de correo electrónico para la empresa no se incluye en el objeto binario”. Revisando la clase vemos como para crear ficheros se usa la función tempnam de php pasándole como parámetro u prefijo. ESE ES EL PROBLEMA. Como nos indican en la documentación http://us3.php.net/manual/en/function.tempnam.php cuando estamos en Windows solo usará los tres primeros caracteres del prefijo, por lo que en dicha clase no se generarán los siguientes archivos necesarios. LA SOLUCIÓN: acortamos el prefijo a dos caracteres por ejemplo

    $clearFile = tempnam($this->tempFileDirectory,’w_’);
    $signedFile = preg_replace(‘/w/’, ‘signed’, $clearFile);
    $encryptedFile = preg_replace(‘/w/’, ‘encrypted’, $clearFile);

    Felicidades por este gran manual

  10. Muy interesante el artículo, muchas gracias por la explicación. Estaba buscando algo así. Aunque he visto algún error de sintaxis la explicación está muy clara y el código también sirve.

    Un saludo y gracias!

  11. Hola
    Estoy intentando utilizar el ejemplo, pero me sale error

    Error detectado – No podemos descodificar el Id. de certificado

    Sabe alguien 100% seguro si este error está de la parte de config de PayPal o de la parte del formulario.

    Puedo compartir el código si alguien quiere

    Muchas gracias de antemano

    Javier

  12. Hola, se supone que la clase Class.PayPalEWP.php la deberia tener instalada la empresa donde yo tengo alojada la web? no?

    como puedo comprobar si la tiene instalada? digo.. por si tengo que pedirle que la instale.

    Saludos

  13. Buenas, vale.. vale.. ahora entendí.

    La definición de la clase esta en el link. 😀 no lo habia visto.

    Pensaba que era una clase definida o que habia que instalar.

    Muchas gracias por todo….

    Ahora cuando empiece a desarrollar los botones…. me surgiran mil dudas.

    OSUS, me puedes enviar tu mail por si me surgen mas preguntas?

  14. Buenas Mauricio,

    Mejor deja tus dudas en los comentarios así quedan disponibles para cualquiera que tenga dudas.
    Igualmente lee todos los comentarios anteriores por si ya estuviera resuelta.

  15. Hola, mi pregunta es de novato, bueno, de supernovato.
    Entiendo bastante bien el código por que me difiendo con el php, vale. Pero ahora es cuando me pegaréis: ¿y todo esto donde lo pongo?
    Bueno el botón (¿un botón por producto?) vale, lo coloco en la página donde tenga el producto o servicio a vender, ¿pero los otros dos scripts?
    Entiendo que el 2º irá a la web que le indiquemos a PayPal al configurar ¿qué? ¿Y el 1º?
    ¿Este código se puede usar tal cual para probar en el SandBox?
    Como veréis ando más bien perdido
    Gracias

  16. Hola. Gracias por el tutorial.
    Necesito un fa, he realizado toda la configuración en la cuenta original de paypal, pero necesito hacer pruebas hasta el final para verificar todo el proceso de compra.
    Como puedo realizar este mismo procedimiento pero en la cuenta ficticia creada en sandbox??

  17. Buenas… alguien me puede orientar… en mi pagina web necesito ademas del metodo de pago por paypal… necesito por tarjeta de credito. (Mastercard, Visa y American Express). pero lo que busco es que el cliente ingrese el tipo y numero de tarjeta en mi pagina web y que al presionar comprar ahi no se como… se haga el pago. Quiero evitar una pagina intermedia de alguna empresa (estilo paypal) para ingresar los datos del cliente. quiero que los haga directamente desde mi web.

    Saludos

  18. Hola,

    Antes de nada, darte la enhorabuena por el articulo porque estaba buscando por la web de paypal y muchas otras y se me hacia todo muy confuso. Ademas, estoy implantando un sistema de anuncios de pago y entonces todo este tutorial me vino de gran ayuda ya que el obetivo final es muy similar al tuyo. La principal duda me surgio con la creacion del certificado. Si le ayuda a alguien, para generarlos en windows, solamente es instalar el openssl para windows con una libreria que pide si no la tienes instalada en el pc. Despues, te vas a la carpeta de instalacion y entras en la subcarpeta bin y pinchas 2 veces en openssl. Seguido, escribes los comendos citados arriba y listo.
    Ahora, me encuentro con el ultimo dilema. Mi web es multiidioma y estoy usando un sistema de subdominios para enseñar el idioma adecuado en pantalla. Entonces, no me valdria el sistema de la url de retroceso automatico porque la url final puede variar en funccion de si antes de pagar estabas en castellano o en otro idioma. La solucion que estoy barajando seria pasar como parametro al paypal la url en caso de exito y la otra en caso de fracaso y ahi pongo las que quiero en funccion del idioma (en cancel_return y en return) y anular en la configuracion del pago el retroceso automatico. Que opinas.

    Saludos

  19. El tutorial me parece genial, pero tengo un problemilla. Hago todos los pasos, genero con openSSl los certificados, subo el público, me bajo el de paypal… pero luego no encripta. Siempre me sale algo así:

    He probado a poner los .pem con rutas relativas, absolutas, en la misma carpeta… y no consigo que me encripte el botón. ¿Alguien sabe qué puede ser? Gracias de antemano por vuestra ayuda.

  20. Hola a todos,

    lo primero gracias por el tutorial, y lo segundo, tengo un problema, me genera el botón codificado pero cuando pulso el entorno de pruebas me dice lo siguiente:
    “Hay un problema con la verificación de la firma del pedido seguro. Favor de comunicarse con el vendedor.”
    ¿A alguien le ha pasado? Estoy desesperada……..
    ¡¡GRACIAS!!

  21. Hola Osus mil gracias por este tutorial, estaba probandolo pero al momento de mandarme al formulario para pagar me da el sigueinte error:

    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.

    ya revise que no aya caracteres raros por todos lados como acentos y esas cosas pero me sigue dando el mismo error, saves por que???

  22. Hola, no tengo claro cuando debo ejecutar el archivo cuya linea 2 es $req = ‘cmd=_notify-validate’;. Este archivo ¿es el que debo poner en la url de configuración de IPN?
    Y, ¿cuando ejecuto el archivo cuya linea 2 es $tx_token = $_GET[‘tx’];?
    Gracias

  23. Hola

    Muy buen articulo, es justo lo que estaba buscando.
    Tengo un problema y es que no logro hallar la clase PayPalEWP para descargarla….
    Se que soy un estupido, pero no la encuentro en el sitio de paypal ¿me puedes dar una mano?

    Muchas gracias

  24. Saludos.
    Muchas gracias por el trabajo que te has pegado al recopilar esta información.
    Me he leido todos los post así como el artículo varias veces pero no termino de hacer funcionar el script.
    He creado las claves, las he subido al servidor, he cambiado el código del script, eliminando los caracteres que aparecen y poniendo cinco guiones (-), he quitado los saltos de linea, todo lo que se me ha ocurrido y continua sin funcionar. Me sigue apareciendo el mensaje de que no se puede descodificar el id. ¿Alguien lo ha resuelto? ¿Además de las soluciones que se plantean en las respuestas alguien ha probado otra cosa?

    No se si la respuesta que devuelve mi script es la correcta o no. Al hacer pruebas con el generador de botones de paypal muestra un codigo de unos 20 caracteres pero a mi me sale una texto coficado enorme. No se si estoy haciendo alguna cosa mal.

    Gracias por adelantado si alguno puede darme una respuesta. Si lo considerais necesario puedo postear el código

    Un saludo

  25. Gracias por el articulo después de corregir lo de los guiones y la solución que daba (hace 2 años xD) “agu_zahara”, lo del error de la función “tempnam”, al fín he conseguido hacer el pago en el entorno de pruebas sandbox espero que funcione igual cuando esté en el entorno real.
    Muchas gracias a todos y en especial al creador del artículo.
    Un saludoooo

  26. crackman y Osus o a cualquiera que este interesado en un donativo:

    Soy Rafa de España Castellón, intento hacer una plataforma de pagos utilizando PayPal, llevo mucho tiempo con este trabajo y necesito vuestra ayuda, me gustaría que me facilitaras el código para implementarlo en mi sitio Web, así como una pequeña explicación o tutorial de este, si consigo hacer funcionar la plataforma de pagos en mi Web no me importa dar un donativo a quien se preste a ayudarme de una forma útil.

    Un saludo Rafa.
    Mi correo es cosm2occelli@hotmail.com

  27. Hola Rafa,

    El código es el que aparece en el artículo, no hay más truco, creo que está bien explicado todo.

    ¿Qué problema tienes exactamente para implementarlo?

  28. hola te agradezco este magnifico tutorial aun que hay que cambiar barias cosas del cogido la verdad ayuda mucho por que ni en paypal lo saben explicar jajaja, espero pronto poner un linck para que puedan descargar el programa para todos los que esta sufriendo y chequen con sus programas

  29. una pregunta lo que pasa es que al recibir los datos de paypal (estoy usando sandbox) la pagina me parece en blanco no hace nada no se si estoy poniendo bien estos datos

    $fp = fsockopen(“www.sandbox.paypal.com”, 80, $errno, $errstr, 30);
    $isError=0;

    por que no me da error ni nada solo no aparece nada ajjaja

  30. Hola,

    Tengo un problema, no sé PHP(sí sé lenguaje C) y necesito usar esos scripts. Veo que ponen numeraciones y no <?php x ejem en los inicios del código, etc… Me refiero que no hay scripts para descargar y manipular luego. ¿Alguien sabe dónde hay algo de esto y que sea para php5?.

    Saludos.

  31. Hola, para aquellos que utilizen sandbox, tanto para IPN y Notificaciones seria el codigo cambiarlo por lo siguiente:

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

  32. Sólo quiero agradecer por haber escrito este fantástico tutorial. He pasado mucho tiempo tratando de estudiar la dinámica de los pagos con PayPal, y como dices: es bastante robusta, pero difícil de entender y los temas están muy enredados. Con tu tutorial he hecho en apenas minutos, -acaso poco más de una hora-, mucho más de lo que yo he hecho buscando información y leyendo otros tutoriales. Muchas gracias por esto.

  33. Osus, tengo un problema seguramente de principiante pero de verdad no encuentro como hacerlo, estoy con lo de los certificados, no encuentro como hacerlo, donde ejecutar los comandos que pones.

    Segun yo entiendo tendria que ser en mi servidor, pero no encuentro donde, escribi a mi distribuidor y el me vende un certificado pero ni siquiera estoy segura de si me serviria…

    Puedes orientarme como hago para sacar esto del certificado público X.509 y su key?? por favor….

  34. @isabel,

    Necesitas tener openssl instalado en alguna máquina a la que tengas acceso. Si tienes acceso ssh a tu servidor, podrás hacerlo allí directamente, si no necesitas instalarlo en tu equipo de desarrollo.

  35. Gracias Osus,

    Si tengo acceso a mi sitio en el servidor, y se supone que tengo el oppenssl “habilitado”, voy a revisar donde puedo verlo y/o ejecutar los comandos para seguir adelante..

    Te agradezco tu ayuda, y si logro hacerlo se lo compartiré…

  36. Buenos dias

    Todo funciona perfecto gracias a todos.

    PREGUNTA.

    1.En el ejemplo tengo el total. como puede mostrar item por item ?
    2.Como configuro para la opción de pago con tarjeta de crédito sin que el usuario tenga cuenta en paypal

    GRACIAS

  37. Solucione mi problema lo dejo para el que tenga la misma duda.

    $paypalParam= array(
    ‘cmd’ => ‘_cart’,
    ‘upload’ => ‘1’,
    ‘business’ => ‘neacss@gmail.com’,
    ‘currency_code’ => ‘USD’,
    ‘lc’ => ‘EN’,
    );

    $i=1;

    while ($row = mysql_fetch_array($BD->rsQuery))
    {
    $Item = $row[‘ID’];
    $Name = $row[‘Name’];
    $valorPago = $row[‘Pago’];

    $ItemName =’item_name_’.$i;
    $ItemNumber =’item_number_’.$i;
    $ItemAmount =’amount_’.$i;

    $paypalParam[$ItemName] =$Name;
    $paypalParam[$ItemNumber] =$Item;
    $paypalParam[$ItemAmount] =$valorPago;

    $i++;

    }

  38. Hola Osus,

    Estoy tratando de implementar el codigo y me aparece el siguiente error:

    La dirección de correo electrónico para la empresa no se incluye en el objeto binario. Póngase en contacto con el comercio PayPal.

    Sabes que puede ser lo que este haciendo mal?

    Gracias!

  39. Hola Osus,
    No he podido terminar de implementar el pago de paypal..

    Me marca el error “No podemos descodificar el Id. de certificado.
    ” ya he leido todo el blog y corregido todo lo que dicen ( lo de los 5 guiones, comillas y todo eso) y me sigue marcando el mismo error…

    Sabes de alguna otra cosa que pueda ser??

    Agradezco tu ayuda..

  40. He solucionado mi problema, y no creo de verdad lo que era, lo dejo por si alguien tiene el mismo problema…

    Solo quite los n en la linea:
    encryptButton($paypalParam).”n—–END PKCS7—–”/>

    además de corregir comillas y los guiones medios…. la linea me quedo finalmente asi:
    encryptButton($paypalParam).’—–END PKCS7—–“/>

    y listo, espero que a alguien le sirva…

    Saludos!!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *