| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- <?php
- namespace App\Services\Didit;
- use App\Data\Didit\Session\Parts\Request\ContactDetailsData;
- use App\Data\Didit\Session\Parts\Request\ExpectedDetailsData;
- use App\Data\Didit\Session\SessionRequestData;
- use App\Data\Didit\Session\SessionResponseData;
- use App\Enums\IdentityVerificationStatusEnum;
- use App\Enums\UserTypeEnum;
- use App\Models\Client;
- use App\Models\IdentityVerification;
- use App\Models\Provider;
- use App\Models\User;
- use App\Services\Didit\Concerns\SendsDiditRequests;
- use Illuminate\Database\Eloquent\Model;
- use Illuminate\Support\Facades\DB;
- use RuntimeException;
- class DiditSessionService
- {
- use SendsDiditRequests;
- public function createSession(User $user, bool $native = false): IdentityVerification
- {
- $profile = $this->profileFor($user);
- if (! $profile) {
- throw new RuntimeException(__('identity_verification.profile_missing'));
- }
- if ($profile->identity_verification_status === IdentityVerificationStatusEnum::APPROVED) {
- throw new RuntimeException(__('identity_verification.already_approved'));
- }
- $maxAttempts = (int) config('services.didit.max_attempts', 3);
- if ((int) $profile->identity_verification_attempts >= $maxAttempts) {
- throw new RuntimeException(__('identity_verification.attempts_exhausted'));
- }
- $open = IdentityVerification::query()
- ->where('user_id', $user->id)
- ->whereIn('didit_status', ['Not Started', 'In Progress'])
- ->latest('id')
- ->first();
- if ($open) {
- return $open;
- }
- $response = $this->diditRequest(
- method: 'POST',
- path: '/v3/session/',
- errorMessage: __('identity_verification.session_failed'),
- payload: $this->buildRequest($user, $profile, $native),
- );
- $session = SessionResponseData::fromResponse($response);
- return DB::transaction(function () use ($user, $profile, $session) {
- $attempt = (int) $profile->identity_verification_attempts + 1;
- $profile->forceFill([
- 'identity_verification_status' => IdentityVerificationStatusEnum::PENDING->value,
- ])->save();
- return IdentityVerification::create([
- 'user_id' => $user->id,
- 'session_id' => $session->sessionId,
- 'session_token' => $session->sessionToken,
- 'workflow_id' => $session->workflowId,
- 'didit_status' => $session->status ?? 'Not Started',
- 'attempt' => $attempt,
- 'started_at' => now(),
- ]);
- });
- }
- public function getDecision(string $sessionId): array
- {
- return $this->diditRequest(
- method: 'GET',
- path: "/v3/session/{$sessionId}/decision/",
- errorMessage: __('identity_verification.decision_failed'),
- );
- }
- public function verificationUrl(IdentityVerification $verification): string
- {
- return 'https://verify.didit.me/pt/session/'.$verification->session_token;
- }
- //
- private function buildRequest(User $user, Model $profile, bool $native = false): SessionRequestData
- {
- return new SessionRequestData(
- workflowId: $this->workflowFor($user),
- vendorData: (string) $user->id,
- callback: $this->callbackFor($user, $native),
- language: 'pt',
- expectedDetails: ExpectedDetailsData::fromName(
- fullName: $user->name,
- dateOfBirth: $profile->birth_date?->format('Y-m-d'),
- document: $profile->document,
- ),
- contactDetails: new ContactDetailsData(
- email: $user->email,
- phone: $user->phone,
- ),
- );
- }
- private const APP_SCHEMES = [
- 'provider' => 'br.com.diarista.provider',
- 'client' => 'br.com.diarista.client',
- ];
- private function callbackFor(User $user, bool $native = false): ?string
- {
- $app = $user->type === UserTypeEnum::PROVIDER ? 'provider' : 'client';
- if ($native) {
- return self::APP_SCHEMES[$app].'://verification/done';
- }
- $callback = config('services.didit.callback_url');
- if (! is_string($callback) || $callback === '') {
- return null;
- }
- return $callback.(str_contains($callback, '?') ? '&' : '?').'app='.$app;
- }
- private function workflowFor(User $user): string
- {
- $workflow = $user->type === UserTypeEnum::PROVIDER
- ? config('services.didit.workflow_provider')
- : config('services.didit.workflow_client');
- if (! is_string($workflow) || $workflow === '') {
- throw new RuntimeException(__('identity_verification.workflow_missing'));
- }
- return $workflow;
- }
- private function profileFor(User $user): Provider|Client|null
- {
- return $user->type === UserTypeEnum::PROVIDER
- ? $user->provider
- : $user->client;
- }
- }
|