Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Payments 101 for a Developer (github.com/juspay)
284 points by manojr13 on April 26, 2023 | hide | past | favorite | 72 comments


Good write up, but it's rather rudimentary.

For people interested in FinTech/Payments, here's a great compendium and resources for the field: https://fintechgtm.substack.com/p/us-fintech-and-payments-cr...

I would also recommend the three books highlighted:

* Field Guide to Global Payments

* Anatomy of a Swipe

* Payment Systems in the US


a topic I had no idea I was casually interested in & wanted to read books about despite the fact that I have no plans to work in this sector, my favorite (not sarcastic at all)


Great resources. Thanks.


Good, but missing some basic concepts:

- void, a refund on authorization - account verification, used to store a card, without authorization - card on file, a stored card - BIN, bank identification number - POS, a payment in store, physical terminal - card not present, payment from distance (ecom, moto) - moto, mail order, telephone order

....and alot more


Thanks. Too many details make the developers run away from the 101 class ;-)

But will definitely cover tm in 102


I dig this as a quick intro. I've worked directly with payments at several orgs now, and yet didn't really grok payments until I read Payments Systems in the U.S. - Third Edition: A Guide for the Payments Professional. Afterward, I was actually able to understand how the pieces fit together. It is concise, and highly recommended to anyone working with payment systems.

https://amzn.to/447BLVI


How generic is that? Is it relevant to someone who deals mostly with stuff within EU?


Nice share. It gives me an idea...

It would be cool if there was a unified payments API interface that payment providers (paypal, cashapp, stripe, ccbill, payment cloud, segpay, epoch, whatever) would agree to use. Hopefully, users would drive adoption, and feel free to swap providers. Also, platform agnostic (apple ios, android, web, etc). I dunno, just thinking out loud.


Building such a thing would be extremely difficult. When you start getting to the local level with banks, networks, and governments, there are all kinds of different things you have to deal with.

You have all the different forms of payment that exist (credit card, banks, prepaid, ewallets, and even cash (reference number flows where the user takes a QR code into a store or kiosk, scans it, then pays in cash)). Then the details within those flows vary greatly by country/region. Credit cards have 3DS flows, plus CIT/MIT information. Banks want to do all kinds of 2FA, regularly they want the user to be redirected to their website to complete it. And on mobile, you could redirect to a bank or ewallet's app to confirm the payment. Then beyond that, you have various risk signals that different countries want to fight fraud. Some are lax, some are extremely invasive.

Once a payment has been initiated, knowing that it is Completed/Accepted can be really complicated. Credit cards, once you have an auth, a capture is all but guaranteed, but you still have chargebacks to deal with. ACH has a fuzzy window about when it can be reversed. Various other forms of payment have anti-fraud mechanisms that allow payments to be reversed with various windows about when that can happen.

You will always have various governments come in and force new rules that don't play nicely with whatever uniform API you create. For example, the Royal Bank of India forcing all storage of credit card numbers to happen within their country's boundries (data localization). This all of a sudden may force a flow that was using credit cards just fine to now require you to use tokens in their place.

It feels like the payments space should be easier than it is, but various regulations and security/privacy measures that change by region regularly will mess with such an API.

Edit: to add some more fun examples: it's also good to understand that some payment systems in the world are still very manual. There are people with spreadsheets that generate reports. So as a processor, you can get a response from a bank where 2 numbers are transposed in a report. Or you get reports where you aren't given a transaction_id, just a date and amount and you have to figure it out (see the UK's BACS DDICA reports).


My friend, do you not realize you make my case? :D


Yeah, I think you're right.

I think you could build such an API, but there will be so many gotchyas with each special form of payment, it will be really difficult to use well. Knowing which fields to populate for a given form of payments starts getting more complicated, and dealing with the odd side-effects of each also start to multiply.

I think the processors out there (Adyen, Stripe, Worldpay, dLocal and others) do as well as they can given the ecosystem.



I'd guess Stripe and PayPal are quite happy with the current vendor lock-in


Yes but it is extremely risky for the business if Stripe or Paypal is its only processor. If for whatever reason your account is flagged by the processor, you wouldn't be able to accept payments


https://www.w3.org/TR/payment-request/

On paper it looks kinda nice. I've seen some discussion about implementing it from the payment method perspective.

Problem is that Google would be massively privileged, as browser orchestrates the process and payment methods aren't necessarily looking for the fair compromise either.


What if network tokenization becomes more mainstream? If that happens browsers would't be able to vault users' card details


I'm not sure if I fully understand your point. In this solution browser is not expected to vault card. It should just be intermediary between payment methods and payment gateways (of course saving card inside browser can be one of the payment methods).

Also depends what do you mean by more mainstream. Google Pay and Apple Pay both support tokenization. So do many other payment methods - I would say that it's mainstream. Next step would be refusing plain cards at all.

Google Pay is everything that Google needs for Chrome to have full solution.


There is something like this omnipay its a framework that lets any payment processor (gateway ) integrate so you can switch processors.

So a project would use omnipay and then select what processors they want their clients to be able to use. Clients bring their own API keys or OAuth.

I believe it's in PHP and Ruby.


Chargebee support quite a few payment processors too.

Unfortunately none of them worked for me, because PayPal (the only one usable in my country) has been unusable. One of the big reasons is because the only bank that supports them in my country can't create a usable online profile.

But even with PayPal itself, they think I haven't confirmed my email address when I have. Although I stopped getting those emails, so perhaps the situation resolved itself.

I'm going with Lemon Squeezy now.

The lesson I have learnt in this ordeal is that you need to confirm, as much as possible, that the payment provider is usable for you. Are you approved? Are payouts accepted in your country? Tick every single box you can before you write a single line of code for a specific payment provider.


Yes. The devil is in the details. Small businesses should better opt for a merchant on record who can manage all such complexity.


That would be a payments switch like https://hyperswitch.io/


There is for the platform.

https://developer.mozilla.org/en-US/docs/Web/API/Payment_Req...

It works on Safari/iOS/MacOS and Chrome/Android (but weirdly enough, Firefox doesn’t support it).


Bolt has an open source Go package that tries to do that: https://github.com/BoltApp/sleet


That sounds like a protocol. It would be nice. Someone got downvoted for mentioning Bitcoin, but blockchains are protocols capable of transferring value.


Honestly this was their initial promise when the community was super niche, it was two things:

- Normalized money transfers independent of the regular financial system

- Reducing currency interchange fees

Bitcoin was suppose to be this electronic ledger store for valuation to facilitate these things, as I recall.

Really got away from itself


Stellar could be this open-network/protocol for transferring value. I don't see a lot of developers talking about it, but it's really really a good tool for this use case and i think it will be :)


kind of like spreedly https://www.spreedly.com/

API + unified card tokenization


I had this idea once for a Wordpress plugin for Woocommerce websites. A plugin that would abstract all providers APIs to Woocommerce. Paid versions of the plugin would allow the merchant to work with several providers in parallel in order to reduce transaction fees (increasing the operational margin then).


It exists in India; it is built and works pretty well. Its called ‘UPI’ Unified Payments Interface


Fednow has the potential to create a similar UPI like impact on US


There is, it's called the Bitcoin Lightning Network.


Not bad, but this is very high level. In Payments, the devil is in the details. Things like tokenization, security authorization, fraud detection, various kinds of payments rails, recurring payments, cross border payments, etc often matter.


Absolutely. Just trying to tame such devils using open source and community as the tools


I was under the assumption that Stripe, PayPal, Square, etc are not payment processors but either payment facilitators or payment gateways (depending on the platform) in that they don't actual process the payments but rather provide a convenient PCI-compliant way of moving the transactions to the actual payment processor (Something like NCR, GlobalPay, Elvaon, etc). In Stripe's case in particular I thought they were a payment facilitator and as a payment facilitator they board you as a sub-merchant which makes the process of getting an MID easier. Is that right or does Stripe actually process payments?


Stripe is a Payment Facilitator, and they pioneered the modern PayFac model. That’s one of the reasons that the word Stripe appears on your credit card statement when you pay someone that is using Stripe. Additionally it means they front the risk of accepting payments on your behalf. They are also a payment processor. Those aren’t exclusive operating models, at least in the US.

https://stripe.com/payment-facilitation https://stripe.com/guides/payfacs


Both Stripe and PayPal are payments processors.


A better description would be "Card Payments 101 for a Developer". There is more to payments than just cards.


An even better one might be "Card Payments 101" as I don't think anything here is specific to software or developers, even at a high level.


Agree. But covered cards because it is the most complex form of payment with a lot of intermediaries. So understanding the longest path, will help to prepare as developer for payments industry


Disagree there. I think that international wires are probably the most complicated.


This is a good overview but its high level, are there any other resources to understand payment flows for individual payment methods better?


I've linked one here: https://news.ycombinator.com/item?id=35717604 It is VERY comprehensive.


> a Non-PCI compliant merchant's website cannot directly accept the card data from the user (on the frontend user interface)

This needs rewording, I am not sure if they're trying to make a subtler point but on the surface this is not correct - you can of course accept card data from the user in your frontend and then send it to e.g. a Stripe-like PCI compliant service directly without it ever touching your servers.

The point is it must not touch your servers. This might be the subtlety in the wording here - the differentiation of frontend and backend and user interface. As long as 'the frontend' runs only in the user's browser, it is completely fine.


The key words are “directly accept”. If you use a properly implemented hosted payment page, your systems don’t touch the card data.


There is a distinction between the frontend user interface running locally in the user's browser and the backend code running on your server.

It's possible to 'accept' user input of card details in a frontend that you build and host, so long as you do not submit that data to a server you control -- you instead submit it directly from your frontend to a third party service that is PCI compliant.


That distinction doesn’t matter, and you shouldn’t do that, unless you want that portion of your code to be considered in scope for an auditor. If your code touches card data, it’s in scope. No matter where it runs.

Edit: a brief explainer of what is considered in scope. https://secureframe.com/blog/pci-scope


So if your frontend is using SSR, you can't accept card data?


As long as the frontend sends the card details only directly back to the PCI compliant service's servers, you are fine. This can still be done if your frontend is server rendered -- the data isn't there yet when you server render the form.

What I believe you can't do is have your own frontend send the data in the form to your own backend, then forward on to the other service from there. Once the plaintext card details touch your servers you have to be PCI compliant, even if you aren't storing them.

If you absolutely can't do the former on your frontend, eg because you don't want to use JS or something similar, then you can use services like Stripe checkout where they host the frontend on a URL you redirect to from your app, etc.


In that case I think it is just slightly more convenient to render a PCI compliant entity's frontend as an iframe inside your application and have it send the details directly to the processor's server, perhaps saves one additional hop


Could be, I guess the downside of this is that you don't get full control of the UI which is a problem for some products. Depends on the tradeoffs I guess.

In general I am a fan of just using things like Stripe Checkout though - it's not just about compliance but also just the complexity of getting the frontend part right with the myriad different payment flows, errors, and other subtle details that exist.

But my original comment was more just clearing up confusion that you can absolutely do the frontend UI customly if you want to - there's no issue with this and PCI compliance, that only kicks in once the data goes to your server.


Yes that makes sense.

Have you considered using Stripe Elements? It has loads of customization options that you can configure using an appearance API


I have tried it, though years ago. It's good but quite low level - it gives you some nice components which is a bit of work saved but does still leave you with all of the (really complex) flows to implement.


This always feels weird to me. Who is auditing my site to make sure I don’t send the details to my server, or some nefarious server, along with the Stripe request? The user would only see the actions of the Stripe success/failure and never know a copy was made elsewhere.


If your frontend handles card data, it is in scope. Among other things, you will have to prove that you are not sending card data to your backend servers in any way (logs, etc.).


Prove to who? If I sign up for Stripe, all I have to do is complete a questionnaire annually. I could easily lie or make my frontend compliant during that time period and nefarious afterwards.

It seems like a veil of security versus any actual security. My guess is that it's really just meant to assign liability to the merchant when nefarious stuff happens and there's plenty of ways a fraudster could shield themselves from that as well.

At the end of the day, as a customer visiting some random merchant website showing a "Powered by Stripe" logo does not actually make me feel like my CC data is secure. Anytime I enter info into a UI/DOM that is not directly under the stripe.com/paypal.com/etc (full page load), I don't feel my info is necessarily safe; but that's what they want me to believe. It's totally possible to just put a "powered by Stripe" UI element on a page without having any relationship with Stripe. And, the false security of that UI element tricks you into putting your info into some random site. I just don't see how that's secure at all to train users that anytime you see that UI element you can safely input your payment information regardless of the site you are on.


Stripe must diligently ensure their merchants are not improperly handling card data. Failing to do this could cost them their PCI status, so they will definitely shut down your account if they find you’re not properly using their services, meaning you’ll lose any funds in it along with your ability to use their services. Any other PayFac worth their salt will also begin to refuse your account if you continue bad bahavior. If you read Stripe’s docs, you’ll see specific instructions on how to use their elements (don’t host them locally, as an example), and I assume they have a variety of automated and manual methods to flag improper use.

Stripe aside, if you claim to not be in scope, but that claim is in question, then you’ll likely have to prove you do not improperly handle card data to an auditor, or risk fines and/or loss of any funds you’ve accumulated so far.

PCI isn’t perfect, but they do have business reasons to stop most obvious bad behavior.


I would prefer to see a process based approach to a terminology approach. Since payments are transactions, it would be better understood if explained in the form of steps.


It is indeed explained through eight steps in the second half of the article


Is there something like that, but for EMV/POS?


Can acquirers be non bank entities as?


Yeah they can be. For example, Fiserv is an acquirer


Okay this is a very comprehensive explainer and we keep coming back to this (I'm a contributor)


missed a disclaimer?


What would that be?


that the commenter is associated with the project.


Indeed, they posted about this project previously: https://news.ycombinator.com/item?id=35537675


In that case that would be a disclosure. A disclaimer warns the reader that they might not know what they're talking about, which is the opposite of what's intended here.


Why does that require a disclaimer? Also, unless they edited their comment, they mention that they're a contributor


It's etiquette (maybe even a rule?) to clearly state when you have a relationship with something you're commenting on.


They edited their comment.


Nice share


Thanks for the feedback




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: