Skip to main content

PHP SDK for MONCRENEAU

The official PHP SDK to integrate MONCRENEAU into your Laravel, Symfony, or standard PHP applications.

Installation

composer require moncreneau/sdk

Configuration

Standard PHP

<?php

require_once 'vendor/autoload.php';

use Moncreneau\Client;

$client = new Client('YOUR_API_KEY');

With Advanced Configuration

<?php

use Moncreneau\Client;
use Moncreneau\Configuration;

$config = new Configuration([
'api_key' => 'YOUR_API_KEY',
'base_url' => 'https://mc-prd.duckdns.org/api/v1',
'timeout' => 30,
'verify_ssl' => true,
]);

$client = new Client($config);

Usage Examples

List Departments

<?php

require_once 'vendor/autoload.php';

use Moncreneau\Client;

$client = new Client('YOUR_API_KEY');

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

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

Create an Appointment

<?php

require_once 'vendor/autoload.php';

use Moncreneau\Client;
use Moncreneau\Exception\InsufficientCreditsException;

$client = new Client('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";
echo "Status: {$appointment->status}\n";

} catch (InsufficientCreditsException $e) {
echo "❌ Insufficient credits: {$e->getMessage()}\n";
} catch (Exception $e) {
echo "❌ Error: {$e->getMessage()}\n";
}

Check Availability

<?php

require_once 'vendor/autoload.php';

use Moncreneau\Client;

$client = new Client('YOUR_API_KEY');

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

if ($availability->available) {
echo "✅ Slot available!\n";
echo "Remaining slots: {$availability->remainingSlots}\n";
} else {
echo "❌ Slot unavailable\n";
echo "Reason: {$availability->unavailabilityReason}\n";
}
} catch (Exception $e) {
echo "Error: {$e->getMessage()}\n";
}

Cancel an Appointment

<?php

require_once 'vendor/autoload.php';

use Moncreneau\Client;

$client = new Client('YOUR_API_KEY');

try {
$cancelled = $client->appointments()->cancel(123);

echo "✅ Appointment cancelled\n";
echo "Status: {$cancelled->status}\n";
echo "💰 1 credit refunded\n";

} catch (Exception $e) {
echo "❌ Error: {$e->getMessage()}\n";
}

Laravel Integration

Service Provider

Create app/Providers/MoncreneauServiceProvider.php:

<?php

namespace App\Providers;

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

class MoncreneauServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(Client::class, function ($app) {
return new Client(config('services.moncreneau.key'));
});
}
}

Configuration config/services.php:

<?php

return [
// ...
'moncreneau' => [
'key' => env('MONCRENEAU_API_KEY'),
'base_url' => env('MONCRENEAU_BASE_URL', 'https://mc-prd.duckdns.org/api/v1'),
],
];

.env file:

MONCRENEAU_API_KEY=YOUR_API_KEY
MONCRENEAU_BASE_URL=https://mc-prd.duckdns.org/api/v1

Laravel Controller

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Moncreneau\Client;
use Moncreneau\Exception\InsufficientCreditsException;

class AppointmentController extends Controller
{
private Client $moncreneau;

public function __construct(Client $moncreneau)
{
$this->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 (InsufficientCreditsException $e) {
return response()->json([
'error' => $e->getMessage()
], 402);
}
}

public function checkAvailability(Request $request, int $departmentId)
{
$dateTime = $request->query('dateTime');

$availability = $this->moncreneau->departments()->checkAvailability(
$departmentId,
$dateTime
);

return response()->json($availability);
}
}

Symfony Integration

Service Configuration

config/services.yaml file:

services:
Moncreneau\Client:
arguments:
$apiKey: '%env(MONCRENEAU_API_KEY)%'

App\Service\AppointmentService:
arguments:
$client: '@Moncreneau\Client'

Symfony Service

<?php

namespace App\Service;

use Moncreneau\Client;
use Moncreneau\Exception\InsufficientCreditsException;

class AppointmentService
{
private Client $client;

public function __construct(Client $client)
{
$this->client = $client;
}

public function createAppointment(array $data): object
{
try {
return $this->client->appointments()->create($data);
} catch (InsufficientCreditsException $e) {
throw new \RuntimeException('Insufficient credits', 0, $e);
}
}

public function listDepartments(): array
{
return $this->client->departments()->list();
}
}

Error Handling

The SDK uses typed exceptions:

<?php

use Moncreneau\Client;
use Moncreneau\Exception\InsufficientCreditsException;
use Moncreneau\Exception\ValidationException;
use Moncreneau\Exception\NotFoundException;
use Moncreneau\Exception\UnauthorizedException;
use Moncreneau\Exception\ApiException;

$client = new Client('YOUR_API_KEY');

try {
$appointment = $client->appointments()->create($data);

} catch (InsufficientCreditsException $e) {
// Not enough credits
echo "Insufficient credits: {$e->getMessage()}\n";

} catch (ValidationException $e) {
// Validation failed
echo "Validation: {$e->getErrors()}\n";

} catch (NotFoundException $e) {
// Resource not found
echo "Not found: {$e->getMessage()}\n";

} catch (UnauthorizedException $e) {
// Invalid API Key
echo "Invalid API Key\n";

} catch (ApiException $e) {
// Generic API error
echo "API error: {$e->getMessage()}\n";
echo "Status: {$e->getStatusCode()}\n";

} catch (Exception $e) {
// Generic error
echo "Error: {$e->getMessage()}\n";
}

Advanced Configuration

Timeout and Retry

<?php

use Moncreneau\Client;
use Moncreneau\Configuration;

$config = new Configuration([
'api_key' => 'YOUR_API_KEY',
'timeout' => 30, // seconds
'connect_timeout' => 10,
'max_retries' => 3,
'retry_delay' => 1000, // milliseconds
]);

$client = new Client($config);

PSR-3 Logger

<?php

use Moncreneau\Client;
use Moncreneau\Configuration;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$logger = new Logger('moncreneau');
$logger->pushHandler(new StreamHandler('php://stdout', Logger::DEBUG));

$config = new Configuration([
'api_key' => 'YOUR_API_KEY',
'logger' => $logger,
'debug' => true,
]);

$client = new Client($config);

Webhooks

Verify webhook signatures:

<?php

use Moncreneau\Webhook;

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

$webhook = new Webhook($_ENV['WEBHOOK_SECRET']);

if (!$webhook->verifySignature($payload, $signature)) {
http_response_code(401);
die('Invalid signature');
}

$event = json_decode($payload);
error_log("Event: {$event->type}");

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

Unit Tests with PHPUnit

<?php

namespace Tests\Unit;

use PHPUnit\Framework\TestCase;
use Moncreneau\Client;
use Moncreneau\Exception\InsufficientCreditsException;

class AppointmentTest extends TestCase
{
private Client $client;

protected function setUp(): void
{
$this->client = new Client($_ENV['MONCRENEAU_API_KEY']);
}

public function testCreateAppointment()
{
$appointment = $this->client->appointments()->create([
'departmentId' => 5,
'dateTime' => '2026-02-15T10:00:00',
'name' => 'Test User'
]);

$this->assertIsInt($appointment->id);
$this->assertEquals('PENDING', $appointment->status);
$this->assertNotEmpty($appointment->qrCode);
}

public function testInsufficientCredits()
{
$this->expectException(InsufficientCreditsException::class);

// Create multiple appointments to exhaust credits
$this->client->appointments()->create([...]);
}
}

Resources