> Manuales > Taller de PHP

Alcanzado ya nuestro objetivo de contruir un carrito de compras sencillo, vamos a agregarle 2 funcionalidades:

1) El envío de un mail al cliente con el detalle de su compra.

2) La integración con una Plataforma de Pagos.

1) El envío del mail es sencillo. La forma de armar la tabla de productos es muy similar a la que usamos para mostrarlos en el archivo vercarrito.php, de manera que no vamos a abundar en detalles.

La diferencia estriba en que guardamos todo el html que conformará el cuerpo del mensaje en una variable que llamamos $html y finalmente enviamos el mensaje con la función mail, la cual tiene como parámetros (en este orden) el e-mail del destinatario, el título del mensaje, el cuerpo del mensaje y las cabeceras que harán que el mensaje sea interpretado como HTML, además de proporcionar el nombre y la dirección de correo del remitente.

Archivo mailer.php

<?php
session_start();
$carro=$_SESSION['carro'];
//Guardamos en la
//variable $html el
//cuerpo del mensaje
$html = "
<html>
<head>
<title>Detalle de artículos Comprados</title>
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">
<style type=\"text/css\">
<!--
.tit {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 9px;
color: #FFFFFF;
}
.prod {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 9px;
color: #333333;
}
h1 {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 20px;
color: #990000;
}
-->
</style>
</head>
<body>
<table width=\"414\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" align=\"center\">
<tr bgcolor=\"#333333\" class=\"tit\">
<td width=\"198\">Producto</td>
<td width=\"107\">Precio</td>
<td width=\"109\" align=\"center\">Cantidad de Unidades</td>
</tr>";
$color=array("#ffffff","#F0F0F0");
$contador=0;
$suma=0;
foreach($carro as $k => $v){
$contador++;
$subto=$v['cantidad']*$v['precio'];
$suma=$suma+$subto;
$html.="<tr bgcolor=\"".$color[$contador%2]."\" class=\"prod\">
<td>".$v['producto']."</td>
<td>".$v['precio']."</td>
<td align=\"center\">".$v['cantidad']."</td>
</tr>";
}
$html .=
"</table>
<div align=\"center\"><span class=\"prod\">Total de Artículos: ".count($carro)."</span> </div><br>
<div align=\"center\"><span class=\"prod\">Total: \$".number_format($suma,2)."</span></div><br>
<div align=\"left\"><span class=\"prod\">
Aquí escribiremos un mensaje cualquiera, por ejemplo, cuáles son nuestras opciones de pago
</span></div>";
//Como queremos enviar el
//mensaje en formato html,
//colocamos las 2 cabeceras
//que nos permitirán hacerlo
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset= iso-8859-1\r\n";
//Las siguientes 2 cabeceras,
//permitirán que el destinatario
//sepa a quién responder y
//quién le ha enviado el
//mensaje
$headers .= "Reply-To: mailremitente@dominio.com\r\n";
$headers .= "From: Nombre del Remitente<mailremitente@dominio.com>\r\n";
//En este ejemplo suponemos
//que el mail del destinatario
//lo hemos enviado desde un
//formulario con el método post,
//pero es indistinto desde donde
//se lo obtenga (consulta a la
//base de datos, almacenado en
//una variable de sesión,
//enviado por get,etc.)
mail("{$_POST['email']}","Detalle de su compra en nuestro website",$html,$headers);
?>


2) Ya tenemos nuestro carrito y sabemos cómo enviarle un mail con los productos seleccionados al comprador, pero aún no hemos resuelto cómo haremos que éste nos pague.

Podríamos agregar, en el mail que hicimos anteriormente, algunas instrucciones para formalizar el pago a través de una transferencia o depósito bancario... es una opción.

Pero también podemos hacer que el cliente procese su compra antes de abandonar nuestra página.

Una manera de hacer esto último es integrar nuestro carrito con una Plataforma de Pagos como Paypal. Para ello debemos sacar previamente una cuenta en https://www.paypal.com/, donde nos pedirán, entre otros requisitos, una dirección de correo electrónico que nos servirá para que el sistema de Paypal nos identifique como vendedores cuando un comprador realice una compra desde nuestro website.

Debemos tener en cuenta que, en el ejemplo que presentaremos, mientras se realice el proceso de pago el comprador oscilará entre nuestro servidor y el servidor de Paypal. Independientemente del protocolo que use nuestro servidor para las transacciones web (lo más probable es que use protocolo HTTP), Paypal usa protocolo HTTPS, que es más apropiado para el tráfico de información sensible, como por ejemplo números de tarjetas de crédito.

El esquema de trabajo que utilizaremos es el siguiente: en nuestro website procesaremos la selección de los artículos y calcularemos los precios. Luego derivaremos esa información y a nuestro cliente a Paypal. Ya en Paypal y bajo el paraguas del protocolo HTTPS, el cliente se identificará, verá los productos que ha seleccionado en nuestro website junto con el importe de los mismos, y elegirá alguna alternativa de pago o suspenderá la compra o el sistema le indicará que no tiene fondos suficientes o una larga lista de etcéteras. En cualquiera de todos estos casos, al terminar, Paypal redireccionará nuevamente al comprador a nuestro website.

En resumen, en el esquema descripto pueden presentarse básicamente dos alternativas: que el pago se concrete o que el pago no se concrete.

Primera alternativa: Se concreta el pago.


Si el pago se realiza correctamente, Paypal derivará al cliente a una página de nuestro site que nosotros le indiquemos para los casos de éxito en el pago (la llamaremos ipn_success.php), devolviéndonos al mismo tiempo algunas variables que nos servirán para realizar nuestros procesos: por ejemplo, si vendimos un acceso a un servicio web por 3 meses, actualizar la base de datos dándole permisos al comprador por ese período o enviar un mail a alguien diciéndole que debe entregar x detalle de productos a x cliente, descontar del stock, etc.

Segunda alternativa: No se concreta el pago.



Si el pago no se concreta, Paypal devolverá al cliente a una página de nuestro site que nosotros le indiquemos para los casos de fracaso en el pago (la llamaremos ipn_error.php). En esta oportunidad no deberemos procesar nada: sólo debereremos notificar al cliente que por alguna razón el pago no pudo concretarse.

Bueno, terminadas las explicaciones generales, vamos a los hechos. A la página vercarrito.php le agregaremos un botón que llamaremos "Finalizar Compra" el cual, al ser presionado, derivará a la página en la que procesaremos el envío a Paypal, a la cual llamaremos "regpago.php".

Este es nuestro botón "Finalizar Compra":

La página vercarrito.php quedará así (Note que enviaremos el Total del Importe del carrito utilizando el método get):

<?php
session_start();
$carro=$_SESSION['carro'];
?>
<html>
<head>
<title>PRODUCTOS AGREGADOS AL CARRITO</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
<!--
.tit {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 9px;
color: #FFFFFF;
}
.prod {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 9px;
color: #333333;
}
h1 {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 20px;
color: #990000;
}
-->
</style>
</head>
<body>
<h1 align="center">Carrito</h1>
<?php
if($carro){
?>
<table width="720" border="0" cellspacing="0" cellpadding="0" align="center">
<tr bgcolor="#333333" class="tit">
<td width="105">Producto</td>
<td width="207">Precio</td>
<td colspan="2" align="center">Cantidad de Unidades</td>
<td width="100" align="center">Borrar</td>
<td width="159" align="center">Actualizar</td>
</tr>
<?php
$color=array("#ffffff","#F0F0F0");
$contador=0;
$suma=0;
foreach($carro as $k => $v){
$subto=$v['cantidad']*$v['precio'];
$suma=$suma+$subto;
$contador++;
?>
<form name="a<?php echo $v['identificador'] ?>" method="post" action="agregacar.php?<?php echo SID ?>" id="a<?php echo $v['identificador'] ?>">
<tr bgcolor="<?php echo $color[$contador%2]; ?>" class='prod'>
<td><?php echo $v['producto'] ?></td>
<td><?php echo $v['precio'] ?></td>
<td width="43" align="center"><?php echo $v['cantidad'] ?></td>
<td width="136" align="center">
<input name="cantidad" type="text" id="cantidad" value="<?php echo $v['cantidad'] ?>" size="8">
<input name="id" type="hidden" id="id" value="<?php echo $v['id'] ?>"> </td>
<td align="center"><a href="borracar.php?<?php echo SID ?>&id=<?php echo $v['id'] ?>"><img src="trash.gif" width="12" height="14" border="0"></a></td>
<td align="center">
<input name="imageField" type="image" src="actualizar.gif" width="20" height="20" border="0"></td>
</tr></form>
<?php }?>
</table>
<div align="center"><span class="prod">Total de Artículos: <?php echo count($carro); ?></span>
</div><br>
<div align="center"><span class="prod">Total: $<?php echo number_format($suma,2); ?></span></div>
<br>
<div align="center"><span class="prod">Continuar la selección de productos</span>
<a href="catalogo.php?<?php echo SID;?>"><img src="continuar.gif" width="13" height="13" border="0" align="absmiddle"></a>
<a href="regpago.php?<?php echo SID;?>&costo=<?php echo $suma; ?>"><img src="finalizarcompra.gif" width="135" height="16" border="0" align="absmiddle"></a>
</div>
<?php }else{ ?>
<p align="center"> <span class="prod">No hay productos seleccionados</span> <a href="catalogo.php?<?php echo SID;?>"><img src="continuar.gif" width="13" height="13" border="0"></a>
<?php }?>
</p>
</body>
</html>


En la página regpago.php, como dijimos, recogeremos los productos y el Total del Importe y los enviaremos a Paypal valiéndonos de un formulario que contendrá varios campos ocultos cuya función explicaremos más tarde. En definitiva, la página regpago.php tendrá la siguiente estructura:

<?php
session_start();
//Asignamos todos los
//valores guardados en
//la sesión a la variable
//$carro, como hicimos en
//las páginas anteriores
$carro=$_SESSION['carro'];
//$products es la variable
//que usaremos para mostrar
//los productos en esta página
//(separados por '+')
$products='';
//$products2 es la que usaremos
//para enviar a Paypal
//(separados por ',')
$products2='';
foreach($carro as $k => $v){
$unidad=$v['cantidad']>1?" unidades de":" unidad de";
$products.=$v['cantidad'].$unidad.$v['producto']."+";
$products2.=$v['cantidad'].$unidad.$v['producto'].", ";
}
//eliminamos el último '+':
$products=substr($products,0,(strlen($products)-1));
//eliminamos la última coma
//y el espacio que sigue a
//la misma:
$products2=substr($products2,0,(strlen($products2)-2));
?>
<html>
<head>
<title>Finalizar Compra</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
<!--
.tit {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 9px;
color: #FFFFFF;
}
.prod {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 9px;
color: #333333;
}
h1 {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 20px;
color: #990000;
}
-->
</style>
</head>

<body>
<!-- Creamos el formulario para enviar a Paypal -->
<form action="https://www.paypal.com/cgi-bin/webscr" name="f1" id="f1" method="post">
<fieldset>
<legend class="prod"><strong>Finalizar la Compra</strong> <a href="#" onclick="javascript:window.open('https://www.paypal.com/cgi-bin/webscr?cmd=xpt/popup/OLCWhatIsPayPal-outside','olcwhatispaypal','toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=no, width=400, height=350');"><img src="https://www.paypal.com/en_US/i/bnr/horizontal_solution_PP.gif" alt="Solution Graphics" border="0" align="absmiddle"></a></legend>
<input type="hidden" name="shipping" value="0">
<input type="hidden" name="cbt" value="Presione aquí para volver a www.nuestrositio.com >>">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="rm" value="2">
<input type="hidden" name="bn" value="nombre de la empresa vendedora">
<input type="hidden" name="business" value="maildelvendedor@dominio.com">
<input type="hidden" name="item_name" value="<?php echo $products2; ?>">
<input type="hidden" name="item_number" value="Nombre del comprador">
<input type="hidden" name="amount" value="<?php echo number_format($_GET['costo'],2) ?>">
<input type="hidden" name="custom" value="<?php echo $_GET['costo'] ?>">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="image_url" value="">
<input type="hidden" name="return" value="http://www.nuestrodominio.com/ipn_success.php">
<input type="hidden" name="cancel_return" value="http://www.nuestrodominio.com/ipn_error.php">
<input type="hidden" name="no_shipping" value="0">
<input type="hidden" name="no_note" value="0">
<!-- Mostramos el detalle de la compra -->
<table width="50%" border="0" align="center" cellpadding="3" cellspacing="0" bgcolor="#EABB5D" style=" border-color:#000000; border-style:solid;border-width:1px;">
<tr>
<td align="left" valign="top"><span class="prod"><strong>Detalle de los Productos Seleccionados</strong>:</span><br>
<span class="texto1negro"> </span><span class="prod"><strong>Productos:</strong> <?php echo $products; ?><br>
<strong>Pecio Total:</strong> $<?php echo number_format($_GET['costo'],2) ?> </span></td>
</tr>
</table>
<input type="submit" name="Submit" value="Enviar">
</fieldset>
</form>

</body>
</html>


En regpago.php mostramos el detalle de los artículos y el total del importe que habíamos enviado desde vercarrito.php.
Pero veamos qué significan los campos hidden con los cuales trabajaremos (los que no mencionemos conviene dejarlos como están):

shipping: Es el costo de envío. Para nuestro ejemplo es cero, pero si no fuera ese el caso, aquí deberíamos colocar el importe correspondiente al total del costo de envío.

cbt: Es el mensaje que verá en Paypal el usuario al finalizar el proceso de pago.

rm: Es el método con que Paypal devolverá las variables a la página ipn_success.php (1 es get 2 es post).

bn: Esta es la identificación de la integración que estamos haciendo, normalmente la identificaremos con el nombre de la empresa vendedora.

business: Es el mail que el vendedor registró en su cuenta de Paypal.

item_name: Es el detalle de lo que estamos vendiendo.

item_number: Aquí va el número de item. Podemos completarlo con un código de operación o utilizarlo para otra cosa (personalmente lo utilizo para guardar el nombre del comprador, ya que cuando la operación se realiza y Paypal automáticamente genera sendos mails al vendedor y al comprador, suele incluir este dato y al vendedor le sirve para saber rápidamente quien es el comprador).

amount: Es el importe total de la operación.

custom: Aquí podemos colocar cualquier variable que luego necesitemos para realizar nuestros procesos cuando Paypal redireccione al usuario a nuestra página de éxito.

currency_code: La moneda en que expresamos los valores:USD,GBP,JPY,CAD,EUR.

image_url: Es la ruta absoluta de la imagen que aparecerá en la cabecera de la página de Paypal cuando el comprador esté pagando. Se utiliza para que no perdamos del todo la identidad de nuestro site durante el proceso de pago, pero a menos que la imagen esté guardada en un servidor con protocolo HTTPS, es mejor dejar este campo en blanco ya que, si no lo hacemos de esa manera, cuando el comprador ingrese a Paypal le aparecerá un mensaje diciéndole que la página contiene elementos seguros y no seguros, cosa que puede asustar a algunos compradores.

return: Aquí colocaremos la ruta absoluta a la página ipn_success.php. Es la página a la que Paypal redirecciona al comprador si el pago se realiza correctamente, y a la que envía las variables que utilizaremos para los procesos ligados a la compra: generar un envío de productos, enviar un mail, descontar del stock, cambiar un nivel de acceso, etc.

cancel_return: Aquí colocaremos la ruta absoluta a la página ipn_error.php. Es la página a la que Paypal redirecciona al comprador si el pago no se realiza correctamente.
En ella deberemos colocar un mensaje del tipo "Ocurrió un error y la operación no puedo realizarse..." para notificar el fallo al comprador.

Como vemos, Paypal actúa como un gran if:

if(pago==exitoso){enviar a ipn_success.php
}else{enviar a ipn_error.php
}


De manera que no analizaremos demasiado la página ipn_error.php, ya que incluso puede ser estática. Veremos cómo podemos recuperar todas las variables que devuelve Paypal en ipn_success.php.

Si queremos saber todas las variables que Paypal nos envía, escribimos lo siguiente en el archivo ipn_success.php y luego realizamos una compra ficticia:

<?php
echo '<pre>';
print_r($_POST);
echo '</pre>';
?>


Si no queremos hacerlo, sabemos que la variable que siempre recibiremos es custom, y para recogerla podemos hacerlo así:

<?php
echo $_POST['custom'];
?>


En realidad, con custom es suficiente, ya que en ella podemos guardar todos los datos que necesitemos (es la ventaja de trabajar con el método post, con get estaríamos limitados). Por ejemplo, si hiciéramos lo siguiente:

<input type="hidden" name="custom" value="<?php echo $valor1."separator".$valor2."separator".$valor3; ?>">

Luego en ipn_success.php podríamos recuperar los valores de esta manera:

<?php
$vec=explode('separator',$_POST['custom']);
for($i=0;$i<count($vec);$i++){
echo '$valor1='.$vec[$i];
}
?>


Bueno, con esto tenemos un panorama general de cómo integrar nuestro carrito con Paypal. Sólo nos faltó señalar una cosa muy importante: Paypal proporciona una plataforma de pruebas en la que se pueden realizar operaciones ficticias, que funciona igual que la plaraforma real, sólo que no hay dinero verdadero de por medio. Esto da la posibilidad de hacer todas las comprobaciones necesarias y solucionar todos los errores antes de poner online nuestra integración.

Dicha Plataforma de pruebas se llama Sandbox, y para poder utilizarla sólo hay que crearse una cuenta de pruebas en Paypal y cambiar el action de nuestro formulario en regpago.php, que era "https://www.paypal.com/cgi-bin/webscr", por este otro: "https:/www.sandbox.paypal.com/cgi-bin/webscr", y el mail de <input type="hidden" name="business" value="maildelvendedor@dominio.com"> por el que consignemos en la cuenta de pruebas que creemos.

Para terminar, decir solamente que lo mejor es posibilitar más de una alternativa de pago. Podríamos, por ejemplo, hacer que el botón "Finalizar Compra" de vercarrito.php remitiese a una página en la cual se ofrecieran 2 alternativas de pago: una manual y otra automática. Si el usuario seleccionara la opción manual, le enviaríamos un mail con el detalle de los artículos como vimos en el punto 1) y las instrucciones de pago o de cómo contactarse. Si, en cambio, optase por la manera automática, lo enviaríamos a la integración con Paypal que hemos visto en el punto 2).

Andrés Fernández

Manual