Creando una plataforma de pago con PayPal y CodeIgniter 3 (parte 1)
- Andrés Cruz
PayPal es una plataforma de pago fundamental en estos días, es una forma segura de pago que lo aceptan múltiples sitios en Internet y como toda gran plataforma, PayPal cuenta con una API la cual podemos emplear para integrar desde nuestro PHP y de esta forma crear una plataforma de pago; específicamente nos interesa integrar esta API mediante una librería para CodeIgniter que es nuestro caso de interés para esta entrada.
Un punto importante al momento de querer monetizar nuestras aplicaciones es decidir la estrategia para llevar a cabo dicha labor, colocar banners publicitarios, ofreciendo servicios, vendiendos productos, etc; estos dos últimos casos tienen un punto en común y es la necesidad de incorporar una plataforma de pago desde la aplicación y como siempre queremos que sea sencillo, seguro, fácil de administrar y su integración sea sencilla.
PayPal: Seguro, sencillo y fácil de implementar
Seguro, sencillo y fácil de implementar de emplear son unas de las muchas palabras con la que podemos describir a PayPal y que también nos brinda una Rest API para integrar los servicios de Paypal con las aplicaciones propia realizada en alguna tecnologías como PHP, CodeIgniter, Java, Android, etc como veremos en un pequeño ejemplo que tenemos más abajo.
En esta entrada se explicará los pasos que debemos hacer para integrar la plataforma de pago PayPal con CodeIgniter
Creando cuentas de pruebas (sambox) en PayPal
Lo primero que debemos hacer es crearnos unas cuentas de prueba para desarrolladores (a menos que quieras realizar las pruebas desde cuentas PayPal con fondos reales :)).
Para esto nos vamos al sitio de PayPal Developer y nos registramos; luego de eso nos vamos a la "Dashboard" y "accounts" creamos un par de cuentas:
- Cuenta Personal: Para aquellos que compran.
- Cuenta Business: Para aquellos que venden en Internet.
En general, la cuenta PayPal Business es la que será configurada en la aplicación para recibir los pagos y la cuenta Personal para realizar los pagos en la plataforma.
Descargando la librería de PayPal para CodeIgniter
Existen varias librerías de pago que emplean PayPal y que las podemos usar con CodeIgniter, como siempre en el sofware libre, algunas son de pago, otras tienen meses/años desactualizadas otras manejan otras formas de pago (aparte de PayPal) Omnipay aunque decidí emplear paypal-library-for-codeigniter la cual se encuentra disponible para CodeIgniter 3 y ofrece una sencilla integración y uso con CodeIgniter que permite cumplir con el objetivo de esta entrada la cual es crear una platafoma de pago en línea automatizada.
Integrando la librería paypal-library-for-codeigniter a CodeIgniter
Como todo instalación de librerías para CodeIgniter, es muy sencilla su instalación, basta con copiar el paypal_lib.php
en la carpeta application/libraries/
y el paypallib_config.php
en la carpeta application/config/
.
Creando nuestra plataforma de pagos
1. Datos de prueba (products) y pagos (payments) -SQL-
Supongamos que nuestra estrategia resulta en vender algunas productos; para eso creamos una tabla en Base de Datos como el siguiente:
CREATE TABLE `products` (
`id` int(11) NOT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`image` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`price` float(10,2) NOT NULL,
`status` tinyint(1) NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Y para registrar los pagos:
CREATE TABLE `payments` (
`payment_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`product_id` int(11) NOT NULL,
`txn_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`payment_gross` float(10,2) NOT NULL,
`currency_code` varchar(5) COLLATE utf8_unicode_ci NOT NULL,
`payer_email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`payment_status` varchar(255) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Modelos, controlador para CodeIgniter (PHP)
El modelo que usaremos en CodeIgniter luce de la siguiente manera:
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Product extends CI_Model {
public function __construct() {
parent::__construct();
$this->load->database();
}
public function getRows($id = '') {
$this->db->select('id,name,image,price');
$this->db->from('products');
if ($id) {
$this->db->where('id', $id);
$query = $this->db->get();
$result = $query->row_array();
} else {
$this->db->order_by('name', 'asc');
$query = $this->db->get();
$result = $query->result_array();
}
return !empty($result) ? $result : false;
}
public function insertTransaction($data = array()) {
$insert = $this->db->insert('payments', $data);
return $insert ? true : false;
}
}
Llenamos algunos datos de prueba:
INSERT INTO `products` (`id`, `name`, `image`, `price`, `status`) VALUES (1, 'carro', 'carro.png', 50.00, 1); INSERT INTO `products` (`id`, `name`, `image`, `price`, `status`) VALUES (2, 'moto', 'moto.png', 50.00, 1);
Cómo ves dejaremos para futuras entradas la creación de muchas otra cosas como el login de la cuenta, listado de productos, ect; y solo explicaremos los pasos fundamentales para realizar un pago en PayPal y que este notifique a la aplicación (lo cual sería lo más básico de una pasarela de pago).
2. Procesando la compra
Para procesar la compra crearemos una acción llamada buy
en nuestro controlador PHP que luzca de la siguiente forma:
function buy($id) {
$this->load->model('product');
//Set variables for paypal form
$paypalURL = 'https://www.sandbox.paypal.com/cgi-bin/webscr'; //test PayPal api url
$paypalID = 'andres291190-facilitator@hotmail.com'; //business email
$returnURL = base_url() . 'paypal/success'; //payment success url
$cancelURL = base_url() . 'paypal/cancel'; //payment cancel url
$notifyURL = base_url() . 'paypal/ipn'; //ipn url
//get particular product data
$product = $this->product->getRows($id);
$userID = 1; //current user id
$logo = base_url() . 'assets/images/codexworld-logo.png';
$this->paypal_lib->add_field('business', $paypalID);
$this->paypal_lib->add_field('return', $returnURL);
$this->paypal_lib->add_field('cancel_return', $cancelURL);
$this->paypal_lib->add_field('notify_url', $notifyURL);
$this->paypal_lib->add_field('item_name', $product['name']);
$this->paypal_lib->add_field('custom', $userID);
$this->paypal_lib->add_field('item_number', $product['id']);
$this->paypal_lib->add_field('amount', $product['price']);
$this->paypal_lib->image($logo);
$this->paypal_lib->paypal_auto_form();
}
Como podemos apreciar, indicamos la URL de pruebas de PayPal que procesa los pagos y el identificador de la cuenta configurada que recibirá los fondos a transferir de nuestros usuarios; estos dos parámetros son los únicos que debemos cambiar cuando deseemos pasar de modo de desarrollo a producción.
Los siguientes parámetros consisten el pase de información básica (precio, URL de retorno, nombre y descripción del producto son algunos de ellos) a Paypal para que realice el pago.
Una vez que PayPal procese el pago, el monto lo veremos reflejado en nuestra cuenta de pruebas de PayPal:
Pero un paso muy importante es que PayPal notifique a la aplicación que el pago ha sido realizado y así evitar realizar esta tarea de manera manual; para eso empleamos los IPN que veremos en la siguiente sección.
3. IPN (Instant Payment Notification)
Los IPN son mensajes enviados de manera automática a nuestras aplicaciones vía HTTPS (si, hace poco PayPal solicita que los IPN sean a través de una conexión segura) que nos brinda la información necesaria para desencadenar algún proceso.
Supongamos que nuestra aplicación consiste en la venta de material digital como PDFs y templates web; al seleccionar y pagar el usuario por uno de nuestros recursos vía PayPal, PayPal le notifica a la aplicación vía IPN que el pago fue realizado; una vez hecho esto, la aplicación debe ser capaz de enviarle el material que compró el usuario vía email u de la forma que queramos configurar la aplicación.
4. Configurando el IPN en nuestra cuenta PayPal
Obviamente PayPal no sabe por sí sola a donde va a enviar el mensajes, para eso debemos indicarlo desde nuestra cuenta; para ello nos autenticamos con nuestra cuenta de prueba PayPal de Business, luego clic en Profile, My selling tools y Instant Payment Notification; definimos el IPN con una URL segura:
Como vemos PayPal nos pide que sea una URL segura mediante HTTPS; y debe ser accesible vía Internet (nada de local) lo que nos complica bastante realizar pruebas desde la comodidad de nuestra máquina local.
Finalmente, nuestro acción que recibe el IPN queda de la siguiente manera:
function ipn() {
$paypalInfo = $this->input->post();
$data['user_id'] = $paypalInfo['custom'];
$data['product_id'] = $paypalInfo["item_number"];
$data['txn_id'] = $paypalInfo["txn_id"];
$data['payment_gross'] = $paypalInfo["payment_gross"];
$data['currency_code'] = $paypalInfo["mc_currency"];
$data['payer_email'] = $paypalInfo["payer_email"];
$data['payment_status'] = $paypalInfo["payment_status"];
$paypalURL = $this->paypal_lib->paypal_url;
$result = $this->paypal_lib->curlPost($paypalURL, $paypalInfo);
//check whether the payment is verified
if (eregi("VERIFIED", $result)) {
//insert the transaction data into the database
$this->product->insertTransaction($data);
}
}
Como vemos, recibimos la información del pago mediante un POST (enviado por PayPal), obtenemos la data y luego de esto deberíamos desencadenas cualquier proceso; obviamente si queremos que esto esté en producción deberíamos emplear un nombre un poco más complejo para evitar inyecciones.
Enlace de Interés
La página fuente de donde tomé prácticamente la totalidad del código es: Creating PayPal Sandbox Test Account and Website Payments Pro Account.
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter