Skip to content
Open
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
433 changes: 433 additions & 0 deletions payment_taler/README.md

Large diffs are not rendered by default.

426 changes: 426 additions & 0 deletions payment_taler/README_FR.md

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions payment_taler/REUSE.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# SPDX-FileCopyrightText: 2025 Mael Panouillot <panouillot.mael@gmail.com>
#
# SPDX-License-Identifier: LGPL-3.0-or-later

version = 1
SPDX-PackageName = "TOPS: Taler-Odoo Payment System"
SPDX-PackageSupplier = "Mael Panouillot"
SPDX-PackageDownloadLocation = "https://codeberg.org/Nemael/tops"

[[annotations]]
path = [ "Devlog/*.png", "README_Pictures/*.png", ".gitignore", "security/*.csv" ]
precedence = "aggregate"
SPDX-FileCopyrightText = "2025 Mael Panouillot"
SPDX-License-Identifier = "CC0-1.0"

[[annotations]]
path = [ "static/description/*" ]
precedence = "aggregate"
SPDX-FileCopyrightText = "2025 Mael Panouillot"
SPDX-License-Identifier = "CC-BY-SA-4.0"
15 changes: 15 additions & 0 deletions payment_taler/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# SPDX-FileCopyrightText: 2025 Mael Panouillot <panouillot.mael@gmail.com>
#
# SPDX-License-Identifier: LGPL-3.0-or-later

from odoo.addons.payment import setup_provider, reset_payment_provider

from . import models
from . import controllers

def post_init_hook(env):
setup_provider(env, 'taler')


def uninstall_hook(env):
reset_payment_provider(env, 'taler')
28 changes: 28 additions & 0 deletions payment_taler/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# SPDX-FileCopyrightText: 2025 Mael Panouillot <panouillot.mael@gmail.com>
#
# SPDX-License-Identifier: LGPL-3.0-or-later

{
'name': 'Taler-Odoo Payment System',
'version': '18.0.1.0',
'summary': 'Integration of the Taler payment system in Odoo.',
'author': 'Nemael',
'category': 'Accounting/Payment Providers',
'website': 'https://codeberg.org/Nemael/tops',
'images': ['images/thumbnail.png'],
'depends': ['payment', 'website', 'website_sale', 'account', 'point_of_sale'],
'data': [
'views/taler_payment_template.xml',
'views/taler_provider_view.xml',
'views/taler_invoice_view.xml',
'data/taler_payment_method_data.xml',
'data/taler_payment_provider_data.xml',
'data/email_refund_template_data.xml',
'security/ir.model.access.csv' #The ir security file is not actually used for now, but it will stay included in the files.
],
'post_init_hook': 'post_init_hook',
'uninstall_hook': 'uninstall_hook',
'installable': True,
'application': True,
'license': 'LGPL-3' #Complete license is "LGPL-3.0-or-later", see on top of any files in the module.
}
45 changes: 45 additions & 0 deletions payment_taler/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# SPDX-FileCopyrightText: 2025 Mael Panouillot <panouillot.mael@gmail.com>
#
# SPDX-License-Identifier: LGPL-3.0-or-later

SUPPORTED_LOCALES = [
'en_US', 'fr-FR'
]

SUPPORTED_CURRENCIES = [
#'AED',
#'AUD',
#'BGN',
#'BRL',
#'CAD',
'CHF',
# 'CZK',
# 'DKK',
# 'EUR',
# 'GBP',
#'HKD',
#'HRK',
#'HUF',
#'ILS',
#'ISK',
#'JPY',
#'MXN',
#'MYR',
#'NOK',
#'NZD',
#'PHP',
#'PLN',
#'RON',
#'RUB',
#'SEK',
#'SGD',
#'THB',
#'TWD',
#For testing purposes, USD can be used
# 'USD',
#'ZAR'
]

DEFAULT_PAYMENT_METHOD_CODES = {
'taler'
}
5 changes: 5 additions & 0 deletions payment_taler/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# SPDX-FileCopyrightText: 2025 Mael Panouillot <panouillot.mael@gmail.com>
#
# SPDX-License-Identifier: LGPL-3.0-or-later

from . import taler_controller
61 changes: 61 additions & 0 deletions payment_taler/controllers/taler_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# SPDX-FileCopyrightText: 2025 Mael Panouillot <panouillot.mael@gmail.com>
#
# SPDX-License-Identifier: LGPL-3.0-or-later

from odoo import http
from odoo.http import request
from odoo.addons.payment_taler.utils.utils import talog, tawarn, taerror

class TalerController(http.Controller):
_fulfillment_url = '/payment/taler/return'

# Route that online payments use
@http.route(_fulfillment_url + "/<string:taler_uuid>/<string:recvd_order_id>", type='http', auth='public', methods=['GET'])
def taler_return_from_checkout(self, **data):
talog("Returning after transaction completion. Taler_uuid: " + data['taler_uuid'] + ", Received_order_id: " + data['recvd_order_id'])
reference = data.get('recvd_order_id')
transaction = request.env['payment.transaction'].sudo().search([('reference', '=', reference)])
if not transaction:
taerror("No transaction found for reference: ", data.get('recvd_order_id'))
return
# Fetches the current taler merchant order status from the transaction
received_taler_order_id, taler_order_status = transaction._get_orderid_status()
if received_taler_order_id != transaction.taler_order_id:
taerror("OrderID do not match for reference: ", reference)
return
if data.get('taler_uuid') != transaction.taler_uuid:
taerror("UUID do not match for reference: ", reference)
return
data = {'reference': data.get('recvd_order_id'),
'merchantOrderId': transaction.taler_order_id,
'paymentStatus': taler_order_status
}
transaction._handle_notification_data('taler', data)

return request.redirect('/payment/status')

# Route that invoices use
@http.route(_fulfillment_url + "/<string:taler_uuid>/<string:prefix>/<int:year>/<string:number>/", type='http', auth='public')
def taler_return_from_invoice(self, **data):
reference = data.get('prefix') + "/" + str(data.get('year')) + "/" + data.get('number')
talog("Returning after invoice payment completion. taler_uuid: " + data['taler_uuid'] + ", reference: " + reference)
# Searches in all transactions, one that has the reference received
transaction = request.env['payment.transaction'].sudo().search([('reference', '=', reference)])
if not transaction:
taerror("No transaction found for reference: ", data.get('recvd_order_id'))
return
# Fetches the current taler merchant order status from the transaction
received_taler_order_id, taler_orderStatus = transaction._get_orderid_status()
if received_taler_order_id != transaction.taler_order_id:
taerror("OrderID do not match for reference: ", reference)
return
if data.get('taler_uuid') != transaction.taler_uuid:
taerror("UUID do not match for reference: ", reference)
return
data = {'reference': reference,
'merchantOrderId': transaction.taler_order_id,
'paymentStatus': taler_orderStatus
}
transaction._handle_notification_data('taler', data)

return request.redirect('/payment/status')
47 changes: 47 additions & 0 deletions payment_taler/data/email_refund_template_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 Mael Panouillot <panouillot.mael@gmail.com>

SPDX-License-Identifier: LGPL-3.0-or-later
-->

<odoo>
<!-- Mail template are declared in a NOUPDATE block so users can freely customize/delete them -->
<data noupdate="1">
<record id="email_refund" model="mail.template">
<field name="name">Odoo Taler refund email</field>
<field name="model_id" ref="payment.model_payment_transaction"/>
<field name="subject">Refund initiated for Taler payment, order {{ object.reference }}</field>
<field name="description">Sent to customers when a refund is triggered for Taler payments. It contains the QR code that the customer will have to scan to complete the refund.</field>
<field name="email_from">"{{ object.company_id.name }}"</field>
<field name="email_to">{{ object.partner_email }}</field>
<field name="body_html" type="html">
<div style="font-family: 'Arial'; font-size: 14px;">
<p>
Dear <t t-out="object.partner_id.name or ''"/>
</p>
<p>
A refund for your order <t t-out="object.reference or ''"/> has been initiated for the amount of <t t-out="abs(object.amount) if object.amount else ''"/><t t-out="object.currency_id.symbol or ''"/>
</p>
<p>
To receive the refund, please scan the QR code below with your Taler wallet
</p>
<div style="text-align: center;">
<img t-att-src="'data:image/png;base64,%s' % object.taler_refund_qr" style="max-height:200px; max-width:200px" alt="Refund QR Code"/>
</div>
<p>
If you cannot use the QR code, please use the following URI:<br/>
<t t-out="object.taler_refund_uri or ''"/>
</p>
<p>
For any questions or requests, please contact us at <t t-out="object.company_id.email or ''"/>
</p>
<p>
Thank you,<br/>
<t t-out="object.company_id.name or ''"/>
</p>
</div>
</field>
</record>
</data>
</odoo>
24 changes: 24 additions & 0 deletions payment_taler/data/taler_payment_method_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 Mael Panouillot <panouillot.mael@gmail.com>

SPDX-License-Identifier: LGPL-3.0-or-later
-->

<odoo>
<record id="payment_method_taler" model="payment.method">
<field name="name">Taler</field>
<field name="code">taler</field>
<field name="sequence">1</field>
<field name="active">True</field>
<field name="image" type="base64" file="payment_taler/static/description/icon.png"/>
<!--Edit this support_refund field to accurately reflect current refund functionality. Possible values: none, partial, full_only-->
<field name="support_refund">full_only</field>
</record>

<record id="account_payment_method_taler_in" model="account.payment.method">
<field name="name">Taler</field>
<field name="code">taler</field>
<field name="payment_type">inbound</field>
</record>
</odoo>
23 changes: 23 additions & 0 deletions payment_taler/data/taler_payment_provider_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 Mael Panouillot <panouillot.mael@gmail.com>

SPDX-License-Identifier: LGPL-3.0-or-later
-->

<odoo>
<record id="payment_provider_taler" model="payment.provider">
<field name="name">Taler</field>
<field name="code">taler</field>
<field name="module_id" ref="base.module_payment_taler"/>
<field name="redirect_form_view_id" ref="redirect_form"/>
<field name="image_128"
type="base64"
file="payment_taler/static/description/icon.png"
/>
<field name="payment_method_ids" eval="[Command.set([
ref('payment_taler.payment_method_taler'),
])]" />
</record>
</odoo>

12 changes: 12 additions & 0 deletions payment_taler/i18n/Glossary.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
English, français
merchant, vendeur
seller, commerçant
fulfillment message, message de confirmation
order ID, numéro de commande
wallet, porte-monnaie (virtuel)
order, commande
provider, fournisseur
template, gabarit
token, jeton
found, introuvable
administrator, administrateur boutique
Loading
Loading