{
    "info": {
        "name": "Rune Pay API v1.0",
        "description": "Accept cryptocurrency payments and send payouts.\n\nSet `merchant_api_key` and `payout_api_key` in the collection variables before sending anything. Requests inherit them automatically.",
        "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
    },
    "variable": [
        {
            "key": "base_url",
            "value": "https://rpay.gg/api/v1",
            "type": "string"
        },
        {
            "key": "merchant_api_key",
            "value": "",
            "type": "string"
        },
        {
            "key": "payout_api_key",
            "value": "",
            "type": "string"
        },
        {
            "key": "track_id",
            "value": "",
            "type": "string",
            "description": "Filled in by the create requests; reused by the retrieve ones."
        }
    ],
    "item": [
        {
            "name": "Reference data",
            "description": "Public endpoints. No API key required, no rate limit tied to a key. Cache these — they change rarely.",
            "item": [
                {
                    "name": "List supported currencies",
                    "request": {
                        "method": "GET",
                        "header": [],
                        "url": {
                            "raw": "{{base_url}}/common/currencies",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "common",
                                "currencies"
                            ]
                        },
                        "description": "Returns coins grouped by symbol, each with the networks it can be paid on. Build your checkout selector from this rather than hard-coding a list, because availability changes: a network under maintenance, or one whose provider is unreachable, reports `\"status\": \"unavailable\"` and must not be offered to a customer. A coin's top-level `status` is `true` when at least one of its networks is active.\n\n**`data` is an object keyed by coin symbol, not an array**, and `networks` is keyed by network id. Iterate the values (`Object.values(data)`) rather than indexing by position. Each network also repeats its own `id` so a value-only iteration still knows what it is holding."
                    }
                },
                {
                    "name": "List fiat currencies",
                    "request": {
                        "method": "GET",
                        "header": [],
                        "url": {
                            "raw": "{{base_url}}/common/fiat-currencies",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "common",
                                "fiat-currencies"
                            ]
                        },
                        "description": "You price in fiat and the customer pays in crypto; this is the list of fiat currencies you may price in. Sending an unlisted currency is rejected at creation."
                    }
                },
                {
                    "name": "Current exchange rates",
                    "request": {
                        "method": "GET",
                        "header": [],
                        "url": {
                            "raw": "{{base_url}}/common/prices",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "common",
                                "prices"
                            ]
                        },
                        "description": "Useful for showing an approximate crypto amount before the customer commits. It is **indicative only**: the binding rate is the one locked onto the payment at creation and returned as `rate`. Never compute the amount to charge from this endpoint — use `pay_amount` from the payment itself."
                    }
                },
                {
                    "name": "List networks",
                    "request": {
                        "method": "GET",
                        "header": [],
                        "url": {
                            "raw": "{{base_url}}/common/networks",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "common",
                                "networks"
                            ]
                        },
                        "description": "The same information as currencies, without the grouping. Currencies nests networks under their coin, which is what you want for a checkout selector and not what you want when the question is simply \"what exactly do I put in the `network` field\".\n\nKeyed by network id. Only offer the ones reporting `\"status\": \"active\"`."
                    }
                },
                {
                    "name": "System status",
                    "request": {
                        "method": "GET",
                        "header": [],
                        "url": {
                            "raw": "{{base_url}}/common/status",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "common",
                                "status"
                            ]
                        },
                        "description": "`operational` reflects whether the blockchain provider for that network is reachable and in sync. A network can be enabled but not operational — during a provider outage, for instance. Treat a non-operational network as unavailable for checkout even if it appears in the currencies list."
                    }
                }
            ]
        },
        {
            "name": "Payments",
            "description": "Taking money in. Requires a merchant key (`rp_sec_…`).",
            "item": [
                {
                    "name": "Create a hosted invoice",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "merchant_api_key",
                                "value": "{{merchant_api_key}}",
                                "type": "text"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json",
                                "type": "text"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/payment/invoice",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "payment",
                                "invoice"
                            ]
                        },
                        "description": "The quickest way to take a payment. Rune Pay hosts the checkout page — coin selection, address, QR code, countdown, confirmation tracking — so you only handle the redirect and the callback.\n\nEvery field is optional except `amount`; anything you omit falls back to the defaults configured on the API key, so you can move settings out of your code and into the dashboard. A field sent in the request overrides the key default for that one payment.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"amount\": 25,\n    \"currency\": \"USD\",\n    \"order_id\": \"ORDER-1043\",\n    \"description\": \"Rune verification — 1 year\",\n    \"callback_url\": \"https://example.com/hooks/runepay\",\n    \"return_url\": \"https://example.com/thanks\",\n    \"lifetime\": 60\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "event": [
                        {
                            "listen": "test",
                            "script": {
                                "type": "text/javascript",
                                "exec": [
                                    "const body = pm.response.json();",
                                    "if (body.data && body.data.track_id) {",
                                    "    pm.collectionVariables.set('track_id', body.data.track_id);",
                                    "}"
                                ]
                            }
                        }
                    ]
                },
                {
                    "name": "Create a white-label payment",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "merchant_api_key",
                                "value": "{{merchant_api_key}}",
                                "type": "text"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json",
                                "type": "text"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/payment/white-label",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "payment",
                                "white-label"
                            ]
                        },
                        "description": "Use this when checkout must stay inside your own interface. You get the deposit address, the exact crypto amount and a QR code URL, and you render the page.\n\nThe trade-off is that everything the hosted page does — the countdown, the \"waiting for confirmations\" state, partial-payment handling, expiry — becomes yours to build. `pay_currency` is required here because there is no page for the customer to choose a coin on.\n\nThe response still carries `payment_url`. You do not need it — that is the page you are replacing — but it exists for every payment, and it is the link to send somebody on their phone, or the fallback while your own page is being built.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"amount\": 25,\n    \"currency\": \"USD\",\n    \"pay_currency\": \"USDT\",\n    \"network\": \"TRC20\",\n    \"order_id\": \"ORDER-1044\",\n    \"callback_url\": \"https://example.com/hooks/runepay\"\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "event": [
                        {
                            "listen": "test",
                            "script": {
                                "type": "text/javascript",
                                "exec": [
                                    "const body = pm.response.json();",
                                    "if (body.data && body.data.track_id) {",
                                    "    pm.collectionVariables.set('track_id', body.data.track_id);",
                                    "}"
                                ]
                            }
                        }
                    ]
                },
                {
                    "name": "Retrieve a payment",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "merchant_api_key",
                                "value": "{{merchant_api_key}}",
                                "type": "text"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/payment/{{track_id}}",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "payment",
                                "{{track_id}}"
                            ]
                        },
                        "description": "Returns the same object your callback receives, so you can write one handler for both. Use it to reconcile — after a missed callback, or when a customer asks where their payment is — rather than as a polling loop.\n\nA payment belonging to another merchant returns `404`, not `403`: the API does not reveal that an identifier exists."
                    }
                },
                {
                    "name": "List payments",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "merchant_api_key",
                                "value": "{{merchant_api_key}}",
                                "type": "text"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/payment?",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "payment"
                            ],
                            "query": [
                                {
                                    "key": "size",
                                    "value": "50",
                                    "description": "Results per page, 1–200. Default 25. Values outside the range are clamped, not rejected.",
                                    "disabled": true
                                },
                                {
                                    "key": "page",
                                    "value": "1",
                                    "description": "Page number, starting at 1.",
                                    "disabled": true
                                },
                                {
                                    "key": "order_id",
                                    "value": "ORDER-1043",
                                    "description": "Exact match on your reference.",
                                    "disabled": true
                                },
                                {
                                    "key": "type",
                                    "value": "invoice",
                                    "description": "Filter by kind: `invoice`, `white_label` or `static_address`.",
                                    "disabled": true
                                },
                                {
                                    "key": "currency",
                                    "value": "USDT",
                                    "description": "Filter by the crypto paid in, e.g. `USDT`.",
                                    "disabled": true
                                },
                                {
                                    "key": "from_date",
                                    "value": "1754006400",
                                    "description": "Unix seconds. Only payments created at or after this.",
                                    "disabled": true
                                },
                                {
                                    "key": "to_date",
                                    "value": "1754092800",
                                    "description": "Unix seconds. Only payments created at or before this.",
                                    "disabled": true
                                }
                            ]
                        },
                        "description": "Newest first. Combine filters freely — they AND together. Intended for reconciliation and reporting; for live status use callbacks."
                    }
                },
                {
                    "name": "Payment statistics",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "merchant_api_key",
                                "value": "{{merchant_api_key}}",
                                "type": "text"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/payment/statistics?",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "payment",
                                "statistics"
                            ],
                            "query": [
                                {
                                    "key": "from_date",
                                    "value": "1754006400",
                                    "description": "Unix seconds. Defaults to thirty days ago.",
                                    "disabled": true
                                },
                                {
                                    "key": "to_date",
                                    "value": "1754092800",
                                    "description": "Unix seconds. Defaults to now.",
                                    "disabled": true
                                }
                            ]
                        },
                        "description": "Aggregates your payments so a dashboard does not have to page the whole history and add it up itself. Defaults to the last thirty days.\n\n**Volume counts confirmed payments only.** Including money that has been promised but not confirmed is how a dashboard ends up flattering the merchant, and the figure would move backwards whenever something expired."
                    }
                },
                {
                    "name": "Cancel a payment",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "merchant_api_key",
                                "value": "{{merchant_api_key}}",
                                "type": "text"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/payment/{{track_id}}/cancel",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "payment",
                                "{{track_id}}",
                                "cancel"
                            ]
                        },
                        "description": "Only a payment that has not yet received money can be cancelled. Once funds are on the way — even unconfirmed — the payment is in a final state and this returns `409`, because the coins are real and cannot be un-sent.\n\nCancelling is optional: a payment expires on its own at `expired_at`. Cancel explicitly when the customer abandons checkout, so your dashboard stays clean."
                    }
                },
                {
                    "name": "Get balances",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "merchant_api_key",
                                "value": "{{merchant_api_key}}",
                                "type": "text"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/balance",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "balance"
                            ]
                        },
                        "description": "The same figures as the payout balance, but reachable with a MERCHANT key.\n\nThat distinction is the point: a merchant who only takes payments can hold no payout key at all — the credential that could move money out — and still see what they have. Reading a balance is not spending it."
                    }
                },
                {
                    "name": "Create a static address",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "merchant_api_key",
                                "value": "{{merchant_api_key}}",
                                "type": "text"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json",
                                "type": "text"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/payment/static-address",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "payment",
                                "static-address"
                            ]
                        },
                        "description": "Unlike an invoice, a static address has no amount and no expiry. Anything sent to it is credited (minus your key's payment fee) and reported by callback. This is how you build user-balance top-ups: mint one address per user, store it, and let them fund it repeatedly.\n\n**The `order_id` is the identity.** Calling again with the same `order_id` and network returns the **same** address with a `200` — retries are free and safe. A different `order_id` mints a **new** address with a `201`. Omitting it entirely gives you one standing address per network. So for a platform with many users, pass each user's ID as `order_id` and every user gets an address of their own.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"network\": \"TRC20\",\n    \"order_id\": \"user-8842\",\n    \"callback_url\": \"https://example.com/hooks/topup\",\n    \"description\": \"Balance top-up\"\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "event": [
                        {
                            "listen": "test",
                            "script": {
                                "type": "text/javascript",
                                "exec": [
                                    "const body = pm.response.json();",
                                    "if (body.data && body.data.track_id) {",
                                    "    pm.collectionVariables.set('track_id', body.data.track_id);",
                                    "}"
                                ]
                            }
                        }
                    ]
                },
                {
                    "name": "List static addresses",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "merchant_api_key",
                                "value": "{{merchant_api_key}}",
                                "type": "text"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/payment/static-address",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "payment",
                                "static-address"
                            ]
                        },
                        "description": "Includes revoked ones, so check `status`. There is no pagination here — the result is capped at 200; keep your own mapping of user to address rather than searching this list at runtime."
                    }
                },
                {
                    "name": "Revoke a static address",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "merchant_api_key",
                                "value": "{{merchant_api_key}}",
                                "type": "text"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/payment/static-address/{{track_id}}/revoke",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "payment",
                                "static-address",
                                "{{track_id}}",
                                "revoke"
                            ]
                        },
                        "description": "Marks it `revoked` and stops watching it.\n\nThe address still exists on the blockchain and anyone who kept it can still send to it. Those funds will **not** be credited or reported. Stop showing a revoked address to customers before you revoke it, not after."
                    }
                }
            ]
        },
        {
            "name": "Payouts",
            "description": "Sending money out. Requires a payout key (`rp_out_…`) and the custodial wallet.",
            "item": [
                {
                    "name": "Get balances",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "payout_api_key",
                                "value": "{{payout_api_key}}",
                                "type": "text"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/payout/balance",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "payout",
                                "balance"
                            ]
                        },
                        "description": "`available` is what you can pay out right now. `locked` is reserved by payouts already queued or awaiting approval — it is still yours, but already committed. Check `available` before queueing a payout, not the sum."
                    }
                },
                {
                    "name": "Create a payout",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "payout_api_key",
                                "value": "{{payout_api_key}}",
                                "type": "text"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json",
                                "type": "text"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/payout",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "payout"
                            ]
                        },
                        "description": "The funds are locked immediately and the payout enters the same pipeline as a dashboard withdrawal — including approval, if your account requires it. This queues a payout; it does not bypass any control.\n\n**The destination address is not recoverable if wrong.** Rune Pay validates the format for the network, but cannot know whether the address is the one you meant. Validate against your own records before calling.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"address\": \"TSkW4NMLLp5ZLbP2NC1Fv3n1RmghJ8UtwT\",\n    \"currency\": \"USDT\",\n    \"network\": \"TRC20\",\n    \"amount\": 100,\n    \"order_id\": \"PAYOUT-556\",\n    \"callback_url\": \"https://example.com/hooks/payout\"\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "event": [
                        {
                            "listen": "test",
                            "script": {
                                "type": "text/javascript",
                                "exec": [
                                    "const body = pm.response.json();",
                                    "if (body.data && body.data.track_id) {",
                                    "    pm.collectionVariables.set('track_id', body.data.track_id);",
                                    "}"
                                ]
                            }
                        }
                    ]
                },
                {
                    "name": "Retrieve a payout",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "payout_api_key",
                                "value": "{{payout_api_key}}",
                                "type": "text"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/payout/{{track_id}}",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "payout",
                                "{{track_id}}"
                            ]
                        },
                        "description": "Watch `tx_hash` to appear once broadcast, and `status` to reach `Confirmed`. On failure, `error` carries the reason — a rejection note from an approver, or the broadcast error."
                    }
                },
                {
                    "name": "List payouts",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "payout_api_key",
                                "value": "{{payout_api_key}}",
                                "type": "text"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/payout?",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "payout"
                            ],
                            "query": [
                                {
                                    "key": "size",
                                    "value": "50",
                                    "description": "Results per page, 1–200. Default 25.",
                                    "disabled": true
                                },
                                {
                                    "key": "page",
                                    "value": "1",
                                    "description": "Page number, starting at 1.",
                                    "disabled": true
                                },
                                {
                                    "key": "currency",
                                    "value": "USDT",
                                    "description": "Filter by currency.",
                                    "disabled": true
                                },
                                {
                                    "key": "status",
                                    "value": "confirmed",
                                    "description": "Filter by internal status, e.g. `sent`, `confirmed`, `rejected`.",
                                    "disabled": true
                                }
                            ]
                        },
                        "description": "Newest first. Same pagination shape as the payment list."
                    }
                }
            ]
        }
    ]
}