Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
WAYL_ENVNoDefault environment for new links: test or live.test
WAYL_API_KEYYesRequired. Merchant token, sent as X-WAYL-AUTHENTICATION.
WAYL_TIMEOUTNoHTTP timeout in seconds.30
WAYL_BASE_URLNoAPI host.https://api.thewayl.com
WAYL_WEBHOOK_URLNoDefault webhook URL for new links.
WAYL_REDIRECT_URLNoWhere buyers land after paying.
WAYL_WEBHOOK_SECRETNoDefault webhook signing secret (10-255 chars).
WAYL_REFERENCE_PREFIXNoPrefix for generated order IDs.book

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
verify_auth_keyA

Check that the configured Wayl API key is accepted by the API.

Call this first when payment tools start failing — it distinguishes a bad or missing
key from a problem with the request itself. Returns the key's validity alongside the
base URL and default environment this server is using.

Makes one network call. To inspect configuration without touching the network —
whether a key is set at all, which env new links default to — use `wayl_status`.

Wayl authenticates before routing, so an unknown path answers 401 rather than 404: a
failure here means the key was rejected *or* WAYL_BASE_URL is wrong, and the status
code cannot tell the two apart. Success says nothing about test versus live — Wayl
uses one key for both, and the environment is chosen per link with `env`.
create_payment_linkA

Create a Wayl payment link and return the checkout URL to send the buyer.

This is the general-purpose builder. For selling a book, `sell_book` is usually less
work — it derives the line items and reference ID for you.

The returned `url` is the hosted checkout page. Nothing is charged until the buyer
completes payment there; poll `check_order_paid` or handle the webhook to learn when
that happens. env='live' takes the buyer's real money; env='test' charges nobody.

`reference_id` must be unique across every link you have ever created; omit it and
one is generated. Passing `webhook_url` without `webhook_secret` is refused — an
unsigned notification cannot be authenticated.

Record the response's `code` and any `webhook_secret` you pass: neither is returned
by any other Wayl endpoint, and no read endpoint reports a link's `env` either. This
call is never retried and Wayl has no idempotency key, so after a timeout check
`get_payment_link` before creating a second link.
get_payment_linkA

Fetch one payment link by your reference ID, including its current status.

Use this to inspect a single order: status, total, timestamps, checkout url. To
answer "can I deliver yet?", call `check_order_paid` instead — it applies the
paid / safeToFulfil verdict rather than leaving you to interpret the status. For many
orders use `get_payment_links_batch`; to browse without knowing IDs use
`list_payment_links`.

Read-only, no side effects. The checkout `code` is returned only by link creation,
and `lineItem` and `webhookSecret` are never echoed back by any endpoint — this call
cannot recover them. `total` comes back as a string, so parse it before doing
arithmetic, and `env` is absent because Wayl never reports which environment a link
belongs to.
list_payment_linksA

List your payment links, newest first, optionally filtered by status.

Use statuses=['Complete', 'Delivered'] to review paid orders, or statuses=['Pending']
to find checkouts a buyer started but never finished; omit `statuses` for every state.
When you already know the reference IDs, use `get_payment_link` or
`get_payment_links_batch` instead of paging through this.

Wayl returns no total count, so do not treat the number of rows as the number of
orders. Keep paging with `nextSkip` while `hasMore` is true — it is a heuristic, true
whenever a full page came back.

Rows are raw Wayl records: `total` is a string, and only status Complete or Delivered
means paid. Nothing here reports which environment a link belongs to, so test and live
orders look identical — confirm with `check_order_paid` before delivering anything.
get_payment_links_batchA

Look up many payment links at once by your own reference IDs (1-100 per call).

Use this when reconciling a batch of orders — far cheaper than calling
`get_payment_link` in a loop. For a single order use `get_payment_link`, or
`check_order_paid` when the question is whether to deliver.

Reference IDs Wayl does not recognise are silently skipped rather than raising, so
`totalFound` below `totalRequested` is normal; the ones that came back missing are
listed under `missingReferenceIds`.

Returns Wayl's raw envelope — `data` alongside `totalRequested` and `totalFound` —
not the enriched record `get_payment_link` gives you. Rows carry no paid verdict:
only status Complete or Delivered counts as settled, and `total` is a string. This is
a POST that creates nothing, but it is not retried on a transient failure.
invalidate_payment_linkA

Cancel a payment link unconditionally so it can no longer be used.

Irreversible: the buyer will not be able to pay through that URL afterwards, and you
would have to issue a new link with a fresh reference ID — reference IDs are unique
across every link you have ever created and cannot be reused.

This does NOT check the link's status first, and Wayl documents no error for
invalidating a link that has already been paid — the outcome in that case is
undefined. Prefer `invalidate_payment_link_if_pending`, or confirm with
`check_order_paid` first.

It cancels the checkout, not the money: if the buyer already paid, use `create_refund`.
Returns Wayl's raw envelope, and the write is not retried on a transient failure.
invalidate_payment_link_if_pendingA

Cancel a payment link only if it is still pending; otherwise do nothing.

Use this to retire a checkout the buyer abandoned, or to withdraw a link you priced
wrong before anyone pays it. It is the safe version of `invalidate_payment_link`,
which cancels without checking status first.

A success response does NOT mean the link was cancelled — Wayl also answers with
success when the link was not pending and nothing happened. Do not report the order
as cancelled on the strength of this call alone; confirm with `get_payment_link`.

Cancellation is irreversible: nobody can pay through that URL afterwards and you
would have to issue a new link with a fresh reference ID. This never moves money —
to return money on an order that was already paid, use `create_refund`.
list_productsA

List the products in your Wayl catalogue, newest first.

Covers Digital, Physical and Service products; Subscription products are not
returned by this endpoint. Digital products are the relevant kind for selling
ebooks, since they carry downloadable files.

This returns richer records than `get_product` does — stock (`qt`, `unlimited`),
variants (`inventories`), discounts and the downloadable file URL appear only here.
To inspect one product's stock, page this endpoint and filter by `id`.

Wayl returns no total count, so do not treat the number of rows as the size of the
catalogue: keep paging with `nextSkip` while `hasMore` is true. `price` comes back
as a string of whole IQD. Listing changes nothing and charges nobody — selling still
means creating a link with `sell_book` or `create_payment_link`.
get_productA

Fetch one product's basic details by ID. Use it when you already have the ID from list_products or a product URL — there is no lookup by name or slug.

Returns a reduced field set: id, name, price, status, url, image, tags and
description. Stock (`qt`, `unlimited`), variants (`inventories`), discounts and
downloadable files are NOT returned here — for those, page `list_products` and
filter by id.

`price` is a string of whole IQD; parse it before doing arithmetic. Read-only:
nothing in the catalogue changes and nobody is charged. A blank product_id is
rejected before any request is made. The catalogue is unrelated to payment links —
selling still means creating one with `sell_book` or `create_payment_link`.
create_refundA

Request a refund against a paid order. This sends real money back to a customer.

The order must already be paid and linked to a customer, and `amount` may not exceed
what the buyer actually paid — run `check_order_paid` first if you are unsure the
order settled.

Wayl reviews the request, so the refund starts in status 'Requested' rather than being
applied immediately; while it sits there you can still withdraw it with `cancel_refund`.
Once Wayl moves it to 'Refunded' there is no undo, so confirm the amount with the user
before calling.

This POST is never retried automatically and Wayl offers no idempotency key: call it
twice and you have two refunds. Save the returned `id` — `get_refund` and `cancel_refund`
need it, and `list_refunds` is the only other place to recover it.
list_refundsA

List refund requests, newest first, optionally filtered by order reference or status.

Use this to recover a refund's Wayl `id`: `create_refund` returns it once, and it is the
only handle `get_refund` and `cancel_refund` accept. Pass `reference_id` to see every
refund raised against one order. When you already hold the refund ID, call `get_refund`
instead of paging this.

Refund statuses are 'Requested' (awaiting Wayl's decision, still cancellable),
'Refunded', 'Rejected' and 'Cancelled'. Amounts come back as numbers in whole IQD,
unlike a link's `total`, which is a string.

Wayl returns no total count, so do not read the row count as the number of refunds.
Keep paging with `nextSkip` while `hasMore` is true.
get_refundA

Fetch one refund request by its Wayl refund ID: reason, linkId, referenceId, amount, initiatedBy and current status ('Requested', 'Refunded', 'Rejected' or 'Cancelled').

Use it to poll a refund you raised with `create_refund` — that call returns the `id` you
pass here. If all you have is the order's reference ID, use `list_refunds` with
`reference_id` instead; nothing on the payment link points back to its refunds.

Read-only: it never changes a refund. To withdraw one still in 'Requested', call
`cancel_refund`.

Wayl omits the refund's own ID from this response, so the server re-attaches it as
`refundId`. Amount is a number in whole IQD, unlike a link's `total`, which is a string.
cancel_refundA

Withdraw a refund request before Wayl acts on it, so no money is returned.

Only refunds still in status 'Requested' can be cancelled. Once Wayl has moved one
to Refunded or Rejected this call will not take it back, so check with `get_refund`
first when you are unsure of the state.

`refund_id` is Wayl's own ID for the refund — the `id` returned by `create_refund`
— not your order's reference ID. If you only have the order, find it with
`list_refunds(reference_id=...)`.

This touches the refund request only; the payment link and the buyer's completed
payment are unaffected. To stop a buyer paying in the first place, use
`invalidate_payment_link_if_pending` instead.

Confirm with the user before calling. Undoing it means filing a fresh refund with
a new 100-character reason, and Wayl reviews that from scratch.
sell_bookA

Create a checkout link for a book order, with the price breakdown filled in.

Builds the line items (copies, discount, delivery), computes the total as
price * quantity + delivery_fee - discount, generates a unique reference ID from
the title, and creates the payment link. Returns the checkout `url` to send the
buyer. The total must reach Wayl's 1000 IQD minimum or the call is rejected.

The buyer sees an itemised breakdown rather than a bare number, which is what you
want for anything beyond a single flat-priced copy.

Creating the link charges nobody — it only produces a checkout page, and a link
created with env='test' never moves real money at all. Do NOT deliver the book
(send a download link, ship a copy) until `check_order_paid` or `parse_webhook` returns
`safeToFulfil: true`. That is a different field from `paid`: a sandbox payment
settles and is still not something to ship against.

Use `create_payment_link` instead when you need a webhook, redirect or custom
line items for one order: here those URLs come from the server's
WAYL_WEBHOOK_URL, WAYL_WEBHOOK_SECRET and WAYL_REDIRECT_URL settings and cannot
be set per call. Persist the returned `code` — no other endpoint returns it.
check_order_paidA

Answer whether an order is paid and safe to fulfil, from your reference ID.

Returns `paid: true` only for statuses Complete or Delivered. Wayl documents the
names of its eight link statuses and nothing else, so this server treats only
those two as settled. Check this before sending a download link or shipping a
copy — a link in status Created or Pending means the buyer has not paid yet.

`paid` and `safeToFulfil` are not the same thing. While this server is in test
mode, a settled payment is a sandbox simulation that moved no real money, so
`safeToFulfil` stays false even when `paid` is true. Act on `safeToFulfil`.

Read-only, so poll it as often as you need. When a webhook delivery arrives use
`parse_webhook` instead — it authenticates the payload and reads the webhook's
separate `paymentStatus` vocabulary. For the full link record use
`get_payment_link`; to reconcile many orders use `get_payment_links_batch`.

The returned `total` is a string, as Wayl sends it. Parse it before arithmetic.
verify_webhookA

Check a webhook's HMAC-SHA256 signature and return only a valid/invalid answer.

Prefer `parse_webhook` for an incoming delivery — it verifies the signature *and*
extracts the payment status, event ID and a paid/not-paid verdict in one call.
Reach for this tool only when the boolean alone is what you need.

Runs locally; makes no network call. Treat a `valid: false` result as an attack
or a misconfiguration and ignore the payload — an unverified "payment complete"
event is exactly how someone gets a book without paying.

Pass the body exactly as received; the digest covers the raw request bytes, so
re-serialising the JSON breaks it. Secrets are per link, not per account. This
errors instead of answering when no signature or secret is available, or when the
secret falls outside Wayl's 10-255 characters — one that short cannot have signed
a real delivery.

`valid: true` does not mean the event is new. There is no timestamp or nonce, so a
captured delivery verifies forever. Deduplicate on the payload's `id`.
parse_webhookA

Verify a Wayl webhook and summarise what it says about the order.

Use this for any incoming delivery: it authenticates the signature, parses the
payload and reports whether the order is paid, all locally with no network call.
Use `verify_webhook` when a bare valid/invalid boolean is enough, and
`check_order_paid` when polling by reference ID rather than handling a push.

The webhook's `paymentStatus` is a different vocabulary from the REST API's link
`status` — it reports "Paid", which is not one of the eight link statuses. This
tool reads the right field so you do not have to.

Never act on a payload where `verified` is false; that result carries no order
details. `paid` and `safeToFulfil` are deliberately different: while this server is
in test mode a settled payment is simulated, so `safeToFulfil` stays false even when
`paid` is true. Branch on `safeToFulfil`.

Deduplicate on `eventId` before delivering — Wayl retries, and the signature has no
timestamp, so a replayed request stays valid forever. A verified body that is not a
JSON object raises an error rather than returning a false verdict.
wayl_statusA

Report how this server is configured, without calling the Wayl API.

Call this first when something looks misconfigured: it returns the base URL, whether
an API key is present, which environment new links default to (`defaultEnv` and
`liveMode`), which optional defaults are set, the reference prefix, and the fixed IQD
currency with its 1000 IQD minimum charge.

It reports presence, not validity — `apiKeyConfigured: true` only means a key was
found in the environment. Use `verify_auth_key` to confirm the key actually works.
Secret values are never returned, only booleans saying whether they are set.

Config is read once at start-up, so editing environment variables changes nothing
until the server is restarted. Makes no network call and changes no state.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/muthanii/waylMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server