---
date: 2026-10
tags: [payments, migrations, legacy-code]
---

Migrating Payments in Production to an API Still Under Development

In 2024, I had to migrate the payment integration of an e-commerce platform used by ski resorts across Europe and the United States.

Adyen had informed us that we needed to move away from its classic platform and migrate to its new solution, built on Balance Platform, by a set deadline. The problem was that the new API was still under development, its documentation was incomplete, and our codebase wasn’t making the transition any easier.

I was the only developer responsible for implementing the migration, and our clients needed to keep processing payments throughout the process.

The Platform

The platform was a white-label online store that allowed ski resorts to sell lift tickets under their own brand. Each resort had its own configuration, including its payment provider.

I had taken over maintenance of the application about a year earlier, after the team that had developed it left.

An API Still Under Development

Adyen had provided us with a migration guide, the new API documentation, and a test environment. I created a new branch and started adapting the API calls, but soon discovered that some endpoints and important options didn’t behave as documented.

We contacted Adyen to resolve these issues. Responses typically took a day, and some technical questions required several rounds of emails, slowing down development while the deadline kept getting closer.

During video calls, we confirmed that the new platform was still under development. Some features had bugs, and the documentation didn’t always reflect their actual behavior. Throughout the migration, I worked with multiple versions of the documentation and different members of Adyen’s team.

To avoid relying entirely on their responses, I started exploring the source code of their Ruby library. I found API calls that weren’t yet documented and was able to test them in the sandbox environment. This allowed me to keep making progress while we waited for other issues to be resolved.

A Codebase Shaped by Many Developers

The challenges with Adyen were compounded by the complexity of the legacy codebase. The payment integration was already organized into several layers, but they were tightly coupled. Many developers had worked on the code over time, leaving behind design decisions that made it difficult to maintain.

As a result, migrating to the new API wasn’t simply a matter of replacing an adapter or updating a few API calls. I had to modify different parts of the application while making sure the existing integration continued to work.

I gradually adapted the code until both platforms could coexist, with each client’s configuration determining which one to use. The development work, including delays and difficulties with Adyen, took me between two and three months.

Migrating One Client at a Time

With the code ready, the most delicate part remained: switching real payments over without interrupting them.

Transaction volumes varied considerably between clients. Some processed only one or two transactions a day, while larger ones could handle several transactions per minute during peak periods.

Migrating everyone at once would have introduced unnecessary risk.

Our strategy relied on three decisions:

  1. Migrate one client at a time. Each resort had its own feature flag. We coordinated with Adyen to decide which client to migrate next. They made the necessary changes on their side, and once they confirmed everything was ready, we enabled the flag in production.
  2. Monitor payment operations. I updated the payment code to log every operation and send an email alert whenever an error occurred.
  3. Be able to roll back. If something went wrong, we coordinated with Adyen to move the affected client back to the previous platform and disabled their feature flag.

We started with clients that had the lowest transaction volumes. This allowed us to test the new integration with real payments and uncover problems while keeping their impact limited.

And problems did come up. During the first migrations, we received numerous alerts that we had to investigate together with Adyen. Some issues required fixes on their side, and when they couldn’t be resolved immediately, we rolled back the affected client’s migration.

As we resolved issues and confirmed that each migration was stable, we moved on to higher-volume clients until the process was complete.

The Outcome

The migration wasn’t finished when I got the new API working. It was finished when every client could use it reliably, after rolling out the changes gradually and resolving the issues that came up along the way.

Working closely with Adyen, we completed the migration without interrupting payment processing for our largest clients. The experience reinforced something important for me: in critical systems, how you roll out a change can be just as important as how you implement it.

— EOF