# Quickstart

This guide takes you from zero to a working payment in **under 10 minutes**. You will
create a payment session and redirect a test buyer to the hosted checkout.

<Aside type="note">
All requests on this page use **test mode**. No real money moves. See
[Testing](/guides/testing/) for the test cards.
</Aside>

## Prerequisites

- A Paymee merchant account.
- Your **test secret key** (`sk_test_…`) from the dashboard. See
  [Authentication](/guides/authentication/).

<Steps>

1. ### Create a payment session

   Send your first request. The only required fields are the amount, a unique
   `merchant_reference`, and the buyer's name and email.

   <Tabs syncKey="lang">
   <TabItem label="cURL">

   ```bash
   curl https://api.paymee.online/api/v1/gateway/sessions/ \
     -H "Authorization: Bearer sk_test_your_key_here" \
     -H "Content-Type: application/json" \
     -d '{
       "amount": "10.500",
       "currency": "TND",
       "merchant_reference": "order-0001",
       "first_name": "Aymen",
       "last_name": "Ben Salah",
       "email": "aymen@example.com",
       "return_url": "https://your-site.tn/orders/order-0001/paid",
       "cancel_url": "https://your-site.tn/cart",
       "webhook_url": "https://your-site.tn/webhooks/paymee"
     }'
   ```

   </TabItem>
   <TabItem label="Node.js">

   ```js
   const res = await fetch(
     "https://api.paymee.online/api/v1/gateway/sessions/",
     {
       method: "POST",
       headers: {
         Authorization: "Bearer sk_test_your_key_here",
         "Content-Type": "application/json",
       },
       body: JSON.stringify({
         amount: "10.500",
         currency: "TND",
         merchant_reference: "order-0001",
         first_name: "Aymen",
         last_name: "Ben Salah",
         email: "aymen@example.com",
         return_url: "https://your-site.tn/orders/order-0001/paid",
         cancel_url: "https://your-site.tn/cart",
         webhook_url: "https://your-site.tn/webhooks/paymee",
       }),
     },
   );
   const session = await res.json();
   console.log(session.checkout_url);
   ```

   </TabItem>
   <TabItem label="PHP">

   ```php
   <?php
   $ch = curl_init("https://api.paymee.online/api/v1/gateway/sessions/");
   curl_setopt_array($ch, [
     CURLOPT_RETURNTRANSFER => true,
     CURLOPT_POST => true,
     CURLOPT_HTTPHEADER => [
       "Authorization: Bearer sk_test_your_key_here",
       "Content-Type: application/json",
     ],
     CURLOPT_POSTFIELDS => json_encode([
       "amount" => "10.500",
       "currency" => "TND",
       "merchant_reference" => "order-0001",
       "first_name" => "Aymen",
       "last_name" => "Ben Salah",
       "email" => "aymen@example.com",
       "return_url" => "https://your-site.tn/orders/order-0001/paid",
       "cancel_url" => "https://your-site.tn/cart",
       "webhook_url" => "https://your-site.tn/webhooks/paymee",
     ]),
   ]);
   $session = json_decode(curl_exec($ch), true);
   echo $session["checkout_url"];
   ```

   </TabItem>
   </Tabs>

   Send `amount` as a string with exactly three decimals for TND (`"10.500"`). All URLs
   must use `https://` on a public domain name; to receive webhooks on your own machine,
   expose it through an HTTPS tunnel.

2. ### Read the response

   A `201 Created` returns the session, including its `checkout_url`:

   ```json
   {
     "id": "ps_0b7c3a1e-5d2f-4e8a-9c6b-1f2e3d4c5b6a",
     "merchant_reference": "order-0001",
     "amount": "10.500",
     "currency": "TND",
     "status": "CREATED",
     "livemode": false,
     "checkout_url": "https://pay.paymee.online/checkout/kq2V8Zr3xN0bT6mW1yPdF4sHjL9cA7uE",
     "expires_at": "2026-11-21T10:24:00.000000Z"
   }
   ```

   The full response has more fields — see
   [Hosted checkout](/guides/hosted-checkout/#response).

   <Aside type="tip">
   Sending the same `merchant_reference` (with the same amount and currency) again
   returns the **existing** session with `200 OK` instead of creating a duplicate. This
   makes retries safe — see [Idempotency](/guides/idempotency/).
   </Aside>

3. ### Redirect the buyer

   Send the buyer to the `checkout_url`. They pay on the Paymee-hosted page (with 3-D
   Secure). After a successful payment, Paymee redirects them to your `return_url`; the
   page's **Return to store** button takes them to your `cancel_url`.

   ```js
   res.redirect(session.checkout_url);
   ```

4. ### Pay with a test card

   On the checkout page, use a [test card](/guides/testing/):

   - **Visa** `4509 2111 1111 1119`, expiry `12/26`, CVV `748`
   - **3-D Secure code:** `12345`

5. ### Receive the result

   Do **not** rely on the buyer returning to `return_url` to mark an order paid (they may
   close the tab). Instead, handle the **webhooks** Paymee sends to your `webhook_url`:

   - `session.succeeded` → fulfil the order
   - `session.failed` → every attempt was declined: the session is closed; offer a new
     payment (with a new `merchant_reference`)
   - `session.expired` → the buyer never paid: release the order

   Set up and verify webhooks next: [Webhooks](/guides/webhooks/).

</Steps>

## What's next

- [Hosted checkout flow](/guides/hosted-checkout/) — the full lifecycle and every field.
- [Webhooks](/guides/webhooks/) — verify signatures and handle events reliably.
- [Fulfil an order](/guides/fulfil-an-order/) — the whole flow as code you can copy.
- [Going live](/guides/going-live/) — the production checklist.

Source: https://docs.paymee.online/guides/quickstart/
