Skip to content

Commit

Permalink
Merge pull request #32 from njoguamos/add-id-search-and-verification
Browse files Browse the repository at this point in the history
Add  ID Search & Verification
  • Loading branch information
njoguamos authored Feb 14, 2023
2 parents bb8003f + 933d3db commit a229da5
Show file tree
Hide file tree
Showing 8 changed files with 270 additions and 17 deletions.
78 changes: 76 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,82 @@ Supported currencies

</details>

### 3.10 Know your customer
- [ ] ID Search & Verification
### 3.10 ID Search & Verification


<details>

<summary>Query the various registrar of persons in the various countries in East Africa.</summary>

```php
use NjoguAmos\Jenga\Api\IDVerification;
use NjoguAmos\Jenga\Dto\IDVerificationDto;

$data = new IDVerificationDto(
documentNumber: '555555',
firstName: 'John',
lastName: 'Doe',
dateOfBirth: '20 June 1985',
documentType: 'ID',
countryCode: 'KE',
);

$search = (new IDVerification())->search($data);
```

Example success response
```json
{
"status": true,
"code": 0,
"message": "success",
"data": {
"identity": {
"customer": {
"firstName": "JOHN",
"lastName": "DOE",
"occupation": "",
"gender": "M",
"nationality": "Kenyan",
"deathDate": "",
"fullName": "JOHN JOHN DOE DOE",
"middlename": "JOHN DOE",
"ShortName": "JOHN",
"birthCityName": "",
"birthDate": "1985-06-20T12:00:00",
"faceImage": ""
},
"documentType": "NATIONAL ID",
"documentNumber": "555555",
"documentSerialNumber": "55555555555",
"documentIssueDate": "2011-12-08T12:00:00",
"documentExpirationDate": "",
"IssuedBy": "REPUBLIC OF KENYA",
"additionalIdentityDetails": [
{
"documentType": "",
"documentNumber": "",
"issuedBy": ""
}
],
"address": {
"locationName": "",
"districtName": "",
"subLocationName": "",
"provinceName": "",
"villageName": ""
}
}
}
}

```

Refer to [ID Search & Verification API Reference](https://developer.jengaapi.io/reference/identity-verification)


</details>


### 3.11 MPGS direct integration
- [ ] MPGS Validate Payment
Expand Down
10 changes: 10 additions & 0 deletions src/Api/DefaultJengaConnector.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace NjoguAmos\Jenga\Api;

use NjoguAmos\Jenga\JengaSignature;
use NjoguAmos\Jenga\Models\JengaToken;

abstract class DefaultJengaConnector
Expand Down Expand Up @@ -38,4 +39,13 @@ public function getBaseUrl(): string
{
return $this->baseUrl;
}

public function getSignatureHeader(array $data): array
{
$signature = (new JengaSignature(data: $data))->getSignature();

return [
'signature' => "Bearer $signature"
];
}
}
16 changes: 9 additions & 7 deletions src/Api/ForexExchangeRates.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ public function getEndPoint(): string

public function convert(ExchangeRatesDto $data): string
{
$postData = [
"amount" => $data->amount,
"currencyCode" => $data->currencyCode,
"toCurrency" => $data->toCurrency,
"countryCode" => $data->countryCode ?: config(key: 'jenga.country'),
'accountNumber' => $data->accountNumber ?: config(key: 'jenga.account')
];

return Http::asJson()
->withToken(token: $this->getToken())
->post(url: $this->getEndPoint(), data: [
"amount" => $data->amount,
"currencyCode" => $data->currencyCode,
"toCurrency" => $data->toCurrency,
"countryCode" => $data->countryCode ?: config(key: 'jenga.country'),
'accountNumber' => $data->accountNumber ?: config(key: 'jenga.account')
])->body();
->post(url: $this->getEndPoint(), data: $postData)->body();
}
}
39 changes: 39 additions & 0 deletions src/Api/IDVerification.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace NjoguAmos\Jenga\Api;

use Carbon\Carbon;
use Illuminate\Support\Facades\Http;
use NjoguAmos\Jenga\Concerns\JengaConnector;
use NjoguAmos\Jenga\Dto\IDVerificationDto;

class IDVerification extends DefaultJengaConnector implements JengaConnector
{
public function getEndPoint(): string
{
return $this->getBaseUrl() . '/v3-apis//v3.0/validate/identity';
}

public function search(IDVerificationDto $data): string
{
$signatureData = [
"countryCode" => $data->countryCode ?: config(key: 'jenga.country'),
"documentNumber" => $data->documentNumber,
];

$postData = [
"documentNumber" => $data->documentNumber,
"firstName" => $data->firstName,
"lastName" => $data->lastName,
"dateOfBirth" => Carbon::parse($data->dateOfBirth)->format(format: 'Y-m-d'),
"documentType" => $data->documentType ?: config(key: 'jenga.country'),
"countryCode" => $data->countryCode ?: 'ID'
];

return Http::asJson()
->withToken(token: $this->getToken())
->withHeaders($this->getSignatureHeader($signatureData))
->post(url: $this->getEndPoint(), data: $postData)
->body();
}
}
2 changes: 1 addition & 1 deletion src/Dto/ExchangeRatesDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function __construct(
public ?string $accountNumber = null,

/** the country for which rates are being requested. Valid values are KE, TZ, UG, RW.*/
public string $countryCode = 'KE',
public ?string $countryCode = null,
) {
}
}
29 changes: 29 additions & 0 deletions src/Dto/IDVerificationDto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace NjoguAmos\Jenga\Dto;

class IDVerificationDto
{
public function __construct(
/** The document id number */
public string $documentNumber,

/** First name as per identity document type */
public string $firstName,

/** Last name as per identity document type */
public string $lastName,

/** Date in of birth as per identity document type */
public string $dateOfBirth,

/** The document type of the customer. for example ID, PASSPORT, ALIENID */
public ?string $documentType = null,

/** The country in which the document relates to (only KE and RW enabled for now)*/
public ?string $countryCode = null,
) {
}
}
14 changes: 7 additions & 7 deletions tests/Api/ForexExchangeRatesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@
expect($rates)->toBe(json_encode($response));

Http::assertSent(function (Request $request) use ($url, $token) {
return $request->hasHeader('Authorization', "Bearer $token->access_token") &&
$request->url() == $url &&
$request['amount'] == 1042 &&
$request['currencyCode'] == "USD" &&
$request['toCurrency'] == "KES" &&
$request['accountNumber'] == "1450160649886" &&
$request['countryCode'] == "KE";
return $request->hasHeader('Authorization', "Bearer $token->access_token")
&& $request->url() == $url
&& $request['amount'] == 1042
&& $request['currencyCode'] == "USD"
&& $request['toCurrency'] == "KES"
&& $request['accountNumber'] == "1450160649886"
&& $request['countryCode'] == "KE";
});
});
99 changes: 99 additions & 0 deletions tests/Api/IDVerificationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Http;
use NjoguAmos\Jenga\Api\IDVerification;
use NjoguAmos\Jenga\Dto\IDVerificationDto;
use NjoguAmos\Jenga\JengaSignature;
use NjoguAmos\Jenga\Models\JengaToken;

test(description: 'it can search ID details successfully', closure: function () {
$token = JengaToken::factory()->create();

$url = config(key: 'jenga.host') . '/v3-apis//v3.0/validate/identity';

$response = [
"status" => true,
"code" => 0,
"message" => "success",
"data" => [
"identity" => [
"customer" => [
"firstName" => "JOHN",
"lastName" => "DOE",
"occupation" => "",
"gender" => "M",
"nationality" => "Kenyan",
"deathDate" => "",
"fullName" => "JOHN JOHN DOE DOE",
"middlename" => "JOHN DOE",
"ShortName" => "JOHN",
"birthCityName" => "",
"birthDate" => "1985-06-20T12:00:00",
"faceImage" => ""
],
"documentType" => "NATIONAL ID",
"documentNumber" => "555555",
"documentSerialNumber" => "55555555555",
"documentIssueDate" => "2011-12-08T12:00:00",
"documentExpirationDate" => "",
"IssuedBy" => "REPUBLIC OF KENYA",
"additionalIdentityDetails" => [
[
"documentType" => "",
"documentNumber" => "",
"issuedBy" => ""
]
],
"address" => [
"locationName" => "",
"districtName" => "",
"subLocationName" => "",
"provinceName" => "",
"villageName" => ""
]
]
]
];

$signatureData = [
"countryCode" => 'KE',
"documentNumber" => '555555',
];

$this->artisan(command: 'jenga:keys');

$signature = (new JengaSignature(data: $signatureData))->getSignature();

Http::fake([
$url => Http::response($response, 200),
]);

Http::preventStrayRequests();

$data = new IDVerificationDto(
documentNumber: '555555',
firstName: 'John',
lastName: 'Doe',
dateOfBirth: '20 June 1985',
documentType: 'ID',
countryCode: 'KE',
);


$search = (new IDVerification())->search($data);

expect($search)->toBe(json_encode($response));

Http::assertSent(function (Request $request) use ($url, $token, $signature) {
return
$request->hasHeader('Authorization', "Bearer $token->access_token")
&& $request->hasHeader('signature', "Bearer $signature")
&& $request['documentNumber'] == '555555'
&& $request['firstName'] == 'John'
&& $request['lastName'] == 'Doe'
&& $request['dateOfBirth'] == '1985-06-20'
&& $request['documentType'] == 'ID'
&& $request['countryCode'] == 'KE';
});
});

0 comments on commit a229da5

Please sign in to comment.