DiditDecisionExtractor.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <?php
  2. namespace App\Services\Didit;
  3. class DiditDecisionExtractor
  4. {
  5. public function extract(array $decision): array
  6. {
  7. $id = $this->first($decision, 'id_verifications');
  8. $liveness = $this->first($decision, 'liveness_checks');
  9. $face = $this->first($decision, 'face_matches');
  10. return [
  11. 'id_verification_status' => data_get($id, 'status'),
  12. 'liveness_status' => data_get($liveness, 'status'),
  13. 'face_match_status' => data_get($face, 'status'),
  14. 'liveness_score' => $this->score($liveness, 'liveness_score'),
  15. 'face_match_score' => $this->score($face, 'face_match_score'),
  16. 'warnings' => $this->warnings($decision),
  17. ];
  18. }
  19. public function extractDocument(array $decision): ?string
  20. {
  21. $id = $this->first($decision, 'id_verifications');
  22. $taxNumber = data_get($id, 'extra_fields.tax_number');
  23. return is_string($taxNumber) && $taxNumber !== ''
  24. ? preg_replace('/\D+/', '', $taxNumber)
  25. : null;
  26. }
  27. /** @return list<array<string, mixed>> */
  28. public function warnings(array $decision): array
  29. {
  30. $warnings = [];
  31. foreach ($this->featureKeys() as $key) {
  32. foreach ($this->items($decision, $key) as $item) {
  33. foreach ((array) data_get($item, 'warnings', []) as $warning) {
  34. $warnings[] = $warning;
  35. }
  36. }
  37. }
  38. return $warnings;
  39. }
  40. public function actionableWarnings(array $decision): array
  41. {
  42. return array_values(array_filter(
  43. $this->warnings($decision),
  44. static fn ($warning) => data_get($warning, 'log_type') === 'warning',
  45. ));
  46. }
  47. /** @return list<string> */
  48. public function featureKeys(): array
  49. {
  50. return [
  51. 'id_verifications',
  52. 'liveness_checks',
  53. 'face_matches',
  54. 'ip_analyses',
  55. 'nfc_verifications',
  56. 'aml_screenings',
  57. 'poa_verifications',
  58. ];
  59. }
  60. public function items(array $decision, string $key): array
  61. {
  62. $value = data_get($decision, $key);
  63. return is_array($value) ? $value : [];
  64. }
  65. public function first(array $decision, string $key): ?array
  66. {
  67. $items = $this->items($decision, $key);
  68. return $items === [] ? null : (array) reset($items);
  69. }
  70. private function score(?array $item, string $fallbackKey): ?float
  71. {
  72. if ($item === null) {
  73. return null;
  74. }
  75. $value = data_get($item, 'score')
  76. ?? data_get($item, $fallbackKey)
  77. ?? data_get($item, 'similarity_percentage');
  78. if (! is_numeric($value)) {
  79. return null;
  80. }
  81. $value = (float) $value;
  82. return $value <= 1 ? round($value * 100, 2) : round($value, 2);
  83. }
  84. }