About Sumup
"SumUp is a global financial technology company and the leading mobile point-of-sale (mPOS) company in Europe. Thanks to SumUp, small merchants around the world are able to accept card payments anywhere their business takes them.
SumUp technology makes accepting payments simple so merchants can focus on what they do best, whether they’re brewing coffee or fixing cars. While traditional POS offerings are costly and bureaucratically complex for small businesses to attain, SumUp products are designed to be intuitive and easy-to-use, from paperless on boarding to seamless transactions.
Since its launch, SumUp has earned an impressive global reach and expanded into 31 countries, including Germany, the U.S., and Brazil. SumUp continues to grow and is backed by TPG, Bain Capital Credit, Groupon, Holtzbrinck Ventures, and other renowned venture capital investors.
Beyond the original hardware, mobile, and web apps, SumUp has also developed a suite of APIs and SDKs for integrating SumUp payment into other apps and services. Thanks to these offerings, over two million small businesses around the world rely on SumUp to simply get paid." (source: https://sumup.com/about)
Intro
I joined SumUp in Sofia, Bulgaria in 2016. What impressed me about the company back then was the product - a simple, easy to use card reader, dedicated to small businesses. For me it was very important to pay for a given service cashless, so I saw an excellent opportunity to contribute to achieving this. During my stay at SumUp I participated in several transformations, identity crises, highs and lows. It gave me priceless experience and shaped me as a professional, also helped me to realize what should I aim for in my future endeavors.
Tech Stack
Ruby, Ruby on Rails, JavaScript, Node.js, HTML, CSS, RabbitMQ, PostgreSQL, Jenkins, AWS, Centos7, VIM, Git
System architecture
All backend services were accessed by the client facing ones (frontend, mobile, SDKs, APIs) through a gateway application. There was one database to rule them out, and a database for data warehousing and integration with SalesForce (populated by logical replication).
Frontend The frontend application was done with Angular 1.x. It had a complementary service, called web-backed, which was dedicated to serve the JS bundles and do backend calls.
Backend The backend was a mixture of SOA, monolith and microservices. The majority was written in Ruby, the monolith was Rails app. The backend evolved in the spirit of MVPs, released ASAP in order to be first on the market. Communication between services was done by HTTP calls. Sometimes a single HTTP call spans requests across several other services and a database or external service.
Team(s)
When I started, there were around 15 software developers globally. The devs in Sofia, Bulgaria were focused mostly on the backend. Two of the backend devs were strongly focused on the payments backend, because of their Erlang proficiency. There were also 3 frontend developers and 3 mobile developers, based in Berlin, Germany. There was not any strict team definitions and everyone were able to select features and bugs to work on.
Later on it was announced that the big team of backend developers will be split into software features teams, or service teams. Each service team had a product owner, a QA and backend developers.
As the company continued to grow, it turned out that the service teams are not sufficient, so another reorganization was done. The service teams were transformed to product teams. This time a product team had clearly defined business domain boundaries, but still sharing engineering resources. The two frontend devs were participating in few product teams each.
Release Process
The release process was done old school. It was done once a week, usually outside business hours, early in the morning, with a complex sequence of actions, performed by a release manager (usually some of the backend devs) and further executed by SysOps.
Here's a list of the actions that a release manager had to perform, in order to prepare a release:
- Check if everything is merged into release branches
So, there was an excel spreadsheet, containing all the JIRA tickets tagged for releasing, with a developer and QA in charge, and a link to merged PR to the release branch in GitHub. The RM had to ensure that every ticket is ready for releasing.
- Pull translations for each project that has such
Most of the projects had translations, so before releasing for each project a pull of the latest translations was to be performed. It happened often that translations were out of sync, so the RM had to start from the beginning. Sometimes it happened to update translations a little after the release, which led to smaller release cycles the days after.
- Bump project versions
As the projects source code had to be packaged, and each package had a version, the RM had to bump a line in a meta file, so a new version of the package was created and deployed. Along with the bump in the meta file, a bump was to be performed also in a meta project, that was dedicated to keeping track of project versions deployed to production. This project served also as a hint to RunDecks runbook to build and deploy a given version of the project. Holy shit, yeah!
- Execute Jenkins builds
Once the steps before were done, the RM had to execute a Jenkins build of the given project and wait till the build is done. The build generates an RPM package, ready for deployment.
- Send Release Email
As a last step, a release email including the announcement of projects to be released, as well as links to their builds.
- Release
The release was fully manual, performed by downloading the builds to the corresponding servers, and doing rpm -ivh package... Voila! We have a release DONE!
It was a pure craftsmanship to prepare a release. It was an error prone process. Sometimes it took more of a day to prepare a release. Happily, as time has gone by, the company introduced more modern ways of doing a release.
Projects Highlights
- Fee calculator - tool for calculating transaction fees
- Acesso Integration - integrating prepaid-card service for Brazil customers
- Matera ERP Integration - integrating ERP system for Brazil customers
- Receipts NG - replace old receipts service with a new one
- Expansion in 16 new countries - several tasks to help the expansion to new markets
Acesso Integration
The integration with Acesso was the first big project that I had the chance to work on. It was a project from scratch. Acesso is a main prepaid-card issuer in Brazil, and we wanted to issue prepaid-cards to our clients. I teamed up with the VP of Tech and the Payments Product Owner.
The challenges that we had, was mainly due to the API requests, which fields were written in Portuguese, and given the language barrier, it was difficult to understand what is to be sent in it.
Matera ERP Integration
The integration with Matera was the second big thing that I worked on. The project was needed due to tax challenged in Brazil with issuing invoices for the card readers that we were selling. Here, the main challenge was the delivery of the product. From announcement to delivery, I've got around 10 days, most of them during a company off-site event. Nevertheless, the integration service was there. It was done with Node.js and communication was realized with RabbitMQ. Not a big deal in the end. The problems occurred once we start using it, as the Matera ERP system was constantly deadlocking itself and someone manually had to fix it. Also, the communication between people was unsatisfying. I had to speak with the Point of Contact (PoC) in our office in Brazil, which had in turn to speak with the PoC in Matera. Here I experienced for the first time the cultural barriers between people in Europe and Brazil.
In the end the project was abandoned by the business, as it was clear that we might not need it after all.
Receipts NG
The Receipts NG was the most complex service to work on throughout my career at SumUp. It was basically a service to generate receipts in various formats - svg, png, jpeg, json. Nothing fancy, nothing special - bunch of data turned into a visual form.Why was it so complex after all?
-
It was a successor of the old service (hence the name NG - next generation). Since the whole service architecture was messy, there were hidden legacy services that were still in use by the legacy receipts service. It was an exploratory task to find out who and when is calling the service and why.
-
There was no product owner to get the requirements from. It was basically me and the QA, who, along with testing was also busy with validating the output. We've got a pile of paper receipts from across the world, so we were able to validate against them. Despite, it was not possible to validate every single case, when there are no requirements written. We were back and forth in the development for months.
-
I had to develop svg renderer for the svg format. Think about it as a css for svg files. The biggest challenge was that there was no auto word wrapping. I had to implement something similar to this minimum number of lines . It was not perfect but with some optimizations it was working acceptable. The work on this was further continued by another colleague, which resulted in this ruby gem: svg_drawer.
- While developing this service, SysOps colleague was developing a migration plan to move all of our infrastructure to AWS. The new service was the first candidate to be released there. At some point, the service was released silently to production in minutes, without the bureaucracy.
In the end the project was launched and further developed by the team in Sofia, as I moved to Berlin in the mean time.