Rimest Integration Guide
Accept NANO payments in your application using the Rimest API. Create payment transactions, generate payment links, and get notified instantly — all with a single API key.
Download for LLM / AI assistant llms.txthttps://api.rimest.com
· All responses are JSON.
Authentication
Requests that act on your account — such as POST /CreateTransaction — must include your API key in the X-Api-Key HTTP header. Public read endpoints (GetTransaction, CheckTransactionIsComplete) do not require it. You can find and manage your key on the Account page in the dashboard.
X-Api-Key
Your account API key — format: rms_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxX-Api-Key: rms_your_key_here
Payment Flow
A typical payment integration works in three steps:
Creates a new payment transaction. Returns the transaction guid as a plain JSON string.
Request Headers
X-Api-Key
required
Your account API keyContent-Type
required
application/jsonRequest Body
amount
string
required
Raw NANO integer string, or fiat decimal when currencyCode is setcurrencyCode
int?
optional
null = raw NANO · 840 = USDexpiryMinutes
int?
optional
Payment window in minutes. Default: 10. Minimum: 2.note
string?
optional
Internal note or order reference. Not visible to customers.Example — 5 USD
POST /CreateTransaction
Content-Type: application/json
X-Api-Key: rms_your_key_here
{
"amount": "5.00",
"currencyCode": 840,
"expiryMinutes": 15,
"note": "Order #1042"
}Example — Fixed NANO amount
POST /CreateTransaction
Content-Type: application/json
X-Api-Key: rms_your_key_here
{
"amount": "1000000000000000000000000000000",
"currencyCode": null,
"expiryMinutes": 10
}Response
"a3f7c2d1-84e0-4b2a-9f13-000000000000"Error Responses
400Missing or invalid amount / no API key and no accountGuid401Invalid API key403Account not approved, or owner restricted404Account not found429Rate limit (50/min) or too many open transactions — retry later503Live price unavailable (fiat mode) — retry in a few secondsReturns full details of a transaction. No authentication required — suitable for polling from the customer's browser.
Response Fields
guidstringTransaction identifieramountstringRequired payment in raw NANOfeestringPlatform fee in raw NANO (1% of amount by default)transporterAccountstringNANO address the customer must send toisCompletedbooltrue once payment is receivedcreateDatestring (ISO 8601)Transaction creation time (UTC)completedDatestring (ISO 8601)Confirmation time; default 0001-01-01 until completedexpiryMinutesintPayment window durationaccountobjectPublic account info (name, type). Secrets like API key are never included.{
"guid": "a3f7c2d1-84e0-4b2a-9f13-000000000000",
"amount": "5000000000000000000000000000000",
"fee": "50000000000000000000000000000",
"transporterAccount": "nano_1abc...xyz",
"isCompleted": false,
"createDate": "2026-04-28T10:00:00Z",
"completedDate": "0001-01-01T00:00:00",
"expiryMinutes": 15,
"account": { "name": "My Store", "accountType": 0 }
}Lightweight endpoint to check whether a transaction has been paid. Returns a plain JSON boolean. Useful as a fallback if your webhook was not received.
POST /CheckTransactionIsComplete
Content-Type: application/json
{
"transactionGuid": "a3f7c2d1-84e0-4b2a-9f13-000000000000"
}true // or false
Webhooks
Instead of polling, configure a webhook (callback) URL on your account from the Account page. Rimest will POST to that URL the moment the payment is confirmed on the NANO network — typically within 1 second.
Webhook Payload
eventstring"transaction.completed"transactionGuidstringThe confirmed transaction's GUIDamountstringPaid amount in raw NANOfeestringPlatform fee in raw NANOsenderAccountstringCustomer's NANO addresscompletedDatestring (ISO 8601)Confirmation timestamp (UTC)notestring?The note you set when creating the transactionaccountGuidstringYour Rimest account GUIDWebhook Headers
X-Rimest-Signature
sha256=<hex> — HMAC-SHA256 of the raw JSON body, keyed with your account's API keyX-Rimest-Event
transaction.completedContent-Type
application/jsonPOST https://yoursite.com/webhooks/rimest
Content-Type: application/json
X-Rimest-Event: transaction.completed
X-Rimest-Signature: sha256=3d9e5f...a2c1
{
"event": "transaction.completed",
"transactionGuid": "a3f7c2d1-84e0-4b2a-9f13-000000000000",
"amount": "5000000000000000000000000000000",
"fee": "50000000000000000000000000000",
"senderAccount": "nano_3xyz...",
"completedDate": "2026-04-28T10:02:37Z",
"note": "Order #1042",
"accountGuid": "f1e2d3c4-..."
}Signature Verification
To confirm that a webhook request was sent by Rimest and not a third party, verify the X-Rimest-Signature header. Compute HMAC-SHA256 of the raw request body using your API key as the secret, then compare with the received signature.
Node.js
const crypto = require("crypto");
function verifyRimestWebhook(rawBody, signatureHeader, apiKey) {
const expected = "sha256=" +
crypto.createHmac("sha256", apiKey)
.update(rawBody) // Buffer or string — do NOT parse JSON first
.digest("hex");
// Constant-time comparison to prevent timing attacks
return crypto.timingSafeEqual(
Buffer.from(signatureHeader),
Buffer.from(expected)
);
}
// Express.js example:
app.post("/webhooks/rimest", express.raw({ type: "application/json" }), (req, res) => {
const sig = req.headers["x-rimest-signature"];
if (!verifyRimestWebhook(req.body, sig, process.env.RIMEST_API_KEY)) {
return res.status(401).send("Invalid signature");
}
const event = JSON.parse(req.body);
if (event.event === "transaction.completed") {
// Mark order as paid using event.transactionGuid / event.note
console.log("Payment confirmed:", event.transactionGuid);
}
res.sendStatus(200);
});PHP
<?php
function verifyRimestWebhook(string $rawBody, string $sigHeader, string $apiKey): bool {
$expected = "sha256=" . hash_hmac("sha256", $rawBody, $apiKey);
return hash_equals($expected, $sigHeader); // constant-time compare
}
// Webhook handler:
$rawBody = file_get_contents("php://input");
$sigHeader = $_SERVER["HTTP_X_RIMEST_SIGNATURE"] ?? "";
if (!verifyRimestWebhook($rawBody, $sigHeader, $_ENV["RIMEST_API_KEY"])) {
http_response_code(401);
exit("Invalid signature");
}
$event = json_decode($rawBody, true);
if ($event["event"] === "transaction.completed") {
// Mark order as paid using $event["transactionGuid"] / $event["note"]
error_log("Payment confirmed: " . $event["transactionGuid"]);
}
http_response_code(200);
?>Currency Codes
The currencyCode field follows the ISO 4217 numeric standard. When omitted or null, the amount field is treated as raw NANO.
null
NANO (raw)
Integer string — "1000000000000000000000000000000"840
US Dollar (USD)
Decimal string — "9.99"Amount Format (Raw NANO)
The NANO protocol works with indivisible units called raw. 1 NANO equals exactly 10³⁰ raw:
1 NANO = 1000000000000000000000000000000 raw (10³⁰)Always send and store raw amounts as strings — they exceed JavaScript's safe integer range. Use BigInt in JavaScript or BigInteger / Decimal in your language of choice.
Common Amounts
"1000000000000000000000000000""10000000000000000000000000000""100000000000000000000000000000""1000000000000000000000000000000""10000000000000000000000000000000"JavaScript helper
const NANO_MULTIPLIER = BigInt("1000000000000000000000000000000"); // 10^30
function nanoToRaw(nano) {
const [whole, frac = ""] = String(nano).split(".");
const fracPadded = frac.padEnd(30, "0").slice(0, 30);
return (BigInt(whole) * NANO_MULTIPLIER + BigInt(fracPadded)).toString();
}
function rawToNano(raw) {
const r = BigInt(raw);
const whole = r / NANO_MULTIPLIER;
const frac = r % NANO_MULTIPLIER;
return `${whole}.${frac.toString().padStart(30, "0")}`;
}
nanoToRaw("1") // "1000000000000000000000000000000"
nanoToRaw("0.5") // "500000000000000000000000000000"Code Examples
cURL — Create a $5 USD transaction
curl -X POST https://api.rimest.com/CreateTransaction \
-H "Content-Type: application/json" \
-H "X-Api-Key: rms_your_key_here" \
-d '{
"amount": "5.00",
"currencyCode": 840,
"expiryMinutes": 15,
"note": "Order #1042"
}'Node.js — Full payment flow with webhook
const API_BASE = "https://api.rimest.com";
const API_KEY = process.env.RIMEST_API_KEY;
const PAY_BASE = "https://rimest.com/pay";
// 1. Create transaction — returns payment URL to redirect the customer
async function createPayment(amountUsd, note) {
const res = await fetch(`${API_BASE}/CreateTransaction`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": API_KEY,
},
body: JSON.stringify({
amount: amountUsd.toFixed(2),
currencyCode: 840,
expiryMinutes: 15,
note,
}),
});
if (!res.ok) throw new Error(`Rimest API error: ${res.status}`);
const guid = await res.json();
return `${PAY_BASE}/${guid}`;
}
// 2. Webhook handler (Express) — receives confirmation
const crypto = require("crypto");
app.post("/webhooks/rimest", express.raw({ type: "application/json" }), (req, res) => {
const sig = req.headers["x-rimest-signature"];
const expected = "sha256=" + crypto.createHmac("sha256", API_KEY).update(req.body).digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected)))
return res.status(401).send("Invalid signature");
const event = JSON.parse(req.body);
if (event.event === "transaction.completed") {
// Fulfill the order
fulfillOrder(event.note, event.transactionGuid);
}
res.sendStatus(200);
});PHP — Create & handle webhook
<?php
const API_BASE = "https://api.rimest.com";
const PAY_BASE = "https://rimest.com/pay";
// 1. Create transaction
function createTransaction(float $amountUsd, string $note): string {
$ch = curl_init(API_BASE . "/CreateTransaction");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: " . $_ENV["RIMEST_API_KEY"],
],
CURLOPT_POSTFIELDS => json_encode([
"amount" => number_format($amountUsd, 2, ".", ""),
"currencyCode" => 840,
"expiryMinutes" => 15,
"note" => $note,
]),
]);
$guid = json_decode(curl_exec($ch));
curl_close($ch);
return PAY_BASE . "/" . $guid;
}
// 2. Webhook handler
$rawBody = file_get_contents("php://input");
$sigHeader = $_SERVER["HTTP_X_RIMEST_SIGNATURE"] ?? "";
$expected = "sha256=" . hash_hmac("sha256", $rawBody, $_ENV["RIMEST_API_KEY"]);
if (!hash_equals($expected, $sigHeader)) {
http_response_code(401); exit("Invalid signature");
}
$event = json_decode($rawBody, true);
if ($event["event"] === "transaction.completed") {
fulfillOrder($event["note"], $event["transactionGuid"]);
}
http_response_code(200);
?>