Stripe · Platform

Add PayShare to your checkout

Keep Pay now. Show Split with others for a connected property, and start the session on that merchant’s Stripe account.

Keep your existing checkout. Add Split with others under Pay now. For each order, your server works out which merchant it belongs to and starts the split on that merchant’s Stripe account.

SCREENSHOT NEEDED

Platform checkout showing Pay now and Split with others

When to show the button

Render the official button under Pay now only when the property’s PayShare switch is on and PayShare has accepted it, meaning your last property_status call returned ACTIVE or connection_status returns enabled: true. Use the same button and placement rules as a merchant checkout. See Checkout.

Start a split for the right merchant

  1. Load the booking from your database by its reference

  2. Find its property and the Stripe account you charge for it

  3. Create the order proof on that account

    Use your platform’s Stripe key with the merchant’s account, the same way you create payments for them today.

  4. Start the session with the same account

    Send stripeAccountId as the merchant’s account. Everything else is the same as the merchant request.

  5. Return the session URL to the button

Node.js
// Your platform's start-split route
import Stripe from "stripe";
import { bootstrapSessionFromOrderProof, payshareBootstrapPaymentIntentMetadata } from "@payshare/platform-sdk";

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!); // your platform's key

export async function POST(req: Request) {
  const { bookingId } = await req.json();
  const booking = await getBooking(bookingId);              // your database
  const property = await getProperty(booking.propertyId);   // your database

  // Server-side decisions only. Never read these from the request.
  if (!property.payshareEnabled || !property.stripeAccountId) {
    return Response.json({ error: { message: "Split isn’t available for this booking" } }, { status: 409 });
  }

  const proof = await stripe.paymentIntents.create(
    {
      amount: booking.totalMinor,
      currency: booking.currency.toLowerCase(),
      metadata: payshareBootstrapPaymentIntentMetadata(booking.reference),
    },
    { stripeAccount: property.stripeAccountId },
  );

  const session = await bootstrapSessionFromOrderProof(
    { apiBase: "https://app.payshare.nz" },
    {
      stripeAccountId: property.stripeAccountId,
      paymentIntentId: proof.id,
      successReturnUrl: booking.confirmationUrl,
      cancelReturnUrl: booking.checkoutUrl,
      checkoutExpiresAt: booking.holdExpiresAt.toISOString(),
      orderSummary: {
        merchantDisplayName: property.name,
        itemDescription: booking.description,
      },
    },
  );

  await saveSplitSession(booking.id, session); // keep refundToken server-side
  return Response.json({ redirectUrl: session.sessionUrl, sessionUrl: session.sessionUrl });
}

What guests see

SCREENSHOT NEEDED

PayShare participant payment session

  • Set orderSummary.merchantDisplayName to the property or store name, not your platform’s name.
  • Set orderSummary.itemDescription to what is being bought.
  • Send the property’s checkout hold as checkoutExpiresAt, or checkoutHold: "none".

Errors to expect

  • WEBSITE_SETUP_REQUIRED: the property is not connected, or PayShare is off for it. Hide the button.
  • MERCHANT_NOT_INSTALLED: PayShare is not installed on that Stripe account.
  • PLATFORM_SPLIT_OFF: your merchant rules in PayShare have turned Split off for this merchant.

The full list is in Errors.

Next: Handle completion →