Case study
Payments integration for a US fintech
Card-terminal payments in a React Native product for a US fintech customer: native bridges to BBPOS terminals on iOS and Android, PCI-compliant flows and a release pipeline that the customer team could rely on.
- Role
- Tech lead, iOS and React Native
- Platform
- iOS + Android (React Native with native modules)
- Stack
- React Native · Swift · Kotlin · BBPOS SDK · OAuth 2.0 / JWT · certificate pinning · Fastlane
- Period
- 2019 – 2021
Context
A US fintech needed its React Native product to take card payments through BBPOS terminals, with flows that satisfied PCI requirements and a customer team that expected predictable releases.
The terminal SDKs were native. The product was React Native. The two had to meet without compromising either.
My role
- Led the integration: designed the native bridge modules on iOS and Android, the secure transaction flow and the release pipeline.
- Worked directly with the US customer team on requirements, certification and rollout.
Constraints
- PCI compliance: card data never touches the JavaScript layer or application storage.
- Terminal connectivity and firmware behaviour differ per platform; the bridge had to hide that from the product code.
- Customer-facing timelines with a remote team across time zones.
Key decisions
Decision 1
Native bridge modules with a single typed contract
iOS and Android each got a native module wrapping the BBPOS SDK, exposing one typed interface to React Native. More native code to maintain, but sensitive data stays native and the product team codes against one API.
Decision 2
Idempotent transactions with explicit error recovery
Every transaction carries an idempotency key and a recoverable state machine, so a dropped connection mid-payment cannot double-charge or leave an unknown result. It adds states to design and test; it removes the worst class of payment bug.
Decision 3
Certificate pinning and encrypted payloads over OAuth 2.0 / JWT
Pinning makes certificate rotation an app release concern, which is operational overhead. For payment traffic the protection against interception was worth it.
What I built
- React Native payment flows backed by native Swift and Kotlin bridge modules to BBPOS terminals.
- OAuth 2.0 / JWT authentication, encrypted transaction payloads, certificate pinning.
- Idempotency and error recovery across terminal, app and backend.
- Fastlane CI/CD for both platforms with signed, reproducible builds for the customer team.
Validation
- Terminal test cards and sandbox environments for every transaction state, including dropped connections mid-payment.
- Automated unit tests for the bridge contract on both platforms; manual certification runs with the customer team.
Release and operation
- Fastlane pipelines for iOS and Android with signed builds delivered to the customer on a schedule.
- Release time cut by 20% once the pipeline replaced manual builds.
What changed, and what I'd do next
- Release time reduced by 20% through Fastlane CI/CD.measured
- PCI-compliant payment flows in production for the customer's React Native product.observed
- Card data never reaches the JavaScript layer or app storage.design goal
Measured: a number from logs, analytics or a release pipeline. Observed: seen in production without a formal measurement. Design goal: what the system is built to guarantee.
What I'd do next
- Automate certificate rotation handling so pinning updates do not require an emergency release.
- Publish the bridge contract as a versioned package so other products at the customer could adopt it.