← Home

Developer API

Turn any website or backend into a crypto checkout. Create single-use checkout sessions over REST, drop the embed widget on your storefront, and receive signed webhooks when payments finalize on Solana. Funds settle wallet to wallet; MMO Pay never takes custody.

Authentication

Create an API key in your dashboard and send it as a bearer token. Keys are secret: server-side only, never in browser code or mobile apps.

Authorization: Bearer mmo_sk_...

Verify a key with GET https://pay.mmocoin.pro/api/v1/me.

Create a checkout session

POST /api/v1/checkout-sessions

Returns a single-use hosted checkout URL. Send your buyer there (or open it with the embed widget). The session expires if unpaid.

curl -X POST https://pay.mmocoin.pro/api/v1/checkout-sessions \
  -H "Authorization: Bearer mmo_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Gold pack",
    "amount": 9.99,
    "tokens": ["USDC", "SOL"],
    "clientReferenceId": "order_1042",
    "redirectUrl": "https://yourgame.com/thanks",
    "expiresInMinutes": 60
  }'
{
  "session": {
    "object": "checkout_session",
    "id": "cmc7...",
    "url": "https://pay.mmocoin.pro/pay/gold-pack-ab12cd",
    "status": "open",
    "amount": "9.99",
    "tokens": ["USDC", "SOL"],
    "clientReferenceId": "order_1042",
    "payment": null,
    "expiresAt": "2026-07-20T12:00:00.000Z"
  }
}

Fields: title (required), amount (required unless type is "FLEXIBLE", where the buyer enters the amount), tokens (defaults to every token you accept), description, redirectUrl, clientReferenceId (your order id, echoed back everywhere), metadata (flat JSON, up to 20 keys), and expiresInMinutes (5 to 43200, default 1440).

Read sessions and payments

GET /api/v1/checkout-sessions/:id

Session status is open, completed, or expired. Once completed, the response embeds the settled payment with its on-chain signature and private receipt URL.

GET /api/v1/payments?limit=25&status=SETTLED

Cursor-paginated with nextCursor; pass it back as ?cursor=. Single payments live at /api/v1/payments/:id. Buyers appear as privacy aliases, never raw wallet addresses.

Embed checkout on your site

One script tag turns any element with a data-mmopay attribute into a checkout button that opens a modal, no redirect, no iframe wrangling.

<script src="https://pay.mmocoin.pro/embed.js" async></script>

<button data-mmopay="gold-pack-ab12cd">Buy Gold Pack</button>

<script>
  // Optional: open programmatically (slug or full https://pay.mmocoin.pro/pay/... URL)
  // MMOPay.open("gold-pack-ab12cd");

  window.addEventListener("mmopay:success", (e) => {
    console.log("paid!", e.detail.paymentId, e.detail.receiptUrl);
    MMOPay.close();
  });
</script>

Events on window: mmopay:open, mmopay:status, mmopay:success, mmopay:close. If the link has a redirect URL, the page navigates there after success; disable with MMOPay.open(target, { redirect: false }). For a server-created session, pass session.url straight to MMOPay.open().

Webhooks

Set a webhook URL in your dashboard settings. When a payment settles on-chain we POST a signed event, with retries and backoff:

POST <your webhook URL>
X-MMOPay-Event: payment.settled
X-MMOPay-Timestamp: 1752989400000
X-MMOPay-Signature: sha256=<hex>

{
  "event": "payment.settled",
  "paymentId": "cmc8...",
  "sessionId": "cmc7...",
  "clientReferenceId": "order_1042",
  "amount": "9.99",
  "token": "USDC",
  "buyerAlias": "neon-fox-391",
  "signature": "<solana tx signature>",
  "receiptToken": "...",
  "settledAt": "2026-07-20T11:03:22.000Z"
}

Verify the signature as HMAC-SHA256 over `${timestamp}.${rawBody}` with your webhook secret:

import { createHmac, timingSafeEqual } from "crypto";

function verify(secret, timestamp, rawBody, header) {
  const mac = createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");
  const expected = `sha256=${mac}`;
  return (
    header.length === expected.length &&
    timingSafeEqual(Buffer.from(header), Buffer.from(expected))
  );
}

Treat webhooks as a hint and the API as the source of truth: on receipt, fetch the session or payment and check its status before fulfilling an order.

Errors and limits

Errors return JSON as { "error": "message" } with standard status codes: 400 invalid input, 401 bad key, 404 not found, 429 rate limited. Session creation is limited to 60/minute per key and reads to 240/minute per key.

Questions or missing endpoints? Reach out through the MMOCoin community channels, we build fast.