2023-11-30 16:00:50 +01:00
< ? php
/**
* Invoice Ninja ( https :// invoiceninja . com ) .
*
* @ link https :// github . com / invoiceninja / invoiceninja source repository
*
* @ copyright Copyright ( c ) 2023. Invoice Ninja LLC ( https :// invoiceninja . com )
*
* @ license https :// www . elastic . co / licensing / elastic - license
2023-12-01 14:30:33 +01:00
*
* Documentation of Api - Usage : https :// developer . gocardless . com / bank - account - data / overview
2023-11-30 16:00:50 +01:00
*/
2023-12-01 14:30:33 +01:00
namespace App\Helpers\Bank\Nordigen ;
2023-11-30 16:00:50 +01:00
use App\Exceptions\NordigenApiException ;
use App\Helpers\Bank\Nordigen\Transformer\AccountTransformer ;
use App\Helpers\Bank\Nordigen\Transformer\IncomeTransformer ;
use Illuminate\Support\Facades\Http ;
use Illuminate\Support\Str ;
2023-12-04 08:14:52 +01:00
use Illuminate\Support\Facades\Log ;
2023-11-30 16:00:50 +01:00
class Nordigen
{
2023-12-01 14:30:33 +01:00
public bool $test_mode = false ; // https://developer.gocardless.com/bank-account-data/sandbox
2023-11-30 16:00:50 +01:00
2023-12-01 14:30:33 +01:00
public string $sandbox_institutionId = " SANDBOXFINANCE_SFIN0000 " ;
2023-11-30 16:00:50 +01:00
2023-12-01 14:30:33 +01:00
protected \Nordigen\NordigenPHP\API\NordigenClient $client ;
2023-11-30 16:00:50 +01:00
2023-12-04 08:14:52 +01:00
public function __construct ( string $secret_id , string $secret_key )
2023-11-30 16:00:50 +01:00
{
2023-12-04 08:14:52 +01:00
$this -> client = new \Nordigen\NordigenPHP\API\NordigenClient ( $secret_id , $secret_key );
$this -> client -> createAccessToken (); // access_token is valid 24h -> so we dont have to implement a refresh-cycle
2023-11-30 16:00:50 +01:00
}
2023-12-01 14:30:33 +01:00
// metadata-section for frontend
2023-11-30 16:00:50 +01:00
public function getInstitutions ()
{
2023-12-01 14:30:33 +01:00
if ( $this -> test_mode )
return ( array ) $this -> client -> institution -> getInstitution ( $this -> sandbox_institutionId );
2023-11-30 16:00:50 +01:00
return $this -> client -> institution -> getInstitutions ();
}
2023-12-01 14:30:33 +01:00
// requisition-section
2023-12-05 06:56:52 +01:00
public function createRequisition ( string $redirect , string $initutionId , string $nAccountId )
2023-12-01 14:30:33 +01:00
{
if ( $this -> test_mode && $initutionId != $this -> sandbox_institutionId )
throw new \Exception ( 'invalid institutionId while in test-mode' );
2023-12-05 06:56:52 +01:00
return $this -> client -> requisition -> createRequisition ( $redirect , $initutionId , null , $nAccountId ); // we dont reuse existing requisitions, to prevent double usage of them. see: deleteAccount
2023-12-01 14:30:33 +01:00
}
public function getRequisition ( string $requisitionId )
{
return $this -> client -> requisition -> getRequisition ( $requisitionId );
}
public function cleanupRequisitions ()
{
$requisitions = $this -> client -> requisition -> getRequisitions ();
foreach ( $requisitions as $requisition ) {
// filter to expired OR older than 7 days created and no accounts
if ( $requisition -> status == " EXPIRED " || ( sizeOf ( $requisition -> accounts ) != 0 && strtotime ( $requisition -> created ) > ( new \DateTime ()) -> modify ( '-7 days' )))
continue ;
$this -> client -> requisition -> deleteRequisition ( $requisition -> id );
}
}
// account-section: these methods should be used to get data of connected accounts
public function getAccounts ()
2023-11-30 16:00:50 +01:00
{
// get all valid requisitions
2023-12-05 06:56:52 +01:00
$requisitions = $this -> client -> requisition -> getRequisitions (); // no pagination used?!
2023-11-30 16:00:50 +01:00
// fetch all valid accounts for activated requisitions
2023-12-01 14:30:33 +01:00
$nordigen_accountIds = [];
2023-12-05 06:56:52 +01:00
foreach ( $requisitions [ " results " ] as $requisition ) {
foreach ( $requisition [ " accounts " ] as $accountId ) {
2023-12-01 14:30:33 +01:00
array_push ( $nordigen_accountIds , $accountId );
2023-11-30 16:00:50 +01:00
}
}
2023-12-01 14:30:33 +01:00
$nordigen_accountIds = array_unique ( $nordigen_accountIds );
$nordigen_accounts = [];
foreach ( $nordigen_accountIds as $accountId ) {
$nordigen_account = $this -> getAccount ( $accountId );
array_push ( $nordigen_accounts , $nordigen_account );
}
return $nordigen_accounts ;
2023-11-30 16:00:50 +01:00
}
2023-12-01 14:30:33 +01:00
public function getAccount ( string $account_id )
2023-11-30 16:00:50 +01:00
{
2023-12-01 14:30:33 +01:00
$out = new \stdClass ();
2023-11-30 16:00:50 +01:00
2023-12-05 06:56:52 +01:00
$out -> data = $this -> client -> account ( $account_id ) -> getAccountDetails ()[ " account " ];
2023-12-01 14:30:33 +01:00
$out -> metadata = $this -> client -> account ( $account_id ) -> getAccountMetaData ();
2023-12-05 06:56:52 +01:00
$out -> balances = $this -> client -> account ( $account_id ) -> getAccountBalances ()[ " balances " ];
2023-12-01 14:30:33 +01:00
$out -> institution = $this -> client -> institution -> getInstitution ( $out -> metadata [ " institution_id " ]);
2023-11-30 16:00:50 +01:00
2023-12-01 14:30:33 +01:00
$it = new AccountTransformer ();
return $it -> transform ( $out );
2023-11-30 16:00:50 +01:00
}
2023-12-01 14:30:33 +01:00
public function isAccountActive ( string $account_id )
2023-11-30 16:00:50 +01:00
{
2023-12-01 14:30:33 +01:00
try {
$account = $this -> client -> account ( $account_id ) -> getAccountMetaData ();
if ( $account [ " status " ] != " READY " )
return false ;
return true ;
} catch ( \Exception $e ) {
// TODO: check for not-found exception
return false ;
}
2023-11-30 16:00:50 +01:00
}
2023-12-01 14:30:33 +01:00
/**
* this method will remove all according requisitions => this can result in removing multiple accounts , if a user reuses a requisition
*/
public function deleteAccount ( string $account_id )
2023-11-30 16:00:50 +01:00
{
2023-12-01 14:30:33 +01:00
// get all valid requisitions
$requisitions = $this -> client -> requisition -> getRequisitions ();
// fetch all valid accounts for activated requisitions
foreach ( $requisitions as $requisition ) {
foreach ( $requisition -> accounts as $accountId ) {
if ( $accountId ) {
$this -> client -> requisition -> deleteRequisition ( $accountId );
}
}
}
2023-11-30 16:00:50 +01:00
}
2023-12-01 14:30:33 +01:00
public function getTransactions ( string $accountId , string $dateFrom = null )
2023-11-30 16:00:50 +01:00
{
2023-12-01 14:30:33 +01:00
return $this -> client -> account ( $accountId ) -> getAccountTransactions ( $dateFrom );
}
2023-11-30 16:00:50 +01:00
}