Programske knjižnice VIES

Programske knjižnice omogočajo iskanje podatkov o podjetnikih na podlagi vpisane DDV EU številke. Trenutno so knjižnice API-jev na voljo za naslednje programske jezike:

  • .NET (C#, Visual Basic)
  • Java
  • JavaScript (Node.js)
  • PHP
  • Python
  • C/C++

API ponuja naslednje funkcije:

  • getVIESData – funkcijo potrditve dejavnosti številke EU za DDV, ki jo je dodelila katera koli država članica Evropske unije,
  • getVIESDataParsedfunkcija za potrditev dejavnosti številke EU za DDV, ki jo je dodelila katera koli država članica Evropske unije, in vrnitev razčlenjenega naslova trgovca,
  • getVIESDataAsync – asinhrona funkcija, ki na podlagi poslanega paketa DDV številk omogoča pridobitev trenutnega EU DDV statusa in podatkov trgovca.
  • getVIESDataAsyncResult – funkcija vam omogoča pridobivanje paketnih rezultatov na podlagi žetona, ki ga vrne funkcija getVIESDataAsync
  • getAccountStatus – funkcija za pridobivanje ažurnih podatkov o uporabniškem računu.

Integracija

Vse knjižnice z izvornimi kodami so na voljo za prenos na Prenesi strani. Poleg tega je izvorna koda za knjižnice na voljo tudi v našem uradnem repozitoriju na Github.

Način integracije knjižnice je odvisen od izbranega programskega jezika. Za tiste jezike, ki podpirajo upravljanje knjižnice na podlagi centralnega repozitorija, ga je mogoče uporabiti.

// NuGet Gallery
// https://www.nuget.org/packages/VIESAPI.VIESAPIClient

PM> Install-Package VIESAPI.VIESAPIClient
// No central repository support
// Maven
// https://viesapi.eu/maven/

<repository>
    <id>viesapi</id>
    <url>https://viesapi.eu/maven/releases</url>
</repository>

<dependency>
    <groupId>eu.viesapi</groupId>
    <artifactId>viesapi-client</artifactId>
    <version>1.2.6</version>
</dependency>
// NPM
// https://www.npmjs.com/package/viesapi-client

npm install viesapi-client
// Packagist (Composer)
// https://packagist.org/packages/viesapi/client

composer require viesapi/client
# No central repository support

pip install viesapi-python-client-1.2.6.zip
' No central repository support

Preverjanje pristnosti

Za izvedbo pravilne avtentikacije so potrebne pravilne vrednosti id in key parametre je treba zagotoviti med gradnjo objekta naročnika. The id parameter mora vsebovati veljaven identifikator ključa, ki se uporablja za avtorizacijo. The key parameter mora vsebovati veljavno vrednost ključa, uporabljenega za avtorizacijo. Identifikator ključa in ključ generira uporabnik po prijavi v svoj račun na viesapi.eu portal. Postopek generiranja ključev in identifikatorjev je bil podrobno opisan zgoraj.

Naslednji primer prikazuje, kako uporabljati funkcije knjižnice:

using viesapiLibrary.dll;

// Create the service client object
// id - a string representing the API key identifier
// key - a string representing the API key
VIESAPIClient viesapi = new VIESAPIClient("id", "key");
#include "viesapi.h"

// Create the service client object
// id - a string representing the API key identifier
// key - a string representing the API key
VIESAPIClient* viesapi = NULL;
viesapi_new_prod(&viesapi, "id", "key");
import pl.viesapi.client.*;

// Create the service client object
// id - a string representing the API key identifier
// key - a string representing the API key
VIESAPIClient viesapi = new VIESAPIClient("id", "key");
var VIESAPI = require('viesapiclient');

// Create the service client object
// id - a string representing the API key identifier
// key - a string representing the API key
var viesapi = new VIESAPI.VIESAPIClient('id', 'key');
require_once 'VIESAPI/VIESAPIClient.php';

\VIESAPI\VIESAPIClient::registerAutoloader();

// Create the service client object
// id - a string representing the API key identifier
// key - a string representing the API key
$viesapi = new \VIESAPI\VIESAPIClient('id', 'key');
from viesapi import *
from pprint import pprint

// Create the service client object
// id - a string representing the API key identifier
// key - a string representing the API key
viesapi = VIESAPIClient('id', 'key')
' Create the service client object
' id - a string representing the API key identifier
' key - a string representing the API key
Dim viesapi As New VIESAPIClient
viesapi.URL = "https://www.viesapi.eu/api"
viesapi.Id = "id"
viesapi.Key = "key"

Pozor! Med postopkom preverjanja pristnosti se uporablja trenutni čas odjemalčevega računalnika. Zato se v primeru težav z avtentikacijo pri poskusu povezave s sistemom viesapi.eu najprej prepričajte, da ima računalnik ali strežnik, s katerega je vzpostavljena povezava, pravilen trenutni čas in časovni pas. Več informacij o metodi, ki jo uporablja sistem viesapi.eu za avtentikacijo povpraševanj, lahko najdete tukaj.

Preverjanje številk za DDV EU

Številko EU za DDV potrdite s klicem na getVIESData funkcijo, katere parameter je EU DDV številka, ki jo želimo preveriti. Funkcija omogoča preverjanje EU DDV številk, ki so jih izdale vse države članice Evropske unije.

Naslednji primer prikazuje, kako se funkcije uporabljajo v knjižnicah:

// A call to a method that returns data from a VIES system
VIESData vies = viesapi.GetVIESData("PL1234567890");

if (vies != null) {
	Console.WriteLine(vies);
}
else {
	Console.WriteLine("Error: " + viesapi.LastError + " (code: " + viesapi.LastErrorCode + ")");
}
// A call to a method that returns data from a VIES system
VIESData* vies = viesapi_get_vies_data(viesapi, "PL1234567890");

if (vies != NULL) {
	printf("Kraj: %s\n", vies->CountryCode);
	printf("VAT ID: %s\n", vies->VATNumber);
	printf("Aktywny: %d\n", vies->Valid);
}
else {
	printf("Error: %s (code: %d)\n", viesapi_get_last_err(viesapi), viesapi_get_last_err_code(viesapi));
}
// A call to a method that returns data from a VIES system
VIESData vies = viesapi.getVIESData("PL1234567890");

if (vies != null) {
	System.out.println(vies);
}
else {
	System.out.println("Error: " + viesapi.getLastError() + " (code: " + viesapi.getLastErrorCode() + ")");
}
// A call to a method that returns data from a VIES system
viesapi.getVIESData('PL1234567890').then((vies) => {
	console.log(vies.toString());
}).catch((e) => {
	console.log(e.message);
});
// A call to a method that returns data from a VIES system
$vies = $viesapi->get_vies_data('PL1234567890');

if ($vies) {
	print_r($vies);
}
else {
	echo '<p>Error: ' . $viesapi->get_last_error() . '</p>';
}
# A call to a method that returns data from a VIES system
vies = viesapi.get_vies_data('PL1234567890')

if vies:
    pprint(vars(vies))
else:
    print('Error: ' + viesapi.get_last_error() + ' (code: ' + str(viesapi.get_last_error_code()) + ')')
' A call to a method that returns data from a VIES system
Dim vies As VIESData
Set vies = viesapi.GetVIESData("PL1234567890")

If vies Is Nothing Then
	Console.WriteLine("Error: {0}", viesapi.LastError)
Else
	Console.WriteLine(vies.ToString())
End If

Podroben opis vrnjenih atributov:

  • uid – edinstven identifikator poizvedbe, ki ga ustvari viesapi.eu,
  • countryCode – kodo države, v kateri je registrirano podjetje, povezano z EU DDV številko, navedeno v povpraševanju,
  • vatNumber – številko EU za DDV preverjenega podjetja, navedeno v povpraševanju,
  • valid – odgovor storitve VIES, ki obvešča o trenutnem EU DDV statusu preverjanega subjekta:
    • true – številka EU za DDV, navedena v povpraševanju, je veljavna,
    • false – številka EU za DDV, navedena v povpraševanju, ni veljavna,
  • traderName – firmo podjetja,
  • traderCompanyType – vedno vrne niz znakov '-',
  • traderAddress – naslov podjetja, kjer je podjetje registrirano,
  • id – enolični identifikator poizvedbe, ki ga generira sistem VIES (številka posvetovanja)
  • date – datum izvedbe poizvedbe
  • source – vir podatkov, vedno: http://ec.europa.eu

Preverjanje številk za DDV v EU z razčlenjenim naslovom trgovca

Številko EU za DDV lahko potrdite tudi tako, da pokličete na getVIESDataParsed funkcijo, katere parameter je EU DDV številka, ki jo želimo preveriti. S klicem te funkcije prejmete poleg podatka o statusu zavezanca za DDV tudi razčlenjen naslov trgovca.

Opomba! Zaradi pomanjkanja podatkov, ki jih VIES vrne za trgovce iz Nemčije in Španije, funkcija to stori ne vrniti razčlenjen naslov trgovca (traderAddressComponent) za te države.

Pomembna izjava o omejitvi odgovornosti

Funkcija razčlenjevanja uporablja zunanje algoritme umetne inteligence in API-je za samodejno ekstrahiranje atributov, kot so: mesto, poštna številka, ulica s številko ulice (številka stavbe) in hišna številka, zato ne moremo zagotoviti njenega pravilnega delovanja 100%.

Naslednji primer prikazuje, kako se funkcije uporabljajo v knjižnicah:

// A call to a method that returns data from a VIES system
VIESData vies = viesapi.GetVIESDataParsed("PL1234567890");

if (vies != null) {
	Console.WriteLine(vies);
}
else {
	Console.WriteLine("Error: " + viesapi.LastError + " (code: " + viesapi.LastErrorCode + ")");
}
// A call to a method that returns data from a VIES system
VIESData* vies = viesapi_get_vies_data_parsed(viesapi, "PL1234567890");

if (vies != NULL) {
	printf("Kraj: %s\n", vies->CountryCode);
	printf("VAT ID: %s\n", vies->VATNumber);
	printf("Aktywny: %d\n", vies->Valid);
}
else {
	printf("Error: %s (code: %d)\n", viesapi_get_last_err(viesapi), viesapi_get_last_err_code(viesapi));
}
// A call to a method that returns data from a VIES system
VIESData vies = viesapi.getVIESDataParsed("PL1234567890");

if (vies != null) {
	System.out.println(vies);
}
else {
	System.out.println("Error: " + viesapi.getLastError() + " (code: " + viesapi.getLastErrorCode() + ")");
}
// A call to a method that returns data from a VIES system
viesapi.getVIESDataParsed('PL1234567890').then((vies) => {
	console.log(vies.toString());
}).catch((e) => {
	console.log(e.message);
});
// A call to a method that returns data from a VIES system
$vies = $viesapi->get_vies_data_parsed('PL1234567890');

if ($vies) {
	print_r($vies);
}
else {
	echo '<p>Error: ' . $viesapi->get_last_error() . '</p>';
}
# A call to a method that returns data from a VIES system
vies = viesapi.get_vies_data_parsed('PL1234567890')

if vies:
    pprint(vars(vies))
else:
    print('Error: ' + viesapi.get_last_error() + ' (code: ' + str(viesapi.get_last_error_code()) + ')')
' A call to a method that returns data from a VIES system
Dim vies As VIESData
Set vies = viesapi.GetVIESDataParsed("PL1234567890")

If vies Is Nothing Then
	Console.WriteLine("Error: {0}", viesapi.LastError)
Else
	Console.WriteLine(vies.ToString())
End If

Podroben opis vrnjenih atributov:

  • uid – edinstven identifikator poizvedbe, ki ga ustvari viesapi.eu,
  • countryCode – kodo države, v kateri je registrirano podjetje, povezano z EU DDV številko, navedeno v povpraševanju,
  • vatNumber – številko EU za DDV preverjenega podjetja, navedeno v povpraševanju,
  • valid – odgovor storitve VIES, ki obvešča o trenutnem EU DDV statusu preverjanega subjekta:
    • true – številka EU za DDV, navedena v povpraševanju, je veljavna,
    • false – številka EU za DDV, navedena v povpraševanju, ni veljavna,
  • traderName – firmo podjetja,
  • traderCompanyType – vedno vrne niz znakov '-',
  • traderAddress – naslov podjetja, kjer je podjetje registrirano (originalna oblika)
  • traderAddressComponentpodrobnosti o naslovu združevanja komponent
    • country – ime države trgovca v njenem nacionalnem jeziku
    • postalCode – poštno številko naslova trgovca
    • city – mesto naslova trgovca
    • street -ulica naslova trgovca
    • streetNumber – hišna številka naslova trgovca
    • houseNumber – hišna številka naslova trgovca
  • id – enolični identifikator poizvedbe, ki ga generira sistem VIES (številka posvetovanja)
  • date – datum izvedbe poizvedbe
  • source – vir podatkov, vedno: http://ec.europa.eu

Paketno (asinhrono) preverjanje EU DDV številk

getVIESDataAsync – asinhrona funkcija, ki na podlagi poslanega paketa DDV številk omogoča pridobitev trenutnega EU DDV statusa in podatkov trgovca.
Kot parameter navedite matriko nizov, ki vsebuje EU številke za DDV, za katere je treba preveriti status davčnega zavezanca za DDV v EU in prenesti podatke trgovca.

Najmanjše število poslanih EU številk za DDV je 2, največje pa 99.

Pravilno poklicana funkcija vrne žeton, ki je potreben za pridobitev rezultatov zahteve. Naslednji primer prikazuje, kako se funkcije uporabljajo v knjižnicah:

// Upload batch of VAT numbers and get their current VAT statuses and traders data
List numbers = new List {
	"PL1234567890,
	"DK64839576",
	"CZ8475630234"
};

string token = viesapi.GetVIESDataAsync(numbers);

if (token != null) {
	Console.WriteLine("Batch token: " + token);
} else {
	Console.WriteLine("Error: " + viesapi.LastError + " (code: " + viesapi.LastErrorCode + ")");
}
// Upload batch of VAT numbers and get their current VAT statuses and traders data
char* numbers[] = {
	"PL1234567890,
	"DK64839576",
	"CZ8475630234"
};

token = viesapi_get_vies_data_async(viesapi, numbers, 3);

if (token != NULL) {
	printf("Batch token:  %s\n", token);
} else {
	printf("Error: %s (code: %d)\n", viesapi_get_last_err(viesapi), viesapi_get_last_err_code(viesapi));
}
// Upload batch of VAT numbers and get their current VAT statuses and traders data
List numbers = new ArrayList<>();
numbers.add("PL1234567890");
numbers.add("DK64839576");
numbers.add("CZ8475630234");

String token = viesapi.getVIESDataAsync(numbers);

if (token != null) {
	System.out.println("Batch token: " + token);
} else {
	System.out.println("Error: " + viesapi.getLastError() + " (code: " + viesapi.getLastErrorCode() + ")");
}
// Upload batch of VAT numbers and get their current VAT statuses and traders data
const numbers = [
	'PL1234567890',
	'DK64839576',
	'CZ8475630234'
];

viesapi.getVIESDataAsync(numbers).then((token) => {
	console.log('Batch token: ' + token);
}).catch((e) => {
	console.log(e.message);
});
// Upload batch of VAT numbers and get their current VAT statuses and traders data
$numbers = array(
	'PL1234567890',
	'DK64839576',
	'CZ7710043187'
);

$token = $viesapi->get_vies_data_async($numbers);

if ($token) {
	echo '<pre>Batch token: ' . $token . '</pre>';
} else {
	echo '<p>Error: ' . $viesapi->get_last_error() . ' (code: ' . $viesapi->get_last_error_code() . ')</p>';
}
# Upload batch of VAT numbers and get their current VAT statuses and traders data
numbers = [
    'PL1234567890',
    'DK64839576',
    'CZ7710043187'
]

token = viesapi.get_vies_data_async(numbers)

if token:
    print('Batch token: ' + token)
else:
    print('Error: ' + viesapi.get_last_error() + ' (code: ' + str(viesapi.get_last_error_code()) + ')')
' Not supported yet

Zaradi asinhrone narave funkcije je rezultate mogoče pridobiti po približno 2-3 minutah. Ni pomembno, ali so bile v zahtevku poslane številke 2 ali 99 EU za DDV.

Če ima vsaj ena EU številka za DDV, posredovana v zahtevi, napačno obliko, sistem vrne napako »Številka za DDV ni veljavna«.

Za pridobitev rezultatov za poslano zahtevo pokličite na getVIESDataAsyncResult funkcijo, ki zagotavlja vrednost žetona kot vhodni parameter.

Pomembna opomba!

  1. Funkcija je bila pripravljena kot rešitev za napako, ki jo vrne sistem VIES: “The maximum number of concurrent requests has been reached” (MS_MAX_CONCURRENT_REQ). Priporočamo uporabo pri pošiljanju zahtevkov za Nemčija (DE) in Francija (FR), ki je vrnil zgoraj omenjeno napako.
  2. Dokler se postopek preverjanja vseh EU DDV številk, poslanih v zahtevi, ne zaključi, bodo vsi nadaljnji poskusi zavrnjeni in napaka popravljena “The maximum number of batch request has been reached, please re-submit your request later“.

getVIESDataAsyncResult– funkcija vam omogoča, da pridobite paketne rezultate na podlagi žetona, ki ga vrne getVIESDataAsync funkcijo.

Naslednji primer prikazuje, kako se funkcije uporabljajo v knjižnicah:

// Check batch result and download data (at production it usually takes 2-3 min for result to be ready)
BatchResult result;

while ((result = viesapi.GetVIESDataAsyncResult(token)) == null) {
	if (viesapi.LastErrorCode != Error.BATCH_PROCESSING) {
		Console.WriteLine("Error: " + viesapi.LastError + " (code: " + viesapi.LastErrorCode + ")");
		return;
	}

	Console.WriteLine("Batch is still processing, waiting...");
	Thread.Sleep(30000);
}

// Batch result is ready
Console.WriteLine(result);
// Check batch result and download data (at production it usually takes 2-3 min for result to be ready)
while ((result = viesapi_get_vies_data_async_result(viesapi, token)) == NULL) {
	if (viesapi_get_last_err_code(viesapi) != VIESAPI_ERR_BATCH_PROCESSING) {
		printf("Error: %s (code: %d)\n", viesapi_get_last_err(viesapi), viesapi_get_last_err_code(viesapi));
		return;
	}

	printf("Batch is still processing, waiting...\n");
	Sleep(30000);
}

// Batch result is ready
for (i = 0; i < result->NumbersCount; i++) {
	printf("Country:  %s\n", result->Numbers[i]->CountryCode);
	printf("VAT ID:   %s\n", result->Numbers[i]->VATNumber);
	printf("Is valid: %d\n", result->Numbers[i]->Valid);
	printf("\n");
}

for (i = 0; i < result->ErrorsCount; i++) {
	printf("Country:  %s\n", result->Errors[i]->CountryCode);
	printf("VAT ID:   %s\n", result->Errors[i]->VATNumber);
	printf("Error:    %s\n", result->Errors[i]->Error);
	printf("\n");
}
// Check batch result and download data (at production it usually takes 2-3 min for result to be ready)
BatchResult result;

while ((result = viesapi.getVIESDataAsyncResult(token)) == null) {
	if (viesapi.getLastErrorCode() != eu.viesapi.client.Error.BATCH_PROCESSING) {
		System.out.println("Error: " + viesapi.getLastError() + " (code: " + viesapi.getLastErrorCode() + ")");
		return;
	}

	System.out.println("Batch is still processing, waiting...");
	Thread.sleep(30000);
}

// Batch result is ready
System.out.println(result);
// Check batch result and download data (at production it usually takes 2-3 min for result to be ready)
const looper = setInterval(() => {
	viesapi.getVIESDataAsyncResult(token).then((result) => {
		// Batch result is ready
		console.log(result);
		clearInterval(looper);
	}).catch((e) => {
		console.log(e.message);
	});
}, 30000);
// Check batch result and download data (at production it usually takes 2-3 min for result to be ready)
while (($result = $viesapi->get_vies_data_async_result($token)) === false) {
	if ($viesapi->get_last_error_code() !== \VIESAPI\Error::BATCH_PROCESSING) {
		echo '<p>Error: ' . $viesapi->get_last_error() . ' (code: ' . $viesapi->get_last_error_code() . ')</p>';
		die();
	}

	echo '<p>Batch is still processing, waiting...</p>';
	sleep(30);
}

// Batch result is ready
echo '<pre>' . print_r($result, true) . '</pre>';
# Upload batch of VAT numbers and get their current VAT statuses and traders data
numbers = [
    'PL1234567890',
    'DK64839576',
    'CZ7710043187'
]

token = viesapi.get_vies_data_async(numbers)

if token:
    print('Batch token: ' + token)
else:
    print('Error: ' + viesapi.get_last_error() + ' (code: ' + str(viesapi.get_last_error_code()) + ')')
' Not supported yet

Za vsako številko EU za DDV, posredovano v paketnem klicu, so atributi skladni z odgovorom na getVIESData funkcija se vrne.

Pridobivanje informacij o statusu uporabnikovega računa

Funkcija omogoča prenos vseh osnovnih podatkov o uporabniškem računu, ki se prikažejo po prijavi v račun na portalu viesapi.eu. Funkcija vrne tudi podatek o maksimalnem številu poizvedb, ki so na voljo v okviru izbranega načrta (npr. 5.000 za Poslovni načrt) in skupno število vseh poizvedb v tekočem mesecu na uporabnikovem računu.

Pozor! Klicanje funkcije naredi ne povečati število opravljenih poizvedb.

Naslednji primer ponazarja, kako uporabljati funkcije knjižnice.

// Get current account status
AccountStatus account = viesapi.GetAccountStatus();

if (account != null) {
     Console.WriteLine(account);
}
else {
     Console.WriteLine("Error: " + viesapi.LastError);
}
// Get current account status
AccountStatus* account = viesapi_get_account_status(viesapi);

if (account != NULL) {
	printf("Plan name: %s\n", account->BillingPlanName);
	printf("Price: %.2f\n", account->SubscriptionPrice);
	printf("Number of queries: %d\n", account->TotalCount);
}
else {
	printf("Error: %s\n", viesapi_get_last_err(viesapi));
}
// Get current account status
AccountStatus account = viesapi.getAccountStatus();

if (account != null) {
     System.out.println(account);
}
else {
     System.err.println("Error: " + viesapi.getLastError());
}
// Get current account status
viesapi.getAccountStatus().then((account) => {
	console.log(account.toString());
}).catch((e) => {
	console.log(e.message);
});
// Get current account status
$account = $viesapi->get_account_status();

if ($account) {
     echo '<p>' . print_r($account, true) . '</p>';
}
else {
     echo '<p>Error: ' . $viesapi->get_last_error() . '</p>';
}
# Get current account status
account = viesapi.get_account_status()

if account:
    pprint(vars(account))
else:
    print u'Error: ' + viesapi.get_last_error()
'Get current account status
Dim account As AccountStatus
Set account = viesapi.GetAccountStatus()

If account Is Nothing Then
	Console.WriteLine("Error: {0}", viesapi.LastError)
Else
	Console.WriteLine(account.ToString())
End If

Registracija knjižnice .NET kot predmeta COM

The viesapiLibrary.dll knjižnico lahko registrirate v sistemu Windows kot t.i COM predmet. Nato se lahko na funkcije knjižnice sklicujete iz številnih različnih programskih jezikov in že pripravljenih aplikacij, vklj. Microsoft Excel, Access, SQL Server, Dynamics ali Visual FoxPro.

Če želite registrirati knjižnico kot objekt COM, sledite tem korakom:

  1. Prenesite knjižnica .NET arhivirajte in razpakirajte na lokalni disk na poljubno lokacijo.
  2. Pojdite v imenik z nepakiranimi datotekami knjižnice in poiščite com-register.bat mapa.
  3. Izberite com-register.bat datoteko z miško in izberite Run as administrator ukaz iz kontekstnega menija.

Uporaba knjižnice .NET v MS Excelu

Funkcije knjižnice viesapiLibrary.dll lahko uporabite v aplikaciji MS Excel za pisanje lastnih funkcij in postopkov v Visual Basic jezik. Da bi to omogočili, je potrebno:

  1. Registrirajte se the viesapiLibrary.dll knjižnica kot a COM predmet na Windows.
  2. Zaženite aplikacijo Excel. Izberite DEVELOPER na traku in nato kliknite Visual Basic gumb.
  3. V Visual Basic for Application okno, izberite Tools in potem References iz menija. V Available References seznam, poiščite in izberite VIESAPI Service Client for .NET Framework (C#). Izbiro potrdite z OK gumb.
  4. Iz Insert meni, izberite Module in prilepite funkcijsko kodo, predstavljeno v primerih za Visual Basic, v novo okno.
  5. Končno ustrezne vrednosti w za viesapi.ID in viesapi.Key je treba nastaviti. Način pridobitve ključa in ključa za dostop je opisan v poglavju Generiranje identifikatorja in ključa za dostop