Electronic invoicing with Ruby
This tutorial builds two simple Ruby applications from scratch:
- Receive: connects and authenticates with the Invoicetronic API and downloads any new incoming invoices.
- Send: connects and authenticates with the Invoicetronic API and sends an invoice to the SDI.
Before continuing, make sure all the prerequisites below are met.
Prerequisites
We assume that these prerequisites are met:
- Ruby 2.7+ has been installed
- Bundler has been installed (
gem install bundler) - You obtained an active API Key
- You registered with the Italian Revenue Service (needed for the live environment)
Did you know?
The Ruby SDK is compatible with Rails, Sinatra, and all modern Ruby applications.
Receive
Create the app
The first step is to create the application directory:
Install the SDK
Create a Gemfile with the following content:
Then install the dependencies:
Configure the SDK
Create the file receive.rb:
require 'invoicetronic_sdk'
# Configure the SDK
InvoicetronicSdk.configure do |config|
config.host = 'https://api.invoicetronic.com/v1'
config.username = 'YOUR TEST API KEY (starts with ik_test_)'
config.password = ''
end
As you can see, we configure the SDK by setting the host and HTTP Basic authentication with your test API Key (not the live one). Notice how we use username for the API Key and password empty.
API Key comes in pairs
When you create your account, you obtain a pair of API Keys. One is the test key for the API Sandbox, and the other is the live API's. You can tell the difference because the former starts with ik_test_, while the latter begins with ik_live_. In this tutorial, always use the test key.
Download invoices
We are ready to make a request. We want to download new vendor invoices that may be available from the SDI. Add this code to the file:
require 'base64'
# Download unread invoices
api_instance = InvoicetronicSdk::ReceiveApi.new
begin
inbound_invoices = api_instance.receive_get(
nil, # company_id
nil, # identifier
true, # unread
nil, # committente
nil, # prestatore
nil, # file_name
nil, # last_update_from
nil, # last_update_to
nil, # date_sent_from
nil, # date_sent_to
nil, # document_date_from
nil, # document_date_to
nil, # document_number
true, # include_payload
nil, # page
nil, # page_size
nil # sort
)
puts "Received #{inbound_invoices.length} invoices"
inbound_invoices.each do |invoice|
if invoice.encoding == 'Xml'
File.write(invoice.file_name, invoice.payload)
elsif invoice.encoding == 'Base64'
File.write(invoice.file_name, Base64.decode64(invoice.payload))
end
puts "Downloaded #{invoice.file_name} from a vendor with VAT ID #{invoice.prestatore}"
end
rescue InvoicetronicSdk::ApiError => e
puts "Error: #{e}"
end
Payload Inclusion
We set include_payload to true to retrieve the actual invoice content in the payload property. Without this parameter, the payload field would be nil by default, which increases performance and reduces response size when you only need metadata.
Run the application:
You should obtain an output similar to this one:
Received 3 invoices
Downloaded file1.xml from a vendor with VAT ID IT06157670966
Downloaded file2.xml.p7m from a vendor with VAT ID IT01280270057
Downloaded file3.xml.p7m from a vendor with VAT ID IT01280270057
The files are in the current directory, ready for you to inspect them.
Not receiving invoices in the live environment?
Ensure you registered with the Italian Revenue Service, which is a requirement for the live environment.
What we learned
In this example, we learned several things.
-
We must configure the SDK using
InvoicetronicSdk.configure, setting the host and configuring HTTP Basic authentication with username (API key) and empty password. -
We must instantiate a class representing the endpoint we want to work with. In this case, we leverage
ReceiveApito download incoming invoices. -
Endpoint classes like
ReceiveApioffer methods for interacting with their target entity. We callreceive_getto retrieve invoices. Because we only want new, unread invoices, we passtruefor theunreadparameter. We also passtrueforinclude_payloadto retrieve the actual invoice content. -
Invoice objects expose properties like
encoding,file_name, andpayload. The last one contains the invoice content, as plain text or Base64-encoded, as described byencodingwhich has the values'Xml'or'Base64'.
Source Code on GitHub
The source code for this Quickstart is also available on GitHub.
Send
Create the app
The first step is to create the application directory:
Install the SDK
Create a Gemfile with the following content:
Then install the dependencies:
Configure the SDK
Create the file send.rb:
require 'invoicetronic_sdk'
# Configure the SDK
InvoicetronicSdk.configure do |config|
config.host = 'https://api.invoicetronic.com/v1'
config.username = 'YOUR TEST API KEY (starts with ik_test_)'
config.password = ''
end
As you can see, we configure the SDK by setting the host and HTTP Basic authentication with your test API Key (not the live one).
API Key comes in pairs
When you create your account, you obtain a pair of API Keys. One is the test key for the API Sandbox, and the other is the live API's. You can tell the difference because the former starts with ik_test_, while the latter begins with ik_live_. In this tutorial, always use the test key.
Send an invoice
We are ready to make a request. We want to send an invoice to the SDI. Add this code to the file:
# Send an invoice
file_path = '/some/file/path/filename.xml'
meta_data = {
'internal_id' => '123',
'created_with' => 'myapp',
'some_other_custom_data' => 'value'
}
api_instance = InvoicetronicSdk::SendApi.new
begin
payload = File.read(file_path)
send_data = InvoicetronicSdk::Send.new(
file_name: File.basename(file_path),
payload: payload,
meta_data: meta_data
)
sent_invoice = api_instance.send_post(send_data)
puts "The invoice was sent successfully, it now has the unique Id of #{sent_invoice.id}."
rescue InvoicetronicSdk::ApiError => e
puts "Error: #{e}"
end
Run the application:
You should obtain an output similar to this one:
What we learned
In this example, we learned several things.
-
We must configure the SDK using
InvoicetronicSdk.configure, setting the host and configuring HTTP Basic authentication. -
We must instantiate a class representing the endpoint we want to work with. In this case, we leverage
SendApito send invoices. Endpoint classes likeSendApioffer methods for interacting with their target entity. We callsend_postto send an invoice. -
The
Sendmodel accepts parameters in the constructor:file_name,payload, andmeta_data. The payload contains the invoice content, whilemeta_datais optional and binds custom data to the document.
Source Code on GitHub
The source code for this Quickstart is also available on GitHub.