A principios de junio publicamos la web de Altenwald para la venta de libros técnicos en castellano y aprovechando la salida del segundo volumen de Erlang/OTP. Esta web ha sido creada desde cero en Phoenix Framework hasta conseguir tener un sitio ecommerce completamente funcional, ¿quieres saber cómo se hizo?
En principio la venta de libros estaba centrada en erlang-otp.es. Esta web en principio usaba los botones de compra de PayPal y era HTML estático completamente con los siguientes complementos:
Al no tener el control completo del proceso de compra no podía introducir ofertas, ni más flexibilidad a la hora de realizar las compras. Eso me llevó a realizar los primeros cambios a la web de erlang-otp.es en mayo para permitir comprar productos de otra forma diferente. En ese momento cambié el código estático por código dinámico.
El backend que elegí fue Phoenix Framework. Usa el lenguaje Elixir y la plataforma Erlang. Me gustó ver que Elixir cuenta a día de hoy con una gran cantidad de paquetes disponibles a través de Hex y es muy fácil crear nuevos paquetes y agregar dependencias a través del fichero mix.exs
.
No espero tener un gran tráfico de primeras en la web pero está bien suponer que pueda haberlo en un futuro. Como base de datos tengo PostgreSQL configurado en multi-master gracias a Postgres-BDR (hablaré de ello en otro artículo).
Para frontend no me compliqué y decidí emplear la misma plantilla que estaba usando en la web del libro. Sé que tengo librerías desactualizadas y trabajaré en ello en futuras versiones.
Lo único novedoso entre la comunicación entre frontend y backend es la agregación de websockets. Si navegas un poco por la web, al agregar elementos al carro desde las páginas de los libros o desde la página principal, verás que la página no se recarga y la adición del elemento al carro se hace a través de una comunicación directa con el servidor a través de un websocket.
En un futuro ese mismo canal puede emplearse para chat y cambiar aún más la web sin necesidad de tener que hacer cargas completas de la misma.
En principio el carro de la compra. Ese era el objetivo. Permitir realizar una orden donde agregar elementos. Cada elemento pueda agregarse una o varias veces (cantidad) y el sistema presente en una pantalla el contenido de la orden.
Por otro lado. Ofertas. Era algo que PayPal no permitía (o lo hacía muy difícil). Implementé un sistema de ofertas flexible basado en tres tipos de disparadores:
Hay otras reglas que en caso de estar disponibles se aplican automáticamente también:
También especificamos tres tipos de descuentos a ser aplicados:
En la orden por lo tanto podemos agregar todos los elementos que queramos. Al agregar un elemento ya incluído este elemento sube en cantidad (no aparece dos veces).
En la página del carro podemos ver un cuadro para agregar códigos de descuento, además del formulario para proceder con el pago.
El pago se ha pensado para incluir tantos modos de pago como sea posible. Para no atar al sistema a PayPal. En principio para realizar la prueba implementamos el pago por PayPal y pago por transferencia. Obviamente el segundo pago no es posible a día de hoy de implementar de forma automatizada debido a la problemática que ofrecen los bancos españoles con respecto a la automatización. Pero este modelo abre las puertas para incluir en futuras versiones otros medios como Skrill o Stripe entre otros.
Por último. Una interfaz de administración que permita revisar el estado de las órdenes, cambiar información de los libros, las ofertas, etc. Debido a los cambios en las versiones de Phoenix solo encontré un sistema que permitía realizar esto. No da la suficiente automatización pero es eficaz: Torch.
La idea del sistema es que automatice lo máximo posible. Si un libro se vende y es versión digital, no tenga la necesidad de realizar ningún proceso manual. El comprador debe poder acceder a su compra de forma inmediata.
Las integraciones que hice fueron a través de Tesla, una librería de Elixir que permite crear clientes de API en muy, pero muy, muy pocas líneas de código:
defmodule Altenwaldbooks.Api.Mailchimp do
use Tesla
plug Tesla.Middleware.BaseUrl, "https://#{cfg(:dc)}.api.mailchimp.com"
plug Tesla.Middleware.BasicAuth, username: "anystring",
password: cfg(:api_key)
plug Tesla.Middleware.Headers, [{"content-type", "application/json"}]
plug Tesla.Middleware.JSON
defp cfg(:api_key) do
Application.get_env(:altenwaldbooks, :mailchimp_api_key, "")
end
defp cfg(:dc) do
cfg(:api_key)
|> String.split("-")
|> Enum.at(1)
end
def list_lists(query \\ []) do
get("/3.0/lists", query: query)
end
def list_members(list_id, query \\ []) do
get("/3.0/lists/#{list_id}/members", query: query)
end
def add_member(list_id, data) do
post("/3.0/lists/#{list_id}/members", data)
end
end
Este código presenta la implementación de tres funciones de API: listar las listas, listar miembros y agregar miembros. Las funciones conectadas (plug) hacen todo el trabajo de agregar la autenticación y otros procesos como traducir las estructuras hacia y desde JSON.
Por lo tanto cree ficheros como estos para gestionar:
Con esto, en cada compra se realiza una cantidad importante de acciones y requiere de menos supervisión por mi parte.
Otro de los problemas que tuve es la necesidad de escribir los textos legales. No me gusta escribir directamente en HTML. Busqué un poco y encontré una librería que me permitía escribirlos directamente en Markdown.
Entonces, tenemos instaladas...
sitemap.xml
. Además de las dependencias típicas de Phoenix y PostgreSQL.
Esta es una primera versión de la web de altenwald books. Espero poder seguir trabajando en ella y abordar temas como los usuarios, agregar funcionalidades de compras cruzadas, sugerencias, cambiar de disqus a un sistema de comentarios propio integrado en el sitio, hacer muchos más tests funcionales y mucho más.
Esto han sido solo 3 semanas de desarrollo y no a tiempo completo.
¿Qué te ha parecido? ¿Te atreverías a probar Phoenix Framework? ¿Qué funcionalidades de ecommerce consideras más necesarias? ¡Déjanos tu comentario!