Stripe: Always Forward
A closer look at Stripe’s new Forward API reveals more about the company’s current vulnerabilities than a bold new vision of the future.
Stripe has gone multiprocessor:
Merchants can “use Stripe within an open ecosystem of third-party providers,” Stripe’s Chief Product Officer Will Gaybrick shared in a blog post recapping many of the product announcements shared at Stripe Sessions, the company’s annual developer conference last Wednesday. According to Gaybrick’s keynote address at the event, Stripe is “extending [its] modularity to the very core of Stripe: payments processing.” Going “multiprocessor” is a big strategic shift for Stripe, which has historically made its suite of tightly integrated “financial infrastructure” an all-or-nothing proposition. “It’s a big deal,” Gaybrick would go on to say during his remarks. But as I was looking through Stripe’s documentation, I was left wondering if Stripe’s embrace of competitive payment processors says more about its current vulnerabilities than a bold new vision of its future.
How Stripe’s Forward API Works
At the core of Stripe’s new multiprocessor strategy is its Vault and Forward API, which allows merchants “to tokenize and store card details in Stripe’s PCI-compliant vault and route that data to supported processors or endpoints.” Most payment service providers (PSPs) offer some sort of vault/tokenization service. Indeed, as Simon Taylor points out in his Fintech Brainfood piece, The Token Layer Cake, Stripe popularized the modern payment tokenization technique of client-side payment forms posting sensitive card information directly to a PCI-compliant third-party processor:
This generation of digital payment tokenization started in the early 2010s, coinciding with the emergence of Stripe. At the time, digital payments in the US were in its infancy. It was becoming clear that there were benefits to merchants to retain card-on-file information, but this meant they needed to store it securely. However, the secure storage of massive amounts of sensitive payments was a viable option mostly for enterprise merchants who were willing to navigate the costly and lengthy process of achieving PCI compliance.
Stripe offered an elegant solution. Merchants could store cards with PCI-compliant Stripe and receive a token in return. Since merchants were interacting with just tokens, they not only didn’t have to touch sensitive data, but it also meant their time to market decreased significantly. To this day, this form of PSP Tokenization remains commonplace.
But Stripe’s payment forwarding capabilities are less well known and worth taking a closer look at given they are the basis of “a foundational update on how [Stripe is] thinking about the ecosystem in which we operate,” according to Gaybrick.
Stripe has offered some type of forwarding capabilities since at least 2015 to support the “social commerce” boom from nearly a decade ago. That use case saw apps like Pinterest1, Facebook, and Twitter relying on Stripe and Braintree to securely accept user payment card details from their apps, store those details compliantly, and forward the subsequent transaction requests on to multiple different merchants and/or payment providers.
Here’s how Stripe’s Vault and Forward API works:
Vault:
Merchant collects card details via Payment Elements, a set of prebuilt user interface (UI) components for building web and mobile checkout flows.
Stripe creates and returns a PaymentMethod object, which is a token representing the sensitive card information. The merchant is free to store this alphanumeric string in their database without fear of violating the Payment Card Industry Data Security Standard (PCI DSS for short).
Forward:
Merchant creates a ForwardingRequest using the Vault and Forward API, which tells Stripe the PaymentMethod to reference, which data Stripe should send, and the third-party processor endpoint to hit.
Stripe forwards the request on to the other PSP, but as it does, Stripe replaces certain redacted fields like the card number and CVC with the raw, PCI-sensitive payment details. Said another way, Stripe de-tokenizes the data as it passes it along to another PCI-compliant entity, in this case another processor.
Stripe receives a response from the other PSP, redacts PCI-sensitive data, and stores the redacted response in the body of the ForwardingRequest object, which is returned to merchant as a response to the request they made in step #3. The timeout period for this response is less than a minute.
Note: I’ve used cards in this example, which have PCI-sensitive data, but presumably the Forward API could be used for other types of payment methods, such as bank accounts, and Stripe would redact the sensitive data, which are not under PCI scope.
The magic of the Forward API is in step #3, where Stripe pulls an Indiana Jones and replaces tokenized data with raw payment details as it relays the request to the third-party PSP. Stripe has effectively built a payments-specific reverse proxy. According to Cloudflare, a reverse proxy (vs. a forward proxy) “sits in front of one or more web servers, intercepting requests from clients…to ensure that no client ever communicates directly with that origin server.”
Stripe has identified a real problem here—for itself and its customers. Enterprise customers often work with multiple payment providers and have contracts requiring a minimum amount of payments volume go through certain PSP, so even if an enterprise customer wanted to go all in on using Stripe, they often can’t. Here’s how Stripe President and Co-founder, John Collison explained the situation in an interview with Bloomberg: “as we’ve gotten into these larger and larger customers, they have more constraints, you’re dealing with different parts of the organization, and so this makes it easy to adopt the best parts of Stripe.”
But the current version of the Forward API is limited.
The Limitations of Stripe’s Forward API
My main concern is that payments processed via the Forward API lack some of the polish for which Stripe’s products are famous. For example, Stripe specifically introduced its PaymentMethod and PaymentIntents APIs a few years ago as a replacements for its Sources and Charges APIs, respectively, in and effort to help merchants more easily track complex payment lifecycles (i.e., payment authorization, user-initiated payments). Here’s how Stripe engineer Michelle Bu explained the changes in a blog post explaining how the Stripe API has evolved over the past decade:
“Unlike a Source, there is no state or data specific to the particular transaction type captured on a PaymentMethod object—you can think of it as an object that specifies how to process a payment request.
With Charges and Sources (Stripe’s previous , a “best practice” payments integration for cards, iDEAL, and ACH debit required managing two webhook handlers (one that is time-sensitive and in the critical path to collecting money correctly), dealing with three different times a Charge could succeed, handling two paths to failure, and dealing with two stateful objects.
With PaymentIntents and PaymentMethods, the integration is the same across all payment method types.
The PaymentIntent instructs what to do next when it’s in the requires_action state. Actions are standardized and predictable per payment method; for example, the 3D Secure authentication flow is managed via a set of actions.”
The Forward API feels like a step backwards. From Stripe’s developer documentation:
“The Vault and Forward API doesn’t confirm or capture PaymentIntents. As a result, you might unintentionally use them to capture a payment on Stripe that was already captured on another processor.”
Said another way, Stripe’s intentionally stateful PaymentIntents objects are missing a few states when used with the Forward API. To Stripe’s credit they do make an attempt to address some of these gaps. It supports first-party and third-party idempotency keys to help prevent duplicate charges and offers a standalone 3D Secure authentication flow specifically for merchants that are using multiple processors or initiating payments via travel aggregators like Expedia. It’s difficult to examine how graceful the latter offering is because the feature is still in beta and merchants must contact Stripe via email to get access.
According to Gaybrick, Billing and Radar, Stripe’s subscription billing and fraud tools, respectively, “will work seamlessly with other PSPs by the end of the year.” But those services—like the the Optimized Checkout Suite, which is compatible with the Vault and Forward API today—are mostly focused on the experience before and during a transaction.
The next example of Stripe’s multiprocessor support lacking the polish of Stripe’s more tightly integrated suite of tools comes after the transaction occurs. Ops and risk teams cannot manage refunds and disputes entirely from Stripe in a multiprocessor setup like they can using Stripe Payments. From Stripe’s docs again:
“If you’re using the Vault and the Forward API to make an authorization request, you must handle any post-transaction actions, such as refunds or disputes, directly with the third-party processor.”
A few more caveats about the Forward API from Stripe’s docs:
“When you use the Vault and Forward API to forward card details to a third-party processor, Stripe can’t guarantee that the processor will provide any particular response to your forwarded API requests. If the third-party processor is unresponsive, you must reach out directly to that processor to resolve the issue.”
“The Vault and Forward API treats any response from the destination endpoint as a success and returns a 200, along with the destination endpoint’s response code in the response.body. For example, when the destination endpoint returns a status code of 400 to Stripe, the Vault and Forward API responds with a status code of 200. The response.body includes the destination endpoint’s 400 response and error message. Separately test the API request that you send to your destination endpoint to make sure that you don’t have any errors.”
Now, I understand Stripe can’t control the availability of other PSPs or manage things like refunds and disputes for transactions processed through other PSPs without support from those PSPs (more on that later). But there are more elegant and flexible technical solutions Stripe could have used to solve this problem. For example, data tokenization companies Very Good Security (VGS) and Basis Theory, offer services that function as forward proxies (vs. Stripe’s reverse proxy), which allow merchants to keep their existing integrations into third-party PSPs and simply replace/redact sensitive data from API requests passing through the proxy based on pre-configured rules. This setup requires more work for VGS and Basis Theory but requires less work for merchants. And while, as of today, the Forward API can send data to only six supported third-party processors, the forward proxy approach allows merchants to effectively connect to any third-party PSP “as long as your partner can accept cards through an API endpoint,” according to Basis Theory’s developer documentation2.
VGS and Basis Theory also support more data transfer protocols than Stripe at the moment. In addition to HTTP (which Stripe supports), they both support SFTP, and VGS supports ISO 8583, an international standard for payments initiated with a payment card (credit or debit card). I wouldn’t be surprised if Stripe launches a competitive service soon or acquires a player in the space. I hope to write more on this later.
I can’t blame Stripe for all of the issues I mentioned above; they’re simply limitations of Stripe’s current approach. But that’s kind of my point. Stripe chose to launch a strategically important feature with clear technical limitations when more elegant solutions exist. This choice does not seem inline with the level of technical rigor and craftsmanship Stripe’s founders espouse. Here’s Stripe co-founder and CEO, Patrick Collison from an podcast interview a few weeks ago:
“If Stripe is a monstrously successful business, but what we make isn’t beautiful, and Stripe doesn’t embody a culture of incredibly exacting craftsmanship, I’ll be much less happy.”
I don’t think Stripe should be happy with this release. Gaybrick admitted that Stripe is “just at the starting blocks” of its multiprocessor journey but the Vault and Forward API on its own is not capable of fulfilling the aspiration Gaybrick shared at Sessions for “all of Stripe’s products will gracefully inter-operate with third-party processors.” And while, yes, things may change and improve over time, I don’t think it’s unfair to be critical of the current state of the the Vault and Forward API. This isn’t a beta product. During the keynote Gaybrick made a point of telling the audience that “Mindbody, Blackbaud are using Stripe Forwarding today,” and that the new API is available to others “right now.” Regardless, Stripe seems to be betting a lot of their strategic shift on a capability for which merchants must contact Stripe support in order to gain access.
Now, That’s a NICE Integration
But there is another way. Gaybrick shared a more exciting version of Stripe’s multiprocessor implementation during Stripe Sessions:
“I'm excited to announce that stripe has partnered with the Korean PSP NICEPay to get you localized coverage faster. So, with a mere toggle in the dashboard you can give your customers a fully-localized experience.”
Stripe’s Head of Product for Payment APIs, Money Movement & Storage, Sophie Sakellariadis, shared a few more details in a LinkedIn post last week:
“One of the first steps we are taking to make Stripe interoperable with the broader payments ecosystem is partnering with the best PSPs worldwide to supercharge our global reach. Thanks to our partnership with top Korean PSP NICE Payments, merchants in the US can now get access to any local Korean card brand (there are more than 20!) as well as top wallets KakaoPay, NaverPay, and SamsungPay -- all with the click of a button.
Beta users saw auth rates in Korea improve to >98% (!). We have similar partnerships launching in Nigeria and Indonesia later this year”
Stripe’s documentation explaining how to set up future payments with Korean cards and payment methods mentions creating “mandates” for customers and SetupIntent objects, which indicates that NICE is much more tightly integrated with Stripe than simply using the Forward API. Merchants can use more of the convenience features of the Stripe PaymentIntents API under this setup. The main thing I couldn’t determine is how post-transaction activities such as issuing refunds and challenging disputes occur for NICEPay processed transactions.
At first glance, this approach feels like a more buttoned up approach to Stripe working with other PSPs. But if I had to guess, I’d assume this type of integration will be limited to locales where Stripe can establish a friendly relationship with local PSPs. For example, NICE Holdings, which operates NICEPay has an Indonesian arm, and Paystack, a Nigerian PSP, was acquired by Stripe in 2020. I also imagine PSPs with operations more or less limited to their own countries will be more eager to cooperate with Stripe on this type of integration, while more global PSPs like Adyen would not.
This Is Not an Exit
During Stripe Sessions, Gaybrick mentioned that “over the past few years we’ve quietly made several of Stripe services work better with other PSPs.” One could claim this is a strategic masterstroke by Stripe as it attempts to leave the world of payments behind, focusing instead on higher-value software products. Or maybe Stripe was forced to implement a basic form of payment orchestration to attract and retain important enterprise customers. I don’t know for sure, but if I had to guess, the reason these integrations were completed quietly is because Stripe begrudgingly did them. In fact, the Vault and Forward API’s list of supported endpoints reads like a list of Stripe’s main competition for enterprise-grade customers:
Adyen
Braintree
Checkout
GMO Payment Gateway (a Japanese PSP)
PaymentsOS (PayU)
Worldpay
Adyen, in particular, has been a formidable competitor to Stripe over the past five years, signing deals with long-time Stripe customers Instacart, Postmates, Shopify, and others. Those deals appear to be paying off. Adyen recently shared that North America was its “fastest-growing region in the second half of 2023.” I imagine this Stripe/Adyen competition will only intensify over the next five years. Which is why, Scott Wessman, formerly of Visa and Global Payments, wonders if Stripe’s claim of interoperability is mainly useful for “counter-positioning with Adyen.”
Like Stripe, Adyen is also an all-or-nothing PSP but they take things even further. They’ve never acquired another company—everything is built in house—and they also operate as a bank in many regions. Simon Taylor of Fintech Brainfood claims that “Adyen is modular too if you push,” but you can imagine Stripe’s new pitch to enterprise merchants being lured away by Adyen: “merchants can now use the Vault and Forward API to route contractually obligated transactions to Adyen while keeping everything else running through Stripe.” I believe that this gambit is at the core of Stripe’s strategy: if it’s so easy to work with other PSPs merchants won’t want to leave. As I mentioned above, I think Stripe’s current PSP interoperability needs a lot of work, but it’s an interesting idea, and one I’ve seen before.
In 2010, Braintree started the Credit Card Data Portability initiative, which was “an opt-in community of payment providers that agree to allow a merchant to port credit card and other associated information if the merchant ever decides to move to another provider.” Here’s how Braintree founder Bryan Johnson described the initiative at the time (before he began his quest for immortality):
“We initiated credit card data portability because merchants were in a serious bind. All their stored credit card data was being held hostage, and in the majority of the situations, they were blind-sided. We wanted to level the playing field and allow merchants to choose service providers based on merit, not restrictive business practices.”
The idea was that if Braintree, an upstart compared to large acquirer-processors like First Data, could convince merchants that they wouldn’t be locked into using Braintree forever, those merchants would actually be more willing to give Braintree a shot. It also created pressure on processors like First Data to join the portability initiative. Today, card data portability is more or less a standard across the industry which helped upstarts like Braintree and Stripe grow into what they are today.
We’ll have to wait to see how this all plays out, but, for now, Stripe’s new Forwards API hasn’t moved the payments industry forward.
As a follow-up to this piece, I interviewed Stripe's Head of Product for Payment APIs, the co-founders of Very Good Security, and Basis Theory's CEO/co-founder to learn more about forward vs. reverse proxies. Check it out here:
This batch was powered by:
I worked on Pinterest’s Buyable Pins program from 2016-2018
I got this part slightly wrong. Basis Theory offers a reverse proxy but they use an interesting serverless compute runtime called Reactors that allows more dynamic and flexible routing/modification of request payloads. This approach overcomes some of the limitations of a standard reverse proxy like Stripe offers. You can read more here: A Follow-Up on Stripe: Always Forward
Hey Jareau!
I believe, based off the docs I’ve read, that there’s an inaccuracy in the article because of an inaccuracy in the bt docs.
Basis Theory uses a reverse proxy, not a forward proxy. Proxies are pretty complex but a reverse proxy can forward a http request but it is a completely different protocol from a forward proxy.
A forward proxy is more like a vpn connection than a http api that you hit so it is more flexible with legacy software or services where it’s not possible to control the cname that the server is sending the request to.
The implementation stripe and bt use are basically identical but bt does allow sending the data to any host versus maintaining a fixed set so it is more flexible for the purposes of sending data to many hosts.
I do get the confusion since bt documents theirs as a forward proxy. I think it would be more accurate for them to say it’s a forwarding reverse proxy unless I’m missing something in the docs.
I read this recently and after I’d already written a deep dive into their product stack and new releases but this was great validation for my theory 👏🏽
https://jasshah.substack.com/p/fintech-rr-stripe-growth-product