Skip to content
View all case studies
Independent media & journalism
Independent media & journalism Recorder (Asociația Recorder) Ongoing partnership · ~2+ years July 2026

Recorder: native app engineering and donation platform for independent journalism

Ongoing engineering on native iOS + Android apps and an end-to-end donation platform for Romania's leading independent newsroom — 3k+ recurring subscribers, hundreds of thousands of transactions, and almost 40k Form 230 submissions.

Outcomes

  • Ongoing engineering on native iOS and Android apps serving 3k+ recurring subscribers
  • Payments service processing hundreds of thousands of transactions across four processors
  • Migrated thousands of recurring supporters from Braintree to Stripe with billing-date continuity and a full audit trail
  • Almost 40k Form 230 (3.5% tax-redirection) submissions automated end-to-end for ANAF
  • Five payment and donor sources unified into a single Salesforce CRM
  • Automated payment-health audits and duplicate-customer remediation

Stack

Swift / SwiftUIKotlin / Jetpack ComposeWordPress REST (PHP)Node.js / ExpressStripeBraintree (legacy)PostgreSQLSalesforceFirebaseRender
K+

recurring subscribers

K+

payment transactions

K

Form 230 submissions (almost)

payment processors

The client

Recorder is the leading independent investigative-journalism newsroom in Romania. Funded almost entirely by reader donations, it produces long-form video investigations that repeatedly shape the public debate — by every reasonable metric, one of the most consequential newsrooms in the country.

A platform like that doesn't get to crash on Sunday morning. The apps and the donation stack have to just work.

The challenge

When we joined, Recorder already had native iOS and Android apps in production — but they needed a steady engineering partner to maintain them, ship major features, and keep both platforms in sync for 3k+ recurring subscribers. Underneath, the money was the harder problem: a payments stack handling hundreds of thousands of transactions across four processors, with Braintree being wound down. Donor data was fragmented across Braintree, Stripe, PayPal, Patreon and Benevity, with no single source of truth for retention or reporting. And Form 230 — Romania's 3.5% income-tax redirection to NGOs — had already produced almost 40k submissions through a manual, PII-heavy paperwork process feeding batch PDFs to the tax authority (ANAF).

The apps

01 · Read

Home & investigations

A native feed of investigations, daily news and videostories — instant loads, categories and search on iOS and Android.

02 · Watch & listen

Article, video & audio

Full investigations with embedded video and a chaptered audio player. Playback survives navigation — a mini player stays pinned while readers keep browsing.

03 · Support

Donate in two taps

One-off or monthly donations through Stripe PaymentSheet with Apple Pay and Google Pay — no card typing required.

04 · Manage

History & subscription

Supporters review every past donation across Apple Pay, Google Pay, Link and card, then update or cancel a recurring gift in-app — backed by the unified payments service.

05 · Give more

Form 230, rebuilt natively

Romanians can redirect 3.5% of their income tax to a non-profit. Most NGOs collect it on paper. We shipped the whole ANAF flow in-app — five steps, every county, on-screen signature — now handling almost 40k submissions.

Home & investigations

native app

Article, video & audio

native app

Donate in two taps

native app

History & subscription

native app

Form 230, rebuilt natively

native app

The platform

01 · Native

Two native apps

Swift + SwiftUI on iOS and Kotlin + Jetpack Compose on Android — maintained with feature parity on a shared mobile-api/v1 contract.

02 · API

A REST API on WordPress

A mobile-api/v1 mu-plugin exposes auth, content, donations and profiles on top of the editorial workflow the newsroom already lives in.

03 · Payments

A payments service on Render

A Node/Express service fronts Stripe, Braintree, PayPal and Patreon — hundreds of thousands of transactions, Form 230 contracts in PostgreSQL, and automated health audits.

04 · CRM

One donor view in Salesforce

Apex importers consolidate every payment source plus Form 230 and consent into a single donor record, with segmented retention exports.

05 · Compliance

Form 230, automated

A public submission form plus a batch PDF generator — almost 40k 3.5% tax-redirection forms processed for ANAF, with CNP stripped before CRM import.

06 · Ops

Payment-health guardrails

Automated Stripe audits and duplicate-customer remediation keep the recurring base clean and the reporting honest.

A REST API on top of WordPress

The Recorder editorial team lives in WordPress. Asking them to migrate to a headless CMS just so the apps could have a clean API would tax the people who actually produce the journalism every day.

Instead, we shipped a WordPress mu-plugin that exposes a clean mobile-api/v1 namespace — authentication, articles, dashboard, FAQ, donations, profile and a GDPR consent log. Firebase verifies the ID token; the server issues an app JWT; every authenticated request additionally carries an x-recorder-auth header. The apps consume the same contract, so a feature shipped on one platform lands on the other within days.

Braintree → Stripe

The most stressful part of the whole engagement. Payment-method tokens don't convert between processors, so a lift-and-shift was off the table. We built a transactional migration that recreates each subscription in Stripe first and only cancels the Braintree side on success — preserving billing-cycle anchors and leaving an auditable trail. A WordPress self-service card re-collection flow covered the subset that needed a fresh payment method.

Braintreelegacy / sunset
Stripeprimary
1Export

Braintree subscriptions → CSV

2Recreate

Idempotent Stripe import

3Cancel on success

Braintree cancelled only if Stripe ok

4Audit

Every success & failure logged

Thousands

recurring supporters migrated

4

stage pipeline · billing-date continuity

Transactional Braintree-to-Stripe migration: export, idempotent recreate, cancel-on-success, and full audit — thousands of recurring supporters migrated with billing-date continuity.

Result: thousands of subscribers moved between processors with billing-date continuity, a transactional import-then-cancel pipeline, and a logged outcome for every subscription — on top of a payments layer already processing hundreds of thousands of transactions.

How it unfolded

  1. 2024 · Q2 · 01 / 07

    Partnership begins

    Joined the existing SwiftUI and Compose apps — taking over maintenance, releases and platform work on Recorder's WordPress stack.

  2. 2024 · Q4 · 02 / 07

    Migration design

    The migration toolkit maps Braintree customers to Stripe with a transactional import-then-cancel strategy.

  3. 2025 · Q1 · 03 / 07

    Payments service live

    The Node/Express payments service deploys on Render, unifying Stripe, Braintree, PayPal and Patreon.

  4. 2025 · Q2 · 04 / 07

    Salesforce consolidation

    Apex importers bring every payment source, Form 230 and consent into a single donor view.

  5. 2025 · Q4 · 05 / 07

    Migration hardening

    Duplicate-customer remediation, retention campaigns and Romanian invoice localization across the Stripe base.

  6. 2026 · Q1 · 06 / 07

    Form 230 automation

    An ANAF batch-PDF generator automates the 3.5% tax-redirection paperwork — almost 40k Form 230 submissions and counting.

  7. 2026 · now · 07 / 07

    Continuous product work

    Ongoing app releases, Stripe checkout improvements and automated payment-health audits.

Architecture

Two native clients (iOS SwiftUI, Android Compose) talk to a WordPress REST backend (mobile-api/v1) for content, auth and profile, authenticating via Firebase ID token → app JWT with a GDPR consent log. Payments run through a WordPress Stripe plugin plus a standalone Node/Express service on Render, which integrates Stripe, Braintree, PayPal and Patreon and stores Form 230 contracts in PostgreSQL. A Salesforce CRM consumes that service via daily Apex importers, consolidating every source into one donor view and exporting segmented lists for retention. Batch work — the Braintree→Stripe migration, invoice localization and ANAF PDF generation — runs as offline ops scripts.

Force-directed architecture graph of the Recorder mobile and donation platform.

Decisions that mattered

  • Braintree→Stripe via recreate-then-cancel (transactional), not lift-and-shift — payment-method tokens don't convert, so recreating subscriptions preserved billing anchors and gave an auditable trail, at the cost of a self-service re-collection flow for some donors.
  • WordPress as the mobile content/auth backend — reuse the existing editorial workflow, at the cost of shaping REST and auth as mu-plugins and keeping payments in a separate service.
  • A dedicated payments service on Render fronting every provider — keeps PCI-adjacent, multi-provider logic and the CRM integration out of WordPress, at the cost of another deployable.
  • Strip CNP before CRM import — minimize PII in Salesforce for GDPR, at the cost of keeping ANAF reconciliation in the dedicated Form 230 pipeline.
  • A single dynamic Stripe product with per-amount prices — donation amounts vary continuously, so this avoids a brittle plan lookup table, at the cost of many Price objects.

Outcomes

  • Two native apps maintained and extended on iOS and Android, serving 3k+ recurring subscribers
  • Hundreds of thousands of payment transactions processed across four processors via a dedicated payments service
  • Complete Braintree → Stripe migration with billing-date continuity and auditable transactional imports
  • Almost 40k Form 230 submissions automated end to end — public intake plus ANAF batch PDFs
  • Five payment and donor sources unified into a single Salesforce CRM with automated retention segmentation
  • Operational guardrails: automated Stripe health checks and duplicate-customer remediation

Real journalism deserves real engineering. We're proud this one is in our portfolio.