v1

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.txt
Base URL
https://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.

HeaderValue
X-Api-Key Your account API key — format: rms_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
HTTP Header
X-Api-Key: rms_your_key_here
Never expose your API key in client-side code (JavaScript bundles, mobile apps). Always call the Rimest API from your backend server.

Payment Flow

A typical payment integration works in three steps:

1
Create a transaction
Your server calls POST /CreateTransaction with the amount. You receive a transaction guid.
2
Redirect the customer
Send the customer to the payment page: https://rimest.com/pay/{guid}. The page shows the exact NANO amount and a QR code.
3
Get notified instantly
When the payment is confirmed, Rimest sends a signed POST request to the webhook URL configured on your account. No polling needed.
POST /CreateTransaction

Creates a new payment transaction. Returns the transaction guid as a plain JSON string.

Request Headers

HeaderRequiredDescription
X-Api-Key required Your account API key
Content-Type required application/json

Request Body

FieldTypeRequiredDescription
amount string required Raw NANO integer string, or fiat decimal when currencyCode is set
currencyCode int? optional null = raw NANO · 840 = USD
expiryMinutes int? optional Payment window in minutes. Default: 10. Minimum: 2.
note string? optional Internal note or order reference. Not visible to customers.
The webhook URL is configured once on your account (Account page), not per transaction. The account must also be approved before it can accept payments.

Example — 5 USD

Request
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

Request
POST /CreateTransaction
Content-Type: application/json
X-Api-Key: rms_your_key_here

{
  "amount": "1000000000000000000000000000000",
  "currencyCode": null,
  "expiryMinutes": 10
}

Response

200 OK
"a3f7c2d1-84e0-4b2a-9f13-000000000000"

Error Responses

StatusMeaning
400Missing or invalid amount / no API key and no accountGuid
401Invalid API key
403Account not approved, or owner restricted
404Account not found
429Rate limit (50/min) or too many open transactions — retry later
503Live price unavailable (fiat mode) — retry in a few seconds
GET /GetTransaction?guid={"{guid}"}

Returns full details of a transaction. No authentication required — suitable for polling from the customer's browser.

Response Fields

FieldTypeDescription
guidstringTransaction identifier
amountstringRequired payment in raw NANO
feestringPlatform fee in raw NANO (1% of amount by default)
transporterAccountstringNANO address the customer must send to
isCompletedbooltrue once payment is received
createDatestring (ISO 8601)Transaction creation time (UTC)
completedDatestring (ISO 8601)Confirmation time; default 0001-01-01 until completed
expiryMinutesintPayment window duration
accountobjectPublic account info (name, type). Secrets like API key are never included.
200 OK — Example
{
  "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 }
}
POST /CheckTransactionIsComplete

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.

Request
POST /CheckTransactionIsComplete
Content-Type: application/json

{
  "transactionGuid": "a3f7c2d1-84e0-4b2a-9f13-000000000000"
}
Response
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.

Your endpoint must respond with HTTP 2xx. Rimest will not retry failed webhook deliveries automatically — every attempt is logged on your account page where you can re-send it manually, and CheckTransactionIsComplete works as a programmatic fallback.

Webhook Payload

FieldTypeDescription
eventstring"transaction.completed"
transactionGuidstringThe confirmed transaction's GUID
amountstringPaid amount in raw NANO
feestringPlatform fee in raw NANO
senderAccountstringCustomer's NANO address
completedDatestring (ISO 8601)Confirmation timestamp (UTC)
notestring?The note you set when creating the transaction
accountGuidstringYour Rimest account GUID

Webhook Headers

HeaderValue
X-Rimest-Signature sha256=<hex> — HMAC-SHA256 of the raw JSON body, keyed with your account's API key
X-Rimest-Event transaction.completed
Content-Type application/json
Example Payload
POST 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.

Always use a constant-time comparison to prevent timing attacks. Never compare signatures with == or string equality.

Node.js

JavaScript (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
<?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.

currencyCodeCurrencyamount format
null NANO (raw) Integer string — "1000000000000000000000000000000"
840 US Dollar (USD) Decimal string — "9.99"
When using a fiat currency code, the API fetches the live NANO/fiat exchange rate. If the price feed is temporarily unavailable, the endpoint returns 503 — implement a retry with exponential backoff.

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

NANORaw value (string)
0.001 NANO"1000000000000000000000000000"
0.01 NANO"10000000000000000000000000000"
0.1 NANO"100000000000000000000000000000"
1 NANO"1000000000000000000000000000000"
10 NANO"10000000000000000000000000000000"

JavaScript helper

JavaScript
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
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

JavaScript (Node.js)
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
<?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);
?>
RIMEST

System update in progress

The connection will be restored automatically.

Reconnecting…

Retrying in seconds.

Connection failed

The server cannot be reached. Please retry or refresh the page.

Session paused

The session could not be resumed.
Please refresh the page.