Engineering

Last updated •

Deposits from 20+ countries: payments for inbound travelers

A booking flow where customers abroad pay a 30% deposit up front and the balance is collected after the shoot — and what it has processed so far. · 2 min read

The booking platform I built for a Tokyo photo studio has one job that sounds simple: let someone on the other side of the world reserve a shoot and pay for it before they've met anyone from the studio. I designed, built, deployed, and still operate it on my own.

$19.9k

best month in revenue

754

transactions, Jan 1 – Sep 13, 2026

20+

countries customers book from

The problem

Customers book from 20+ countries before they arrive in Japan. They need to choose a plan, a location, and a time slot in their own language, and pay a deposit in their own currency — before they trust us.

Charging the full amount up front asks a lot of someone who has never worked with the studio. Charging nothing leaves the studio holding a slot for someone who may not show up. A deposit sits between the two.

Deposit now, balance later

At booking, the customer pays a 30% deposit through Stripe. The remaining balance is collected automatically after the shoot. Nobody on the team has to chase an invoice, and the customer pays the rest once the work is done.

Illustration of the payment timing: a deposit at booking, the balance after the shoot.

Illustration of the payment timing: a deposit at booking, the balance after the shoot.

deposit.go
// 30% of the booking total is charged at checkout.func depositAmount(total int64) int64 {	return total * 30 / 100}
Simplified for illustration — not production code.

The arithmetic is the easy part. The work is everything around it: tying the payment to the booking, and making sure the balance step happens after the shoot instead of depending on someone remembering it.

What happens around a booking

  • A photographer is assigned to the booking.
  • The booking is synced to Google Calendar.
  • Every funnel step reports to GA4 and Microsoft Clarity.
  • After the shoot, the remaining balance is collected.

The studio's contract photographers also have an iOS app I built, where they claim open shoots, see earnings per job, and generate month-end invoices. Remaining-balance collection runs from there too, so it's tied to the shoot itself.

Stack

Next.js and TypeScript on the front end, Go and PostgreSQL behind it, deployed on AWS, with Cloudflare and Stripe as part of the setup.

What it has done

Its best month so far brought in about $19,900 (¥3,057,147 in Stripe), the business has handled 1,200+ clients, and the platform processed 754 transactions between January 1 and September 13, 2026. Instrumenting it step by step is also how I found a 39% drop-off between picking a date and picking a time.

Read more

Have something that needs to be built?

Tell me the workflow and what a good outcome looks like. I'll reply with a clear next step.

  • 1,200+ clients handled
  • Published at Mercari
  • 30K followers