---
id: hosted-page
title: The hosted page
summary: pay.ripper.dev/{handle} — the same runtime, no code.
faces: ["public", "agent"]
personalises: ["hosted_page_url", "effective_mode"]
section: front-end
group: Accept a payment
order: 25
---
# The hosted page

Every merchant has `https://pay.ripper.dev/{handle}`. It reads the handle, renders the merchant's
branding and the amount, and runs the SAME runtime through the published loader — created through
the handle route on the merchant's `hosted_page` integration, whose origins are set by the platform.

A page of your own can create one the same way with `handle`:

```js run id=hosted-handle
const result = await ripper.collect({ handle: 'acme-coffee', amount: 4200, currency: 'GBP' });
```

The hosted page always shows the ripper confirmation whatever the integration's
`confirmation_behaviour` says.

The page's headline is the payment link's own headline, or "Complete your payment" when it has
none. When the handle's defaults list items and `extensions.show_order_summary` is on, an order
summary of those items sits beside the checkout (above it on a phone). With no items, or the switch
off, there is no summary. The summary's total comes from the page's cached data and can lag a price
change by up to five minutes; the amount charged is always current.

In test mode a bar across the top of the page says "Test mode — no real money moves", with a
**Test cards** button that lists the reserved test cards.

`/{handle}` is reusable. Once a payment is captured or authorised the page forgets it, so reopening
the page offers a fresh checkout for the same basket, not a record of the payment. A reload in the
same tab during a payment returns to that payment.
