Pagos adaptativos en Paypal
Introducción
Tipos de pagos adaptativos
Los pagos adaptativos nos permiten disponer de un sistema donde los pagos se podrán realizar a varios destinatarios a la vez.
Lo primero que tenemos que tener en mente es la forma en que estos pagos se realizarán pudiendo disponer de las siguientes modalidades:
- Simple: Es una transacción normal entre un usuario y un único destinatario
- Paralelo: Es una transacción donde el pago se reparte entre varios destinatarios
Esto podría ser, por ejemplo, cuando a la hora de pagar por un servicio compuesto (un viaje) tienes que pagar a distintos proveedores: hotel, avión, guía, … - Pagos Encadenados: Esta transacción se utiliza cuando el pago se realiza indirectamente a través de un destinatario principal. Si cogemos el ejemplo anterior del viaje, esto se podría aplicar cuando pagamos a una agencia de viajes. El pagador vé un único destinatario, pero luego el pago se fracciona entre la comisión de la agencia de viajes y el pago a los otros servicios.
(*) Estos pagos encadenados pueden configurarse para que ocurran automáticamente o que se ejecuten de forma manual no antes de 90 días.
Aplicaciones y Sandbox
Antes de nada, hay que indicar que para aquellas personas acostumbradas a trabajar con Paypal mediante formularios POST éste método es ligeramente diferente. Por una parte, crear la aplicación requiere un proceso más complicado y requiere de verificación manual por parte de Paypal y por otra, el proceso implica más pasos ya que es necesario verificar las llamadas.
Aunque es necesario tener una aplicación creada y validada desde Paypal podemos hacer uso de los datos de SANDBOX para la implementación y pruebas.
El proceso de comunicación por paypal se produce a través de una API que podemos invocar mediante el uso de cURL
Datos del SANDBOX
- ID. de la aplicación: APP-80W284485P519543T (fijo para el sandbox)
- URL: https://svcs.sandbox.paypal.com/AdaptivePayments/Pay
- SIGNATURE: Depende de tu cuenta.
- PASSWORD: Depende de tu cuenta.
- USERNAME: Depende de tu cuenta.
Los datos de "Signature", "Username" y "Password" que podemos ver Profile > API credentials
Las llamada cURL que tenemos que preparar deben de llevar los parámetros anteriores en la cabecera.
Suponiendo que hemos creado una clase para nuestro TPV que tiene las propiedades anteriormente mencionadas, el código sería algo parecido a esto:
// Create auth headers $headers = array ( "X-PAYPAL-SECURITY-USERID: " . $this->username, "X-PAYPAL-SECURITY-PASSWORD: " . $this->password, "X-PAYPAL-SECURITY-SIGNATURE: " . $this->signature, "X-PAYPAL-REQUEST-DATA-FORMAT: JSON", "X-PAYPAL-RESPONSE-DATA-FORMAT: JSON", "X-PAYPAL-APPLICATION-ID: " . $this->AppID, );
Luego vendría el contenido del mensaje.
Aquí, a modo de ejemplo podemos ver el caso de un pago encadenado
// Receivers list $this->receivers = array ( array ( "primary" => true, "amount" => 100, "email" => ‘example1@email.com’ ), array ( "primary" => false, "amount" => 500, "email" => ‘example2@email.com’ ) ); // Prepare the request $payload = array ( "actionType" => "PAY", "ipnNotificationUrl" => "http://" . $_SERVER['HTTP_HOST'] . "/notify.php?op=" . $operation, "currencyCode" => "EUR", "receiverList" => array ( "receiver" => $this->receivers ), "returnUrl" => $urlok, "cancelUrl" => $urlnok, "requestEnvelope" => array ( "errorLanguage" => "es_ES", "detailLevel" => "ReturnAll", ) );
Es importante destacar aquí varias cosas:
- Se indica el IPNNotification quién escuchará la confirmación o negación del pago
- Se indica en receiverList un array de destinatarios. Cada uno de estos destinatarios debe de incluir los siguientes elementos
- PRIMARY: Booleano. Indica si es el destinatario principal. Sólo puede haber uno.
- AMOUNT: La cantidad destinada
- EMAIL: La cuenta de Paypal del usuario
Una vez todo preparado, hacemos la llamada
// Start CURL $ch = curl_init(); // Configure curl_setopt ($ch, CURLOPT_URL, $this->url); curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt ($ch, CURLOPT_POSTFIELDS, json_encode ($payload)); curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers); // Get the response $response = json_decode (curl_exec ($ch), true); // Handle the response if ($response['paymentExecStatus'] == 'CREATED') { // Here we can see the // - "paykey" // - "url" // This params are needed to verify the call return array ('status' => 'ok', 'data' => array ( 'ok' => true, 'payKey' => $response['payKey'], 'url' => $this->confirm_url . $response['payKey'] )); } // Handle error if ($response['error']) { return array ('status' => 'error', 'data' => array ('message' => $response['error'][0]['message']));
} // @todo // Handle other possible errors (Bad CURL)
En el caso de funcionar esta llamada, es importante destacar que nos será devuelto una PAYKEY que tendremos que usar posteriormente para verificar el pago a través de las siguiente URL:
https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate
Es decir, cuando el pago se verifique PAYPAL llamará a la URL que indicamos previamente en el campo ipnNotificationUrl pasándole dicha PAYKEY
// Read the data for the INPUT and convert to an ARRAY $raw_post_data = file_get_contents('php://input'); $raw_post_array = explode ('&', $raw_post_data); $myPost = array(); foreach ($raw_post_array as $keyval) { $keyval = explode ('=', $keyval); if (count($keyval) == 2) { $myPost[$keyval[0]] = urldecode($keyval[1]); } } // Prepare params $req = 'cmd=_notify-validate'; if ( function_exists ('get_magic_quotes_gpc')) { $get_magic_quotes_exists = true; } foreach ($myPost as $key => $value) { if ($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) { $value = urlencode (stripslashes($value)); } else { $value = urlencode ($value); } $req .= "&$key=$value"; } // Ask PAYPAL if the operation was valid $ch = curl_init ($this->validate_url); curl_setopt ($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt ($ch, CURLOPT_POST, 1); curl_setopt ($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt ($ch, CURLOPT_POSTFIELDS, $req); curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt ($ch, CURLOPT_FORBID_REUSE, 1); curl_setopt ($ch, CURLOPT_HTTPHEADER, array('Connection: Close')); $res = curl_exec($ch); // Once the data is checked, perform our logic model operations if (strcmp ($res, "VERIFIED") == 0) { Module::call ("tpv", "orderok", $params); } else if (strcmp ($res, "INVALID") == 0) { // Something went wrong. LOG $res for debug } else { // Something went wrong. Maybe cURL failed }
Crear una aplicación
Una vez que esté todo verificado llega el momento de pasar a un entorno real. Para ello, debemos de crear una aplicación.
Las aplicaciones de pagos adaptativos se gestionan desde la siguiente URL
https://www.paypal-apps.com/user/my-account/applications/new
y presentan un formulario donde hay que indicar bastante información acerca del modelo de negocio, tipos de pagos que implementa, y otra serie de información tal como previsiones de ingresos, …
Una vez completado el formulario, este proceso devolverá un ID Temporal que podremos utilizar.
Hasta que ese ID no es completamente aprobado no podremos realizar pagos encadenados, obteniendo hasta entonces el mensaje de permiso denegado
Recordad también que tendremos que cambiar entonces nuestras URLs de pruebas por las del entorno real, tanto las del IPN como la del pago
- https://svcs.paypal.com/AdaptivePayments/Pay
- https://www.paypal.com/cgi-bin/webscr?cmd=_ap-payment&paykey=
- https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate
Bibliografía
- https://developer.paypal.com/docs/classic/adaptive-payments/integration-guide/APIntro/
- https://developer.paypal.com/docs/classic/adaptive-payments/gs_AdaptivePayments/
Comentarios