Weclapp Webhooks
App\Http\Controllers\Weclapp\WebHookCallController
Weclapp pingt die common-api bei CRUD-Events auf Entities (z.B. customer.created, salesOrder.updated). Diese Events werden gespeichert und triggern domänenspezifische Sync-Logik (z. B. ein customer-Event geht via Mapping nach MFR).
Routen
Route::prefix('v1/weclapp/webhooks')->middleware('weclapp')->group(function () {
Route::get('/', [WebHookCallController::class, 'index'])->name('weclapp.webhook.get');
Route::post('/', [WebHookCallController::class, 'index'])->name('weclapp.webhook.post');
});
Sicherheit — IP-Whitelist
Die Routes sind NICHT durch Sanctum geschützt — Weclapp kann keinen Bearer-Token mitschicken. Stattdessen:
App\Http\Middleware\Weclapp (alias 'weclapp') erlaubt nur Requests von:
$wcIps = ['3.73.185.97']; // Weclapp Webhook-Sender
Alles andere bekommt 403 zurück.
Ergänzend kann ein
X-Weclapp-Secret-Header geprüft werden — sieheWebHookCallController::handle()undconfig('services.weclapp.webhook_secret'). Aktuell wird das nicht in der Default-Route benutzt, ist aber im Code vorhanden.
Request-Schema
{
"entityId": "12345",
"entityName": "customer",
"type": "CREATE" // CREATE | UPDATE | DELETE
}
Verarbeitung
Welche Entity → welcher Controller?
Helper::getWeclappController():
'opportunity' => OpportunityController::class,
'task' => TaskController::class,
'contract' => ContractController::class,
// 'customer' / 'party' können ergänzt werden
Welche Entity → welches Mapping?
Helper::getMfrMapping():
'party' => CompanyMapping::class,
'contract' => CustomValueMapping::class,
'customAttributeDefinition' => CustomValueMapping::class,
WebhookCall-Log
Jeder eintreffende Webhook wird in webhook_calls (Common-DB) abgelegt:
\App\Models\Common\Weclapp\WebhookCall::create([
'entityId' => $request->input('entityId'),
'entityName' => $request->input('entityName'),
'type' => $request->input('type'),
'method' => $request->method(),
]);
Nach erfolgreicher Verarbeitung wird isSuccess gesetzt.
Hilfreich für Audit / Debug, wenn ein Sync-Lauf schiefgegangen ist.
Cycle-Prevention via MfrId-Custom-Attribute
Weclapp und MFR halten beide ihre eigenen IDs. Damit ein synchroner Update nicht endlos zurück-getriggert wird:
- die MFR-Id wird in Weclapp als
customAttributemitattributeDefinitionId = 2652615gespeichert - beim Update prüft der Webhook-Handler ob
MfrIdgesetzt ist; wenn ja → kein erneutes Create, nur Update
$mfrId = wcHelper::getCustomAttribute(
$this->weclappQueryResult->customAttributes,
$this->attId, // 2652615
);
Lokal testen
Weclapp pingt nur Production. Lokal kannst du Webhooks per curl simulieren — denk daran, dass die IP-Middleware aktiv ist. Optionen:
- Middleware temporär weichmachen — eigene Test-IP zu
$wcIpsergänzen - Tunnel (ngrok / cloudflared) und in Weclapp den Test-Endpoint registrieren
- PHPUnit/Pest-Feature-Test mit
withoutMiddleware('weclapp')