Skip to main content

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 — siehe WebHookCallController::handle() und config('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 customAttribute mit attributeDefinitionId = 2652615 gespeichert
  • beim Update prüft der Webhook-Handler ob MfrId gesetzt 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:

  1. Middleware temporär weichmachen — eigene Test-IP zu $wcIps ergänzen
  2. Tunnel (ngrok / cloudflared) und in Weclapp den Test-Endpoint registrieren
  3. PHPUnit/Pest-Feature-Test mit withoutMiddleware('weclapp')