Using Bitcoin Core, I would combine
> bitcoin-cli getnewaddress ( "label" "address_type" )
Allows you to generate a new invoice address and label it to identify the current purchasing process. It returns a string with the newly generated address which you can then decorate according to the BIP21 URI scheme to allow operating systems to recognize it as a Bitcoin address, and output that the resulting string using a quick response code tool such as
Finally, you would poll your wallet for new transactions using
> bitcoin-cli listtransactions ( "label" count skip include_watchonly )
which will give you recent transactions relevant to the wallet, or alternatively allows you to specifically filter by the label you previously attached in
getnewaddress. The rpc descriptions I linked are for Bitcoin Core 0.21.0, but older docs are available through the same site.
Note that versions preceding Bitcoin Core 0.17.0 (released in October 2018) are past their End of Life date in their maintenance cycle. I would emphatically recommend using a newer version of Bitcoin than what may have shipped with Ubuntu 16.04.