Nota: este contenido está también disponible en español

If you have ever implemented support for a payment broker in your project there's a chance that you have come across brokers that are a delight to use and implement. And others that are, frankly, a pain in the ass to work with.

Here in Chile, the only choice you have (as we are writing this post in June 2014) if you want to process payments through credit or debit cards is Webpay Plus from Transbank. There are certainly some other services wrapping Transbank platform to offer a more user-friendly interface, but they charge higher rates as they become a re-seller. Also you could implement solutions such as Paypal and operate with dollars, but although it has become recently easier for businesses to transfer Paypal funds to chilean pesos, it is not likely that most of your chilean customers will have Paypal accounts ready with dollars to spend.

Things would not be so terrible if Transbank API was something enjoyable to implement as Stripe or similar. Dream on. Documentation is frequently outdated or incomplete, their list of requirements to fulfill is tough, and they force you to set up your stack with legacy technologies (e.g. you must run CGI scripts) and configurations that cannot be run 100% in the cloud.

Webpay and Django

There are several open-source projects that deal with Webpay. Most of them are plugins for some PHP or Rails frameworks and CMS. Also, there are a whole lot of companies around charging an indecent amount of money just to integrate those on their client's solutions. There was one remarkable effort, though, done by a local fellow sagmor a project called tbk. What we like most about Sagmor's project is that he reverse-engineered the KCC (Kit de Conexión del Comercio in spanish) and came up with a pure Ruby implementation of the Webpay protocol.

So far it's great that there is a working Webpay implementation in Ruby. But we didn't find any Django app for proccessing payments with Webpay. Also, some of the generic existing solutions are focused on certain payment APIs, some others not very well maintained and some others even abandoned.

To our surprise, there is a well designed payment processing Django app, django-getpaid that works well, so we went ahead, forked it and wrote a backend to support Webpay payments. We were exactly looking for something like this, that could be used to set the common foundations for online payment processing, so that we would evolve to implement Webpay first, and other chilean brokers afterwards. It was clearly an opportunity to bring some help to the community by open sourcing a project that would be the reference work for online payments via chilean brokers.

Webpay on Heroku

There were three big issues, at the time of implement the code and technical aspects, we had to overcome with a bit of our geek imagination. It is likely that the same will work for other PasS providers.

1. PaaS providers and CGI

If you are familiar with how Webpay's KCC works, you know that the by-the-book deployment setup requires serving the KCC binaries as CGIs. This configuration is hardly ideal. It is cumbersome to implement when using PaaS providers for deployment and has potential security problems. No to mention that we use gunicorn, which is a WSGI server, it cannot interpret old-school CGI.

We solved this developing a Python context manager that enabled us to keep using Transbank binaries but behind our own Django views. This context manager builds a configured environment for running the binary and collects any logs generated. So, we can still enjoy the peace of mind that comes with the use of Transbank binaries and, at the same time, the wonders of running them however we like.

2. External Proxy Pass

There is one special requirement which states that "You need a static, dedicated IP address to receive requests from Transbank.". Currently, the KCC configurations does not accept a domain name as the address of your application server, it needs to be an IP address. As we used Heroku to test this, we had to set up a VPS running an Nginx server to proxy pass Transbank's requests. Roughly like this:

# on the server section
location / {
    proxy_pass http://yourdomain.com;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host youtdomain.com;
}

3. Logging

The infamous binaries write their logs to disk, but there is no way to set the file path to these. Transbank asks for the logs in order to verify that your integration is correct, but Heroku does not provide by itself permanent storage. So we had to capture the log output and store it into a Django model in the database. As long as payments are not a very frequent operation, we thought that the impact in performance would be litte, a small trade against the complexity of other solutions to this problem.

django-chile-payments

We are pleased to announce the first Django package for online payments in Chile. Although it currently has only the Webpay backend, we expect it to grow up, with the help of the community, to hold others. It is still a little rough around the edges, but definitely works (we have been testing it with the folks at "soporte" in Transbank). Behold:

https://github.com/Nomadblue/django-chile-payments

There is, for sure, a lot of work to do (test coverage is still low, as well as documentation, and of course more backends are desirable) so, you know, contributions welcome! We accept pull requests and, if you are a decent collaborator that reaches our standards and style, we will give you direct push privileges.