Submit a transaction

To submit a transaction send HTTP POST api.fonoa.com/v1/transactions with the following body:

{
    "country_code": "PT",
    "language_code": "PT",
    "currency_code": "EUR",
    "transaction_date": "2023-06-15T01:00:00+00:00",
    "transaction_id": "ref111",
    "operation_regime": "GENERAL",
    "type": "FULL",
    "direction": "SENT",
    "items": [
        {
            "number": 1,
            "name": "Service ABC",
            "description": "Service ABC",
            "quantity": 1.0,
            "unit": "pcs",
            "code": "1",
            "ean": "1",
            "unit_price": 5000.245,
            "net_price": 5000.245,
            "type": "GOODS",
            "tax_breakdown": [
                {
                    "rate": 23,
                    "amount": 1150.05635,
                    "regime": "IVA",
                    "type": "PT"
                }
            ]
        }
    ],
    "supplier": {
        "id": "{supplier_id}"
    },
    "customer": {
        "legal_name": "Customer Legal Name",
        "address": {
            "country_code": "PT",
            "address_line_1": "Lisboa Street 55A",
            "postal_code": "1700-031",
            "city": "Lisboa"
        },
        "tax_information": {
            "tax_number": "123456789"
        },
        "type": "INDIVIDUAL"
    },
    "payments": [
            {
                "type": "CREDIT",
                "amount": 6150.30135
            }
    ],
    "total_amount": 6150.30135,
    "total_net_amount": 5000.245,
    "total_tax_amount": 1150.05635
}

If there are no validation errors clients shall receive 202 Accepted with the following response body:

{  
	"operation_id": "4d697215-76c9-11ed-bfa7-660c4038a014"  
}

🚧

Duplicated submissions

Submitting the same transaction repeatedly within a one-minute timeframe will yield an identical operation_id for each submission.

Validation

Validation rules are dynamically adjusted depending on:

  • Transaction country
  • Client use case (i.e., Reporting, Invoicing, or both)

When a request is incorrect, you will receive a http status code 400 Bad Request and an error response, for example:

{
	"errors": [
		{
			"code": "field_required",
			"message": "supplier must not be empty.",
			"type": "validation"
		},
		{
			"code": "field_required",
			"message": "transaction_id must not be empty.",
			"type": "validation"
		},
		{
			"code": "field_not_valid",
			"message": "items.0.number must be greater than 0.",
			"type": "validation"
		}
	],
	"message": "Invalid transaction payload"
}



Listen to a webhook

Once the transaction has been processed, the webhook will be sent to the URL set during the client onboarding process.

It can take up to 48 hours to process a transaction depending on the Tax Authority system’s availability.

Webhooks have the same payload across the Fonoa platform. More info about it can be found here. Here’s an example payload you will receive from us.

Content-Type: application/json
X-Fonoa-Hmac-SHA256: SIGNATURE (Vide webhooks documentation)

{
  "event_type": "transactions.transaction_completed",
  "delivered_at": "2006-01-02T15:04:05Z",
  "resource_id": "4d697215-76c9-11ed-bfa7-660c4038a014",
  "resource_url": "https://api.fonoa.com/v1/transactions/4d697215-76c9-11ed-bfa7-660c4038a014",
  "webhook_id": "875bd24499d303cbe8afb3db1987d8aa522d63bb"
}


resource_id field matches the Fonoa generated operation_id generated on submitting a transaction.

Clients can access transaction details by sending a GET request to resource_url. If the transaction was successfully processed, a payload is returned which contains a combination of

  • Data submitted by the client
  • Any data enrichments performed by Fonoa
  • Identifiers for the data in Fonoa’s system
  • Pointers to documents that may have been created

⚠️ Generated documents

URLs to documents (see resource_url in the attachments array below) will change in the future. Clients should not rely on these URLs to be long lived. They should not be passed to the client’s end users.

We recommend downloading the files immediately once a webhook is received and storing them on your system.

e.g. Request GET https://api.fonoa.com/v1/transactions/4d697215-76c9-11ed-bfa7-660c4038a014

Response (200 OK):

{
  "operation_id": "4d697215-76c9-11ed-bfa7-660c4038a014",
  "transaction_id": "MY_EXTERNAL_TRANSACTION_ID",
  "document_generated_at": "2019-08-24T14:15:22Z",
  "transaction_number": "00001",
  "unique_transaction_number": "2022-00001",
  "tax_authority_id_1": "50610082300310279826500300001040000000009195917993",
  "status": "SUCCESS",
  "attachments": [
    {
	"kind": "VISUAL",
      "resource_id": "4983240cf1d84f5c91e078d0a41c6001",
      "resource_url": "https://api.fonoa.com/invoicing/v1/invoices/4983240cf1d84f5c91e078d0a41c6001/pdf",
      "type": "PDF"
    }
  ],
  ... // removed full payload for brevity 
}


Processing a webhook

Putting it all together, these are the high level steps to go through when you receive a webhook from Fonoa:

  1. Verify the message (see docs)
  2. Fetch the transaction result using the resource_url
  3. Check if any errors or warnings are present (see Asynchronous Errors)If errors are present, take the required steps to resolve them
  4. If no errors are present, you can store the details and download any attachments present

Idempotency

The Transactions API is idempotent. Fonoa guarantees that the transaction with the provided transaction_id will be processed exactly once.

💡Once the transaction is successfully processed it cannot go back to a failed state.


Submitting a transaction with a successfully processed transaction_id will result in no operation - Fonoa will send a webhook informing the client about the latest successful result.

If the submitted transaction_id was not successfully processed before, Fonoa will re-process it and inform the client about the latest Transaction result via webhooks.

These properties allow clients to safely replay the transaction an arbitrary number of times.


Transaction history

A single transaction may be submitted multiple times. Fonoa assigns each transaction attempt a unique operation ID. Fonoa allows you to fetch all the transaction attempts for a given transaction ID and see their statuses and respective operation IDs.

Here’s an example:

GET https://api.fonoa.com/v1/transactions/history/<transaction_id>

// 200 OK - when transaction ID exists in Fonoa system
{
	"history": [
		{
			"operation_id": "018c5da4-aba6-75df-9c41-5b6f4d394e43",
			"status": "SUCCESS"
		}
	]
}

// 404 Not Found - when transaction ID does not exist in Fonoa system
{
	"message": "transaction with ID MY_NONEXISTENT_TRANSCTION_ID not found.",
	"transaction_id": "MY_NONEXISTENT_TRANSCTION_ID"
}


The transaction may have one of the following statuses:

  • SUCCESS
  • PROCESSING
  • FAILURE

💡Transaction history is eventually consistent, meaning that you might not see the result immediately after submitting the transaction. Don’t use this endpoint for polling purposes. Instead, you should rely on webhooks for the transaction result.