All work
PLAN ZINNIA / PAYMENTS + MARKETPLACE TRUST

Designing trust into
every transaction.

How I designed and built an end-to-end payment lifecycle for a two-sided marketplace—from booking authorization and vendor confirmation through capture and payout.

MY ROLE

Co-Founder & Chief Product Officer
Product design + AI-assisted development

SYSTEM

Stripe Elements, PaymentIntents,
Connect, subscriptions & Transfers

PRODUCT

Plan Zinnia
Wedding marketplace

Booking request confirmation showing no charge until the vendor confirms
The confirmation screen explains that the request has been sent and the card has not been charged. Scroll inside the preview to explore the full screen.
01 / THE TRUST PROBLEM

A wedding booking is
not a normal checkout.

Couples may be paying thousands of dollars to a small business they have never worked with. Vendors need confidence that a booking is real—and that they will actually get paid.

A traditional ecommerce model—click buy, charge immediately—didn’t fit the relationship. A vendor still needed to confirm availability and accept the work, while the couple needed confidence that their payment would not disappear into an uncertain booking.

The design problem became bigger than checkout: how could the product make money movement, commitment, timing, and responsibility understandable to both sides?

Protect the couple

Do not treat an unconfirmed request like a completed transaction. Make status and next steps visible.

Protect the vendor

Give the business a clear opportunity to accept or decline before the payment lifecycle advances.

Keep the system aligned

The interface, booking record, Stripe state, notifications, and payout state all need to tell the same story.

02 / THE PAYMENT MODEL

Separate intent
from commitment.

Instead of immediately capturing payment, Plan Zinnia creates a pending booking and authorizes the payment while the vendor reviews the request. The vendor then has a defined confirmation window.

If the vendor confirms, the payment is captured and the booking moves forward. If they decline—or the request expires—the authorization is canceled rather than becoming a completed charge.

CORE PRODUCT DECISION

Use payment authorization as the bridge between a couple saying “I want to book this” and a vendor saying “I can take this job.”

Payment lifecycle: couple books, payment is authorized, vendor reviews and confirms, payment is captured, the event occurs, and vendor payout is released. Authorization and capture are separate steps.
The product experience maps directly to the underlying payment lifecycle.
03 / DESIGNING THE EXPERIENCE

Every payment state needs
a human explanation.

The challenge was not exposing Stripe terminology. It was translating financial state into language and actions that make sense during an emotional, high-stakes purchase.

The couple needs to know whether a request is pending, confirmed, declined, expired, or canceled. The vendor needs to know what action is required, how long they have, and what happens to the payment when they respond.

01 / Checkout

Show the service, event details, fee breakdown, and payment information before the couple commits.

02 / Pending confirmation

Set expectations: the request exists, payment is authorized, and the vendor still needs to respond.

03 / Vendor decision

Make confirm and decline consequential, understandable actions—not generic status changes.

04 / Confirmed booking

Capture payment, establish the booking relationship, and open the next phase of communication.

05 / Event lifecycle

Keep booking, messaging, operational status, and financial status connected through completion.

06 / Payout

Release vendor funds after the event according to the marketplace payout rules.

Vendor availability and event time selection
Choose an available time before starting checkout. Scroll inside the preview to explore the full screen.
Checkout location step with booking summary and fee breakdown
The event location and booking summary establish the details before payment. Scroll inside the preview to explore the full screen.
Stripe payment form with billing details, payment methods, fees, and cancellation terms
The payment step combines Stripe payment methods with booking expectations and service policies. Scroll inside the preview to explore the full screen.
04 / DESIGNING THE SYSTEM

The UI was only
one layer of the experience.

Underneath the screens, the booking lifecycle coordinates Stripe PaymentIntents with manual capture, Stripe Connect accounts, subscriptions, verified webhooks, scheduled jobs, transactional email, and the Plan Zinnia booking model.

Booking records retain cent-denominated fee breakdowns and payment state so the product can explain what happened without relying on Stripe as the only source of context. Sensitive payment operations happen server-side and identify the current vendor from authenticated context rather than trusting client-provided identity.

DESIGN ↔ ENGINEERING

A “Confirm booking” button is also a financial operation. Designing the interaction meant understanding what should happen to the PaymentIntent, booking status, messages, email, and eventual payout when that button is pressed.

PaymentIntent

Manual capture separates authorization from vendor acceptance.

Stripe Connect

Vendor accounts create the marketplace relationship required for downstream payouts.

Verified webhooks

Subscription events synchronize payment-provider state back into the product.

Scheduled transfers

Eligible vendor payouts are released automatically after the event and required waiting period.

Conceptual payment architecture: couple checkout and vendor review connect to authenticated server-side payment logic, Stripe PaymentIntents, Connect, and Transfers. Booking records track status, fees, and payment state. Scheduled operations check expiration and payout eligibility; verified subscription webhooks synchronize subscription records.
05 / DESIGNING FOR WHEN THINGS GO WRONG

Trust is clearest
at the edges.

The happy path is only part of a payments product. The harder design work is deciding what happens when people do nothing, change their minds, or a system fails.

01

The vendor does not respond.

Pending bookings carry an expiration time. A scheduled job expires stale requests so a couple is not left indefinitely in payment limbo.

02

The vendor declines.

The payment authorization is canceled and the booking state communicates that the request did not become a confirmed booking.

03

Payment and product state disagree.

Payment operations verify Stripe state before downstream actions such as payout, reducing the risk of treating an incomplete payment as settled.

04

A payout is not ready.

The payout job checks booking eligibility and payment success before creating the transfer and marking funds released.

Payment edge cases: declined and expired requests cancel authorization without a charge. Failed capture leaves the booking pending confirmation and shows the vendor an error. Ineligible payouts stay pending, are rechecked hourly, and trigger an admin alert.
06 / THE TAKEAWAY

Payments are a
trust experience.

Building Plan Zinnia’s payment system pushed me beyond designing a checkout screen. I had to think about money as a lifecycle shared by two customers, a payment provider, and the marketplace itself.

The most important design work was making that lifecycle legible: when a couple has committed, when a vendor has committed, when money actually moves, what happens when something goes wrong, and what each person should expect next.

AI-assisted development accelerated implementation, but I remained responsible for the product model, UX decisions, integration behavior, testing, debugging, and evolution of the production system.

WHAT I LEARNED

For high-stakes systems, the interface cannot be designed separately from the state machine underneath it. Trust comes from making both behave as one coherent experience.

Explore the full Plan Zinnia case study
THE TAKEAWAY

Design the screen.
Understand the system.

Back to selected work