I haven't integrated Stripe, but I have integrated WePay, PayPal, Google Checkout, and Amazon Payments into various applications.
WePay's API is very well designed and easy to understand. The documentation is blissfully short and effective. When I had technical questions, a post to their email list got me a detailed response within hours (and usually within minutes). Honestly it's the best developer support experience I have ever had with any product in my 16 years of professional software development. I hope it lasts.
All three of PayPal, Google, and Amazon suck, but I will honestly say that PayPal is probably the worst developer experience I've had in that same time period. And this was for a very simple implementation of a single product one-time purchase.
1) It took hours to figure out what product I wanted. PayPal's product assortment is a trainwreck. What the hell is the difference between Web Payments and Web Payments Pro and Adaptive Payments and about a dozen other things with idiotic names that all sound the same. The chart that tries to help you pick a product is useless.
2) The layout of paypal's website is labyrinthine. Even after I figured out what product I needed, assembling all the relevant documentation was hard.
3) The documentation is flat-out wrong in several (rather important) places. For example, the IPN guide (naturally, a PDF https://cms.paypal.com/cms_content/US/en_US/files/developer/...) on page 9 clearly states that you must explicitly post back messages to paypal to get them to stop sending (which is retarded and screws up transactions), but HN says that this is not the case. You can see my venting about this almost a year ago here: http://news.ycombinator.com/item?id=2341119
4) Posting a technical question to PayPal's forum gave me an unhelpful response from a clearly first-level "read the flowchart" technical support rep. Pointless exercise.
5) PayPal's APIs all feel like they were designed in the 1990s. Seriously, I would be horribly embarrassed to publish an API like that. I put more thought into (and produce better documentation for) my opensource projects. Useless crap websites like Foursquare can come up with solid APIs, there's no excuse for a company that handles actual money to be this janky.
It's vogue to hate PayPal because they really horribly suck. And now there are good alternatives. So I say, let them rot. WePay costs a little bit more but it is worth it not to have bit scary parts of my codebase that I dread going into.
If you are the kind of person who cares about whether the validation closes the IPN retry so you can come up with a reasonable strategy for handling your database transaction policy (which is a good thing: people should care this much about everything they do), then Stripe's documented policy should be a non-starter, as it seems to indicate there is not going to be any retry at all if the request in any way hits your server: "Stripe ensures that webhooks are sent successfully but does not attempt to re-send webhooks that return errors in the response."
WePay's retry policy at least exists, but only retrying three times total, with those three times only spanning a single hour of attempts, is kind of bothersome... I have totally had outages that affected some random load balancer for an hour in the middle of the night: PayPal will retry for something like four days, and has a mechanism to "force flush" the notifications as your infrastructure comes back online.
Honestly, all of these APIs are not that great. Amazon's API, for example, does not let you get the shipping address. They return it as part of the co-branded UI return, but that request to your server, at scale, will sometimes be lost in transit. When the user goes back through the payment process, you are encouraged to look up the existing token the user succeeded in authorizing by CallerReference and then continuing the payment, but that means the shipping address is not sent, and you can't query for it. You can, however, get it via IPN, but if you find some silly bug in your code that drops an IPN's incoming shipping address (but returns a successful result), you are simply screwed and have to talk to the customer to recover the shipping address for that transaction.
Looking more at WePay, I again see the same thing I keep harping about regarding Stripe: I see no mentions of chargebacks. Doing a "site:wepay.com chargeback" search using Google I find their terms of service, but nothing in their API documentation; and omg: their terms of service regarding chargebacks is the worst I have so far seen... $35 ding and your account seems to immediately be put on hold and goes into account review? For a single chargeback? WTF.
Hey Saurik, Just wanted to say that we're aware of the (significant) flaws in the webhook APIs. We're in the process of redesigning them now, so thanks for the feedback on what is important to you.
(Also, just FYI, you can see logs of all the webhooks in your Stripe account, including the response body and response status code, and they can be retried with a button click -- a manual process, yes, but it is at least possible)
I don't understand your PayPal IPN rant at all (I designed IPN; it's not perfect but it works pretty well). PayPal POSTs payment details to you. You capture those details, post them back to PayPal as-is and PayPal tells you if they are valid or not. Pretty simple. Of course there is a unique identifier: the txn_id. And because the validation step is a simple hash that doesn't hit the DB, it's very performant.
The rant was about the retry algorithm, which (from reasonable interpretations of the documentation) seems to "clear" (for lack of a better term) the IPN during a successful "response" (the term used in the PDF), but where a "response" seems to be defined as the verification step, not the HTTP request returning a successful status code.
If this were the case (and it seems from other responses to the rant that it is not, but honestly the documentation seems to read as if it is), then it would not be possible to both verify the validity of IPN requests /and/ guarantee that the information is safely committed to one's database.
In essence, and to explain, there are really only two options: either my server commits to my database before or after I perform the verification.
If I do it after, then I might fail (for whatever reason, let's say out of disk space), but will not get a retry of the IPN as I already cleared it.
If I do it before, and the verification returns "invalid", then I have to attempt to undo what I did to the database, which might not be possible, or itself might fail.
Instead, IPN needs to (and I am under the impression from the responses to the rant that it does) clear the IPN retry if the entire request succeeds, allowing for verification to be separate: you first verify, then commit, and finally return a successful HTTP status code to clear retries; here, if your commit fails, you will get another attempt.
I still don't totally understand the issue. If your commit fails you can return a "500 error" which will cause the IPN to retry.
I can see how the validation step might be confusingly described. For what it's worth, the validation step merely compares a hash of the variables to confirm the authenticity of the IPN. It doesn't touch the DB at all.
The reason you don't understand the issue is because it is implemented correctly, which is why I kept pointing out the responses to the rant that indicated he was wrong about how it actually worked (to make clear I understood this, apparently failing ;P), and kept adding the parenthetical hedges about the documentation. Really: you nailed it, and the PayPal IPN mechanism works great (seriously: no sarcasm).
The rant really was just about how he perceived it working based on what I do feel is a reasonable reading of the documentation (and in fact I think I originally had that interpretation myself until I actually tried it in practice): that the documentation lists the "response" as the verification process, and does not seem to have any provisions for "500 error": again, though, the way it works is fine.
You are being far too generous regarding the documentation. Here's the relevant part:
---
The IPN protocol consists of three steps:
1. PayPal sends your IPN listener a message that notifies you of the event
2. Your listener sends the complete unaltered message back to PayPal; the message must contain the same fields in the same order and be encoded in the same way as the original
message
3. PayPal sends a single word back, which is either VERIFIED if the message originated with PayPal or INVALID if there is any discrepancy with what was originally sent
Your listener must respond to each message, whether or not you intend to do anything with it. If you do not respond, PayPal assumes that the message was not received and resends the message. PayPal continues to resend the message periodically until your listener sends the correct message back, although the interval between resent messages increases each time. The message can be resent for up to four days.
---
This is clear, unambiguous, and - if what you say is correct - just flat out WRONG. My misunderstanding wasn't just "a reasonable interpretation", its the only reasonable interpretation. At the barest minimum, competent documentation should state "PayPal will attempt to resend messages until your handler returns a 200 OK http status code." It doesn't. Anywhere.
This is a perfect example of why working with PayPal is an unacceptable developer experience. And who doubts that one year from now this document won't have changed one bit?
It's not the best wording but doesn't necessarily imply that the payment is dependent on handling the IPN, just that the retrying is affected by the handling.
But it is unforgivable that there does not seem to be any mention of what response the PayPal server is expecting to indicate that the IPN has been successfully caught.
WePay's API is very well designed and easy to understand. The documentation is blissfully short and effective. When I had technical questions, a post to their email list got me a detailed response within hours (and usually within minutes). Honestly it's the best developer support experience I have ever had with any product in my 16 years of professional software development. I hope it lasts.
All three of PayPal, Google, and Amazon suck, but I will honestly say that PayPal is probably the worst developer experience I've had in that same time period. And this was for a very simple implementation of a single product one-time purchase.
1) It took hours to figure out what product I wanted. PayPal's product assortment is a trainwreck. What the hell is the difference between Web Payments and Web Payments Pro and Adaptive Payments and about a dozen other things with idiotic names that all sound the same. The chart that tries to help you pick a product is useless.
2) The layout of paypal's website is labyrinthine. Even after I figured out what product I needed, assembling all the relevant documentation was hard.
3) The documentation is flat-out wrong in several (rather important) places. For example, the IPN guide (naturally, a PDF https://cms.paypal.com/cms_content/US/en_US/files/developer/...) on page 9 clearly states that you must explicitly post back messages to paypal to get them to stop sending (which is retarded and screws up transactions), but HN says that this is not the case. You can see my venting about this almost a year ago here: http://news.ycombinator.com/item?id=2341119
4) Posting a technical question to PayPal's forum gave me an unhelpful response from a clearly first-level "read the flowchart" technical support rep. Pointless exercise.
5) PayPal's APIs all feel like they were designed in the 1990s. Seriously, I would be horribly embarrassed to publish an API like that. I put more thought into (and produce better documentation for) my opensource projects. Useless crap websites like Foursquare can come up with solid APIs, there's no excuse for a company that handles actual money to be this janky.
It's vogue to hate PayPal because they really horribly suck. And now there are good alternatives. So I say, let them rot. WePay costs a little bit more but it is worth it not to have bit scary parts of my codebase that I dread going into.