We’ve been redoing our donation form for this end of year campaign, and have a couple major changes. We’ve talked this in a previous post.
Our first, and probably biggest change is using Stripe to accept non-PayPal donations. This provides lots of advantages we did not have before. It gives us the ability to have better fraud control, accept multiple currencies, and test expired and declined cards. Their dashboard is pretty sweet too.
Stripe requires us to do the donation server side. Our second major change was moving to our own hosting and server using Node.js. This gives us a few other advantages too, the main one being able to switch to PayPal Express Checkout. Some other smaller but still good benefits are we can spin up developer environments and run automated tests. We can use PayPal’s sandbox mode for testing instead of having to do real tests with real donations. Using node made serving up different locales easier. We can now serve up a URL like
https://donate.mozilla.org/de/ instead of the old way which was https://sendto.mozilla.org/page/contribute/givenow-seq-de. This means we no longer need to maintain multiple pages for each locale because the locale is no longer part of the filename, instead it is localized dynamically by the server.
Paypal Express Checkout
PayPal Express Checkout is better for us because it means the user is redirected to our thank you page immediately after making the donation. This means our metrics are more accurate. This was a struggle last year because the traditional PayPal flow has a delay before the redirect, and some people bounce before making it back to our site. The Express Checkout flow is interesting because its purpose is to give the user the ability to pre-authorize their PayPal account with a set amount of money, then it redirects you back to the merchant’s site. The user can then continue adding things to a shopping cart. All we do is pre-authorize their donation, then instead of redirecting back to an eCommerce page, we send them to a thank you page and process the pre-authorize amount.
We can now run unit tests against our code. This is like having robots help with QA. If I land a patch, I’m not going to remember the multitude of things that could break. This unit-testing robot is much better at rembering all the things, so I let it do the QA.
We can now accept credit card donations in multiple currencies. This presented a few challenges in our form like how to display currencies codes for multiple locales. React Intl made this fairly easy, and I am quite happy with the result. It allows us to display the currency symbol only when it’s understood in that locale, otherwise we display the 2- or 3-letter currency code.
Another challenge was thinking about currencies without the concept of cents, like Japanese yen. Computers are actually really bad at doing math with decimal numbers – sometimes they get it wrong. So sensitive numbers are stored in their lowest units, which in most cases is cents. Yen is already in the lowest unit, so we added some extra logic that checks the currency type before converting it to cents; If it is yen, we don’t make a change.
We’ve already made a lot of progress this year, the goal is improve the experience of our international donors and make life easier for our team.