Paywalla exposes a simple, secure API so booking systems, travel tools, event platforms and billing software can create and publish group checkouts on an organization's behalf β and let the platform handle splitting, invitations, payment and receipts.
Group checkout shines wherever one purchase is shared by several payers. Here are common integrations and the outcome each unlocks.
When a customer books a venue, suite or rental for a group, auto-create a group checkout so each guest pays their share to your business directly β no more one person fronting the deposit.
Turn a confirmed itinerary into a collection plan. Publish a checkout per trip, assign amounts per traveler, and let the platform email every participant their pay link.
Sell a table, suite or private experience to several attendees. Each pays their own share; you track group progress and issue individual receipts without a spreadsheet.
Collect tournament fees, facility rentals and registration costs across every family in one link instead of chasing each one individually.
Add a 'split this invoice' action that creates a group checkout from an existing invoice, so clients can divide a bill among co-payers.
Let a chapter or committee fund a shared initiative together β dues, donations and event costs collected straight to the organization.
When one team or department fronts a shared cost β travel, event, equipment β create a group checkout to charge it back to every responsible party, each paying their share straight to the organization with a proper receipt.
Once group checkout is a first-class object in your product, a few new experiences open up β the kind that used to require custom payment infrastructure.
Hospitality, venues, vacation rentals and activity providers that already capture a group booking can attach a split-payment checkout to the reservation.
Planners and OTAs that assemble group trips can trigger collection the moment the itinerary is confirmed.
Tools selling tables, suites, booths or group registrations can let co-attendees split the cost at the point of sale.
Accounting and billing products can offer 'split this invoice' as a one-click option for shared or co-funded bills.
Platforms running memberships and teams can automate collection of shared costs across member households.
Any product serving groups that buy together can embed group checkout as a native payment flow.
Before you send a single payment request, it's worth knowing how the platform handles money, security and state β so you can integrate with confidence.
Every organization connects its own Stripe account. Payments are charged directly to that account β money never passes through or sits in the platform. The platform fee is taken as Stripe's application_fee_amount.
Payment status is never inferred from a page redirect. Stripe webhooks, verified against the raw body and unique event IDs, confirm every charge β so a checkout can't be faked by loading a success page.
Creating, publishing, paying and refunding run in backend functions under a service role. The client never performs or alters a financial operation.
Organizers and participants get high-entropy tokens instead of logins. Links are scoped and can be rotated. Participants never see each other's details.
The total, fee snapshot and allocation are locked when a checkout goes live, so what participants were shown is exactly what they pay.
All amounts are integers (cents) in the database to avoid floating-point drift. The API accepts decimal major units (e.g. 1200.00) and converts them.
Each organization's checkouts, participants and contributions are scoped to the owner. API keys are stored as one-way SHA-256 hashes β a database read can't recover them.
Invitations only email never-before-sent participants. Every sensitive action writes an audit event, and financial events carry idempotency keys.
The API is the last step. These have to be in place first β each lives in the organization's dashboard, not in your code.
Someone signs up and creates the organization. This account owns the Stripe connection and the API key β the API can't exist without it.
Business name, support email, address, default currency and refund terms. The support email and address are snapshotted onto participant receipts at publish time, so set them first.
The owner connects Stripe and finishes onboarding until card payments are active (status 'ready'). The API returns stripe_not_ready until this is done β no test charge will go through without it.
One key per organization, shown only at creation, stored as a one-way SHA-256 hash. Generate it only after the three steps above are complete.
Keep the key in an env var or secrets manager β never in a client app or public repo. This is the only secret you hold; rotate it if it leaks, revoke it if compromised.
Today the platform exposes two ways to create and publish checkouts: a public, key-authenticated REST endpoint for programmatic automation, and a native MCP server for AI clients (ChatGPT, Claude, Cursor). A session-authenticated key manager and a handful of internal functions power the backbone behind both.
A single POST that creates a draft checkout, adds participants, publishes it (emails the organizer), and invites every participant β all in one call. Authenticated with a per-organization API key in the x-api-key header. It returns only a checkout_reference β never organizer or participant links β so a compromised key can't impersonate anyone.
Each organization generates a single API key from Settings (Dashboard β Settings β External API). The key is shown once and stored as a one-way SHA-256 hash. It can be rotated (replacing it) or revoked at any time. Key creation, rotation and revocation are session-authenticated β they require a signed-in organization owner, never just the key.
Behind the public endpoint: the organizer page handles splitting and reminders, a Stripe-verified webhook reconciles every payment, and per-participant receipt generation runs after each confirmed charge. You don't call these β but knowing they exist explains why creation alone is enough to start a full collection flow.
The same create-checkout capability, exposed as a native MCP server so an AI assistant can check readiness and publish a checkout on your behalf after you confirm β no API key or code required. Authenticated with your Paywalla session over OAuth and scoped to the organizations you own. See the MCP section β
Three steps: get a key, call the endpoint, store the reference.
Sign in, complete your organization profile and connect Stripe in Settings until card payments are active.
In Settings β External API, click Generate API key. Copy it once β it won't be shown again β and store it server-side in a secret or env var.
Send a JSON body to https://group-split-sync.base44.app/functions/createCheckoutApi with your key in the x-api-key header. The platform publishes it and emails everyone.
Keep the returned checkout_reference against your booking/order for reconciliation and support.
Copy any block. Amounts are decimal major units (e.g. 1200 means $1,200.00); the API converts to minor units.
curl -X POST https://group-split-sync.base44.app/functions/createCheckoutApi \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"title": "Weekend cabin rental",
"target_amount": 1200,
"currency": "usd",
"deadline": "2026-10-01",
"description": "3-night cabin for 6 guests",
"organizer": { "name": "Morgan Reyes", "email": "morgan@example.com" },
"participants": [
{ "name": "Alex Kim", "email": "alex@example.com", "assigned_amount": 400 },
{ "name": "Sam Lee", "email": "sam@example.com", "assigned_amount": 400 },
{ "name": "Pat Ng", "email": "pat@example.com", "assigned_amount": 400 }
]
}'// Create + publish a group checkout from a booking confirmation page.
async function createGroupCheckout({ bookingId, total, dueDate, organizer, guests }) {
const res = await fetch(
"https://group-split-sync.base44.app/functions/createCheckoutApi",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": process.env.PAYWALLA_API_KEY
},
body: JSON.stringify({
title: `Booking ${bookingId}`,
idempotency_key: bookingId, // makes retries safe: replays, never duplicates
target_amount: total, // decimal major units, e.g. 1200
currency: "usd",
deadline: dueDate, // ISO 8601
organizer, // { name, email }
participants: guests.map(g => ({
name: g.name,
email: g.email,
assigned_amount: g.share // optional; leave off for an un-split checkout
}))
})
}
);
const data = await res.json();
if (data.status !== "success") {
// Handle by data.error_code: validation, stripe_not_ready, rate_limited, ...
throw new Error(`[${data.error_code}] ${data.message}`);
}
// Store this against your booking for reconciliation & support.
return data.checkout_reference;
}import crypto from "node:crypto";
// Server-side: keep the key in an env var, never ship it to the browser.
const key = process.env.PAYWALLA_API_KEY;
const res = await fetch("https://group-split-sync.base44.app/functions/createCheckoutApi", {
method: "POST",
headers: { "Content-Type": "application/json", "x-api-key": key },
body: JSON.stringify({
title: "Reunion dinner β Table 12",
target_amount: 540,
currency: "usd",
deadline: new Date(Date.now() + 7 * 86400000).toISOString(),
organizer: { name: "Dana Patel", email: "dana@example.com" },
participants: [
{ name: "Riley", email: "riley@example.com" },
{ name: "Jamie", email: "jamie@example.com" }
]
})
});
const body = await res.json();
if (body.status === "success") console.log("Created", body.checkout_reference);
else console.error(body.error_code, body.message);{
"status": "success",
"checkout_reference": "gc_a1b2c3d4e5f6g7h8"
}{
"status": "error",
"error_code": "validation",
"message": "target_amount must be greater than zero; participants[1].email is invalid"
}The full contract for a create-checkout call β headers, limits, every field, and what comes back.
POST https://group-split-sync.base44.app/functions/createCheckoutApix-api-key: YOUR_API_KEY β or Authorization: Bearer YOUR_API_KEYContent-Type: application/jsonA success returns only status and checkout_reference β store it against your booking or order for reconciliation and support. The platform deliberately never returns organizer or participant pay links, so a leaked key can't impersonate anyone. When you send an idempotency_key, a retry returns the same reference plus idempotent_replay: true β no second checkout, no duplicate emails.
There is no outbound webhook to your system today: the platform emails the organizer and participants directly, and live payment status lives on the organizer page and dashboard. If you need programmatic status, refunds, or reminders, that's the next API β tell us you need it.
No sandbox or test key. The API charges the org's live Stripe β there's no separate test endpoint. Validate with a small real checkout first, and confirm with the org whether their Stripe is in test mode before automating a high-volume flow.
Every error is JSON with status, error_code and message. Branch on error_code in your client.
Paywalla also exposes the same create-checkout capability as a native MCP server, so an AI assistant β ChatGPT, Claude or Cursor β can check readiness and create a published checkout on your behalf, after you confirm, without writing any code.
A Streamable HTTP MCP server at /api/mcp on your published domain, authenticated with your Paywalla session over OAuth. It exposes exactly two tools and opts out of every entity, so the AI can't read or write raw records β it can only check readiness and create checkouts, scoped to the organizations you own.
get_paywalla_readinessRead-only Β· idempotentChecks whether the signed-in user's organization is ready to create and publish a live checkout β profile, Stripe, support email, address and refund terms β and lists what's blocking if not. Call this before gathering any participant details. If the user owns more than one organization, it returns the list and requires an explicit choice; it never silently picks the payout org.
create_group_checkoutConsequential Β· idempotentCreates and immediately publishes a checkout β emails the organizer their private management link and every participant their personal pay link. Requires explicit confirmation after a full preview (org, title, total, currency, deadline, organizer, every participant and amount, and a clear statement that it goes live now). Returns only a checkout_reference β never organizer or participant links.
The MCP server is live only once Paywalla is published. It activates automatically on the next publish.
Open the Connect page and copy the MCP server URL β it's resolved from your published domain, so it's always correct.
Open /connectIn ChatGPT, Claude or Cursor, add a custom MCP server and paste the URL. Step-by-step guides for each client are on the Connect page.
Open /connectThe client opens Paywalla's consent page. Sign in with your own account and approve the tools. The connection is scoped to your organization and revocable; your API key is never shared with the AI.
A successful call is only the start. Here's who the platform touches, what they're told, and what they should expect next β mirror it in your product's copy and support.
They created the checkout from your product and own the guest list, the split and the deadline.
Each guest gets their own pay link by email β no account, no app, no shared link.
They connected Stripe and receive every payment directly β the platform never holds their money.
A few things developers should know about the platform before going live.
Before integrating, complete your organization profile (name, support email, address, default currency, refund terms) in Settings. Several of these become snapshots on receipts and checkouts at publish time.
Connect Stripe and finish onboarding until card payments are active. The API will refuse to publish with stripe_not_ready otherwise. Place a small real test checkout end-to-end through the dashboard so you understand the flow before automating it.
Store it in a secrets manager or server-side env var β never in a client app or public repo. Rotate it immediately if it leaks; revoke it if compromised.
Send a unique reference in your system per call. The API returns a checkout_reference you can store alongside it for reconciliation and support.
Parse the status and error_code fields, not just the HTTP code. Retry only idempotent calls (creation is effectively idempotent per key, but avoid duplicate submits on 5xx until you've checked whether a checkout was created).
The endpoint caps bursts per key. For high volume, queue and throttle; don't fire a request per user interaction in a tight loop.
Every participant needs a valid email and name. Emails with whitespace are rejected to prevent header injection. Dedupe on your side if it matters to your UX.
Creation publishes and emails the organizer and every participant automatically. Don't try to email participants yourself β you don't have their secure pay links, by design.
Pass deadline as an ISO 8601 timestamp. The platform stores it as-is; use UTC to avoid off-by-one due dates across regions.
Refunds, reminders, share-view toggles and split edits happen through the organizer link and dashboard. If you need them programmatically, tell us β that's a likely next API.
The API deliberately returns only a checkout_reference, never organizer or pay links, so a compromised integration can't impersonate an organizer or pay on someone's behalf.
Validate with a single test checkout, confirm the email + receipt flow, then wire it into your real booking or event flow.
One thing to do first: make sure your account is fully set up and Stripe is connected, active and tested with a small real checkout through the dashboard. The API can't publish until Stripe is ready, and it's far easier to understand the flow once you've run it by hand.