Case· ÁGORA Jiu-Jitsu Academy

Why checkout was freezing on iOS: an EVO integration diagnosis for ÁGORA Jiu-Jitsu

Technical diagnosis and integration architecture between app, website, and EVO for a jiu-jitsu academy in the US — from the root cause of an iOS checkout bug to the blueprint for a secure middleware connecting multiple front-ends to the EVO API.

ÁGORA Jiu-Jitsu Academy, a gym in the United States that uses EVO (a management software widely used by gyms) for enrollments and billing, came to us with a concrete problem: the online enrollment checkout was failing in different ways depending on the plan, and the client wanted to know whether the fix was adjusting what already existed or building something new — an app, a website, and a dedicated integration layer with EVO.

The symptom

On the Kids Plan, the payment button simply didn't show up at checkout on iPhone/Safari — with no error message at all. On the adult plan, on the same device, everything worked normally. The obvious hypothesis would be "an iOS payment bug," but that didn't explain why only one specific plan was failing.

The investigation

We ruled out hypotheses one by one, with real testing, not guesswork. The payment gateway and Safari itself were ruled out: the recurring adult plan worked fine on the same device. Plan configuration was also ruled out — comparing both plans directly through the EVO API, the age-range fields, payment method, and registration rules were identical.

The real cause showed up under direct reproduction: the payment button existed and was clickable, but the Kids Plan page didn't scroll all the way down on iOS — the button sat below the visible area, inaccessible through normal scrolling, and only appeared if you manually zoomed out. A classic Safari-on-iOS viewport bug (the 100vh behavior, where the address bar reduces the screen's usable height). The Kids page had one extra paragraph of text compared to the adult page, and that extra content pushed the button outside the scrollable area.

A finding more critical than the bug

During testing, we found something more serious than the missing button: filling in the data up through the payment step — without completing the purchase — automatically triggered three emails (contract, questionnaire, and login invite) before any payment confirmation. We checked via the API whether this EVO CRM behavior could be configured or turned off programmatically — it can't. It's an internal panel feature, opaque to any external integration. That turns the problem from a "configuration tweak" into a "structural platform limitation."

The recommended architecture

For a business that depends on conveying hospitality and trust through its digital experience, sending a contract before the decision to pay breaks that experience. Our technical recommendation was a dedicated middleware (BFF) as the sole authenticated client of the EVO API — no app, website, or checkout would talk to EVO directly. This middleware maintains its own state machine (draft → awaiting payment → paid → enrolled) and only triggers the prospect-to-member conversion in EVO after payment is confirmed — giving precise control over exactly when EVO's communication automations fire. The same layer also solves the family-checkout problem, treating "family" as a first-class concept instead of separate enrollments per dependent.

FITI or a custom middleware?

Before recommending we build something new, we assessed whether EVO's own white-label app (FITI) would solve the problems. The answer was no: the UI bugs (missing button, address validation) might not recur on a different interface, but the structural limitations — the family flow and premature communication triggers — come from EVO's backend/CRM, not the screen. Any interface built on the same API inherits the same restrictions. Our final recommendation was clear: use FITI as a short-term stopgap, and treat the custom middleware as the real path to resolving the structural findings.

This stage was scoped and delivered as a technical diagnosis and architecture — a document, with no changes made to the client's production environment. Implementing the middleware and the app is a future phase, not yet contracted.