stripe-archive / react-stripe-elements

Moved to stripe/react-stripe-js.
https://github.com/stripe/react-stripe-js
MIT License
3.03k stars 319 forks source link

Poor documentation #451

Closed zehawki closed 3 years ago

zehawki commented 4 years ago

Stripe guys, this project is littered with seriously poor documentation. I was about to create a new issue about the reference to AddressSection, and then I see this has been pointed out 2 years ago and still nobody at Stripe thinks this is the least bit important to update.

The root cause for many issues here is poor documentation, and the community has asked multiple times for better documentation, better usage examples, better components, clarity on why certain decisions are being taken to remove components or change things, but much of this is not getting acted on.

Given this is an official library from Stripe and not someone's love child, it is disappointing to see such immaturity. May I remind authors of the promise made on the landing page of Stripe:

We believe that payments is a problem rooted in code, not finance. We obsessively seek out elegant, composable abstractions that enable robust, scalable, flexible integrations. Because we eliminate needless complexity and extraneous details, you can get up and running with Stripe in just a couple of minutes.

oliver-stripe commented 4 years ago

Thanks for your feedback. I assume it is https://github.com/stripe/react-stripe-elements/issues/68 you are referencing? Would the request here be to call out that the implementation of AddressSection is left up to the developer?

jmitchell33 commented 4 years ago

I couldn't agree more. The documentation here and on Stripe's page looks like it's copy/pasted from multiple sources and the result is you have references to Components and other parts of code that are just sloppy and difficult to follow.

The documentation and this project would really benefit from a simple guide that walks you through setting this up, with working code - especially since Stripe is asking us to trust that the rest of the code behind the scenes is not equally sloppy and should be trusted to handle sensitive information and transactions.

zehawki commented 4 years ago

@oliver-stripe Its multiple things. Off the top of my head its #68, #415, #312, but could be more.

The code at https://github.com/stripe/react-stripe-elements is different from the code in the jsfiddle (https://jsfiddle.net/mbarrett_stripe/6jLze147/) is different from the code at https://stripe.com/docs/recipes/elements-react. Someone like me who’s starting out with Stripe has no idea which is the one piece of fully functional boiler plate code to start with, and build out from there.


Further the Stripe site also has horrendous documentation. A couple of weeks ago, I've sent a document to Stripe support detailing all the issues I've found, here's part of it that concerns this project:

Part B: So far so good, now the mess starts on https://stripe.com/docs/recipes/elements-react

In Step 3, the code for src/CheckoutForm.js sends only token.id to the backend, no amount, currency, customer details etc. a. How can a charge be created with just a token.id?? b. Below it says “In the submit method, tokenize the card information by invoking createToken on the stripe prop.”

  1. So I looked up createToken on https://stripe.com/docs/stripe-js/reference#stripe-create-token a. It shows a method with 2 params: stripe.createToken(element, tokenData) b. But the example code shows stripe.createToken(card).then(function(result) c. What is “card” out the blue here? There’s no explanation of what card is. There’s no explanation of the format of tokenData. d. So anyway, here I understood that the first param is element and the second is tokenData according to the API doc
  2. Back to Step 3 on https://stripe.com/docs/recipes/elements-react, the code has this.props.stripe.createToken({name: "Name"}); which looks like tokenData param, so what happened to the element param that was mentioned in the API??4. Then in Step 4, suddenly we have amount, currency and description being sent to stripe. Where did these params come from if they were not sent by the front end in Step 3?

Such inconsistency makes it really hard for this documentation to be useful. I should have quickly gotten to the point of making the first test transaction within an hour of starting since most of this is just reusing components, code and paradigms that have been already used a zillion times by your customers

tstirrat15 commented 4 years ago

To add to the list: there are a couple of different APIs and workflows that stripe-js supports (namely Charges and Payment Intents), and the documentation around this library flips between them depending on whether you're looking at the GH docs, the stripe docs, or the linked fiddle.

Additionally, it looks like the way to confirmCardPayment is to hand the confirmCardPayment function a ref to the CardElement, and there isn't an example of that that I've found in these docs.

tstirrat15 commented 4 years ago

Hmm. My second point is moot - I didn't see that the methods in injectStripe are designed to automatically reference the elements that are under the Elements. I found it in the source code before I found it in the README, though.

ghost commented 4 years ago

@tstirrat15

I'm hoping you can help as im also struggling to understand the documentation from this library and the official documentation.

Am i right in assuming that this library only provides functionality to display UI elements? and so the confirmCardPayment must be done using the window.Stripe object?

  1. Im at the point now where i have generated a paymentIntent from the backend and sent that to the frontend.
  2. The user fills in their card details ( i am using the seperate elements CardNumberElement, CardExpiryElement, CardCVCElement).
  3. Now i need to submit the card details. I believe i should be using confirmCardPayment from the window.Stripe object.

However im not sure how exactly to pass in each of the card pieces to the function.

      this.state.stripe.confirmCardPayment(this.state.paymentIntent.client_secret, {
            payment_method: {
            }
        }).then(function (result: any) {
            console.log(result);
            if (result.error) {
              // Display error.message in your UI.
            } else {
              // The payment has succeeded. Display a success message.
            }
          });
tstirrat15 commented 4 years ago

@KayHS this is also where I got hung up. I started writing an implementation that would do it with refs, but then I found the handleCardPayment method on the stripe object injected by injectStripe, which is different than confirmCardPayment and includes the handles on the inputs.

When you use handleCardPayment, it should already have the payment method in place - you can pass additional info, but it should Just Work^tm to do

stripe.handleCardPayment(this.state.paymentIntent.client_secret);
ghost commented 4 years ago

@tstirrat15

Hi, I think ive done it using the solution with "refs" i take a ref of the cardNumber and pass it to payment_method.card. However im confused why it successfully completes the payment without having to add the CVC and expiry date.

I've not had a chance to look into handleCardPayment.

ghost commented 4 years ago

Just FYI @tstirrat15 handleCardPayment is deprecated https://stripe.com/docs/stripe-js/reference#deprecated

tstirrat15 commented 4 years ago

Of course it is -_-

You have to use handleCardPayment if you want to use the context injection that this library provides. That's how I ended up on that.

If you're not using that feature, I wonder whether this library is even worth using...

tstirrat15 commented 4 years ago

It also looks like you can get references to the elements through an elements prop.

DavidSabine commented 4 years ago

Regarding the quality of documentation: I think this is a classic case of "expertise bias".

The "expertise bias" goes like this: "When you're an expert, and you have to explain the same thing again and again, you're naturally biased to think that everyone is stupid except you."

Developers within Stripe have created the tools and work with them everyday — they've developed tribal domain knowledge and therefore feel strongly the tools are easy to use and the docs are easy to understand.

However, without that tribal knowledge and experience, the tools need to be explained, the docs need to be clear, and new users face a learning curve that the Stripe developers have never suffered (or had day-to-day help from their more experienced colleagues if they were hired later).

I was struggling with the docs 10 months ago and so logged into the Stripe IRC channel to talk with devs. I didn't think my questions were stupid, but one of the devs told me I should (paraphrasing) "go study the documents and learn React fundamentals before trying to implement Stripe Elements".

I certainly have not learned everything I need to know about React -- that much is true -- but clearly this developer thought their docs were clear as crystal. I'm glad to learn from others in this thread who have struggled.

defusioner commented 4 years ago

Well, took me some more time than 5 minutes to have an up-and-running thing.

The problem is that your example is like a spaghetti:

Seriously, guys..

@DavidSabine It is not natural bias. Natural bias it's when I explain what is machine learning and you do not understand. Here it is just poor docs.

Actually I've found how to by passing via jsfiddle, thanks god @mbarrett-stripe made it

D19cannon commented 4 years ago

Agree with this topic... I find it to be a hell to get stripe up and running. Especially since I am using an entirely different stack than what the documentation provides.

I wish there would a clear setup for obviously react with the most simple and adequate example there is with a short explanation of a comment what certain components to and why it is structure as it is.

Also, what if people want a custom payment method? It keeps pointing me to this "charge" topic, which makes sense to me, however, it only show some stuff how to send a payment request from the backend. What would be nice to have documented it is, how to send only a payment request with a card validation with x information (total price, card info etc and return a success/failed transaction.

Right now, I am building an ecommerce project (template) where I am using Headles WP, Gatsby, Graphql, Apollo. I am getting my products from woocommerce and custom product information with ACF. It seems utterly useless do duplicate my products in Stripe, when all I need is a payment confirmation.

iMerica commented 4 years ago

I agree 100% with the general sentiment here. It also seems like Stripe has declared bankruptcy on this project in favor of this new project stripe/react-stripe-js.

They refer to this as a "legacy project" project that should be migrated from, which implies its going to be deprecated. Am I wrong? Maybe someone from Stripe can chime in.

asolove-stripe commented 4 years ago

👋 Hi there, I'm Adam, the Engineering Manager for the team at Stripe responsible for this project.

Thank you all for your honest feedback in this thread. I want to apologize for the current state of the React<>Stripe integration experience and to assure you that we take this feedback very seriously — many teams at Stripe have already been heads-down working on the overall integration experience of our payments APIs for several months. We expect to be in a much better situation shortly.

As for the React integration experience specifically, besides solving the ergonomics problems with this library, we are in the process of making React support first-class throughout Stripe, with React-specific examples throughout the main docs and more attention to the React impact of API and product changes.

We do have a beta of a new version of the library that some of you have referenced. We built it to solve many of the ergonomic problems mentioned in this thread: it uses modern React design patterns and removes React context injection that made the API diverge from our vanilla JS API. The library is still in beta — it doesn’t yet have type definitions or all of the documentation we would have when it launches. That said, we would love for you to try it out and email us directly (asolove@stripe.com) if you have questions or want to provide feedback before we launch.

If you’re already developing with the current library and want to continue using it, I am happy to provide direct support, especially if you have code snippets that aren’t working. Email me at asolove@stripe.com. I am sorry to hear about the negative experience with our support team on IRC and will follow up to make sure we are always providing helpful, actionable advice and not talking down to folks.

If you’re interested in hearing more details about some of the issues mentioned in this thread, read on!


Let's talk about the current problems with this repo. There are a lot of very justified complaints in this thread, some of which overlap and some of which are separate. So I want to share the way we have been thinking about the underlying causes and solutions to the pain that people are feeling:


Thanks for reading until the end of this comment. Again, I apologize for the current state of this library — we’re working on it! We’re looking forward to hearing more of your feedback on the new version of the library.

DavidSabine commented 4 years ago

👋 Hi there, I'm Adam, the Engineering Manager for the team at Stripe responsible for this project.

Thank you all...

Hi Adam.

Thank you for providing some clarity. Your post is very helpful as I (and others, no doubt) chart a course for our apps.

I've started following the new react-stripe-js repo and will watch it closely.

cycleops commented 4 years ago

Probably naive of me, but why isn't it as straightforward as a library that hides all the complexity and just opens a payment modal based on setting state to show: <Stripe amount={25.00} receipt={handleReceipt} options... /> Perhaps allow you to override the library's form with your own for the sake of consistent looks.

tstirrat15 commented 4 years ago

Short answer is that yes, it's much more complicated than that. An example: the way that Stripe lets you get around PCI compliance (i.e. not having to worry about "handling user card information") using their Elements is that what look like form elements in your web page are actually small iframes that point at a site controlled by Stripe that contain only the input element in question. It's either really clever or completely insane depending on how you look at it.

cycleops commented 4 years ago

I didn't mean to imply that the process isn't complex; I'm sure it is. I'm asking why the complexity can't be managed differently. Why can't the library just provide a component that accepts some props and gives you back a result that's either a receipt or an error? And I'm sure iframes are a great way to handle PCI compliance. I just don't know why it seems to be so complicated to use them. Also, I don't mean to sound arrogant or critical. I really wonder why it isn't easier to use.

DavidSabine commented 4 years ago

I really wonder why it isn't easier to use.

Hi @cycleops, I wondered the same thing.

I have finished an implementation now, and it's complexity no longer bothers me. It took a solid 6 weeks, however, to learn my way through implementing Stripe's CardElement in my Gatsbyjs+Reactjs environment. https://scrum.works/agile-training/Professional_Scrum_Master_(PSM)-Toronto-sku_G7QAB5vamtj1lm

To be clear: I succeeded with the react-stripe-js package. I found good docs here: https://stripe.com/docs/payments/accept-a-payment (a good starting point)

I think the documentation is still poor, but improving. Stripe's engineers could offer many more example implementations — I believe that would be most helpful.

cycleops commented 4 years ago

@DavidSabine, 6 weeks! Oh, no -- I'm only on day 2! Congrats on finishing. It looks nice.

iMerica commented 4 years ago

Why can't the library just provide a component that accepts some props and gives you back a result that's either a receipt or an error

This is the million dollar question @cycleops. I completely agree.

it's complexity no longer bothers me.

Same here, but I attribute that to the "Ikea Effect". We seem to forget how absolutely painful it is to learn Stripe from scratch even in the year 2020 because we already endured the pain.

asolove-stripe commented 4 years ago

Hi all! Thanks for the great feedback. We definitely need to do a better job explaining how this repo relates to a full Stripe integration, why some of these feature requests would lead to a poor experience, and what other options Stripe has to help you get started.

But to hopefully help with your short-term problem:

On Sun, Apr 26, 2020 at 11:41 AM Michael notifications@github.com wrote:

Why can't the library just provide a component that accepts some props and gives you back a result that's either a receipt or an error

This is the million dollar question @cycleops https://github.com/cycleops. I completely agree.

it's complexity no longer bothers me.

Same here, but I attribute that to the "Ikea Effect https://en.wikipedia.org/wiki/IKEA_effect". We seem to forget how absolutely painful it is to learn Stripe from scratch even in the year 2020 because we already endured the pain.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/stripe/react-stripe-elements/issues/451#issuecomment-619592754, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHTD6YFQOM4DD46FO64NVLTRORW43ANCNFSM4JFQ5IZA .

DavidSabine commented 4 years ago

...hopefully help with your short-term problem: - If you want to use Stripe.js in your own payment page, I'd strongly recommend starting with our full walkthrough of integrating Stripe: https://stripe.com/docs/payments/integration-builder

OMG. I wish that resource existed when I started my work. I'm certain that would have reduced my learning curve from 6 weeks to ... (anti-climactic tone) less than 6 weeks.

In all seriousness. That's a beautiful resource. Kudos to the team who built it!

mpmw commented 4 years ago

@DaivdSabine: Hi David. Thank you for your message. You're right; that's the way to go. I tried it at first and then decided I wanted more customization. Ironically, after getting my custom implementation to work, I decided to go back to Stripe's Card Element and addressed the problem of it not accommodating narrow displays by overlaying a large "rotate screen" image whenever the window is narrower than 650px.

asolove-stripe commented 4 years ago

@mpmw yikes that sounds difficult. I would love to chat, both about making it easier to use the split elements and to make sure the combined card element is working for you. We test it on screens down to an iPhone 8 in portrait mode, so I would not expect it to require 650px of width to work. Want to make sure we're seeing the same thing you are. Could you send me an email at asolove@stripe.com if you have some time?

mpmw commented 4 years ago

@Adam: Very kind of you. Thank you. I do feel like an ass for getting off-topic and the combined card element getting caught in the crossfire. As noted, I was at the height of frustration with the documentation, so much of my grievance with the combined element is akin to being annoyed at a Phillips screwdriver for not fitting flathead screws.

@(all)...

This does come back to the documentation and the points previously made by David Sabine. As customers, we look at the product differently. You know those websites that list all of their products by manufacturer instead of by type — so you have to click through a dozen brands (you have never heard of) one-by-one to find the product you’re looking for? That’s what Stripe’s documentation is. At the outset, I don’t know why I would want one brand over the other; I’m just looking for a garage door (or whatever).

At the outset, when looking to implement something from a new company, I for one would like an overview that lists the products (e.g., flathead, phillips, allen) and gives the pros and cons of each. In absence of that in Stripe’s documentation (which I previously described as an unwelcomed scavenger hunt), I went through three different implementations starting with the combined element (which wasn’t customizable enough for my needs, but which was definitely easy enough to use despite the horrible documentation), mounting individual fields (which was tremendously hindered by the piecemeal documentation), and finally using the checkout component (which was a piece of cake despite the inadequate documentation). Aside from the docs’ other problems, if they did a better job of not presenting Stripe’s products as if they came from disparate companies, I could have confined myself to one Stripe implementation. For instance…

“The combined element is ideal for [these situations] and a horizontal presentation of the fields where the minimum space required is x-pixels. Here are some other possibilities: ___” Now, I still would wish for a vertical presentation, but I would have known what I was getting up front, and I would have been pointed where I needed to go before trying to put a round peg into a square hole. With the ornamentation I wanted to have around the combined element control, I ended up needing about 650 pixels in total. The control nicely does what it was designed to do in its horizontal orientation and is, in fact, quite elegant and efficient, not to mention smart in its presentation (e.g., the way it shows the last four digits of a credit card entry when the number field needs to be truncated). That’s beautiful, especially with the animation. It just wasn’t something I was appreciating while having it not fit my design. I would drop the checkout mechanism in a heartbeat if the combined element offered a vertical operation. Who wouldn’t go for the progressive disclosure of fields walking a customer through the entry, as opposed to starting with a large cumbersome form?

In closing (@Adam), I think I have covered all of my bases here: I have hopefully made amends for disparaging your team’s hard work; I have, without exaggeration, acknowledged the elegance of the combined element in a horizontal orientation; and I have hopefully sparked your competitive nature in throwing down a gauntlet against a less elegant (although equally easily implemented) checkout element that seeks to unseat your control from its rightful place in Stripe implementations.

sashko-stripe commented 3 years ago

Hi all. Thank you for the in-depth discussion here. I've recently joined as the engineering manager responsible for this area, and making sure our documentation is on point (and makes sense from the perspective of the users) is a top priority for me and the whole team.

The project has since migrated to React Stripe.js, so I'm going to close this issue. We also have many plans to continue improving documentation this year and in the future. Please let me know if you have any ideas or thoughts at sashko@stripe.com.