This guide shows how to order hosting from PHP using cURL, with safe retries and clear error handling. It uses the SyllHost Reseller API but the pattern fits any similar API.
Before you start
- API access enabled and a key created. See the quick start.
- Your key stored in an environment variable, e.g.
SYLL_KEY. - A product id from
GET /products.
A small client function
function syll($method, $path, $body = null, $idem = null) {
$ch = curl_init('https://syllhost.com/api/v1' . $path);
$headers = ['Authorization: Bearer ' . getenv('SYLL_KEY'), 'Content-Type: application/json'];
if ($idem) $headers[] = 'Idempotency-Key: ' . $idem;
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 60,
CURLOPT_CUSTOMREQUEST => $method, CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => $body ? json_encode($body) : null,
]);
$raw = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return [$status, json_decode($raw, true)];
}
Place an order
[$status, $res] = syll('POST', '/orders/hosting', [
'product_id' => 3, 'cycle' => 'monthly', 'domain' => 'acme-traders.com',
'reference' => 'CUST-77',
'billing' => ['name' => 'Acme Traders', 'email' => 'accounts@acme.example', 'country' => 'PK'],
], 'order-1001');
if (isset($res['error'])) {
// $res['error']['code'] e.g. insufficient_balance, validation_failed, conflict
} else {
$serviceId = $res['data']['service']['id'];
}
Handle each outcome
| Status | What to do |
|---|---|
| 200/201 | Save order_number, service id and invoice number. |
| 402 | Balance too low. Top up and retry with the same key. |
| 409 | Conflict, e.g. key reused for a different order. Check your key logic. |
| 422 | Fix the input; fields lists problems. |
| 429 | Wait for the Retry-After seconds. |
| timeout / 5xx | Retry with the same Idempotency-Key. |
After the order
The account is usually created at once. If service.status is pending, poll GET /services/{id}. Set the first cPanel password with POST /services/{id}/password; the password is shown once, so store it securely.
Security reminder
Keep the key on the server only. See API key security, idempotency and error handling.
Structure your code for growth
Keep API calls in one class or file, separate from your checkout and email code. That way key handling, retries and logging live in one place. Return clean results such as the order number and service id and throw a typed exception for errors, so the rest of your application never touches raw responses.
What to store in your database
| Field | Why |
|---|---|
| Your order id and idempotency key | Safe retries |
| API order_number | Support and lookup |
| Service id | Polling and password resets |
| Invoice number | Accounting |
| Status and timestamps | Reporting |
Background processing
Do not place orders while the customer waits on a checkout page. Queue the job, return a friendly "setting up your account" page, and update the customer when the service becomes active. This avoids timeouts and keeps your checkout responsive.
FAQ
Should I use Guzzle or another library?
Yes, if your project already does. cURL is shown because it works everywhere.
Build with our API: read the Reseller API reference and the step-by-step guide. API access is enabled per account, so contact us to request it.