Skip to main content

PHP SDK

Not published yet

The PHP SDK exists as source code but is not yet published on Packagist. It cannot be installed via composer require today. The code below documents the API as it will look once the SDK is published — in the meantime, use the public API directly over HTTP (see the Laravel example using Guzzle).

Installation (coming soon)​

composer require moncreneau/moncreneau-php

Configuration​

<?php

require_once 'vendor/autoload.php';

use Moncreneau\Moncreneau;

$client = new Moncreneau('YOUR_API_KEY');

With options:

<?php

use Moncreneau\Moncreneau;

$client = new Moncreneau('YOUR_API_KEY', [
'baseUrl' => 'https://mc-prd.duckdns.org/api/v1',
'timeout' => 30,
]);

List departments​

<?php

require_once 'vendor/autoload.php';

use Moncreneau\Moncreneau;

$client = new Moncreneau('YOUR_API_KEY');

try {
$departments = $client->departments->list();

foreach ($departments as $dept) {
echo sprintf("ID: %d - %s\n", $dept['id'], $dept['name']);
}
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}

Create an appointment​

<?php

require_once 'vendor/autoload.php';

use Moncreneau\Moncreneau;
use Moncreneau\Exceptions\MoncreneauException;

$client = new Moncreneau('YOUR_API_KEY');

try {
$appointment = $client->appointments->create([
'departmentId' => 5,
'dateTime' => '2026-02-15T10:00:00',
'name' => 'Amadou Diallo'
]);

echo "✅ Appointment created!\n";
echo "ID: {$appointment['id']}\n";
echo "QR Code: {$appointment['qrCode']}\n";

} catch (MoncreneauException $e) {
if ($e->getErrorCode() === 'INSUFFICIENT_CREDITS') {
echo "❌ Insufficient credits: {$e->getMessage()}\n";
} else {
echo "❌ Error: {$e->getMessage()}\n";
}
}

Check slot availability​

The backend checks a single slot (dateTime), not a date range.

<?php

use Moncreneau\Moncreneau;

$client = new Moncreneau('YOUR_API_KEY');

$availability = $client->departments->getAvailability('5', '2026-02-15T10:00:00');

if ($availability['available']) {
echo "✅ Slot available! Remaining slots: {$availability['remainingSlots']}\n";
} else {
echo "❌ Slot unavailable: {$availability['unavailabilityReason']}\n";
}

Cancel an appointment​

<?php

use Moncreneau\Moncreneau;

$client = new Moncreneau('YOUR_API_KEY');

$client->appointments->cancel('123');
echo "✅ Appointment cancelled, 1 credit refunded\n";

Laravel integration​

<?php
// app/Providers/MoncreneauServiceProvider.php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Moncreneau\Moncreneau;

class MoncreneauServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(Moncreneau::class, function ($app) {
return new Moncreneau(config('services.moncreneau.key'));
});
}
}
<?php
// app/Http/Controllers/AppointmentController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Moncreneau\Moncreneau;
use Moncreneau\Exceptions\MoncreneauException;

class AppointmentController extends Controller
{
public function __construct(private Moncreneau $moncreneau) {}

public function store(Request $request)
{
$validated = $request->validate([
'department_id' => 'required|integer',
'date_time' => 'required|date_format:Y-m-d\TH:i:s',
'name' => 'required|string',
]);

try {
$appointment = $this->moncreneau->appointments->create([
'departmentId' => $validated['department_id'],
'dateTime' => $validated['date_time'],
'name' => $validated['name'],
]);

return response()->json($appointment, 201);

} catch (MoncreneauException $e) {
$status = $e->getErrorCode() === 'INSUFFICIENT_CREDITS' ? 402 : $e->getStatusCode();
return response()->json(['error' => $e->getMessage()], $status);
}
}
}

Error handling​

There is only one exception class, Moncreneau\Exceptions\MoncreneauException — the business error code is available via getErrorCode():

<?php

use Moncreneau\Moncreneau;
use Moncreneau\Exceptions\MoncreneauException;

$client = new Moncreneau('YOUR_API_KEY');

try {
$appointment = $client->appointments->create($data);
} catch (MoncreneauException $e) {
switch ($e->getErrorCode()) {
case 'INSUFFICIENT_CREDITS':
echo "Insufficient credits: {$e->getMessage()}\n";
break;
case 'VALIDATION_ERROR':
echo "Validation: " . json_encode($e->getDetails()) . "\n";
break;
case 'INVALID_API_KEY':
echo "Invalid API key\n";
break;
default:
echo "Error {$e->getErrorCode()} (HTTP {$e->getStatusCode()}): {$e->getMessage()}\n";
}
}

Webhook verification​

verifyWebhookSignature is a static method on the Moncreneau class, not an instance method:

<?php

use Moncreneau\Moncreneau;

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_MONCRENEAU_SIGNATURE'];

if (!Moncreneau::verifyWebhookSignature($payload, $signature, $_ENV['WEBHOOK_SECRET'])) {
http_response_code(401);
die('Invalid signature');
}

$event = json_decode($payload);
error_log("Event: " . $_SERVER['HTTP_X_MONCRENEAU_EVENT']);

http_response_code(200);
echo json_encode(['received' => true]);

See Webhook Security for the signature format details.