Adding online payments to your app: what to plan for
Adding online payments to a web or mobile app? What to plan beyond the checkout form: webhooks, double charges, refunds, disputes, tax and test mode.
"Can we take payments online?" sounds like one feature. In practice it touches almost every part of an app: orders, emails, the admin side, accounting and support. Most of the work isn't the payment form. It's everything that has to happen after someone pays, or after a payment fails.
This is what I plan for when a business asks me to add payments to a web or mobile app.
Let the provider handle the card
I don't build my own card form. Providers like Stripe, PayPal or Adyen offer hosted checkout pages and embedded fields where the card details go straight to them and never touch your server. That keeps you out of most of the card-security rules, and it gives customers a form they already trust, with wallets like Apple Pay and Google Pay included.
Pick the provider by where your customers are, which currencies and payment methods they expect, and what your accountant needs from it. Not by which one has the nicest logo.
Trust the webhook, not the browser
The most common mistake I see in payment code: the app marks an order as paid when the customer lands on the "thank you" page. But people close tabs, lose signal and press back. And some payment methods take minutes or days to confirm.
The reliable signal is the provider's webhook, a message from their server to yours saying the payment succeeded, failed or was refunded. The order changes status only when that message arrives and is verified. The thank-you page just shows what the server already knows.
Make every step safe to repeat
Webhooks can arrive twice, late or out of order. A customer can double-click "pay". So each step has to be safe to run more than once:
- the payment request carries a unique key, so a retry doesn't charge twice
- a webhook that was already handled is ignored the second time
- an order can't go from "refunded" back to "paid" because an old message arrived late
This is invisible when it works and very visible when it doesn't, usually as a customer charged twice.
Plan for the unhappy paths
Success is one path. These are the others, and each needs a decision:
- Failed payment: keep the cart, show a clear reason, let them try another method.
- Refund, full or partial: who can issue it, and what happens to the order and the stock.
- Dispute or chargeback: who gets told, and what evidence you keep.
- Subscription renewal fails: how many retries, what the customer sees, when access stops.
Write these down with the people who handle money and support. They are business rules, not code details.
Don't forget the paperwork
Payments come with obligations that vary by country: tax on the invoice, receipts, which details the invoice must show. Many providers can calculate tax and send receipts for you. Decide early what your provider does and what your app or accounting tool has to do, so nothing is done twice or not at all.
Test with fake money first
Every major provider has a test mode with test cards for success, failure, slow confirmation and disputes. I run through every path above in test mode, including webhooks that arrive twice, before anything goes live. Then one small real payment and a refund on production, to be sure.
Adding payments to your app
Tell me what you sell, where your customers are and what your app runs on today. Describe it on the scope page or get in touch, and I will tell you which parts above matter most for your case.
Freelance full stack engineer in Jakarta. I build web and mobile apps, rescue unmaintained software and join busy teams.