Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0742b68e48 | ||
|
|
0aa893767d | ||
|
|
6a22f82a73 | ||
|
|
17cb4f7814 | ||
|
|
c469a3b4c1 | ||
|
|
cfbee77a5b |
@@ -1,12 +1,12 @@
|
|||||||
# payment_btcpay
|
# payment_btcpay
|
||||||
# BTCPay Server payment gateway for Odoo 16.0
|
# BTCPay Server payment gateway for Odoo 17.0
|
||||||
|
|
||||||
## This is the module to connect Odoo 16.0 and BTCPay
|
## This is the module to connect Odoo 17.0 and BTCPay
|
||||||
This module allows you to accept bitcoin (and other cryptocurrency) payments in your Odoo e-commerce store.
|
This module allows you to accept bitcoin (and other cryptocurrency) payments in your Odoo e-commerce store.
|
||||||

|

|
||||||
|
|
||||||
## Install the module
|
## Install the module
|
||||||
* Clone our [repository](https://github.com/btcpayserver/odoo) or download the .zip from the [releases page](https://github.com/btcpayserver/odoo/releases
|
* Clone our [repository](https://github.com/btcpayserver/odoo) or download the .zip from the [releases page](https://github.com/btcpayserver/odoo/releases)
|
||||||
* Place the `payment_btcpay` directory in your Odoo addons directory
|
* Place the `payment_btcpay` directory in your Odoo addons directory
|
||||||
* Install dependencies by running `pip install -r requirements.txt` (from inside the `payment_btcpay` directory)
|
* Install dependencies by running `pip install -r requirements.txt` (from inside the `payment_btcpay` directory)
|
||||||
* Restart Odoo
|
* Restart Odoo
|
||||||
@@ -21,7 +21,6 @@ This module allows you to accept bitcoin (and other cryptocurrency) payments in
|
|||||||
In the BTCPay settings form, tab "Credentials":
|
In the BTCPay settings form, tab "Credentials":
|
||||||
* Set field "State" to enabled
|
* Set field "State" to enabled
|
||||||
* Set field "BTCPay Server URL" as test or live URL including https://. Example URL: https://testnet.demo.btcpayserver.org
|
* Set field "BTCPay Server URL" as test or live URL including https://. Example URL: https://testnet.demo.btcpayserver.org
|
||||||
* Set field "Confirmation URL" where the customer will return after payment
|
|
||||||
* Get a pairing code from your BTCPay Server store: Settings -> Access Tokens
|
* Get a pairing code from your BTCPay Server store: Settings -> Access Tokens
|
||||||
* Click on "Create Token" button
|
* Click on "Create Token" button
|
||||||
* Label: enter e.g. "My odoo store"
|
* Label: enter e.g. "My odoo store"
|
||||||
@@ -34,9 +33,15 @@ In the BTCPay settings form, tab "Credentials":
|
|||||||
* Field Facade, keep default 'merchant'.
|
* Field Facade, keep default 'merchant'.
|
||||||
|
|
||||||
On the tab "Configuration":
|
On the tab "Configuration":
|
||||||
* Set field "Payment Journal" to "Bank", you can click the dropdown and click on the suggestion "Bank"
|
* Make sure field "Payment Journal" is set to "Bank", otherwise you can click the dropdown and click on the suggestion "Bank"
|
||||||
* Now you can **save** the settings
|
* Now you can **save** the settings
|
||||||
|
|
||||||
|
Check the payment method is enabled:
|
||||||
|
* Go to **Website** -> **Configuration** -> **Payment Methods**
|
||||||
|
* Make sure "Pay with Bitcoin / Lightning Network" is active
|
||||||
|
|
||||||
|
Congrats, all done. Do some testing to be sure all works.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## How does the payment page look?
|
## How does the payment page look?
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ from . import models
|
|||||||
from odoo.addons.payment import setup_provider, reset_payment_provider
|
from odoo.addons.payment import setup_provider, reset_payment_provider
|
||||||
|
|
||||||
|
|
||||||
def post_init_hook(cr, registry):
|
def post_init_hook(env):
|
||||||
setup_provider(cr, registry, 'btcpay')
|
setup_provider(env, 'btcpay')
|
||||||
|
|
||||||
|
|
||||||
def uninstall_hook(cr, registry):
|
def uninstall_hook(env):
|
||||||
reset_payment_provider(cr, registry, 'btcpay')
|
reset_payment_provider(env, 'btcpay')
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#******************************************************************************
|
#******************************************************************************
|
||||||
# PAYMENT BTCPAY FOR ODOO
|
# PAYMENT BTCPAY FOR ODOO
|
||||||
#
|
#
|
||||||
# Copyright (C) 2023 Susanna Fort <susannafm@gmail.com>
|
# Copyright (C) 2024 Susanna Fort <susannafm@gmail.com>, ndeet
|
||||||
#
|
#
|
||||||
#******************************************************************************
|
#******************************************************************************
|
||||||
#
|
#
|
||||||
@@ -21,11 +21,11 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
'name': 'Payment Provider: BTCPay',
|
'name': 'Payment Provider: BTCPay',
|
||||||
'summary': 'This module integrates BTCPAY - pay with Bitcoin - with Odoo v16.0',
|
'summary': 'This module integrates BTCPAY - pay with Bitcoin - with Odoo v17.0',
|
||||||
'author': 'Vandekul',
|
'author': 'Vandekul',
|
||||||
'website': 'https://github.com/btcpayserver/odoo',
|
'website': 'https://github.com/btcpayserver/odoo',
|
||||||
'category': 'Accounting/Payment Providers',
|
'category': 'Accounting/Payment Providers',
|
||||||
'version': '16.0.0',
|
'version': '17.0.1.0',
|
||||||
'license': 'GPL-3',
|
'license': 'GPL-3',
|
||||||
'application': False,
|
'application': False,
|
||||||
'installable': True,
|
'installable': True,
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ _logger = logging.getLogger(__name__)
|
|||||||
class BTCPayController(http.Controller):
|
class BTCPayController(http.Controller):
|
||||||
_checkout_url = '/btcpay/checkout'
|
_checkout_url = '/btcpay/checkout'
|
||||||
_notify_url = '/payment/btcpay/ipn'
|
_notify_url = '/payment/btcpay/ipn'
|
||||||
|
_return_url = '/payment/btcpay/return'
|
||||||
|
|
||||||
@http.route(_checkout_url, type='http', auth='public', csrf=False, website=True)
|
@http.route(_checkout_url, type='http', auth='public', csrf=False, website=True)
|
||||||
def checkout(self, **data):
|
def checkout(self, **data):
|
||||||
@@ -49,15 +50,17 @@ class BTCPayController(http.Controller):
|
|||||||
_logger.info("CHECKOUT: notification received from BTCPay with data:\n%s", pprint.pformat(data))
|
_logger.info("CHECKOUT: notification received from BTCPay with data:\n%s", pprint.pformat(data))
|
||||||
tx_sudo = request.env['payment.transaction'].sudo()._get_tx_from_notification_data('btcpay', data)
|
tx_sudo = request.env['payment.transaction'].sudo()._get_tx_from_notification_data('btcpay', data)
|
||||||
provider = tx_sudo.provider_id
|
provider = tx_sudo.provider_id
|
||||||
notificationURL = str(data.get('notify_url')).replace("http://", "https://")
|
notification_url = str(data.get('notify_url')).replace("http://", "https://")
|
||||||
|
base_url = request.env['ir.config_parameter'].sudo().get_param('web.base.url')
|
||||||
|
redirect_url = urls.url_join(base_url, self._return_url)
|
||||||
client = BTCPayClient(host=provider.btcpay_location, pem=provider.btcpay_privateKey, tokens={provider.btcpay_facade: provider.btcpay_token})
|
client = BTCPayClient(host=provider.btcpay_location, pem=provider.btcpay_privateKey, tokens={provider.btcpay_facade: provider.btcpay_token})
|
||||||
invoice = client.create_invoice(
|
invoice = client.create_invoice(
|
||||||
{"price": data.get('amount'),
|
{"price": data.get('amount'),
|
||||||
"currency": data.get('currency_id'),
|
"currency": data.get('currency_id'),
|
||||||
"orderId": data.get('reference'),
|
"orderId": data.get('reference'),
|
||||||
"token": provider.btcpay_token,
|
"token": provider.btcpay_token,
|
||||||
"redirectURL": provider.btcpay_confirmationURL,
|
"redirectURL": redirect_url,
|
||||||
"notificationURL": notificationURL,
|
"notificationURL": notification_url,
|
||||||
"extendedNotifications": True,
|
"extendedNotifications": True,
|
||||||
"buyer": {"email": data.get('email'),
|
"buyer": {"email": data.get('email'),
|
||||||
"name": data.get('name'),
|
"name": data.get('name'),
|
||||||
@@ -66,7 +69,7 @@ class BTCPayController(http.Controller):
|
|||||||
"postalCode": data.get('zip'),
|
"postalCode": data.get('zip'),
|
||||||
"country": data.get('country'),
|
"country": data.get('country'),
|
||||||
"notify": False}})
|
"notify": False}})
|
||||||
_logger.info('Invoice %s \n NOTIFY URL: %s', invoice, notificationURL)
|
_logger.info('Invoice %s \n NOTIFY URL: %s', invoice, notification_url)
|
||||||
return werkzeug.utils.redirect(invoice['url'])
|
return werkzeug.utils.redirect(invoice['url'])
|
||||||
|
|
||||||
@http.route(_notify_url, type='json', auth='public', csrf=False)
|
@http.route(_notify_url, type='json', auth='public', csrf=False)
|
||||||
@@ -97,3 +100,13 @@ class BTCPayController(http.Controller):
|
|||||||
except ValidationError: # Acknowledge the notification to avoid getting spammed
|
except ValidationError: # Acknowledge the notification to avoid getting spammed
|
||||||
_logger.exception("Unable to handle the notification data; skipping to acknowledge")
|
_logger.exception("Unable to handle the notification data; skipping to acknowledge")
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
@http.route(_return_url, type='http', auth="public", methods=['GET'], crsf=False, save_session=False)
|
||||||
|
def btcpay_return_from_redirect(self, **data):
|
||||||
|
""" BTCPay return
|
||||||
|
|
||||||
|
We could process and check the invoice status here but there is no need to as the status get's updated via
|
||||||
|
IPN anyway, so just show the user the order confirmation / payment status page.
|
||||||
|
"""
|
||||||
|
_logger.info("BTCPay: user returned to shop after payment")
|
||||||
|
return request.redirect('/payment/status')
|
||||||
@@ -1,13 +1,26 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<odoo noupdate="1">
|
<odoo noupdate="1">
|
||||||
|
|
||||||
|
<record id="payment_method_btcpay" model="payment.method">
|
||||||
|
<field name="name">Pay with Bitcoin / Lightning Network</field>
|
||||||
|
<field name="code">btcpay</field>
|
||||||
|
<field name="active">True</field>
|
||||||
|
<field name="image" type="base64" file="payment_btcpay/static/description/icon.png"/>
|
||||||
|
<field name="support_tokenization">False</field>
|
||||||
|
<field name="support_express_checkout">False</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
<record id="payment_provider_btcpay" model="payment.provider">
|
<record id="payment_provider_btcpay" model="payment.provider">
|
||||||
<field name="name">BTCPay payments</field>
|
<field name="name">BTCPay payments</field>
|
||||||
<field name="display_as">Pay with Bitcoin / Lightning Network</field>
|
|
||||||
<field name="code">btcpay</field>
|
<field name="code">btcpay</field>
|
||||||
<field name="image_128" type="base64" file="payment_btcpay/static/description/icon.png"/>
|
<field name="image_128" type="base64" file="payment_btcpay/static/description/icon.png"/>
|
||||||
<field name="module_id" ref="base.module_payment_btcpay"/>
|
|
||||||
<field name="redirect_form_view_id" ref="redirect_form"/>
|
<field name="redirect_form_view_id" ref="redirect_form"/>
|
||||||
|
<field name="module_id" ref="base.module_payment_btcpay"/>
|
||||||
|
<field name="payment_method_ids"
|
||||||
|
eval="[Command.set([
|
||||||
|
ref('payment_btcpay.payment_method_btcpay'),
|
||||||
|
])]"
|
||||||
|
/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
</odoo>
|
</odoo>
|
||||||
@@ -14,7 +14,6 @@ class PaymentProvider(models.Model):
|
|||||||
selection_add=[('btcpay', "BTCPay")], ondelete={'btcpay': 'set default'})
|
selection_add=[('btcpay', "BTCPay")], ondelete={'btcpay': 'set default'})
|
||||||
|
|
||||||
btcpay_location = fields.Char(string='BTCPay Server URL', size=64, help='URL where your BTCPay Server instance is reachable (where you log into your BTCPay Server).', default='https://testnet.demo.btcpayserver.org')
|
btcpay_location = fields.Char(string='BTCPay Server URL', size=64, help='URL where your BTCPay Server instance is reachable (where you log into your BTCPay Server).', default='https://testnet.demo.btcpayserver.org')
|
||||||
btcpay_confirmationURL = fields.Char(string='Confirmation URL', help='Confirmation URL to return after BTCPay payment', default='http://yourdomain/shop/confirmation')
|
|
||||||
btcpay_pairingCode = fields.Char(string='Pairing Code', help='Create paring Code in your BTCPay server and put here')
|
btcpay_pairingCode = fields.Char(string='Pairing Code', help='Create paring Code in your BTCPay server and put here')
|
||||||
|
|
||||||
btcpay_token = fields.Char(string='Token', help='Access Token to BTCPay. Leave empty, will be autogenerated during pairing.')
|
btcpay_token = fields.Char(string='Token', help='Access Token to BTCPay. Leave empty, will be autogenerated during pairing.')
|
||||||
|
|||||||
@@ -115,15 +115,15 @@ class PaymentTransaction(models.Model):
|
|||||||
self.btcpay_txid = notification_data.get('txid')
|
self.btcpay_txid = notification_data.get('txid')
|
||||||
self.btcpay_status = notification_data.get('status')
|
self.btcpay_status = notification_data.get('status')
|
||||||
|
|
||||||
if self.btcpay_status in ['paid']:
|
if self.btcpay_status in ['paid','processing']:
|
||||||
self._set_pending(state_message=notification_data.get('pending_reason'))
|
self._set_pending(state_message=notification_data.get('pending_reason'))
|
||||||
elif self.btcpay_status in ['confirmed']:
|
elif self.btcpay_status in ['confirmed', 'complete']:
|
||||||
self._set_done()
|
self._set_done()
|
||||||
confirmed_orders = self._check_amount_and_confirm_order()
|
confirmed_orders = self._check_amount_and_confirm_order()
|
||||||
confirmed_orders._send_order_confirmation_mail()
|
confirmed_orders._send_order_confirmation_mail()
|
||||||
elif self.btcpay_status in ['new']:
|
elif self.btcpay_status in ['new']:
|
||||||
self.btcpay_invoiceId = notification_data.get('invoiceID')
|
self.btcpay_invoiceId = notification_data.get('invoiceID')
|
||||||
elif self.btcpay_status in ['cancel']:
|
elif self.btcpay_status in ['cancel','cancelled']:
|
||||||
self._set_canceled()
|
self._set_canceled()
|
||||||
elif self.btcpay_status in ['invalid']:
|
elif self.btcpay_status in ['invalid']:
|
||||||
_logger.info(
|
_logger.info(
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 109 KiB |
@@ -4,7 +4,7 @@
|
|||||||
<section class="oe_container">
|
<section class="oe_container">
|
||||||
<div class="oe_row oe_spaced">
|
<div class="oe_row oe_spaced">
|
||||||
<h2 class="oe_slogan">BTCPay Gateway</h2>
|
<h2 class="oe_slogan">BTCPay Gateway</h2>
|
||||||
<h3 class="oe_slogan">This is the module to connect Odoo 16.0 and Btcpay</h3>
|
<h3 class="oe_slogan">This is the module to connect Odoo 17.0 and BTCPay</h3>
|
||||||
<div class="oe_span6">
|
<div class="oe_span6">
|
||||||
<div class="oe_bg_img">
|
<div class="oe_bg_img">
|
||||||
<img src="BTCPayServer_org.png" class="oe_picture oe_screenshot">
|
<img src="BTCPayServer_org.png" class="oe_picture oe_screenshot">
|
||||||
|
|||||||
@@ -7,12 +7,11 @@
|
|||||||
<field name="inherit_id" ref="payment.payment_provider_form"/>
|
<field name="inherit_id" ref="payment.payment_provider_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<group name="provider_credentials" position='inside'>
|
<group name="provider_credentials" position='inside'>
|
||||||
<group attrs="{'invisible': [('code', '!=', 'btcpay')]}">
|
<group invisible="code != 'btcpay'">
|
||||||
<field name="btcpay_location"/>
|
<field name="btcpay_location"/>
|
||||||
<field name="btcpay_confirmationURL"/>
|
|
||||||
<field name="btcpay_pairingCode"/>
|
<field name="btcpay_pairingCode"/>
|
||||||
</group>
|
</group>
|
||||||
<group attrs="{'invisible': [('code', '!=', 'btcpay')]}">
|
<group invisible="code != 'btcpay'">
|
||||||
<field name="btcpay_token"/>
|
<field name="btcpay_token"/>
|
||||||
<field name="btcpay_privateKey"/>
|
<field name="btcpay_privateKey"/>
|
||||||
<field name="btcpay_facade"/>
|
<field name="btcpay_facade"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user