Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] l10n_fr_payment_payfip #544

Draft
wants to merge 2 commits into
base: 16.0
Choose a base branch
from
Draft
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
206 changes: 206 additions & 0 deletions l10n_fr_payment_payfip/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@

# Created by https://www.gitignore.io/api/python,pycharm
# Edit at https://www.gitignore.io/?templates=python,pycharm

### PyCharm ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf

# Generated files
.idea/**/contentModel.xml

# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# Gradle
.idea/**/gradle.xml
.idea/**/libraries

# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr

# CMake
cmake-build-*/

# Mongo Explorer plugin
.idea/**/mongoSettings.xml

# File-based project format
*.iws

# IntelliJ
out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Cursive Clojure plugin
.idea/replstate.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

# Editor-based Rest Client
.idea/httpRequests

# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser

### PyCharm Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721

# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr

# Sonarlint plugin
.idea/**/sonarlint/

# SonarQube Plugin
.idea/**/sonarIssues.xml

# Markdown Navigator plugin
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator/

### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# pyenv
.python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# Mr Developer
.mr.developer.cfg
.project
.pydevproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# End of https://www.gitignore.io/api/python,pycharm

# SPECIFIC PYCHARM #

.idea/

####################


6 changes: 6 additions & 0 deletions l10n_fr_payment_payfip/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Changelog
All notable changes to this project will be documented in this file.

## [16.0.1] 2024-03-06
### Initialisation of the module.

34 changes: 34 additions & 0 deletions l10n_fr_payment_payfip/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
l10n_fr_payment_payfip
=========
This module add an option to use payfip

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

Bugs are tracked on `GitHub Issues <https://github.com/Moka-Tourisme/l10n-france/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed feedback.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

## Authors

* Moka Tourisme

## Contributors

* Horvat Damien : <https://github.com/PlantBasedStudio>
* Duciel Romain : <https://github.com/Rom10811>


## Maintainers

This module is maintained by Moka Tourisme.


This module is a addon for the `Odoo/addons/payment <https://github.com/odoo/odoo/tree/16.0/addons/payment>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
12 changes: 12 additions & 0 deletions l10n_fr_payment_payfip/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from . import models
from . import controllers

from odoo.addons.payment import setup_provider, reset_payment_provider


def post_init_hook(cr, registry):
setup_provider(cr, registry, 'payfip')


def uninstall_hook(cr, registry):
reset_payment_provider(cr, registry, 'payfip')
28 changes: 28 additions & 0 deletions l10n_fr_payment_payfip/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "Intermédiaire de paiement PayFIP",
"version": "16.0.1.0.1",
"summary": """Intermédiaire de paiement : Implémentation de PayFIP""",
"author": "MokaTourisme," "Odoo Community Association (OCA)",
"website": "https://github.com/OCA/l10n-france",
"license": "AGPL-3",
"category": "Accounting",
"external_dependencies": {
"python": [
"openupgradelib",
]
},
"depends": ["payment", "l10n_fr"],
"qweb": [],
"init_xml": [],
"update_xml": [],
"data": [
# Views must be before data to avoid loading issues
"views/payment_payfip_templates.xml",
"views/payment_views.xml",
"data/payment_provider_data.xml",
],
"demo": [],
"application": False,
"auto_install": False,
"installable": True,
}
1 change: 1 addition & 0 deletions l10n_fr_payment_payfip/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import main
66 changes: 66 additions & 0 deletions l10n_fr_payment_payfip/controllers/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import logging
import pprint
import werkzeug

from odoo import http
from odoo.http import request

from odoo.exceptions import ValidationError


_logger = logging.getLogger(__name__)


class PayFIPController(http.Controller):
_payment_url = '/payment/payfip/pay'
_return_url = '/payment/payfip/dpn'
_notification_url = '/payment/payfip/ipn'

@http.route(_payment_url, type='http', auth='public', methods=['GET', 'POST'], csrf=False, save_session=False)
def payfip_pay(self, **post):
reference = post.pop('objet', False)
amount = float(post.pop('montant', 0))
return_url = post.pop('urlredirect', '/payment/status')
tx = request.env['payment.transaction'].sudo().search([('reference', '=', reference), ('amount', '=', amount)])
if tx and tx.provider_id.code == 'payfip':
# PayFIP doesn't accept two attempts with the same operation identifier, we check if transaction has
# already sent and recreate it in this case.
if tx.payfip_sent_to_webservice:
tx = tx.copy({
'reference': request.env['payment.transaction'].get_next_reference(tx.reference),
})

tx.write({
'payfip_return_url': return_url,
'payfip_sent_to_webservice': True,
})
return werkzeug.utils.redirect('{url}?idop={idop}'.format(
url="https://www.payfip.gouv.fr/tpa/paiementws.web",
idop=tx.payfip_operation_identifier,
))
else:
return werkzeug.utils.redirect('/')

@http.route(_notification_url, type='http', auth='public', methods=['POST'], csrf=False, save_session=False)
def payfip_ipn(self, **post):
"""Process PayFIP IPN."""
_logger.debug('Beginning PayFIP IPN form_feedback with post data %s', pprint.pformat(post))
if not post or not post.get('idop'):
raise ValidationError("No idOp found for transaction on PayFIP")

idop = post.get('idop', False)
tx_sudo = request.env['payment.transaction'].sudo()._get_tx_from_notification_data('payfip', idop)
tx_sudo._handle_notification_data('payfip', idop)

return ''

@http.route(_return_url, type="http", auth="public", methods=["POST", "GET"], csrf=False, save_session=False)
def payfip_dpn(self, **post):
"""Process PayFIP DPN."""
_logger.debug('Beginning PayFIP DPN form_feedback with post data %s', pprint.pformat(post))

idop = post.get('idop', False)
tx_sudo = request.env['payment.transaction'].sudo()._get_tx_from_notification_data('payfip', idop)
tx_sudo._handle_notification_data('payfip', idop)

return request.redirect('/payment/status')
31 changes: 31 additions & 0 deletions l10n_fr_payment_payfip/data/payment_provider.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="payment.payment_provider_payfip" model="payment.provider">
<field name="name">PayFIP</field>
<field name="image_128" type="base64" file="l10n_fr_payment_payfip/static/src/img/payfip_icon.png"/>
<field name="provider">payfip</field>
<field name="company_id" ref="base.main_company"/>
<field name="redirect_form_view_id" ref="redirect_form"/>
<field name="pre_msg">
<![CDATA[<p>You will be redirected to the PayFIP website after clicking on the payment button.</p>]]>
</field>
<field name="payfip_customer_number">dummy</field>
<field name="description" type="html">
<p>PayFIP est un système de paiement en ligne français proposé pa la Direction générale des Finances
Publiques. Son but est de faciliter le paiement des services publics locaux.
</p>
<ul class="list-inline">
<li><i class="fa fa-check"/>eCommerce
</li>
</ul>
</field>
</record>
</data>

<record id="payment_method_payfip" model="account.payment.method">
<field name="name">PayFip</field>
<field name="code">payfip</field>
<field name="payment_type">inbound</field>
</record>
</odoo>
Loading