RO ANAF OAuth Service
Access info
Endpoint | https://ro-anaf-oauth-api.socrate.io/graphql |
Required access keys | Tenant-level service access key |
Pricing | Please contact us for details at contact@bitsoftware.ro |
Notes | To call the service, the access key must be provided in the x-api-key header of the HTTP request. If you are using the GraphQL console, you can view the service’s documentation and schema only after entering an access key. Make sure that the scope of the key allows access to the queries and mutations that you require. For example, to grant the key access to all queries and mutations, the keys’s scope must be set to ro-anaf-oauth-api:query:* ro-anaf-oauth-api:mutation:* . |
Usage
The RO ANAF OAuth Service enables you to obtain OAuth access tokens from the Romanian National Agency of Fiscal Administration (ANAF). Such tokens are necessary if your application should provide to users (for example, to authorized bookkeepers) the ability to submit any of the following data to ANAF:
- E-Transport declarations, through the RO E-Transport Service
- E-Factura electronic invoice submissions, through the RO E-Factura Service
As with the OAuth Service, your application does not need to implement a direct interface to ANAF, since all interaction is taken over by SBS, namely:
- the OAuth access and refresh tokens obtained from ANAF are stored and managed by SBS on behalf of your application. Your application can access the authorization details (excluding any sensitive information) through the
authorizations
query. - Periodical refresh of access tokens is also taken care of by SBS automatically; there is no need to implement a process for this.
Prerequisites
Before using this service, the following prerequisites must be in place:
- If you haven’t done that already, set up your app’s OAuth 2.0 secrets to be used in communication with ANAF. For step-by-step details, see Configure ANAF OAuth 2.0 secrets
- The organization for which ANAF OAuth 2.0 authorization takes place must exist in SBS. You can add new organizations from the SBS Portal, or programmatically through the Organizations Service.
Implementation
Once the prerequisites are met, you can start implementing the ANAF OAuth process in your application. Depending on the kind of your application, there are two possible implementation paths:
- Applications with a desktop interface
- Applications with a Web interface
notify
mutation of the RO E-Transport Service or the uploadInvoice
mutation of the RO E-Factura Service).
Applications with a desktop interface
If your application does not have a Web interface, it cannot handle by itself the authorization response received from ANAF. This is the case of desktop apps that are installed on multiple clients and are all managed by a centralized application server (which does not provide a Web interface). For such scenarios, SBS provides a default callback URL, which is https://ro-anaf-oauth-api.socrate.io/oauth-callback
. The default callback URL will handle the OAuth authorization response from ANAF, and, in case of success, will take the user to either the default success URL, or to a custom return success URL if you configured one.
socrate.io
domain, this implementation requires that the socrate.io
domain be in the allow list as part of your company’s security policies. This is particularly important when your app is a desktop app with multiple installed client instances that are all communicating with a centralized application server. In such cases, both the client desktop instance and the centralized application server must have socrate.io
in the allow list.
A possible implementation could look as follows:
In the diagram above, the following happens:
- When the user clicks a button from the Organization page or screen (for example, “Authorize with ANAF”), your application must run the
generateAuthorizationRequest
mutation of the RO ANAF OAuth Service. As a result, you get an authorization request object in the response. The authorization request includes a url and a shortUrl. - Your app should now redirect the user to the shortUrl. The purpose of this step is to prevent the user from issuing a request to ANAF servers if they cannot access the default callback URL (for example, because of their company’s security policies). If the HTTP request fails at this stage, this indicates that most likely the
socrate.io
domain is not in the allow list on the user’s computer; therefore, it doesn’t make sense to proceed to ANAF authorization. Otherwise, if the HTTP status code indicates non-failure, the request will be automatically forwarded by SBS (thesocrate.io
domain) to ANAF for processing. - For successful authorization, the user is expected to have inserted a dongle in the USB port of the computer, from which the ANAF client certificate is read. The dongle is provided by ANAF to entities relevant for ANAF reporting, such as authorized bookkeepers or company directors.
- If the authorization was successful, the following happens:
- SBS finalizes the authorization automatically by calling the
finalizeAuthorization
mutation with required parameters; - The user is taken to the default success URL, which is on the
socrate.io
domain. There are no parameters involved; this is a static page that displays a generic success message.
- SBS finalizes the authorization automatically by calling the
- If the ANAF OAuth authorization ends with an error, the user is taken to the default error URL, which is on the
socrate.io
domain.
Apart from showing the user the success or error URLs, this approach does not provide an explicit indication to your app about when the ANAF authorization process has finished (with either success or error). Therefore, in order to confirm that the ANAF authorization was successful and the authorization details have reached the SBS system, your application should run the authorizations
query.
Applications with a Web interface
For applications that have a Web interface, using a custom callback URL is the recommended approach. A possible implementation could look as follows:
In the diagram above, the following happens:
- When the user clicks a button from the Organization page or screen (for example, “Authorize with ANAF”), an ANAF authorization process is triggered through a call to
generateAuthorizationRequest
mutation of the RO ANAF OAuth Service. As a result, you get an authorization request object in the response. The authorization request includes a URL from ANAF in the response. - Your app should now redirect the user to the received URL. As a result, the user’s browser is taken to ANAF website for the manual authorization process.
- For successful authorization, the user is expected to have inserted a dongle in the USB port of the computer, from which the ANAF client certificate is read. The dongle is provided by ANAF to entities relevant for ANAF reporting, such as authorized bookkeepers or company directors.
- If the authorization is successful, the user is taken to the callback URL with the following query parameters:
state
andcode
in case of successful authorizationstate
anderror
in case of error
- If the authorization was successful, you must run the
finalizeAuthorizationRequest
mutation, providing the previously received state and code as input. In the response, you will get an authorization object that provides information about the authorization that just took place. You can access all currently available authorizations through theauthorizations
query. - If the authorization encountered an error from ANAF, your app must handle it accordingly.
Applications with a Web interface and the default callback URL
If your app has a Web interface, you can also use a “lazy” approach that does not require you to implement handling of the ANAF OAuth response at a custom URL. Instead, you can configure a default callback URL similar to how this is done for apps with a desktop interface. The diagram for this approach looks the same as the one described for apps with a desktop interface.
Using custom return URLs for success and error
When you use the default callback URL, you might optionally want the user to be redirected to a custom URL after the ANAF OAuth authorization process completes. Namely, if the process completed successfully, you might want to show the user a custom success URL instead of the default one. The same applies to the error URL.
To implement such behavior, you must provide the optional onSuccessReturnUrl
and onFailureReturnUrl
arguments to the generateAuthorizationRequest
mutation. In this case, the implementation could look as follows:
Queries
authorizations
Returns a list of authorizations already obtained from ANAF.
Arguments
Argument | Type | Description |
---|---|---|
organizationID | ID! |
The ID of the organization from the Organizations service. |
filter | AuthorizationsFilter! |
Specifies the criteria by which to filter the result. |
AuthorizationsFilter
input
Attribute | Type | Description |
---|---|---|
scope | Scope! |
An enumeration with the following values: EFACTURA, ETRANSPORT. |
Result
Authorization
type
Attribute | Type | Description |
---|---|---|
id | ID |
The ID of the authorization. |
organizationId | ID |
The ID of the organization from the Organizations service to which this authorization applies. |
scope | Scope |
An enumeration with the following values: EFACTURA, ETRANSPORT. |
createdAt | DateTime |
The date and time when the authorization was created. |
updatedAt | DateTime |
The date and time when the authorization was last updated. |
authorizationRequests
Returns a list of previously generated authorization requests.
Arguments
Argument | Type | Description |
---|---|---|
organizationID | ID! |
The ID of the organization from the Organizations service. |
filter | AuthorizationRequestsFilter! |
Specifies the criteria by which to filter the result. |
AuthorizationRequestsFilter
input
Attribute | Type | Description |
---|---|---|
scope | Scope! |
An enumeration with the following values: EFACTURA, ETRANSPORT. |
Result
See the AuthorizationRequest
type.
organizations
Returns a list of active organizations defined in the Organizations Service. This is a convenience query used to obtain the list of organizations without having to query the Organizations Service separately.
Result
The result is an array of Organization
. Note this is a simplified type compared to the Organization
type from the Organizations Service, and contains only the fields relevant for the RO ANAF OAuth 2.0 Service.
Organization
type
Attribute | Type | Description |
---|---|---|
id | ID! |
Specifies the organization’s unique identifier. |
name | String |
Specifies the organization’s name. |
tin | String |
Specifies the organization’s tax identification number (TIN) (in Romanian, CIF - cod de identificare fiscală) issued by ANAF (in Romanian, ANAF - Agenția Națională de Administrare Fiscală). |
regNo | String |
Specifies the organization’s registration number issued by the National Trade Registration Office (in Romanian, ONRC - Oficiul National al Registrului Comerțului). |
country | CountryCode |
Enum value that identifies the ISO 3166-2 two-letter country code. |
createdAt | DateTime |
The date and time when the organization record was created in SBS. |
version
Returns the API version.
Mutations
generateAuthorizationRequest
Creates an authorization request object. The goal of this mutation is to obtain the URL to which the user’s browser must be redirected for the ANAF authorization process. For implementations that use the default OAuth callback URL, it is recommended that the user’s browser be redirected to shortUrl instead of url. This ensures that no request will be sent to ANAF if the user cannot access the callback URL (for example, due to their organization’s security policies).
Arguments
Argument | Type | Description |
---|---|---|
organizationID | ID! |
The ID of the organization from the Organizations service. |
input | GenerateAuthorizationRequestInput! |
Provides the input arguments. |
GenerateAuthorizationRequestInput
input
Argument | Type | Description |
---|---|---|
scope | Scope! |
Mandatory. Valid values are either EFACTURA or ETRANSPORT, depending on the service for which this authorization is used. |
onSuccessReturnUrl | Uri |
Optional. Applicable only if the OAuth callback URL is the default one (https://ro-anaf-oauth-api.socrate.io/oauth-callback ). When this value is provided, the user’s browser will be redirected to onSuccessReturnUrl after performing a successful authorization with ANAF. |
onFailureReturnUrl | Uri |
Optional. Applicable only if the OAuth callback URL is the default one (https://ro-anaf-oauth-api.socrate.io/oauth-callback ). When this value is provided, the user’s browser will be redirected to onFailureReturnUrl if an error was encountered during authorization with ANAF. |
oauthCallback | Uri |
Optional. If supplied, this callback URL will be used for authorization, if it is defined in the additional ANAF OAuth 2.0 secrets in your SBS application. See Managing additional ANAF OAuth 2.0 secrets. |
Result
AuthorizationRequest
type
Attribute | Type | Description |
---|---|---|
scope | Scope |
This field informs about the service for which this authorization request was generated. Valid values are either EFACTURA or ETRANSPORT. |
url | Uri |
This field specifies the URL to which your app must redirect the user’s browser in order to initiate the user’s authorization process with ANAF. |
state | String |
This value identifies the state of the authorization and is also included in the url as a query parameter. When the user’s authorization process with ANAF completes successfully, the state query parameter will be passed to the OAuth callback URL, alongside code. |
shortUrl | Uri |
Applicable for implementations where the OAuth callback URL is the default one (https://ro-anaf-oauth-api.socrate.io/oauth-callback ). Your app should redirect the user’s browser to this URL to verify if the callback URL is not blocked due to security policies in their organization. |
createdAt | DateTime |
The date and time when the authorization request was created. |
finalizeAuthorizationRequest
Running this mutation is required only in implementations where a custom OAuth callback URL is used. Once the user completes the ANAF authorization request, the browser is redirected to the callback URL with the following query parameters:
- the state URL parameter (the same as the one obtained from
generateAuthorizationRequest
call) - a code URL parameter (upon successful approval) or an error URL parameter (upon failed approval).
Both state and code are required as input arguments to finalizeAuthorizationRequest
to finalize the authorization and store the ANAF access and refresh tokens in SBS.
Arguments
finalizeAuthorizationRequestInput
input
Argument | Type | Description |
---|---|---|
state | String! |
Mandatory. Set this to the authorization state returned by generateAuthorization . |
code | String! |
Mandatory. Set this to the authorization code received in the callback URL. |
Result
An object of type Authorization.
revokeAuthorization
Revokes a previously approved authorization.
Arguments
Argument | Type | Description |
---|---|---|
organizationId | ID! |
Mandatory. The ID of the organization from the Organizations service for which the authorization is to be revoked. |
id | ID! |
Mandatory. The ID of the authorization that is to be revoked. |
Result
An object of type Authorization.