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 approve it. That puts a hold on their card: their bank reserves the money, but they are not charged until everyone has approved.

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.

Once every participant has approved, all the holds are turned into real charges together and the money lands in your Stripe account.

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

A card hold cannot last forever: Stripe gives us 7 days. So every split records an authorization_expires_at of 7 days after it was created.

We do not let it run that close. A clean-up runs every 6 hours and cancels any order still waiting after 6 days, so we release the holds ourselves with about a day to spare, rather than letting them lapse 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 to release the hold and we then cannot read the payment back to find out why, we genuinely cannot tell those two cases apart. So we record nothing, the share stays authorised, and that person is told we are still confirming what happened rather than being given an answer that might be wrong. We flag it for a human to settle.

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 sitting on your Stripe account belongs to an order still waiting on approvals. Cancel any single one of them — by hand, or with a script that tidies up old uncaptured payments — and you cancel the entire order. The other holds are released, the order moves to canceled, every participant is emailed to say they were not charged, and a checkout_split.canceled webhook fires. None of it can be undone, and your buyer has to start over.

To stop an order, use the SharePay dashboard or POST /api/checkout-splits/:id/cancel.

If you do run automated tidy-ups in Stripe, ours are easy to skip: every payment we create is tagged with checkout_split_id, participant_id, order_reference and participant_email.

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_idYour Stripe account, which the hold is placed on
publishable_keySharePay's public Stripe key, safe to use in a browser

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

fee was recorded when the split was created and is never recalculated. So it always matches what the card will actually be charged, even if our pricing changes while the hold is still open.

client_secret, stripe_account_id and publishable_key are everything Stripe.js needs to take the card on your Stripe account. You get the same client_secret per participant from POST /api/checkout-splits.

Anyone holding a pay link can pay that share — there is no password on it. Treat each one as a secret, and never put one participant's link on a page another participant can see.