MolnPayDocs
API reference

Invoices

GET/v1/invoices
AuthorizationBearer <token>

Authorization: Bearer mp<64 hex> for live, mptest<64 hex> for test.

The token is the prefix plus 64 lowercase hex characters (32 CSPRNG bytes) and nothing else — no separators, no embedded fields — so nothing in it needs quoting, escaping or encoding. Send it in the Authorization header and nowhere else. Never put it in a query string: URLs reach access logs, proxy logs, browser history and Referer headers, and a key that lands in any of those is a leaked key. A key's KIND (checkout, payout or wallet) is a property of the key, not of the string: it is chosen at creation, returned by GET /v1/ping, and decides which routes the key may reach.

The full key is shown exactly once, at creation. No endpoint can return it afterwards. Moving funds additionally requires signing to be enabled globally, for your project, and for that key — so a read-only key is a supported configuration.

In: header

Query Parameters

limit?integer
Range1 <= value <= 100
Default25
cursor?string

Opaque cursor from the previous page's next_cursor.

status?string

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/v1/invoices"
{  "object": "list",  "has_more": true,  "next_cursor": "string",  "data": [    {      "object": "invoice",      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",      "reference_id": "string",      "title": "string",      "price_amount": "string",      "price_currency": "string",      "status": "string",      "received_amount": "string",      "fee_bps": 0,      "fee_fixed_cents": "string",      "fee_cap_cents": "string",      "expires_at": "2019-08-24T14:15:22Z",      "paid_at": "2019-08-24T14:15:22Z",      "created_at": "2019-08-24T14:15:22Z"    }  ]}
POST/v1/invoices

Mints one payment address per chain you accept (identical on every EVM chain) and locks a rate per asset for the life of the invoice. The payer sends the quoted atomic amount to the address; the settler credits it once final.

price_amount is integer MINOR units of price_currency (cents), as a string. Only USD is priced today.

The fee is frozen onto the invoice at creation (fee_bps, fee_fixed_cents, fee_cap_cents) from your plan and is charged to your operational balance when the payment credits — never taken out of the coins.

A reference_id makes the create idempotent: a retry returns the FIRST invoice, addresses and rates included.

Live invoices require an active, funded plan (see GET /v1/billing); test projects are never gated.

AuthorizationBearer <token>

Authorization: Bearer mp<64 hex> for live, mptest<64 hex> for test.

The token is the prefix plus 64 lowercase hex characters (32 CSPRNG bytes) and nothing else — no separators, no embedded fields — so nothing in it needs quoting, escaping or encoding. Send it in the Authorization header and nowhere else. Never put it in a query string: URLs reach access logs, proxy logs, browser history and Referer headers, and a key that lands in any of those is a leaked key. A key's KIND (checkout, payout or wallet) is a property of the key, not of the string: it is chosen at creation, returned by GET /v1/ping, and decides which routes the key may reach.

The full key is shown exactly once, at creation. No endpoint can return it afterwards. Moving funds additionally requires signing to be enabled globally, for your project, and for that key — so a read-only key is a supported configuration.

In: header

Header Parameters

Idempotency-Key?string

Recommended. Replays the stored response for a repeated key.

Lengthlength <= 255

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/v1/invoices" \  -H "Content-Type: application/json" \  -d '{    "price_amount": "string"  }'
{  "object": "invoice",  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "reference_id": "string",  "title": "string",  "description": "string",  "price_amount": "string",  "price_currency": "string",  "status": "open",  "fee_bps": 0,  "fee_fixed_cents": "string",  "fee_cap_cents": "string",  "metadata": {},  "return_url": "string",  "cancel_url": "string",  "expires_at": "2019-08-24T14:15:22Z",  "created_at": "2019-08-24T14:15:22Z",  "received_amount": "string",  "excess_amount": "string",  "checkout_url": "string",  "addresses": [    {      "chain": "ethereum",      "address": "string",      "memo": "string"    }  ],  "quotes": [    {      "chain": "ethereum",      "asset": "string",      "contract": "string",      "amount_atomic": "1500000000000000000",      "amount": "string",      "decimals": 0,      "rate": "string",      "rate_source": "string"    }  ]}
GET/v1/invoices/{id}
AuthorizationBearer <token>

Authorization: Bearer mp<64 hex> for live, mptest<64 hex> for test.

The token is the prefix plus 64 lowercase hex characters (32 CSPRNG bytes) and nothing else — no separators, no embedded fields — so nothing in it needs quoting, escaping or encoding. Send it in the Authorization header and nowhere else. Never put it in a query string: URLs reach access logs, proxy logs, browser history and Referer headers, and a key that lands in any of those is a leaked key. A key's KIND (checkout, payout or wallet) is a property of the key, not of the string: it is chosen at creation, returned by GET /v1/ping, and decides which routes the key may reach.

The full key is shown exactly once, at creation. No endpoint can return it afterwards. Moving funds additionally requires signing to be enabled globally, for your project, and for that key — so a read-only key is a supported configuration.

In: header

Path Parameters

id*string

The invoice's public id.

Formatuuid

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/v1/invoices/497f6eca-6276-4993-bfeb-53cbbbba6f08"
{  "object": "invoice",  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "reference_id": "string",  "title": "string",  "description": "string",  "price_amount": "string",  "price_currency": "string",  "status": "open",  "fee_bps": 0,  "fee_fixed_cents": "string",  "fee_cap_cents": "string",  "metadata": {},  "return_url": "string",  "cancel_url": "string",  "expires_at": "2019-08-24T14:15:22Z",  "created_at": "2019-08-24T14:15:22Z",  "received_amount": "string",  "excess_amount": "string",  "checkout_url": "string",  "addresses": [    {      "chain": "ethereum",      "address": "string",      "memo": "string"    }  ],  "quotes": [    {      "chain": "ethereum",      "asset": "string",      "contract": "string",      "amount_atomic": "1500000000000000000",      "amount": "string",      "decimals": 0,      "rate": "string",      "rate_source": "string"    }  ]}
POST/v1/invoices/{id}/cancel

Closes the window early, for an order that was abandoned or replaced. Needs invoices:write rather than a payout scope, because cancelling moves no money.

🔴 IT DOES NOT CLOSE THE PAYMENT ADDRESS. The address is an ordinary keyless customer wallet and stays watched forever, so a transfer arriving afterwards is still detected and still credited — surfaced as late, never voided.

An invoice that has already received money cannot be cancelled: reversing a credited payment is a refund, which needs a destination only the payer can give.

AuthorizationBearer <token>

Authorization: Bearer mp<64 hex> for live, mptest<64 hex> for test.

The token is the prefix plus 64 lowercase hex characters (32 CSPRNG bytes) and nothing else — no separators, no embedded fields — so nothing in it needs quoting, escaping or encoding. Send it in the Authorization header and nowhere else. Never put it in a query string: URLs reach access logs, proxy logs, browser history and Referer headers, and a key that lands in any of those is a leaked key. A key's KIND (checkout, payout or wallet) is a property of the key, not of the string: it is chosen at creation, returned by GET /v1/ping, and decides which routes the key may reach.

The full key is shown exactly once, at creation. No endpoint can return it afterwards. Moving funds additionally requires signing to be enabled globally, for your project, and for that key — so a read-only key is a supported configuration.

In: header

Path Parameters

id*string

The invoice's public id.

Formatuuid

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/v1/invoices/497f6eca-6276-4993-bfeb-53cbbbba6f08/cancel"
{  "object": "invoice",  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "reference_id": "string",  "title": "string",  "description": "string",  "price_amount": "string",  "price_currency": "string",  "status": "open",  "fee_bps": 0,  "fee_fixed_cents": "string",  "fee_cap_cents": "string",  "metadata": {},  "return_url": "string",  "cancel_url": "string",  "expires_at": "2019-08-24T14:15:22Z",  "created_at": "2019-08-24T14:15:22Z",  "received_amount": "string",  "excess_amount": "string",  "checkout_url": "string",  "addresses": [    {      "chain": "ethereum",      "address": "string",      "memo": "string"    }  ],  "quotes": [    {      "chain": "ethereum",      "asset": "string",      "contract": "string",      "amount_atomic": "1500000000000000000",      "amount": "string",      "decimals": 0,      "rate": "string",      "rate_source": "string"    }  ]}