Lorsqu'un partenaire (exemple: Kayapa) tente de vérifier l'identité d'un citoyen via l'API Partner, et qu'il y a une correspondance partielle dans le nom (ex: "Sebastian" vs "Sebastien") mais que le NIU est identique, le systÚme crée un challenge de vérification qui apparaßt dans l'application mobile SagaPass du citoyen.
Kayapa envoie:
{
"niu": "1229182158",
"first_name": "Dary Sebastien",
"last_name": "Petion",
"date_of_birth": "2007-03-16"
}
Base de données SagaPass:
NIU: 1229182158
Nom: Dary Sebastian Petion
âĄïž NIU identique â + Nom similaire mais pas exact (80%+ de similaritĂ©) â Challenge créé
Le partenaire reçoit une réponse HTTP 409 avec:
{
"success": false,
"verified": false,
"error": "name_verification_required",
"status": "pending_user_confirmation",
"message": "Une différence a été détectée dans le nom. L'utilisateur doit confirmer son identité dans son application SagaPass.",
"data": {
"challenge_id": 42,
"sagapass_name": "Dary Sebastian Petion",
"partner_name": "Dary Sebastien Petion",
"expires_at": "2026-04-02T17:48:15Z",
"action_required": "L'utilisateur recevra une notification dans son application SagaPass..."
}
}
L'utilisateur ouvre son application SagaPass et voit une alerte/notification dans son écran d'accueil:
â ïž VĂRIFICATION D'IDENTITĂ REQUISE
Le service "Kayapa" tente de vérifier votre identité mais a détecté
une différence dans votre nom:
âą Votre nom officiel SagaPass: Dary Sebastian Petion
âą Nom que vous avez fourni Ă Kayapa: Dary Sebastien Petion
â ïž IMPORTANT: Votre nom officiel SagaPass ne peut pas ĂȘtre modifiĂ© ici.
Que souhaitez-vous faire ?
[â
C'est bien moi - Je vais corriger mon nom chez Kayapa]
[â Ce n'est pas moi - Tentative frauduleuse]
Note importante: Le nom dans SagaPass est le nom officiel et ne changera jamais automatiquement. Si l'utilisateur confirme son identité, c'est lui qui doit corriger son nom cÎté Kayapa pour qu'il corresponde à son nom SagaPass.
GET /api/mobile/verification-challenges
Authorization: Bearer {user_token}
Réponse:
{
"success": true,
"count": 2,
"challenges": [
{
"id": 42,
"partner_name": "Kayapa",
"name_discrepancy": {
"sagapass_name": "Dary Sebastian Petion",
"partner_name": "Dary Sebastien Petion",
"similarity": 92.31
},
"created_at": "2026-03-31T17:48:15Z",
"expires_at": "2026-04-02T17:48:15Z",
"time_left_hours": 45
}
]
}
GET /api/mobile/verification-challenges/{id}
Authorization: Bearer {user_token}
POST /api/mobile/verification-challenges/{id}/respond
Authorization: Bearer {user_token}
Content-Type: application/json
{
"action": "confirm", // "confirm" | "reject"
"message": "C'est bien moi, je vais corriger mon nom chez Kayapa"
}
Actions possibles:
| Action | Description | Effet |
|--------|-------------|-------|
| confirm | "C'est bien moi" | â
L'utilisateur DOIT corriger son nom chez Kayapa
â
SagaPass garde le nom officiel (JAMAIS modifié automatiquement)
â
Prochaine vérification avec nom corrigé réussira |
| reject | "Ce n'est pas moi" | â Signale une tentative frauduleuse
â La vĂ©rification Kayapa Ă©choue dĂ©finitivement
â ïž Alerte de sĂ©curitĂ© enregistrĂ©e |
Réponse:
{
"success": true,
"message": "Vous avez confirmé votre identité. Veuillez corriger votre nom sur le service partenaire (Kayapa) pour qu'il corresponde à votre nom SagaPass.",
"data": {
"action_required": "Corrigez votre nom chez Kayapa: Dary Sebastian Petion",
"sagapass_official_name": "Dary Sebastian Petion"
},
"challenge": {
"id": 42,
"status": "confirmed",
"responded_at": "2026-03-31T18:12:45Z"
}
}
Le systÚme utilise similar_text() pour calculer la similarité entre les noms:
// Exemple 1: Correspondance exacte (100%)
"Dary Sebastian" vs "Dary Sebastian" â 100% â Pas de challenge
// Exemple 2: Correspondance partielle (>80%)
"Dary Sebastian Petion" vs "Dary Sebastien Petion" â 92% â Challenge créé
// Exemple 3: Aucune correspondance (<80%)
"Jean Dupont" vs "Pierre Martin" â 15% â Erreur "duplicate_niu"
Un challenge est créé SI ET SEULEMENT SI:
partner_verification_challenges| Champ | Type | Description |
|-------|------|-------------|
| id | bigint | ID unique |
| user_id | bigint | Citoyen SagaPass concerné |
| partner_verification_id | bigint | Lien vers partner_verifications |
| partner_name | string | Nom du partenaire (ex: "Kayapa") |
| name_discrepancy | json | {"sagapass_name": "...", "partner_name": "...", "similarity": 92} |
| verification_data | json | Données complÚtes envoyées par le partenaire |
| status | enum | pending, confirmed, rejected, expired |
| user_response | text | Réponse textuelle de l'utilisateur |
| responded_at | timestamp | Date de réponse |
| expires_at | timestamp | Expiration (48h aprÚs création) |
NIU: 1229182158 (identique) â
Nom SagaPass (OFFICIEL): "Dary Sebastian Petion"
Nom Kayapa (INCORRECT): "Dary Sebastien Petion"
Similarité: 92%
â Challenge créé
â Notification envoyĂ©e Ă l'utilisateur
â Utilisateur confirme "c'est bien moi"
â Message: "Corrigez votre nom chez Kayapa en: Dary Sebastian Petion"
â Utilisateur corrige son nom chez Kayapa
â Prochaine tentative Kayapa: succĂšs automatique
IMPORTANT: Le nom SagaPass n'est JAMAIS modifié. C'est le nom officiel et fait foi.
NIU: 7890123456 (identique) â
Nom SagaPass: "Marie Dubois"
Nom Kayapa: "Marie Jean-Baptiste"
Similarité: 45%
â Erreur "duplicate_niu" (similaritĂ© < 80%)
â Pas de challenge (trop de diffĂ©rence)
â L'utilisateur doit contacter le support
â Mise Ă jour possible via admin panel
NIU: 5555555555 (identique) â
Nom SagaPass: "Jean Dupont"
Nom Kayapa: "Louis Martin"
Similarité: 10%
â Erreur "duplicate_niu"
â Log de sĂ©curitĂ© créé
â Alerte automatique au service anti-fraude
Pour envoyer des notifications push Ă l'app mobile SagaPass:
// Dans PartnerVerifyController::createVerificationChallenge()
// Récupérer le token FCM de l'utilisateur
$fcmToken = $user->fcm_token;
if ($fcmToken) {
$notification = [
'title' => 'â ïž VĂ©rification d'identitĂ© requise',
'body' => "Le service {$app->name} a détecté une différence dans votre nom. Veuillez confirmer votre identité.",
'click_action' => 'FLUTTER_NOTIFICATION_CLICK',
'data' => [
'type' => 'verification_challenge',
'challenge_id' => $challenge->id,
'partner_name' => $app->name,
],
];
// Envoyer via FCM
\App\Services\FirebaseService::send($fcmToken, $notification);
}
<?php
// test-verification-challenge.php
require __DIR__.'/vendor/autoload.php';
$app = require_once __DIR__.'/bootstrap/app.php';
$app->make(\Illuminate\Contracts\Console\Kernel::class)->bootstrap();
use App\Models\User;
use Illuminate\Support\Facades\Http;
// 1. Créer un utilisateur test
$user = User::create([
'first_name' => 'Dary',
'last_name' => 'Sebastian Petion',
'niu' => '1229182158',
'email' => 'dary.test@example.ht',
'phone' => '+50947974323',
'date_of_birth' => '2007-03-16',
'account_level' => 'basic',
]);
// 2. Simuler appel Partner API avec variation nom
$response = Http::withBasicAuth('client_id', 'client_secret')
->post('http://localhost:8080/api/partner/v1/verify', [
'encrypted' => false,
'first_name' => 'Dary Sebastien',
'last_name' => 'Petion',
'niu' => '1229182158',
'date_of_birth' => '2007-03-16',
]);
// 3. Vérifier la réponse
assert($response->status() === 409);
assert($response->json('error') === 'name_verification_required');
echo "â
Challenge créé avec succÚs\n";
echo "Challenge ID: " . $response->json('data.challenge_id') . "\n";
partner_verification_challengesPartnerVerificationChallengePartnerVerifyControllerVerificationChallengeController)VerificationChallengeCardverification_challenge_service.dartPour questions sur ce systĂšme:
Date de création: Mars 2026 Version: 1.0