Moosyl logo

Checkout Session

Use Moosyl hosted checkout: create a checkout session on your server and redirect customers to a Moosyl payment page where they pay with their bank app.

A checkout session is a Moosyl-hosted payment page. Your server creates the session with your secret key, gets back a checkoutUrl, and redirects the customer there. The customer picks their bank app and pays; Moosyl then sends them to your successUrl or cancelUrl.

Use it when you don't want to build any payment UI yourself.

Create a session

You can create a session in two ways.

From an order ID

Pass your own transactionId and the amount in MRU. Moosyl creates the payment request for you. If a payment request with that transactionId already exists, Moosyl uses it and ignores amount.

import { Moosyl } from "moosyl-sdk";

const moosyl = new Moosyl(process.env.MOOSYL_SECRET_KEY!);

const { checkoutUrl } = await moosyl.createCheckoutSession({
  transactionId: "order_1043",
  amount: 2500,
  phoneNumber: "22222222",
  successUrl: "https://example.com/orders/1043/paid",
  cancelUrl: "https://example.com/orders/1043",
  expiresInMinutes: 30,
});
curl https://api.moosyl.com/checkout-session \
  -H "Authorization: $MOOSYL_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transactionId": "order_1043",
    "amount": 2500,
    "successUrl": "https://example.com/orders/1043/paid",
    "cancelUrl": "https://example.com/orders/1043"
  }'

From an existing payment request

If you already created a payment request (with POST /payment-request), pass its id as paymentRequestId. The other payment fields are then ignored.

const { checkoutUrl } = await moosyl.createCheckoutSession({
  paymentRequestId: "b7a4e0f2-5c3d-4a8e-9f10-6d2e8c7b1a53",
  successUrl: "https://example.com/orders/1043/paid",
  cancelUrl: "https://example.com/orders/1043",
  expiresInMinutes: 30,
});

Parameters

FieldRequiredNotes
paymentRequestIdOne of these twoUse an existing payment request.
transactionIdOne of these twoYour own order ID, unique per environment.
amountWith a new transactionIdWhole MRU, greater than 0.
phoneNumberNoCustomer's 8-digit phone number, e.g. 22222222.
successUrlNoWhere the customer goes after paying.
cancelUrlNoWhere the customer goes if they cancel.
expiresInMinutesNo5 to 1440. Defaults to 30.

moosyl-sdk requires more fields

The TypeScript SDK's types require successUrl, cancelUrl and expiresInMinutes, and phoneNumber when you pass transactionId. The HTTP API treats them as optional.

Response

{
  "data": {
    "id": "c4f8e2a1-6b3d-4e9f-a7c5-1d8b3e6f2a90",
    "paymentRequestId": "b7a4e0f2-5c3d-4a8e-9f10-6d2e8c7b1a53",
    "status": "open",
    "successUrl": "https://example.com/orders/1043/paid",
    "cancelUrl": "https://example.com/orders/1043",
    "expiresAt": "2026-09-25T10:44:02.000Z"
  },
  "checkoutUrl": "https://payments.moosyl.com/checkout/c4f8e2a1-6b3d-4e9f-a7c5-1d8b3e6f2a90"
}

A session's status is open, completed, expired or cancelled. If an open session already exists for the same payment request, Moosyl returns that session instead of creating a new one. A payment request that's already paid can't get a new session.

Redirect the customer

Send the customer to checkoutUrl, from your server with a redirect or from your frontend:

window.location.href = checkoutUrl;

Confirm the payment

Reaching your successUrl is not proof of payment: anyone can open that URL. Fulfil the order when you receive a webhook for the payment with status: "completed", matching it to your order by transactionId.

Next steps