Skip to content

Commit

Permalink
Release new version v14.0.0.8
Browse files Browse the repository at this point in the history
- Option to Single-Click payments for credit cards.
- Options to enable/disable inline credit cards components.
  • Loading branch information
odoo-mvds committed Jan 25, 2022
1 parent 86f87f4 commit da48073
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 23 deletions.
2 changes: 1 addition & 1 deletion payment_mollie_official/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

{
'name': 'Mollie Payments',
'version': '14.0.0.7',
'version': '14.0.0.8',
'category': 'eCommerce',
'license': 'LGPL-3',
'author': 'Mollie',
Expand Down
1 change: 1 addition & 0 deletions payment_mollie_official/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
from . import res_partner
from . import account_move
from . import product
from . import res_user
from . import voucher_lines
from . import account_payment_register
11 changes: 11 additions & 0 deletions payment_mollie_official/models/mollie_method.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,14 @@ class MolliePaymentMethod(models.Model):
fees_int_var = fields.Float('Variable international fees (in percents)')

mollie_voucher_ids = fields.One2many('mollie.voucher.line', 'method_id', string='Mollie Voucher Config')

def _mollie_show_creditcard_option(self):
if self.method_id_code != 'creditcard':
return False
acquirer_sudo = self.sudo().parent_id
self.env.user._mollie_validate_customer_id(acquirer_sudo)
if acquirer_sudo.mollie_profile_id and acquirer_sudo.sudo().mollie_use_components:
return True
if acquirer_sudo.sudo().mollie_show_save_card and not self.env.user.has_group('base.group_public'):
return True
return False
38 changes: 33 additions & 5 deletions payment_mollie_official/models/payment_acquirer.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class PaymentAcquirerMollie(models.Model):
mollie_voucher_ids = fields.One2many('mollie.voucher.line', 'acquirer_id', string='Mollie Voucher Config')
mollie_voucher_enabled = fields.Boolean(compute="_compute_mollie_voucher_enabled")

mollie_use_components = fields.Boolean(string='Mollie Components')
mollie_show_save_card = fields.Boolean(string='Single-Click payments')

def _get_feature_support(self):
res = super(PaymentAcquirerMollie, self)._get_feature_support()
res['fees'].append('mollie')
Expand Down Expand Up @@ -280,7 +283,7 @@ def _mollie_create_order(self, transaction):

order_type = 'Sale Order' if order_source._name == 'sale.order' else 'Invoice'

payment_data = {
order_data = {
'method': transaction.mollie_payment_method,
'amount': {
'currency': transaction.currency_id.name,
Expand Down Expand Up @@ -308,17 +311,25 @@ def _mollie_create_order(self, transaction):
# Mollie throws error with local URL
webhook_url = self._mollie_webhook_url(transaction.id)
if "://localhost" not in webhook_url and "://192.168." not in webhook_url:
payment_data['webhookUrl'] = webhook_url
order_data['webhookUrl'] = webhook_url

payment_data = {}
# Add if transection has cardToken
if transaction.mollie_payment_token:
payment_data['payment'] = {'cardToken': transaction.mollie_payment_token}
payment_data['cardToken'] = transaction.mollie_payment_token

# Add if transection has issuer
if transaction.mollie_payment_issuer:
payment_data['payment'] = {'issuer': transaction.mollie_payment_issuer}
payment_data['issuer'] = transaction.mollie_payment_issuer

# Add if transaction has save card option
mollie_customer_id = transaction._get_transaction_customer_id()
if mollie_customer_id:
payment_data['customerId'] = mollie_customer_id

result = self._api_mollie_create_order(payment_data)
if payment_data:
order_data['payment'] = payment_data
result = self._api_mollie_create_order(order_data)

# We are setting acquirer reference as we are receiving it before 3DS payment
# So we can identify transaction with mollie respose
Expand Down Expand Up @@ -358,6 +369,11 @@ def _mollie_create_payment(self, transaction):
if transaction.mollie_payment_issuer:
payment_data['issuer'] = transaction.mollie_payment_issuer

# Add if transaction has save card option
mollie_customer_id = transaction._get_transaction_customer_id()
if mollie_customer_id:
payment_data['customerId'] = mollie_customer_id

result = self._api_mollie_create_payment(payment_data)

# We are setting acquirer reference as we are receiving it before 3DS payment
Expand Down Expand Up @@ -432,6 +448,18 @@ def _api_mollie_get_order(self, tx_id):
mollie_client = self._api_mollie_get_client()
return mollie_client.orders.get(tx_id, embed="payments")

def _api_mollie_create_customer_id(self):
mollie_client = self._api_mollie_get_client()
sudo_user = self.env.user.sudo()
customer_data = {'name': sudo_user.name, 'metadata': {'odoo_user_id': self.env.user.id}}
if sudo_user.email:
customer_data['email'] = sudo_user.email
return mollie_client.customers.create(customer_data)

def _api_get_customer_data(self, customer_id):
mollie_client = self._api_mollie_get_client()
return mollie_client.customers.get(customer_id)

def _api_mollie_get_active_payment_methods(self, api_type=None, extra_params={}):
result = {}

Expand Down
19 changes: 19 additions & 0 deletions payment_mollie_official/models/payment_transection.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class PaymentTransaction(models.Model):
mollie_payment_method = fields.Char()
mollie_payment_issuer = fields.Char()
mollie_reminder_payment_id = fields.Many2one('account.payment', string='Reminder Payment', readonly=True)
mollie_save_card = fields.Boolean()

def mollie_create(self, vals):
create_vals = {}
Expand All @@ -34,6 +35,9 @@ def mollie_create(self, vals):
if request and request.params.get('mollie_issuer'):
create_vals['mollie_payment_issuer'] = request.params.get('mollie_issuer')

if request and request.params.get('mollie_save_card'):
create_vals['mollie_save_card'] = request.params.get('mollie_save_card')

if vals.get('fees') and isinstance(vals['fees'], dict):
payment_method = create_vals.get('mollie_payment_method')
vals['fees'] = vals['fees'].get(payment_method, 0)
Expand Down Expand Up @@ -167,3 +171,18 @@ def mollie_manual_payment_validation(self):
self.form_feedback(data, "mollie")
if self.state == 'done' and not self.is_processed:
self._post_process_after_done()

def _get_transaction_customer_id(self):
""" This method return mollie customer id if needed in transection
It will create new customer id if needed.
"""
mollie_customer_id = False
if self.mollie_save_card and not self.env.user.has_group('base.group_public'): # for extra security
user_sudo = self.env.user.sudo()
mollie_customer_id = user_sudo.mollie_customer_id
if not mollie_customer_id:
customer_id_data = self.acquirer_id._api_mollie_create_customer_id()
if customer_id_data and customer_id_data.get('id'):
user_sudo.mollie_customer_id = customer_id_data.get('id')
mollie_customer_id = user_sudo.mollie_customer_id
return mollie_customer_id
18 changes: 18 additions & 0 deletions payment_mollie_official/models/res_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

# -*- coding: utf-8 -*-

from odoo import _, api, fields, models


class ResUsers(models.Model):
_inherit = 'res.users'

mollie_customer_id = fields.Char()

def _mollie_validate_customer_id(self, acquirer):
self.ensure_one()
customer_id = self.sudo().mollie_customer_id
if customer_id:
customer_data = acquirer._api_get_customer_data(customer_id)
if customer_data.get('status') == 410: # customer ID deleted
self.mollie_customer_id = False
11 changes: 11 additions & 0 deletions payment_mollie_official/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,17 @@ <h1 style="color: #000;font-weight: bold;/* font-size: 50px; */" class="mt-5 tex
<span style="width:73px;height: 10px;display:inline-block;border-radius: 4px;background-color: #0077ff;"> </span>
</div>

<div class="card mx-auto w-md-75">
<div class="card-header bg-200">
<h4 class="m-0">v14.0.0.8</h4>
</div>
<div class="card-body">
<div> <b class="text-success"> NEW </b> Option to <b> Single-Click payments </b> for credit cards. </div>
<div> <b class="text-success"> NEW </b> Options to enable/disable inline credit cards components. </div>
<div class="alert alert-warning"> After the update, if you face <i>500 internal server error</i>, then follow given link <b> https://github.com/mollie/mollie-odoo/wiki/Mollie-Payments-(extended)-Module#Manually-Upgrade-Module</b> </div>
</div>
</div>

<div class="card mx-auto w-md-75">
<div class="card-header bg-200">
<h4 class="m-0">v14.0.0.7</h4>
Expand Down
31 changes: 22 additions & 9 deletions payment_mollie_official/static/src/js/payment_form.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ var _t = core._t;
publicWidget.registry.PaymentForm.include({
events: _.extend({
'click .o_issuer': '_clickIssuer',
'change input[name="mollieCardType"]': '_onChangeCardType',
}, publicWidget.registry.PaymentForm.prototype.events),
/**
* @override
Expand Down Expand Up @@ -58,7 +59,7 @@ publicWidget.registry.PaymentForm.include({
*/
updateNewPaymentDisplayStatus: function () {
var self = this;
var $checkedRadio = this.$('input[type="radio"]:checked');
var $checkedRadio = this.$('.o_payment_acquirer_select input[type="radio"]:checked');
if ($checkedRadio.length !== 1) {
return;
}
Expand Down Expand Up @@ -97,12 +98,13 @@ publicWidget.registry.PaymentForm.include({
var button = ev.target;
}

var $checkedRadio = this.$('input[type="radio"]:checked');
var $checkedRadio = this.$('.o_payment_acquirer_select input[type="radio"]:checked');
if ($checkedRadio.length === 1 && $checkedRadio.data('provider') === 'mollie') {
// Right now pass and submit the from to get mollie component token.
this.disableButton(button);
var methodName = $checkedRadio.data('methodname');
if (methodName === 'creditcard') {
const useSavedCard = this.$('#mollieSavedCard').prop('checked');
if (methodName === 'creditcard' && this.$('#o_mollie_component').length && !useSavedCard) {
return this._getMollieToken(button)
.then(this._createMollieTransaction.bind(this, methodName, button));
} else {
Expand Down Expand Up @@ -159,24 +161,26 @@ publicWidget.registry.PaymentForm.include({
* @private
*/
_createMollieTransaction: function (paymentmethod, button, token) {
if (!token && paymentmethod === 'creditcard') {
return;
}
var self = this;
var issuer = false;
var checked_radio = this.$('input[type="radio"]:checked')[0];
var checked_radio = this.$('.o_payment_acquirer_select input[type="radio"]:checked')[0];
var acquirer_id = this.getAcquirerIdFromRadio(checked_radio);
var $tx_url = this.$el.find('input[name="prepare_tx_url"]');
if (paymentmethod === 'ideal') {
issuer = this.$('#o_payment_form_acq_ideal .o_issuer.active').data('methodname');
}

let useSavedCard = $('#mollieSavedCard').prop('checked');
if (paymentmethod === 'creditcard' && (this.$('#o_mollie_save_card').length || useSavedCard)) {
useSavedCard = this.$('#o_mollie_save_card input').prop("checked") || useSavedCard;
}

if ($tx_url.length === 1) {
return this._rpc({
route: $tx_url[0].value,
params: {
'acquirer_id': parseInt(acquirer_id),
'save_token': false,
'mollie_save_card': useSavedCard,
'access_token': this.options.accessToken,
'success_url': this.options.successUrl,
'error_url': this.options.errorUrl,
Expand Down Expand Up @@ -309,7 +313,16 @@ publicWidget.registry.PaymentForm.include({
var $container = $(ev.currentTarget).closest('.o_issuer_container');
$container.find('.o_issuer').removeClass('active');
$(ev.currentTarget).addClass('active');
}
},

/**
* @private
* @param {MouseEvent} ev
*/
_onChangeCardType: function (ev) {
this.$('#o_mollie_component').toggleClass('d-none', $(ev.currentTarget).val() !== 'component');
this.$('#o_mollie_save_card').toggleClass('d-none', $(ev.currentTarget).val() !== 'component');
},

});

Expand Down
22 changes: 20 additions & 2 deletions payment_mollie_official/views/payment_mollie_templates.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
</ul>
</div>
<t t-if="payment_method.method_id_code == 'creditcard'">
<div id="o_payment_form_acq_creditcard" t-attf-class="d-none card-footer">
<div id="o_payment_form_acq_creditcard" t-attf-class="d-none card-footer" t-if="payment_method._mollie_show_creditcard_option()">
<t t-call="payment_mollie_official.mollie_creditcard_component"/>
</div>
</t>
Expand All @@ -77,8 +77,20 @@
</template>

<template id="mollie_creditcard_component">
<t t-set="has_mollie_customer_id" t-value="request.env.user.sudo().mollie_customer_id"/>
<t t-set="mollie_components_enabled" t-value="acq.sudo().mollie_use_components"/>
<div>
<div id="o_mollie_component" t-att-data-profile_id="acq.sudo().mollie_profile_id" t-att-data-mode="acq.sudo().state">
<div t-if="mollie_components_enabled and has_mollie_customer_id" class="ml-2">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="mollieCardType" id="mollieSavedCard" value="saved_card" checked="checked"/>
<label class="form-check-label mt-0" for="mollieSavedCard">Use Saved Card </label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="mollieCardType" id="mollieInlineCard" value="component"/>
<label class="form-check-label mt-0" for="mollieInlineCard">Fill Card Details</label>
</div>
</div>
<div id="o_mollie_component" t-att-class="has_mollie_customer_id and 'd-none' or ''" t-if="mollie_components_enabled" t-att-data-profile_id="acq.sudo().mollie_profile_id" t-att-data-mode="acq.sudo().state">
<div class="form-row o_mollie_form mb-1">
<div class="col-md-12">
<label class="label text-muted mb-1" for="mollie-card-holder">Card Holder</label>
Expand All @@ -102,6 +114,12 @@
</div>
</div>
</div>
<div id="o_mollie_save_card" t-att-class="has_mollie_customer_id and 'd-none' or ''" t-if="acq.sudo().mollie_show_save_card" groups="!base.group_public">
<label>
<input name="o_mollie_save_card" type="checkbox"/>
Save my card details
</label>
</div>
</div>
</template>

Expand Down
12 changes: 6 additions & 6 deletions payment_mollie_official/views/payment_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
<group attrs="{'invisible': [('provider', '!=', 'mollie')]}">
<field name="mollie_api_key_test" attrs="{'required':[ ('provider', '=', 'mollie'), ('state', '=', 'test')]}" password="True"/>
<field name="mollie_api_key_prod" attrs="{'required':[ ('provider', '=', 'mollie'), ('state', '=', 'enabled')]}" password="True"/>
<field name="mollie_profile_id" attrs="{'required':[ ('provider', '=', 'mollie'), ('state', '=', 'enabled')]}" password="True"/>
<field name="mollie_voucher_enabled" invisible="1"/>
<label string=" " for="mollie_profile_id"> </label>
<small class="text-muted"> Credit card option will not be displayed without profile ID.
<field name="mollie_use_components" />
<field name="mollie_profile_id" password="True" attrs="{'invisible': [('mollie_use_components', '=', False)], 'required': [('mollie_use_components', '=', True)]}"/>
<label string=" " for="mollie_profile_id" attrs="{'invisible': [('mollie_use_components', '=', False)]}"> </label>
<small class="text-muted" attrs="{'invisible': [('mollie_use_components', '=', False)]}"> Credit card option will not be displayed without profile ID.
<br/>
<b><a href="https://www.mollie.com/dashboard/developers/api-keys" target="_new"> Get your API keys <i class="fa fa-arrow-right"> </i> </a></b>
<br/>
<br/>
</small>
<field name="mollie_show_save_card" />
<field name="mollie_voucher_enabled" invisible="1"/>
</group>
</xpath>
<page name="acquirer_credentials" position="after">
Expand Down

0 comments on commit da48073

Please sign in to comment.