9 Commits
Author SHA1 Message Date
ndeet 1421168374 Bumping version. 2024-07-31 14:22:32 +02:00
ndeet 600a054314 Make sure email is passed, also if used in PoS context.
(cherry picked from commit 6042284704)
2024-07-31 14:20:25 +02:00
ndeet bc934a0745 Updating teaser image. 2024-07-17 16:53:38 +02:00
ndeet c5cd74e03f Minor clarification. 2024-07-09 11:13:11 +02:00
ndeet 9e2475f415 Update docs to latest changes. 2024-07-09 10:26:02 +02:00
ndeet 488aea8771 Remove customizable return url and redirect the user to order confirmation / payment status page as it would be expected.
(cherry picked from commit 6a22f82a73)
2024-07-08 16:40:27 +02:00
ndeet 0f31982616 Fix IPN processing to cover additional invoice states.
(cherry picked from commit 17cb4f7814)
2024-07-08 11:13:03 +02:00
ndeet c32776ba60 Change version to match 17.0 branch scheme. 2024-07-08 09:22:04 +02:00
ndeet 43636e52e3 Fix typo. 2024-07-08 09:19:18 +02:00
8 changed files with 27 additions and 17 deletions
+5 -6
View File
@@ -1,12 +1,12 @@
# payment_btcpay # BTCPay Server payment gateway for Odoo 16
# BTCPay Server payment gateway for Odoo 16.0
## This is the module to connect Odoo 16.0 and BTCPay ## This is the module to connect Odoo 16 and BTCPay Server
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.
![BTCPay Server Website](../payment_btcpay/static/description/BTCPayServer_org.png) ![BTCPay Server Banner](../payment_btcpay/static/description/BTCPay-Odoo-16-featured.png)
## 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)
* Make sure you are on branch `16.0` or downloaded a release tagged with version v16.x
* 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"
+1 -1
View File
@@ -25,7 +25,7 @@
'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': '16.0.1.1',
'license': 'GPL-3', 'license': 'GPL-3',
'application': False, 'application': False,
'installable': True, 'installable': True,
+18 -5
View File
@@ -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,24 +50,26 @@ 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') or 'noemailavailable@example.com',
"name": data.get('name'), "name": data.get('name'),
"address1": data.get('street'), "address1": data.get('street'),
"locality": data.get('city'), "locality": data.get('city'),
"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')
@@ -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.')
+3 -3
View File
@@ -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.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 109 KiB

@@ -9,7 +9,6 @@
<group name="provider_credentials" position='inside'> <group name="provider_credentials" position='inside'>
<group attrs="{'invisible': [('code', '!=', 'btcpay')]}"> <group attrs="{'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 attrs="{'invisible': [('code', '!=', 'btcpay')]}">