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:

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:

  1. 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
  2. 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:

  1. Applications with a desktop interface
  2. Applications with a Web interface

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.

A possible implementation could look as follows:

Apps with desktop interface

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 (the socrate.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:
    1. SBS finalizes the authorization automatically by calling the finalizeAuthorization mutation with required parameters;
    2. 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.
  • 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:

Apps with Web interface

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 and code in case of successful authorization
    • state and error 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 the authorizations 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:

Apps with custom return URL

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.

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:

  1. the state URL parameter (the same as the one obtained from generateAuthorizationRequest call)
  2. 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.