Hosted checkout
The fastest way to collect a payment — open a Mediquo checkout URL, no UI to build.
The hosted checkout runs the entire payment flow at checkout.mediquo.com. You
open a URL with the payment details; Mediquo renders the portal, processes the
payment, and reports the result. There's nothing to build, theme, or maintain.
This is the integration the Mediquo native apps use inside a WebView, and it
works equally well in an <iframe> or a new tab.
There are two routes, depending on how the payment session is created — the same split as the web components:
| Route | Use when | Who creates the session |
|---|---|---|
/appointment | You're charging for a booked appointment | Mediquo, from a slot and service |
/ | You're charging for anything else | Your backend, ahead of time |
Charge for an appointment
Send the user to /appointment with the booking details in the URL:
https://checkout.mediquo.com/appointment?api_key=KEY&slot_id=SLOT123&service_id=SVC456#token=USER_TOKENParameters
Parameter names are snake_case.
| Parameter | Required | Default | Notes |
|---|---|---|---|
api_key | Yes | — | Your Mediquo API key. |
token | Yes | — | User auth token. #fragment only — see below. |
slot_id | Yes | — | The booked appointment slot. |
service_id | Yes | — | The service being charged. |
locale | No | es_ES | One of es_ES, en_US, pt_PT, de_DE, ca_ES. |
consultation_reason | No | — | Free text recorded on the consultation. |
env | No | production | development or production. |
Charge for a custom session
When the charge isn't an appointment, create the payment session on your backend
first, then send the user to / with the resulting session in the URL:
https://checkout.mediquo.com/?api_key=KEY&session_id=SESS123&payment_url=https%3A%2F%2F…#token=USER_TOKENParameters
api_key, token, locale and env are the same as above. Instead of a slot,
this route takes the session your backend created:
| Parameter | Required | Default | Notes |
|---|---|---|---|
session_id | Yes | — | The id used to poll the payment status. |
payment_url | Yes | — | Fully-qualified payment portal URL. URL-encode it before adding it to the query string. |
These are the same { sessionId, paymentUrl } a provideSession callback returns
with the <mq-checkout> component —
here you pass them in the URL instead of a callback.
The user token
Put the user token in the URL #fragment (#token=...), never the query
string. The fragment is never sent to servers, so the token stays out of access
logs and the Referer header. A token placed in the query string is ignored and
the page reports it as missing.
If a required parameter is missing or invalid, the page shows a plain-text message listing what's wrong and does not start the payment.
Handle the outcome
The page reports the result with a single message — the same shape on every platform:
{ "type": "success" | "denied" | "error", "payload": { ... }, "v": 1 }In a web or <iframe> embed, listen for it on the window:
window.addEventListener("message", (event) => {
const { type, payload } = JSON.parse(event.data);
if (type === "success") {
console.log("payment confirmed", payload);
}
});Native apps receive the same message through their WebView bridge, so a single build covers iOS, Android, and the web.
type | payload | Meaning |
|---|---|---|
success | { appointmentId } on /appointment, { sessionId, reference } on / | The payment was confirmed. |
denied | { sessionId } | The gateway rejected the payment. |
error | { reason } | Authentication failed, the session couldn't be created, or the flow timed out. |
For full control over the look and feel instead, embed the web components directly.