Skip to content

Hosted checkout flow

Download .md

The hosted checkout is the standard way to accept a card payment. Paymee hosts the payment page and handles 3-D Secure, so card data never reaches your servers.

  1. Create a session — POST /gateway/sessions/ with the amount, buyer, and your URLs. The response includes a checkout_url.
  2. Redirect the buyer to checkout_url.
  3. Buyer pays on the Paymee-hosted page (with 3-D Secure).
  4. Paymee redirects the buyer to your return_url (success/processing) or cancel_url (abandoned).
  5. Paymee sends a webhook to your webhook_url with the authoritative result. Fulfil the order here, not on the browser redirect.
sequenceDiagram
    participant S as Your server
    participant P as Paymee
    participant B as Buyer
    S->>P: POST /gateway/sessions/
    P-->>S: { checkout_url }
    S->>B: redirect to checkout_url
    B->>P: pays on hosted page (3-D Secure)
    P->>B: redirect to return_url / cancel_url
    P->>S: webhook (authoritative result) → fulfil

POST https://api.paymee.online/api/v1/gateway/sessions/

Field Type Required Notes
amount string ✅ Decimal string with currency-correct precision. TND has 3 decimals — see Amounts & currency.
currency string – ISO 4217. Defaults to your account’s currency (TND for Tunisian merchants).
merchant_reference string ✅ Your unique reference for this payment. Reusing it returns the existing session — see Idempotency.
first_name string ✅ Buyer’s given name.
last_name string ✅ Buyer’s surname.
email string ✅ Buyer’s email.
phone string – Buyer’s phone.
description string – Shown on the checkout page.
order_id string – Your display-friendly order id.
items array – Line items: [{ name, quantity, unit_price, description }].
metadata object – Arbitrary key/values echoed back to you (e.g. on webhooks).
return_url string – Where the buyer is sent after paying.
cancel_url string – Where the buyer is sent if they cancel.
webhook_url string – Where Paymee posts the result. Falls back to your account default if omitted.
max_attempts integer – Max payment attempts on the session (1–10, default 5).

See the full schema, including responses, in the API Reference → Create a payment session.

201 Created (or 200 OK if the merchant_reference already existed):

{
"id": "ps_3Nk8x2c9aQ...",
"merchant_reference": "order-0001",
"order_number": "PM-014A2C",
"amount": "10.500",
"currency": "TND",
"status": "CREATED",
"checkout_url": "https://pay.paymee.online/checkout/tok_abc123...",
"buyer_first_name": "Aymen",
"buyer_last_name": "Ben Salah",
"buyer_email": "aymen@example.com"
}

Redirect the buyer to checkout_url.

A session moves through these statuses (status field):

Status Meaning
CREATED Session created, awaiting the first payment attempt.
PROCESSING A payment attempt is in progress with the acquirer (buyer on the hosted page).
PENDING A prior attempt was declined and the session can be retried (still cancellable).
SUCCEEDED Payment succeeded. Terminal.
FAILED Payment declined with no attempts left. Terminal.
EXPIRED Session expired before completion (default TTL 24 h). Terminal.
CANCELED Canceled by you or the buyer. Terminal.
stateDiagram-v2
    direction LR
    [*] --> CREATED
    CREATED --> PROCESSING: payment attempt
    PROCESSING --> SUCCEEDED: approved
    PROCESSING --> PENDING: declined, retries left
    PENDING --> PROCESSING: buyer retries
    PROCESSING --> FAILED: attempts exhausted
    CREATED --> CANCELED: cancel
    PENDING --> CANCELED: cancel
    CREATED --> EXPIRED: TTL
    PENDING --> EXPIRED: TTL
    SUCCEEDED --> [*]
    FAILED --> [*]
    CANCELED --> [*]
    EXPIRED --> [*]

Only CREATED and PENDING sessions can be canceled — once an attempt is PROCESSING, you must wait for it to resolve.

You can fetch the current status at any time with GET /gateway/sessions/{id}/ — useful as a fallback or reconciliation check. Webhooks are the primary mechanism; polling is the backup.

To cancel a session that hasn’t reached a terminal state, call POST /gateway/sessions/{id}/cancel/.