Have you always wondered how to monetize your web applications 🤑? Time to start making those benjamins 💸💸. In this how-to guide, you will learn how...
For further actions, you may consider blocking this person and/or reporting abuse
Shouldn't the
client-id
be imported from somewhere safe like the.env
file withprocess.env.PAYPAL_CLIENT_ID
. Or it's not a sensible id? I know that for the sake of simplicty here is hardcoded in the component, but might be worth pointing this out. Congrats on the useful post btw!Client ID is Class 4 data.
Client id is non-sensitive data, but still be prudent about sharing or posting it. And yes I did it for the sake of simplicty! Thank you for your comment
Yes, I thought that I was not, however I think that any credential —regardless of its sensitiveness— should always be stored in
.env
. Just as a good practice. Thank you for the clarification.I agree with you! I just didn’t explained that for the simplicity of the tutorial but I will add a note ;) thank you!
My experience
As someone who actually updated their PayPal setup not long ago using this exact technique, I would recommend caution.
This article looks good, but the truth is the
react-paypal-js
package is not very flexible and will bring you many headaches.Packaging
The package downloads a dynamically generated script at
runtime
, meaning the "versioning" of your code is not static, it's dynamic with all the problems from such method.My website uses static site generation (SSG) to pre-compile each page as static HTML. Because of this, I can only use hashes for my Content Security Policy (CSP). Because PayPal change that dynamically generated script on the fly, my PROD environment stopped working on 2 occasions in the last 6 months... I had to adjust the hash to get back the functionality.
To avoid this, my options are very limited.
I could use a
nonce
, but I can kiss goodbye to my "perfect" reliability from static site generation (SSG) and I'll be forced to use server side generation (SSG).The only other solution is to lower my Content Security Policy to pretty much accept anything from anyone...
So for security reasons, PayPal is kinda forcing me to go all SSR or remove the Content Security Policy altogether... All because PayPal decided to download at runtime a script instead of simply versioning their API like any normal and reliable service. It's a nightmare to manage, enough to look at other solutions...
Styling
You don't have much control on the styling. Everything is hidden away in an
iframe
, meaning those border radius ain't gonna fly.It wouldn't be so bad if the PayPal button was actually styled correctly, but there are many glitches that just make your site look amateurish. You can't control the outline color or the button size much, it doesn't integrate well with your design, you have to design around PayPal instead. It's not a nice experience at all to be honest...
State
The
onCreateOrder
andonApproveOrder
functions you pass are memoized within the PayPal iframe.This means if you want dynamic pricing, like doing a "give what you want", then you're in for a lot of fun! If you want to select between 3 options and charge the according price, you're in for a lot of fun too! You kinda have to go through hoops and loops like a circus animal to make it work. It does work, but the problem is it doesn't work like anything you've ever seen in React. It's a very awkward developer experience.
Conclusion
I did upgrade using this setup and it works, as long as PayPal don't change anything on their side it's rock solid.
But if I had to redo it again, I would probably not choose this solution because of the heap of headaches it creates.
I would probably go with a payment processor like Stripe because it has both a wonderful developer experience (DX) and an awesome user experience (UX). It also offers a lot more flexibility for payment sources (GPay, Apple Pay, Credit card, Alipay, WeChat, etc.), styling and there's no shenanigan with how stuff is loaded or updated in React. Their doc is also top notch! It ain't PayPal, but then again PayPal is not the defacto payment source anymore either...
Do your research before jumping on the bandwagon
Hi! Thank you so much for you feedback :) If you have a few minutes of you time in the next few weeks I would love to set a quick call with you to see discuss this valuable feedback :) let me know! Thank you
Hi,
I can definitely take some time to discuss with you.
Although my weeks are a bit crazy at the moment, so it might take a bit of time before we can set this up.
I'll send you a DM when I can schedule something.
Sounds like a plan, thank you!
Hi, currently I'm having issues passing a state as the price on create order, do you have any solution for this?
You can't pass state as the button is memoized.
What you can do is pass a function that checks a
ref
. You can adjust the value of theref
however you need.It's completely crazy to have to use this kind of method, but that's the only work around I've found for dynamic pricing...
Thank you so much for sharing. Very useful.
thank you so much!
Anytime :)))
Amazing!! Thanks
Great post, thanks for the info!
The
initialOptions
should be like so, instead of what you suggested @devpato. I think it was a typo from your end. Take note of theclientId
What if you're fetching the client id from the server? It seems the client id is set as undefined no matter what (useState, useEffect, etc).
is create vite@latest working with this?