Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
69 changes: 69 additions & 0 deletions monero-rpc-odoo-pos/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
Monero Odoo
=========================


[![Build Status](https://api.travis-ci.com/t-900-a/moneroodoo.svg?branch=main)](https://travis-ci.com/t-900-a/moneroodoo)
[![codecov](https://codecov.io/gh/t-900-a/moneroodoo/branch/main/graph/badge.svg?token=10S5GGNRHH)](https://codecov.io/gh/t-900-a/moneroodoo)

Allows you to accept Monero as Payment within your Odoo Ecommerce shop

Configuration
=============

* Monero - This quickstart guide can guide you through the configuration of Monero specific
components. https://monero-python.readthedocs.io/en/latest/quickstart.html
* monerod
* https://www.getmonero.org/resources/moneropedia/daemon.html
* Download: https://www.getmonero.org/downloads/#cli
* monero-wallet-rpc
* Use a view-key on the server
* https://www.getmonero.org/resources/developer-guides/wallet-rpc.html
* Download: https://www.getmonero.org/downloads/#cli
* Odoo - Add-ons are installed by adding the specific module folder to the add-ons
directory (restart
required)
* queue-job
* https://github.com/OCA/queue
* monero-rpc-odoo-pos
* https://github.com/monero-integrations/moneroodoo
* The Monero payment acquirer is configured similar to other payment acquirers
* https://www.odoo.com/documentation/user/14.0/general/payment_acquirers/payment_acquirers.html#configuration
* Currency rate
* You will need to manually add currency rate for Monero
* https://www.odoo.com/documentation/user/14.0/accounting/others/multicurrencies/how_it_works.html
* Pricelist
* A pricelist should be created specifically for Monero
* https://www.odoo.com/documentation/user/14.0/website/publish/multi_website.html#pricelists



Usage
=====

* At Ecommerce checkout your customer's will be presented with the option to pay
with Monero

Bug Tracker
===========

Bugs are tracked on [GitHub Issues](https://github.com/monero-integrations/moneroodoo/issues).
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
[feedback](https://github.com/monero-integrations/moneroodoo/issues/new?body=module:%20monero-rpc-odoo%0Aversion:%14.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**)?

Credits
=======

Contributors

* T-900 <https://github.com/t-900-a>

Maintainers

This module is maintained by Monero-Integrations.
![Monero-Integrations](/monero-rpc-odoo/static/src/img/monero-integrations.png)


This module is part of the [monero-integrations/moneroodoo](https://github.com/monero-integrations/moneroodoo) project on GitHub.

You are welcome to contribute. To learn how please visit the [Monero Taiga](https://taiga.getmonero.org/project/t-900-monero-x-odoo-integrations/).
1 change: 1 addition & 0 deletions monero-rpc-odoo-pos/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import controllers, models
36 changes: 36 additions & 0 deletions monero-rpc-odoo-pos/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "monero-rpc-odoo-pos",
"summary": "Allows you to accept Monero Payments within Odoo Point Of Sale",
"author": "Monero Integrations",
"website": "https://monerointegrations.com/",
# Categories can be used to filter modules in modules listing
# for the full list
"category": "Accounting",
"version": "14.0.0.0.1",
# any module necessary for this one to work correctly
"depends": [
"account",
"base_setup",
"web",
"queue_job",
"point_of_sale",
],
"external_dependencies": {"python": ["monero"]},
# always loaded
"data": [
# "data/currency.xml", # not including as xmr may already be there
"data/monero_xmr_payment_method.xml",
"data/queue.xml",
"views/pos_payment_method_form.xml",
"views/pos_payment_method_views.xml",
"views/pos_payment_views.xml",
],
# only loaded in demonstration mode
# TODO add demo data
"demo": [
"demo/demo.xml",
],
"installable": True,
"application": True,
"classifiers": ["License :: OSI Approved :: MIT License"],
}
1 change: 1 addition & 0 deletions monero-rpc-odoo-pos/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import monero_controller
110 changes: 110 additions & 0 deletions monero-rpc-odoo-pos/controllers/monero_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import logging

from odoo.http import request
from odoo import http
from odoo.exceptions import ValidationError

from monero.wallet import Wallet

from monero.backends.jsonrpc import Unauthorized
from requests.exceptions import SSLError
from odoo.addons.queue_job.exception import RetryableJobError


class MoneroPaymentMethodRPCUnauthorized(Unauthorized):
pass


class MoneroPaymentMethodRPCSSLError(SSLError):
pass


class NoTXFound(RetryableJobError):
pass


class NumConfirmationsNotMet(RetryableJobError):
pass


class MoneroAddressReuse(Exception):
pass


_logger = logging.getLogger(__name__)


class MoneroController(http.Controller):
@http.route(
"/pos/monero/get_address",
type="json",
auth="public",
website=True,
methods=["POST"],
)
def get_address(self, **kwargs):
"""
Function retrieves a Monero subaddress that will be used on the client side
Client side will display a qr code
Client side will pass subaddress via field "wallet_address" when
pos.order.create_from_ui is called
:param kwargs: payment_method_id
:return: wallet_address
"""

payment_method = (
request.env["pos.payment.method"]
.sudo()
.browse(int(kwargs.get("payment_method_id")))
)

if payment_method is not None:
try:
wallet: Wallet = payment_method.get_wallet()
except MoneroPaymentMethodRPCUnauthorized:
_logger.error(
"USER IMPACT: Monero POS Payment Method "
"can't authenticate with RPC "
"due to user name or password"
)
raise ValidationError(
"Current technical issues "
"prevent Monero from being accepted, "
"choose another payment method"
)
except MoneroPaymentMethodRPCSSLError:
_logger.error(
"USER IMPACT: Monero POS Payment Method "
"experienced an SSL Error with RPC"
)
raise ValidationError(
"Current technical issues "
"prevent Monero from being accepted, "
"choose another payment method"
)
except Exception as e:
_logger.error(
f"USER IMPACT: Monero POS Payment Method "
f"experienced an Error with RPC: {e.__class__.__name__}"
)
raise ValidationError(
"Current technical issues "
"prevent Monero from being accepted, "
"choose another payment method"
)

res = {
"wallet_address": wallet.new_address()[0],
}
else:
_logger.error(
"USER IMPACT: Monero POS Payment Method"
"experienced an Error with payment method: Not Found"
)
raise ValidationError(
"Current technical issues "
"prevent Monero from being accepted, "
"choose another payment method"
)

return res
17 changes: 17 additions & 0 deletions monero-rpc-odoo-pos/data/currency.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<!--XMR Currency Record-->
<record id="currency_xmr" model="res.currency">
<field name="name">XMR</field>
<field name="currency_unit_label">Monero</field>
<field name="display_name">Monero</field>
<field name="symbol">ɱ</field>
<field name="position">after</field>
<field name="active">True</field>
<!-- Monero has 12 decimal places, but Odoo only allows up to 6 -->
<field name="decimal_places">6</field>
<field name="rounding">0.000001</field>
</record>
</data>
</odoo>
18 changes: 18 additions & 0 deletions monero-rpc-odoo-pos/data/monero_xmr_payment_method.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="pos_payment_method_monero_rpc" model="pos.payment.method">
<field name="name">Monero RPC</field>
<field name="use_payment_terminal">monero-rpc</field>
<field name="active">True</field>
<field name="is_cryptocurrency">True</field>
<field name="type">xmr</field>
<field name="num_confirmation_required">0</field>
<field name="rpc_protocol">http</field>
<field name="monero_rpc_config_host">127.0.0.1</field>
<field name="monero_rpc_config_port">18082</field>
<field name="monero_rpc_config_user">user</field>
<field name="monero_rpc_config_password">password</field>
</record>
</data>
</odoo>
26 changes: 26 additions & 0 deletions monero-rpc-odoo-pos/data/queue.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="channel_monero_pos_zeroconf_processing" model="queue.job.channel">
<field name="name">monero_pos_zeroconf_processing</field>
<field name="parent_id" ref="queue_job.channel_root"/>
</record>
<record id="job_function_pos_payment_monero_zeroconf"
model="queue.job.function">
<field name="model_id" ref="point_of_sale.model_pos_payment"></field>
<field name="method">process_transaction</field>
<field name="channel_id" ref="channel_monero_pos_zeroconf_processing"/>
<field name="retry_pattern" eval="{1: 15,16: 60 * 1,30: 60 * 3}"/>
</record>
<record id="channel_monero_pos_secure_processing" model="queue.job.channel">
<field name="name">monero_pos_secure_processing</field>
<field name="parent_id" ref="queue_job.channel_root"/>
</record>
<record id="job_function_pos_payment_monero_secure" model="queue.job.function">
<field name="model_id" ref="point_of_sale.model_pos_payment"></field>
<field name="method">process_transaction</field>
<field name="channel_id" ref="channel_monero_pos_secure_processing"/>
<field name="retry_pattern" eval="{1: 60 * 2, 20: 60 * 4}"/>
</record>
</data>
</odoo>
File renamed without changes.
5 changes: 5 additions & 0 deletions monero-rpc-odoo-pos/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from . import pos_order, pos_payment, pos_payment_method, exceptions

# TODO automate prices list for currencies,
# the lists would be updated at a chosen interval with the correct conversion
# https://taiga.getmonero.org/project/t-900-monero-x-odoo-integrations/us/23
23 changes: 23 additions & 0 deletions monero-rpc-odoo-pos/models/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from monero.backends.jsonrpc import Unauthorized
from requests.exceptions import SSLError
from odoo.addons.queue_job.exception import RetryableJobError


class MoneroPaymentMethodRPCUnauthorized(Unauthorized):
pass


class MoneroPaymentMethodRPCSSLError(SSLError):
pass


class NoTXFound(RetryableJobError):
pass


class NumConfirmationsNotMet(RetryableJobError):
pass


class MoneroAddressReuse(Exception):
pass
9 changes: 9 additions & 0 deletions monero-rpc-odoo-pos/models/pos_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import logging

from odoo import models

_logger = logging.getLogger(__name__)


class MoneroPosOrder(models.Model):
_inherit = "pos.order"
Loading