No Abstractions: our API design principle

An API design philosophy called “no abstractions” argues that financial APIs should mirror underlying payment network concepts and terminology (like NACHA or FedACH fields) rather than hide them behind high-level, unified models. Supporters say this approach better serves domain experts, reduces leaky abstractions, and simplifies reasoning about edge cases, while critics question the value-add of intermediaries and worry about duplicated complexity when networks differ or evolve. The thread also branches into related concerns such as layering low- and high-level APIs, versioning when external specs change, and best practices for representing money values without floating-point errors.

Perceived value of a “no‑abstractions” payments API

  • Some see strong value in a provider that exposes underlying payment rails (ACH, card networks) without inventing new concepts.
  • Others argue that if the API mirrors underlying services too closely, it risks being “just a middleman” unless it clearly adds value (e.g., licensing, infra, unified access).
  • Several comments stress that avoiding direct integrations with networks like ACH, Visa/Mastercard, or international rails is already a major value-add, given their archaic tech (batch files, FTP, CSV workflows) and complex business relationships.

What “no abstractions” actually means

  • Interpreted as:
    • Use the networks’ own terminology and structures.
    • Model resources on real network messages/events.
    • Avoid “unifying” different schemes into a single generic object unless absolutely necessary.
  • Many point out this is still an abstraction choice, just “abstraction-light” or “fewer generalizations.”

Comparison to Stripe’s higher-level model

  • Stripe is praised for simplicity and polish but criticized for “leaky abstractions”:
    • Different behavior of SetupIntents by payment method/region.
    • Disputes, fees, authorization/capture windows differing per rail.
    • Connect transfers behaving differently across countries.
  • Takeaway: you must still understand underlying payment specifics; a uniform surface can mislead.

Low-level vs high-level APIs

  • Strong support for offering both:
    • A low-level, network-faithful API for experts.
    • A higher-level, convenience API for common use cases, possibly built on top.
  • Examples referenced: git “plumbing vs porcelain,” filesystems, graphics APIs, Kubernetes, .NET, etc.
  • Tradeoffs noted: larger surface area, potential state mismatches, but better ergonomics.

Domain language and DDD

  • Multiple comments connect this approach to Domain-Driven Design’s “ubiquitous language”: use the same terms domain experts already use.
  • For this product, the “domain” appears to be the payment networks themselves, which suits users who are payments specialists more than generalist app developers.

Money representation in APIs

  • Wide agreement: do not use floats for currency.
  • Suggested patterns:
    • Integers in “minor units” (cents, fils, etc.), or higher multipliers for more precision.
    • Fixed-point or decimal/bigdecimal types.
  • JSON numeric parsing pitfalls in JavaScript are discussed; some argue JSON numbers are abstract and can be parsed into precise types.

Skepticism and naming

  • Several commenters find “No Abstractions” a misleading or marketing-ish title; they prefer framings like “carefully scoped abstractions” or “minimize generalization.”
  • Concerns raised about tight coupling to external specs: if network specs evolve, APIs may require versioning and added maintenance complexity.