Skip to main content

Participants pay

Each participant has their own link:

https://share-pay.co.uk/split/pay/<pay_token>

They open it, see only their share, and authorise a card hold. The page works in any browser. Someone with the SharePay app installed opens the link in the app instead, which shows the same share and then hands off to the same secure card page, so the amount and the outcome are identical either way.

What the payer is charged

Three lines, in this order: their share, a flat 20p SharePay service fee, and the total charged to their card. The hold and the eventual charge are both for that total, and the button they press quotes it, so nobody meets the 20p after the fact. You receive the share. See what SharePay charges.

LineOn a £40 share
Your share of <your business name>£40.00
SharePay service fee£0.20
Total charged to your card£40.20

A participant whose share was cancelled sees their share alone, because nothing was charged and nothing ever will be.

When every participant has authorised, the engine captures all the holds to your account at once.

There is no decline button

If someone never approves, the group runs out of time and all holds are released. Nobody is charged, including the people who already approved. There is no explicit decline action anywhere in the flow: an unapproved share simply expires.

That means a group that has gone quiet does not produce a fast checkout_split.canceled webhook. It produces one up to six days later, when the expiry job reaches it.

The time limit, precisely

Each split is stamped with an authorization_expires_at of creation plus 7 days, matching Stripe's manual-capture window. A job runs every 6 hours and cancels any split still pending more than 6 days after it was created, so a hold is always released by us with roughly a day to spare rather than expiring unpredictably at Stripe's end.

A release we cannot get through to Stripe is the one exception: that hold is left to lapse at authorization_expires_at on Stripe's own schedule. The share is still canceled, because nothing was or ever will be captured, and the customer's copy says they were not charged rather than promising the hold has already gone.

A share that has already been captured, typically because you took it by hand in your own Stripe dashboard, is the other exception. It is recorded captured, not canceled, whether we learn it from Stripe refusing the release or from the capture webhook arriving first, and we check which case it is rather than assuming. That person is not sent the "you were not charged" email, and both the pay page and the app tell them plainly that their share was charged and quote the real figure, rather than repeating the order's cancellation at them. It is a charge on a cancelled order, so we alert ourselves to reconcile it with you.

If Stripe refuses the release and we cannot read the PaymentIntent back at all, we cannot tell those two apart. Nothing is written to that share, it stays authorised, that person is told we are still confirming what happened rather than being given either answer, and we alert ourselves to settle it by hand.

authorization_expires_at is on GET /api/checkout-splits/:id, so you can show an exact deadline rather than an estimate. Note the job only looks at splits whose status is still pending.

Do not cancel SharePay holds in your Stripe dashboard

Every uncaptured hold on your connected account belongs to a split that is still collecting approvals. Cancelling any one of them, by hand in Stripe or with an automated sweep of uncaptured PaymentIntents, cancels the whole split: the remaining holds are released, the split moves to canceled, every participant is emailed to say they were not charged, and a checkout_split.canceled webhook fires. It cannot be undone, and the buyer has to start again.

To stop a split, use POST /api/checkout-splits/:id/cancel or the SharePay dashboard. Every SharePay PaymentIntent carries checkout_split_id, participant_id, order_reference and participant_email in its Stripe metadata, so you can filter them out of any housekeeping job.

What we email your customers

SharePay sends transactional email directly to the participants, under your business name. This is not optional, is not configurable, and does not use your own from-address. Expect it to arrive alongside your own order emails.

WhenWho gets itSubject
The split is createdEvery participant except the person who created it<creator's name> invited you to split <order reference>
The split capturesEvery participantYour £<total charged> for <your business name> was charged
The split is cancelled or expiresEvery participantNames your business and says they were not charged

The invite carries the pay link, your business name, the order reference, that person's share, the 20p service fee and the total their card will be charged. The capture email quotes that same total, not the bare share, so it matches their statement. All three are best-effort: a delivery failure is logged and never blocks the payment.

Host the pay step yourself

You do not have to send people to share-pay.co.uk. The pay view behind that page is a public endpoint, so you can render the payment step in your own brand:

GET /api/checkout-splits/pay/<pay_token>

No credentials, rate limited to 60 requests a minute per IP. Returns:

FieldNotes
merchant_nameYour business name
order_referenceThe order this split is for
currencygbp
amountThis participant's share only, as a decimal string in pounds
feeThe SharePay service fee on this share, normally 0.20. 0.00 for a participant whose share was cancelled, because nothing was charged
totalWhat the card is charged: amount plus fee. 0.00 for a cancelled participant. Quote this, not amount, on any button or confirmation
split_statusThe split's lifecycle status
participant_statusThis participant's own status
counts{ authorised, total }, for a "3 of 4 approved" indicator
client_secretStripe client secret for placing this hold. null once the participant is no longer pending, because there is nothing left to confirm
stripe_account_idThe connected account the hold is opened on
publishable_keySharePay's Stripe publishable key

An unknown or dead token returns 404 {"error":"This split link is no longer valid."}.

fee is the figure frozen onto that participant's PaymentIntent when the split was created, not a live recalculation, so it always agrees with what the card will actually be charged even if our pricing changes while the hold is open.

client_secret, stripe_account_id and publishable_key are everything Stripe.js needs to confirm the card on the connected account. The same clientSecret is also returned per participant by POST /api/checkout-splits.

A pay token is a bearer credential for one person's share. Treat it as a secret, and never render another participant's token on a page.