summaryrefslogtreecommitdiff
path: root/addons/payment/static/src
diff options
context:
space:
mode:
authorToufik Benjaa <tbe@odoo.com>2018-07-11 17:47:29 +0200
committerToufik Benjaa <tbe@odoo.com>2018-09-19 18:25:32 +0200
commit6ed44181d081b3cfd8875dc82e4e155970cc07f5 (patch)
tree5449ac99ea4191b9b747918d0d1d8702ebad3cc5 /addons/payment/static/src
parent46dc8ceef90ec5472b1aa4b45509f23d6c3e2624 (diff)
[IMP] payment_*: payment acquirers error handling
This commit aims to improve the user experience when using payment acquirers. There currently are no error feedback with some acquirers, which leaves the user wondering what is going on and what is the real status of its payment. In some cases, the user is currently being redirected to the home page even though the payment has failed. We want to make it more obvious to the user that something unexpected has happened by redirecting to an intermediate page that will provide good feedback on payments status. Another goal of this commit is to order acquirers by sequence instead of by flow and to select the first acquirer by default. This feature was already implmented in commit fe294fd43e521bd2d339e962f43acf46c3d4cb97, some UI adaptations were needed though. Related to task #36680 Closes #26958
Diffstat (limited to 'addons/payment/static/src')
-rw-r--r--addons/payment/static/src/js/payment_processing.js125
-rw-r--r--addons/payment/static/src/xml/payment_processing.xml150
2 files changed, 275 insertions, 0 deletions
diff --git a/addons/payment/static/src/js/payment_processing.js b/addons/payment/static/src/js/payment_processing.js
new file mode 100644
index 00000000000..b40c2074131
--- /dev/null
+++ b/addons/payment/static/src/js/payment_processing.js
@@ -0,0 +1,125 @@
+odoo.define('payment.processing', function (require) {
+ 'use strict';
+
+ var Widget = require('web.Widget');
+ var Ajax = require('web.ajax');
+ var Core = require('web.core');
+ var Qweb = Core.qweb;
+ var _t = Core._t;
+
+ $.blockUI.defaults.css.border = '0';
+ $.blockUI.defaults.css["background-color"] = '';
+ $.blockUI.defaults.overlayCSS["opacity"] = '0.9';
+
+ return Widget.extend({
+ /* Members */
+ _payment_tx_ids: null,
+ _pollCount: 0,
+ /* Events */
+ events: {
+
+ },
+ /* deps */
+ xmlDependencies: ['/payment/static/src/xml/payment_processing.xml'],
+ /* Widget overrides */
+ init: function (parent, payment_tx_ids) {
+ this._super.apply(this, arguments);
+ //
+ this._payment_tx_ids = payment_tx_ids;
+ },
+ start: function() {
+ this.displayLoading();
+ this.poll();
+ return this._super.apply(this, arguments);
+ },
+ /* Methods */
+ startPolling: function () {
+ var timeout = 3000;
+ //
+ if(this._pollCount >= 10 && this._pollCount < 20) {
+ timeout = 10000;
+ }
+ else if(this._pollCount >= 20) {
+ timeout = 30000;
+ }
+ //
+ setTimeout(this.poll.bind(this), timeout);
+ this._pollCount ++;
+ },
+ poll: function () {
+ var self = this;
+ Ajax.jsonRpc('/payment/process/poll', 'call', {}).then(function(data) {
+ if(data.success === true) {
+ self.processPolledData(data.transactions);
+ }
+ else {
+ switch(data.error) {
+ case "no_tx_found":
+ self.displayContent("payment.no_tx_found", {});
+ break;
+ default: // if an exception is raised
+ self.displayContent("payment.exception", {exception_msg: data.error});
+ break;
+ }
+ }
+ self.startPolling();
+ }).always(function(){
+ if ($.blockUI) {
+ $.unblockUI();
+ }
+ }).fail(function(e) {
+ self.displayContent("payment.rpc_error", {});
+ self.startPolling();
+ });
+ },
+ processPolledData: function (transactions) {
+ var render_values = {
+ 'tx_draft': [],
+ 'tx_pending': [],
+ 'tx_authorized': [],
+ 'tx_done': [],
+ 'tx_cancel': [],
+ 'tx_error': [],
+ };
+ // group the transaction according to their state
+ transactions.forEach(tx => {
+ var key = 'tx_' + tx.state;
+ if(key in render_values) {
+ render_values[key].push(tx);
+ }
+ });
+
+ function countTxInState(states) {
+ var nbTx = 0;
+ for (var prop in render_values) {
+ if (states.indexOf(prop) > -1 && render_values.hasOwnProperty(prop)) {
+ nbTx += render_values[prop].length;
+ }
+ }
+ return nbTx;
+ }
+ // if there's only one tx to manage
+ if(countTxInState(['tx_done', 'tx_error']) === 1) {
+ var tx = render_values['tx_done'][0] || render_values['tx_error'][0];
+ if (tx) {
+ window.location = tx.return_url;
+ return;
+ }
+ }
+
+ this.displayContent("payment.display_tx_list", render_values);
+ },
+ displayContent: function (xmlid, render_values) {
+ var html = Qweb.render(xmlid, render_values);
+ this.$el.find('.o_payment_processing_content').html(html);
+ },
+ displayLoading: function () {
+ var msg = _t("We are processing your payments, please wait ...");
+ $.blockUI({
+ 'message': '<h2 class="text-white"><img src="/web/static/src/img/spin.png" class="fa-pulse"/>' +
+ ' <br />' + msg +
+ '</h2>'
+ });
+ },
+ });
+});
diff --git a/addons/payment/static/src/xml/payment_processing.xml b/addons/payment/static/src/xml/payment_processing.xml
new file mode 100644
index 00000000000..386a03bb117
--- /dev/null
+++ b/addons/payment/static/src/xml/payment_processing.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates id="payment" xml:space="preserve">
+ <!-- The templates here as rendered by 'payment_processing.js', you can also take
+ a look at payment_templates.xml (xmlid: payment_process_page) for more infos-->
+ <t t-name="payment.display_tx_list">
+ <div>
+ <!-- Error transactions -->
+ <div t-if="tx_error.length > 0">
+ <h1>Payments failed</h1>
+ <ul class="list-group">
+ <t t-foreach="tx_error" t-as="tx">
+ <li class="list-group-item">
+ <h4 class="list-group-item-heading mb5">
+ <t t-esc="tx['reference']"/>
+ <span class="badge pull-right"><t t-esc="tx['amount']"/> <t t-esc="tx['currency']"/></span>
+ </h4>
+ <small class="list-group-item-text">
+ An error occured during the processing of this payment.<br/>
+ <strong>Reason:</strong> <t t-esc="tx['state_message']"/>
+ </small>
+ </li>
+ </t>
+ </ul>
+ </div>
+ <div t-if="tx_done.length > 0 || tx_authorized.length > 0 || tx_pending.length > 0">
+ <h1>Payments received</h1>
+ <div class="list-group">
+ <!-- Done transactions -->
+ <t t-foreach="tx_done" t-as="tx">
+ <a t-att-href="tx['return_url']" class="list-group-item">
+ <h4 class="list-group-item-heading mb5">
+ <t t-esc="tx['reference']"/>
+ <span class="badge pull-right"><t t-esc="tx['amount']"/> <t t-esc="tx['currency']"/></span>
+ </h4>
+ <small class="list-group-item-text">
+ <t t-if="!tx['is_processed']">
+ Your order is being processed, please wait ... <i class="fa fa-cog fa-spin"/>
+ </t>
+ <t t-else="">
+ Your order has been processed.<br/>
+ Click here to be redirected to the confirmation page.
+ </t>
+ </small>
+ </a>
+ </t>
+ <!-- Pending transactions -->
+ <t t-foreach="tx_pending" t-as="tx">
+ <a t-att-href="tx['return_url']" class="list-group-item">
+ <h4 class="list-group-item-heading mb5">
+ <t t-esc="tx['reference']"/>
+ <span class="badge pull-right"><t t-esc="tx['amount']"/> <t t-esc="tx['currency']"/></span>
+ </h4>
+ <small class="list-group-item-text">
+ <t t-if="tx['message_to_display']">
+ <t t-raw="tx['message_to_display']"/>
+ </t>
+ <t t-else="">
+ Your payment is in pending state.<br/>
+ You will be notified when the payment is fully confirmed.<br/>
+ You can click here to be redirected to the confirmation page.
+ </t>
+ </small>
+ </a>
+ </t>
+ <!-- Authorized transactions -->
+ <t t-foreach="tx_authorized" t-as="tx">
+ <li class="list-group-item">
+ <h4 class="list-group-item-heading mb5">
+ <t t-esc="tx['reference']"/>
+ <span class="badge pull-right"><t t-esc="tx['amount']"/> <t t-esc="tx['currency']"/></span>
+ </h4>
+ <small class="list-group-item-text">
+ <t t-if="tx['message_to_display']">
+ <t t-raw="tx['message_to_display']"/>
+ </t>
+ <t t-else="">
+ Your payment has been received but need to be confirmed manually.<br/>
+ You will be notified when the payment is confirmed.
+ </t>
+ </small>
+ </li>
+ </t>
+ </div>
+ </div>
+ <!-- Draft transactions -->
+ <div t-if="tx_draft.length > 0">
+ <h1>Waiting for payment</h1>
+ <ul class="list-group">
+ <t t-foreach="tx_draft" t-as="tx">
+ <li class="list-group-item">
+ <h4 class="list-group-item-heading mb5">
+ <t t-esc="tx['reference']"/>
+ <span class="badge pull-right"><t t-esc="tx['amount']"/> <t t-esc="tx['currency']"/></span>
+ </h4>
+ <small class="list-group-item-text">
+ <t t-if="tx['message_to_display']">
+ <t t-raw="tx['message_to_display']"/>
+ </t>
+ <t t-else="">
+ We are waiting for the payment acquirer to confirm the payment.
+ </t>
+ </small>
+ </li>
+ </t>
+ </ul>
+ </div>
+ <!-- Cancel transactions -->
+ <div t-if="tx_cancel.length > 0">
+ <h1>Cancelled payments</h1>
+ <ul class="list-group">
+ <t t-foreach="tx_cancel" t-as="tx">
+ <li class="list-group-item">
+ <h4 class="list-group-item-heading mb5">
+ <t t-esc="tx['reference']"/>
+ <span class="badge pull-right"><t t-esc="tx['amount']"/> <t t-esc="tx['currency']"/></span>
+ </h4>
+ <small class="list-group-item-text">
+ This transaction has been cancelled.<br/>
+ No payment has been processed.
+ </small>
+ </li>
+ </t>
+ </ul>
+ </div>
+ </div>
+ </t>
+
+ <t t-name="payment.no_tx_found">
+ <div class="text-center">
+ <p>We are not able to find your payment, but don't worry.</p>
+ <p>You should receive an email confirming your payment in a few minutes.</p>
+ <p>If, the payment hasn't been confirmed you can contact us.</p>
+ </div>
+ </t>
+
+ <t t-name="payment.rpc_error">
+ <div class="text-center">
+ <p><strong>Server error:</strong> Unable to contact the Odoo server.</p>
+ <p>Please wait ... <i class="fa fa-refresh fa-spin"></i></p>
+ </div>
+ </t>
+
+ <t t-name="payment.exception">
+ <div class="text-center">
+ <h2>Internal server error</h2>
+ <pre><t t-esc="exception_msg"/></pre>
+ </div>
+ </t>
+
+</templates>