Cómo procesar los pagos con tarjetas de crédito con PayPal Pro usando PHP
Spanish (Español) translation by steven (you can also view the original English article)
PayPal es una de las plataformas de procesamiento de pagos más populares disponibles en la actualidad por muchas razones. Su facilidad de uso y su conexión a la plataforma de eBay son solo la punta del iceberg. Si bien una de sus características más populares es la capacidad de simplemente iniciar sesión en tu cuenta de PayPal para enviar pagos, los comerciantes que usan PayPal también pueden aceptar tarjetas de crédito directamente, tal como lo proporcionaría una solución de cuenta de comerciante tradicional.
PayPal llama a esta solución "Payments Pro", y te mostraré exactamente cómo puedes procesar tarjetas de crédito directamente con la API de PayPal utilizando su API de servicio web Payments Pro.
Paso 1: Configurar la estructura del directorio
Lo primero que me gusta hacer con cualquier proyecto es crear una estructura básica organizada para el proyecto. En este caso, nuestra estructura es muy simple ya que nuestro proyecto constará de solo 2 archivos:

Como habrás adivinado, almacenaremos nuestra información de configuración en config.php y, por supuesto, manejaremos el código de procesamiento en process-credit-card.php.
Paso 2: Configurar el archivo de configuración
Nuestro archivo /includes/config.php albergará nuestros valores para la información de la API de PayPal que necesitamos, incluida la URL del punto final, la versión de la API y nuestro nombre de usuario, contraseña y firma de la API que usaremos.
1 |
// Set sandbox (test mode) to true/false.
|
2 |
$sandbox = TRUE; |
3 |
|
4 |
// Set PayPal API version and credentials.
|
5 |
$api_version = '85.0'; |
6 |
$api_endpoint = $sandbox ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp'; |
7 |
$api_username = $sandbox ? 'SANDBOX_USERNAME_GOES_HERE' : 'LIVE_USERNAME_GOES_HERE'; |
8 |
$api_password = $sandbox ? 'SANDBOX_PASSWORD_GOES_HERE' : 'LIVE_PASSWORD_GOES_HERE'; |
9 |
$api_signature = $sandbox ? 'SANDBOX_SIGNATURE_GOES_HERE' : 'LIVE_SIGNATURE_GOES_HERE'; |
Al revisar el código de config.php, puedes ver que primero configuramos una variable para $sandbox. Por ahora, dejaremos esto en TRUE porque queremos interactuar con los servidores de prueba (sandbox) de PayPal para fines de desarrollo. Deberás recordar cambiar esto a FALSE cuando estés listo para mover tu proyecto a un servidor en producción.
Luego, en función del valor de $sandbox, establecemos valores en otras variables para la información de nuestra API. Solo querrás completar esos marcadores de posición con tus propios detalles en consecuencia. Ahora estamos listos para crear nuestra secuencia de comandos para el procesamiento de tarjetas de crédito.
Paso 3: Crea una solicitud de la API
Ahora podemos comenzar a construir nuestra página process-credit-card.php. Lo primero que debemos hacer aquí es incluir nuestro archivo de configuración.
1 |
// Include config file
|
2 |
require_once('includes/config.php'); |
A continuación, necesitamos crear una cadena de par nombre-valor que incluya todos los datos que necesitamos para enviar a PayPal para procesar este pago. Una cadena de par nombre-valor se parece a algo que puedes ver al pasar datos a través de parámetros de URL. Solo necesitamos asegurarnos de que los nombres de nuestros parámetros estén en mayúsculas.
1 |
PARAM1=value1&PARAM2=value2&PARAM3=value3…etc. |
Por lo tanto, podrías estar pensando "¿Cómo sé qué usar para los nombres de mis variables en mi cadena?" La buena noticia es que PayPal proporciona muy buena documentación al respecto. Podemos ver todas las posibles variables que podemos pasar a PayPal, incluidos los detalles del cliente, los detalles del artículo del pedido y la información de la tarjeta de crédito. Parte de esta información es necesaria para procesar un pago, pero muchas de las variables disponibles son opcionales. Para fines de demostración, lo mantendremos bastante simple y solo pasaremos la información requerida.
Almacenaremos todos nuestros parámetros de solicitud en una matriz para que podamos recorrer esta matriz para generar fácilmente nuestra cadena NVP. Todas las solicitudes requieren los siguientes parámetros de forma predeterminada:
-
METHOD: El nombre de la llamada a la API que estás realizando. -
USER: El nombre de usuario de la API -
PWD: La contraseña de la API -
SIGNATURE: La firma de la API -
VERSION: La versión de la API
Luego, puedes consultar la documentación de PayPal para cualquier solicitud de API que desees realizar para ver qué otros parámetros deben incluirse. Por el bien de esta demostración, nuestra matriz se construirá de la siguiente manera.
1 |
// Store request params in an array
|
2 |
$request_params = array |
3 |
(
|
4 |
'METHOD' => 'DoDirectPayment', |
5 |
'USER' => $api_username, |
6 |
'PWD' => $api_password, |
7 |
'SIGNATURE' => $api_signature, |
8 |
'VERSION' => $api_version, |
9 |
'PAYMENTACTION' => 'Sale', |
10 |
'IPADDRESS' => $_SERVER['REMOTE_ADDR'], |
11 |
'CREDITCARDTYPE' => 'MasterCard', |
12 |
'ACCT' => '5522340006063638', |
13 |
'EXPDATE' => '022013', |
14 |
'CVV2' => '456', |
15 |
'FIRSTNAME' => 'Tester', |
16 |
'LASTNAME' => 'Testerson', |
17 |
'STREET' => '707 W. Bay Drive', |
18 |
'CITY' => 'Largo', |
19 |
'STATE' => 'FL', |
20 |
'COUNTRYCODE' => 'US', |
21 |
'ZIP' => '33770', |
22 |
'AMT' => '100.00', |
23 |
'CURRENCYCODE' => 'USD', |
24 |
'DESC' => 'Testing Payments Pro' |
25 |
);
|
Notarás que estamos usando nuestras variables de configuración de config.php, y luego simplemente estoy cargando datos estáticos para los otros valores. Sin embargo, en un proyecto estándar, lo más probable es que llenes estos valores con datos de un formulario, datos de sesión o alguna otra forma de datos dinámicos.
Ahora podemos simplemente recorrer esta matriz para generar nuestra cadena NVP.
1 |
// Loop through $request_params array to generate the NVP string.
|
2 |
$nvp_string = ''; |
3 |
foreach($request_params as $var=>$val) |
4 |
{
|
5 |
$nvp_string .= '&'.$var.'='.urlencode($val); |
6 |
}
|
El valor de $nvp_string ahora es:
1 |
METHOD=DoDirectPayment&USER=sandbo*****e.com&PWD=12***74&SIGNATURE=AiKZ******6W18v&VERSION=85.0&PAYMENTACTION=Sale&IPADDRESS=72.135.111.9&CREDITCARDTYPE=MasterCard&ACCT=5522340006063638&EXPDATE=022013&CVV2=456&FIRSTNAME=Tester&LASTNAME=Testerson&STREET=707+W.+Bay+Drive&CITY=Largo&STATE=FL&COUNTRYCODE=US&ZIP=33770&AMT=100.00&CURRENCYCODE=USD&DESC=Testing+Payments+Pro |
Esta cadena es la que enviaremos a PayPal para nuestra solicitud.
Paso 4: Enviar la solicitud HTTP a PayPal
Ahora que nuestra cadena de NVP está lista, debemos enviarla al servidor de PayPal para que se procese en consecuencia. Para hacer esto, usaremos los métodos CURL de PHP.
1 |
// Send NVP string to PayPal and store response
|
2 |
$curl = curl_init(); |
3 |
curl_setopt($curl, CURLOPT_VERBOSE, 1); |
4 |
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); |
5 |
curl_setopt($curl, CURLOPT_TIMEOUT, 30); |
6 |
curl_setopt($curl, CURLOPT_URL, $api_endpoint); |
7 |
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); |
8 |
curl_setopt($curl, CURLOPT_POSTFIELDS, $nvp_string); |
9 |
|
10 |
$result = curl_exec($curl); |
11 |
curl_close($curl); |
Aquí puedes ver que hemos configurado CURL con algunas opciones simples y estamos usando nuestras variables $api_endpoint y $nvp_string en consecuencia.
Estos datos se enviarán a PayPal y recibiremos la respuesta de la API en nuestra variable $result para que podamos ver el resultado y enviar al usuario a una página exitosa o fallida en función de si la llamada tuvo éxito o no.
Paso 5: Analizar la respuesta de la API
El valor que obtenemos en $result del paso anterior será una cadena NVP como la que generamos y enviamos a PayPal. Cuando ejecutamos nuestro script actual, obtenemos una respuesta exitosa que se ve así:
1 |
TIMESTAMP=2012%2d04%2d16T07%3a59%3a36Z&CORRELATIONID=9eb40cd84a7d3&ACK=Success&VERSION=85%2e0&BUILD=2764190&AMT=100%2e00&CURRENCYCODE=USD&AVSCODE=X&CVV2MATCH=M&TRANSACTIONID=160896645A8111040 |
Una forma muy sencilla de analizar este resultado es utilizar la función de PHP parse_str(). Esto cargará todos los datos de respuesta en variables PHP que coincidan con los nombres y valores devueltos en la respuesta. Por ejemplo, si hacemos lo siguiente:
1 |
// Parse the API response
|
2 |
$nvp_response_array = parse_str($result); |
Terminaríamos con acceso a las siguientes variables de PHP:
$TIMESTAMP$CORRELATIONID$ACK$VERSION$BUILD$AMT$CURRENCYCODE$AVSCODE$CVV2MATCH$TRANSACTIONID
Luego, podemos proceder a usar estas variables para presentar información a nuestro cliente, completar valores en los recibos de correo electrónico que nos gustaría generar, actualizar la información de la base de datos o cualquier otra cosa que necesitemos hacer una vez que se complete un pedido.
El valor de $ACK es lo que nos dirá si la llamada a la API fue exitosa o no. Los valores de $ACK pueden ser:
SuccessSuccessWithWarningFailureFailureWithWarning
Simplemente puedes redirigir a tu usuario a donde necesita ir y mostrarle información basada en este valor.
Una llamada de API fallida dará como resultado parámetros adicionales que proporcionan información sobre por qué falló la transacción. Si vuelvo a ejecutar esta prueba con un número de tarjeta de crédito no válida, por ejemplo, obtengo la siguiente respuesta de PayPal:
1 |
TIMESTAMP=2012%2d04%2d16T08%3a08%3a52Z&CORRELATIONID=590d41dbb31e0&ACK=Failure&VERSION=85%2e0&BUILD=2764190&L_ERRORCODE0=10527&L_SHORTMESSAGE0=Invalid%20Data&L_LONGMESSAGE0=This%20transaction%20cannot%20be%20processed%2e%20Please%20enter%20a%20valid%20credit%20card%20number%20and%20type%2e&L_SEVERITYCODE0=Error&AMT=100%2e00&CURRENCYCODE=USD |
Ahora, cuando usamos parse_str() terminamos con las siguientes variables PHP disponibles para nosotros:
$TIMESTAMP$CORRELATIONID$ACK$VERSION$BUILD$L_ERRORCODE0$L_SHORTMESSAGE0$L_LONGMESSAGE0$L_SEVERITYCODE0$AMT$CURRENCYCODE
En este caso, $ACK muestra una falla, por lo que sabemos que la llamada no tuvo éxito y podemos verificar los parámetros de error para obtener más detalles sobre lo que salió mal.
Opción para analizar información adicional
Si bien el método anterior para analizar la respuesta funciona bien, personalmente prefiero trabajar con matrices de datos. Como tal, utilizo la siguiente función para convertir la respuesta de PayPal en una matriz.
1 |
// Function to convert NTP string to an array
|
2 |
function NVPToArray($NVPString) |
3 |
{
|
4 |
$proArray = array(); |
5 |
while(strlen($NVPString)) |
6 |
{
|
7 |
// name
|
8 |
$keypos= strpos($NVPString,'='); |
9 |
$keyval = substr($NVPString,0,$keypos); |
10 |
// value
|
11 |
$valuepos = strpos($NVPString,'&') ? strpos($NVPString,'&'): strlen($NVPString); |
12 |
$valval = substr($NVPString,$keypos+1,$valuepos-$keypos-1); |
13 |
// decoding the respose
|
14 |
$proArray[$keyval] = urldecode($valval); |
15 |
$NVPString = substr($NVPString,$valuepos+1,strlen($NVPString)); |
16 |
}
|
17 |
return $proArray; |
18 |
}
|
Esto me permite ver todos los datos de respuesta disponibles simplemente mirando el contenido de la matriz:
Si ejecuto mi script nuevamente ahora, obtengo el siguiente resultado en la pantalla:
1 |
Array
|
2 |
(
|
3 |
[TIMESTAMP] => 2012-04-16T08:15:41Z |
4 |
[CORRELATIONID] => 9a652cbabfdd9 |
5 |
[ACK] => Success |
6 |
[VERSION] => 85.0 |
7 |
[BUILD] => 2764190 |
8 |
[AMT] => 100.00 |
9 |
[CURRENCYCODE] => USD |
10 |
[AVSCODE] => X |
11 |
[CVV2MATCH] => M |
12 |
[TRANSACTIONID] => 6VR832690S591564M |
13 |
)
|
Y si volviera a causar un error, obtengo lo siguiente:
1 |
Array
|
2 |
(
|
3 |
[TIMESTAMP] => 2012-04-16T08:18:46Z |
4 |
[CORRELATIONID] => 2db182b912a9 |
5 |
[ACK] => Failure |
6 |
[VERSION] => 85.0 |
7 |
[BUILD] => 2764190 |
8 |
[L_ERRORCODE0] => 10527 |
9 |
[L_SHORTMESSAGE0] => Invalid Data |
10 |
[L_LONGMESSAGE0] => This transaction cannot be processed. Please enter a valid credit card number and type. |
11 |
[L_SEVERITYCODE0] => Error |
12 |
[AMT] => 100.00 |
13 |
[CURRENCYCODE] => USD |
14 |
)
|
Puedes ver que esta es una matriz de resultados agradable y fácil de navegar que contiene todo lo que podríamos necesitar para mover al usuario a través de nuestra aplicación y actualizar las fuentes de datos según sea necesario.
Conclusión
Como puedes ver, procesar pagos con tarjetas de crédito con PayPal Pro es en realidad un procedimiento muy simple. Solo implica unos pocos pasos estándar para trabajar con servicios web API, y un conocimiento básico de cómo trabajar con datos de matriz también puede ayudar.
¡Buena suerte y feliz codificación!



