Skip to content

Connect your billing ​

How a billing system (WHMCS, a shop, your own) keeps devices in step with what customers pay. Every step is one request.

Before you start ​

  1. Create a key under Settings > API Keys: Acts as an administrator, or the reseller the billing sells for; Read and write; limited to your billing server's address. See API keys.

  2. Note the plan ids your products sell:

    sh
    curl https://panel.example.com/api/rest/v1/tariff-plans -H "Authorization: Bearer mtx_your_key"

    Map each product to a tariff_plan_id. A product's billing period should match the plan's months.

  3. Keep two ids in your billing for each customer and service: the Mintrix subscriber_id and device_id.

A new order is paid ​

Add the customer once, then the box:

sh
# 1. The customer
curl -X POST https://panel.example.com/api/rest/v1/subscribers \
  -H "Authorization: Bearer mtx_your_key" -H "Content-Type: application/json" \
  -d '{"name": "Anna Berg", "email": "[email protected]", "phone": "+49 151 2345678"}'
# → {"id": 7, ...}

# 2. The box, on the product's plan; the invoice number as Idempotency-Key
curl -X POST https://panel.example.com/api/rest/v1/devices \
  -H "Authorization: Bearer mtx_your_key" -H "Content-Type: application/json" \
  -H "Idempotency-Key: invoice-10041" \
  -d '{"subscriber_id": 7, "mac": "00:1A:79:12:34:56", "tariff_plan_id": 2}'
# → {"id": 41, "expires_at": "2027-10-22T12:00:00Z", ...}

Store 7 and 41. If the device request fails with a network error, send it again with the same Idempotency-Key: the customer is charged once.

A renewal is paid ​

sh
curl -X POST https://panel.example.com/api/rest/v1/devices/41/renew \
  -H "Authorization: Bearer mtx_your_key" \
  -H "Idempotency-Key: invoice-10042"

The new expiry is the old one plus the plan's months, so paying early is fine. For an upgrade, send the new plan: -d '{"tariff_plan_id": 5}'.

Payment is overdue ​

Switch the box off, and on again when they pay:

sh
curl -X PATCH https://panel.example.com/api/rest/v1/devices/41 \
  -H "Authorization: Bearer mtx_your_key" -H "Content-Type: application/json" \
  -d '{"enabled": false}'

You do not have to: when the expiry date passes, Mintrix switches the device off by itself. A renewal after that switches it on again.

The service is cancelled ​

sh
curl -X DELETE https://panel.example.com/api/rest/v1/devices/41 -H "Authorization: Bearer mtx_your_key"
# When the customer has no devices left:
curl -X DELETE https://panel.example.com/api/rest/v1/subscribers/7 -H "Authorization: Bearer mtx_your_key"

Handle refusals ​

AnswerIn your billing
409 insufficient_creditThe reseller must top up; keep the order pending and retry
409 already_existsThe box is already in Mintrix: find it with GET /devices?mac=… and store its id
409 device_limit, license_limitTell an administrator; nothing was charged
502 ministra_failed, 503, 5xx, network errorsRetry later with the same Idempotency-Key
429Wait Retry-After seconds

All errors: Requests and errors.

Check now and then ​

Compare your billing with Mintrix once a day, e.g. devices that expire soon:

sh
curl "https://panel.example.com/api/rest/v1/devices?expires_before=2026-11-01&enabled=1&limit=100" \
  -H "Authorization: Bearer mtx_your_key"

The same in PHP ​

php
<?php
function mintrix(string $method, string $path, array $body = [], ?string $idempotencyKey = null): array
{
    $ch = curl_init('https://panel.example.com/api/rest/v1' . $path);
    curl_setopt_array($ch, [
        CURLOPT_CUSTOMREQUEST => $method,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 60,
        CURLOPT_HTTPHEADER => array_filter([
            'Authorization: Bearer ' . getenv('MINTRIX_API_KEY'),
            'Content-Type: application/json',
            $idempotencyKey ? 'Idempotency-Key: ' . $idempotencyKey : null,
        ]),
        CURLOPT_POSTFIELDS => $body ? json_encode($body) : null,
    ]);
    $answer = json_decode((string) curl_exec($ch), true) ?? [];
    $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    curl_close($ch);

    if ($status >= 400) {
        throw new RuntimeException(($answer['error'] ?? 'http_' . $status) . ': ' . ($answer['message'] ?? ''), $status);
    }

    return $answer;
}

// A renewal was paid
$device = mintrix('POST', '/devices/41/renew', [], 'invoice-10042');
echo $device['expires_at'];

Integrated media software