Transbank y PHP (parte 1): Preparación de ambiente
Transbank nos entrega distintos productos para pagar en la web a través de su API SOAP¹. Además, deja a nuestra disposición varios SDK para distintos lenguajes, que nos facilitan la vida a la hora de conectarnos al API, haciendo la parte difícil por nosotros. ¿El problema? Que ni la documentación ni los SDK son tan amigables como podrían ser.
Esta es la preparación para una serie de guías en las que integraremos todos los productos de Transbank utilizando contenedores en Docker y el framework de PHP Lumen.
Aclaración: Estas guías no pretenden ser un tutorial para PHP, Docker, ni ninguna otra de las herramientas que se utilizan, pero consideran breves explicaciones de los cambios realizados en cada paso.
- Preparación de ambiente
- Integrando Webpay Plus Normal
- Integrando Webpay Plus Mall (en proceso)
- Integrando Webpay Oneclick Normal (en proceso)
- Integrando Webpay Oneclick Mall (en proceso)
En esta guía de preparación, nos preocuparemos de dejar lista la configuración con todo lo necesario para ejecutar nuestro sistema de prueba, así como la programación de los componentes mínimos necesarios para después preocuparnos sólo de la integración de productos de Transbank.
1. Herramientas necesarias
Docker es una herramienta que automatiza la instalación y uso de contenedores. Para instalar docker puedes seguir las instrucciones en la documentación (en inglés):
- Instalar docker desktop (Windows y Mac OS)
- Instalar docker engine (Linux y otros)
Un contenedor es un sistema virtualizado que permite correr aplicaciones aisladas de nuestro sistema, pues contiene dentro de si nuestra aplicación y todas las bibliotecas y herramientas necesarias para que se ejecute.
Además utilizaremos docker compose, una herramienta de docker que automatiza el uso de aplicaciones que utilizan varios contenedores. Para instalar, también puedes seguir la documentación (en inglés).
Finalmente utilizaremos git, que aunque no es necesario para el desarrollo y ejecución de nuestro proyecto, si nos permitirá llevar un control de nuestras modificaciones y un registro de lo que hicimos en cada paso de estas guías. Para instalarlo, podemos descargar los binarios directamente desde su sitio oficial.
2. Creando nuestro proyecto
Es lo primero que debemos hacer, crear un directorio que contendrá todo el código y la información de nuestro proyecto. Y para crear el nuestro, utilizaremos composer sin la necesidad de instalarlo en nuestro equipo. En vez de eso, ejecutaremos composer a través de su imagen oficial para docker, ejecutando:
$ docker run --rm -ti -v $PWD:/app composer create-project --prefer-dist laravel/lumen transbank-integration-php
De todas formas, si ya tienes composer instalado en tu equipo, quizás te sea más fácil utilizarlo directamente con:
$ composer create-project --prefer-dist laravel/lumen transbank-integration-php
En ambos casos, terminaremos con un nuevo directorio con nombre transbank-integration-php
, y dentro de él tendremos el código base y las bibliotecas de PHP para correr un proyecto de Lumen es un micro-framework de PHP, una versión minimalista del conocido.
Lumen es un micro-framework de PHP, una versión minimalista del conocido Laravel. Pone énfasis en la velocidad de ejecución, y está orientado al desarrollo de microservicios y APIs.
Para instalar ahora el SDK oficial de transbank para PHP, nos ubicaremos en el directorio del proyecto, y ejecutamos:
$ docker run --rm -ti -v $PWD:/app composer require transbank/transbank-sdk
Modificamos la zona horaria en el archivo de configuración .env
:
Y finalmente habilitamos el uso de modelos Eloquent
y de Facades
en Lumen, quitando el comentario de las líneas 26 y 28 del archivo bootstrap/app.php
:
Con esto tendremos nuestro proyecto con todas las bibliotecas necesarias para ejecutarse sin problemas.
3. Inicializando git
Ya que tenemos una instalación fresca de nuestro framework de desarrollo, es un buen momento para comenzar con el control de versiones de nuestro código. Nos ubicaremos dentro del directorio transbank-integration-php
, y crearemos un nuevo repositorio local ejecutando:
$ git init
¿Aún no conoces git? Quizás te sea útil este kit de superviviencia para git, orientado a nuevos usuarios que necesitan utilizarlo rápido para integrarse a sus equipos de trabajo.
Ya está, tenemos nuestro repositorio. Para guardar el estado actual del proyecto, crearemos nuestro primer commit ejecutando:
$ git add .
$ git commit -m 'Initialize project'
No es necesario preocuparse por los archivos que debemos ignorar, pues Lumen incluye por defecto un archivo .gitignore
con el contenido necesario para evitar que git haga seguimiento de archivos y directorios innecesarios.
4. Utilizando contenedores
Ya tenemos el código básico de nuestro proyecto, y probaremos que todo funciona correctamente creando un nuevo contenedor que nos permita ejecutarlo. Para ello, crearemos un nuevo archivo docker/transbank.dockerfile
en nuestro proyecto, con el siguiente contenido:
En este dockerfile nos basamos en la imagen oficial de PHP que incluye el servidor http Apache, y lo modificamos ligeramente cambiando la ubicación por defecto de nuestro index.php
al directorio /var/www/html/public/
dentro del contenedor. Luego instalamos dependencias necesarias, dejamos el php.ini
de producción y actualizamos algunas configuraciones. Si necesitas más detalles para entender lo que está pasando, puedes revisar la documentación acá.
Algunos notarán que en el dockerfile no copiamos nuestro código al contenedor. Esto es porque lo haremos dinámicamente, para evitar tener que reconstruir el contenedor cada vez que realicemos cambios en nuestro código. Para lograrlo, utilizaremos docker compose, que se configura con un archivo docker-compose.yml
en la raíz de nuestro proyecto. Crearemos el archivo y definiremos un nuevo servicio que se ejecute utilizando el contenedor que definimos más arriba, con:
Los dos puntos más importantes son el mapeo del directorio de nuestro proyecto (./
) con el directorio /var/www/html/
del contenedor utilizando volúmenes, y el enlace del puerto 80 de nuestro equipo con el puerto 80 del contenedor. Si necesitas más detalles de la configuración de compose, puedes ver la documentación acá.
Para ejecutar todo esto, basta con construir nuestro contenedor y levantar el servicio que acabamos de definir. Ambos pasos los podemos ejecutar con un:
$ docker-compose up
Ahora, si visitamos http://localhost/, deberíamos ver algo como esto:
Como podemos ver, nuestro sitio está funcionando correctamente dentro del contenedor que acabamos de crear. Si quieres detener la ejecución, solo debes presionar Ctrl + C
en la terminal en la que está ejecutándose el contenedor.
Podemos guardar nuestros avances con:
$ git add .
$ git commit -m 'Dockerize the project'
5. Utilizando una base de datos
Los ejemplos oficiales de integración con Transbank no lidian con bases de datos, y utilizan en cambio variables de sesión para persistir la información necesaria. Y si bien puede ser suficiente para explicar el concepto, en estos artículos utilizaremos una base de datos para guardar toda la información que enviemos en las peticiones y la respuesta correspondiente.
¿Complicado? Para nada. Utilizaremos una base de datos PostgreSQL, usando su imagen oficial para docker. Para ello, modificaremos nuestro archivo docker-compose.yml
agregando las siguientes líneas:
Compose lee por defecto el contenido del archivo .env
en nuestro proyecto (que ya existe, ya que Lumen utiliza el mismo archivo para sus configuraciones), así que utilizamos los valores registrados allí para la configuración de PostgreSQL.
Ahora necesitaremos modificar el archivo .env
para configurar nuestra nueva base de datos, tal como sigue:
Ahora debemos agregar los drivers necesarios para que Apache y PHP sean capaces de conectarse a PostgreSQL. Para eso, agregaremos una nueva línea en nuestro archivo transbank.dockerfile
:
Y, como modificamos el dockerfile, tendremos que reconstruir el contenedor del servicio transbank con el comando:
$ docker-compose build transbank
Eventualmente será necesario correr las migraciones para nuestro sistema. Para hacerlo simple, podemos correr las migraciones cada vez que iniciemos el servicio transbank. Para esto necesitamos cambiar la ejecución por defecto del contenedor, agregando el comando de ejecución de migraciones, así que crearemos en el directorio docker
un nuevo archivo llamado init.sh
con el siguiente contenido:
donde tenemos dos comandos: la ejecución de las migraciones, y el script por defecto de ejecución para la imagen php:apache
. Los comandos están unidos por un &&
, de modo que si cualquiera de ambos falla, terminará la ejecución del contenedor y se reiniciará.
Ahora debemos modificar la descripción del servicio transbank
en el archivo docker-compose.yml
, para que utilice este script de inicio y requiera que primero se levante el servicio db
:
Finalmente, para poder revisar los cambios que ocurran en nuestra base de datos, agregaremos el servicio adminer a docker-compose.yml
:
Podemos probar estos cambios ejecutando nuevamente:
$ docker-compose up
En la dirección http://localhost:8080/ veremos al interfaz de adminer, y si ingresamos la información para conectarnos (la misma que tenemos en nuestro archivo .env
), deberíamos ver algo como lo siguiente:
Como todo funciona, podemos guardar nuestros cambios en git con:
$ git add .
$ git commit -m 'Configure database'
6. Configurando layouts
En nuestro sistema necesitaremos dos tipos de vistas: Las vistas que mostrarán o solicitarán información al usuario, y las vistas para formularios que se envíen automáticamente (una funcionalidad necesaria en varios productos de transbank).
Para las vistas para mostrar o solicitar información, crearemos su layout resources/views/layouts/app.blade.php
. El archivo tendrá tres secciones, una para el título, otra para ubicarnos en el sitio, y una para el contenido de la vista. Podemos definirlo como sigue:
Para los formularios que necesitamos que se envíen automáticamente, crearemos el layout resources/views/layouts/autosend.blade.php
. En él sólo agregaremos una sección de para el formulario y el código necesario en javascript para enviar el formulario automáticamente:
Y guardamos nuestros cambios en git con:
$ git add .
$ git commit -m 'Create app layouts'
Finalmente, tenemos toda la configuración y generalidades del proyecto listas para iniciar nuestro desarrollo.
7. Preparando pagos
Ya esta todo configurado, ahora sólo necesitamos programar unos últimos detalles, que luego nos serán útiles en las guías que vienen.
Modelo de pagos
Primero, necesitamos almacenar los datos de compra en una sencilla tabla de pagos que contendrá sólo el monto a pagar. Para eso, y mientras los servicios definidos para compose
corriendo, crearemos una migración ejecutando:
$ docker-compose exec transbank php artisan make:migration create_payments_table --create=payments
En la clase resultante, modificaremos el método up
para que quede:
Ahora que tenemos nuestra migración lista, podemos crear un modelo Eloquent que nos facilite la vida a la hora de tratar con esta tabla, con constantes que indiquen el estado del pago y una descripción para el estado. Para ello, crearemos el archivo app/Payment.php
con el contenido:
No olvidemos que nuestras migraciones se ejecutan cada vez que iniciamos el servicio de transbank, así que para que los cambios en la base de datos tengan efecto, tendremos que reiniciar los servicios de compose.
Controlador de pagos
Luego necesitamos crear el controlador pagos. Para los pagos, necesitaremos una vista que liste los pagos realizados, que nos permita crear nuevos pagos, y que nos permita seleccionar el método de pago. Para esto, crearemos un nuevo archivo app/Http/Controllers/PaymentController.php
con el contenido:
Y creamos las rutas para ambos métodos en el archivo routes/web.php
:
Vistas de pagos
Ahora sólo nos falta crear las vistas que definimos en el controlador. Primero crearemos la vista de principal de pagos en el archivo resources/views/payments/index.blade.php
, que listará los pagos en la base de datos y tendrá un formulario para crear un nuevo pago:
Y para finalizar, crearemos la vista de selección de pago para las compras en resources/views/payments/select_payment_method.blade.php
, donde en las guías que siguen iremos agregando los distintos productos de transbank:
Corroborando funcionamiento
Esta vez, si entramos a http://localhost/, las cosas habrán cambiado. En vez de la vista por defecto de Lumen, veremos algo como esto:
Podemos agregar un monto cualquiera en el formulario (por ejemplo, 35000) y enviarlo. Con esto, estaremos creando una nueva instancia de payment
en la base de datos, y podremos ver la vista de selección método de pago, con una lista vacía actualmente:
Y si presionamos el link en los breadcrumbs para volver a Pagos, veremos algo como esto:
Como vemos, tenemos la lógica básica de creación de pagos funcionando, así que es seguro guardar nuestros cambios en git con:
$ git add .
$ git commit -m 'Implement payments logic'
¡Todo listo!
Con estos pasos, ya hemos finalizado todos los preparativos, y podemos comenzar a integrar los métodos de transbank. ¡Nos leemos en las guías que siguen!
(1) Además está en proceso de implementación un API REST, que abordaremos en artículos posteriores.