mirror of
https://github.com/moodle/moodle.git
synced 2025-04-13 04:22:07 +02:00
MDL-69166 core_payment: payment gateways can have a surcharge
This commit is contained in:
parent
11b2d9e9ac
commit
e3e83185ed
@ -23,7 +23,10 @@
|
||||
*/
|
||||
|
||||
$string['callbacknotimplemented'] = 'The callback is not implemented for component {$a}.';
|
||||
$string['feeincludesurcharge'] = '{$a->fee} (includes {$a->surcharge}% surcharge for using this payment type)';
|
||||
$string['nogateway'] = 'There is no payment gateway that can be used.';
|
||||
$string['nogatewayselected'] = 'You first need to select a payment gateway.';
|
||||
$string['selectpaymenttype'] = 'Select payment type';
|
||||
$string['supportedcurrencies'] = 'Supported currencies';
|
||||
$string['surcharge'] = 'Surcharge (percentage)';
|
||||
$string['surcharge_desc'] = 'The surcharge is an additional percentage charged to users who choose to pay using this payment gateway.';
|
||||
|
2
payment/amd/build/gateways_modal.min.js
vendored
2
payment/amd/build/gateways_modal.min.js
vendored
@ -1,2 +1,2 @@
|
||||
define ("core_payment/gateways_modal",["exports","core/modal_factory","core/templates","core/str","./repository","./selectors","core/modal_events","core_payment/events","core/toast","core/notification","./modal_gateways"],function(a,b,c,d,e,f,g,h,i,j,k){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.registerEventListeners=a.registerEventListenersBySelector=void 0;b=l(b);c=l(c);f=l(f);g=l(g);h=l(h);j=l(j);k=l(k);var o="undefined"!=typeof window?window:"undefined"!=typeof self?self:"undefined"!=typeof global?global:{};function l(a){return a&&a.__esModule?a:{default:a}}function m(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function n(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){m(h,d,e,f,g,"next",a)}function g(a){m(h,d,e,f,g,"throw",a)}f(void 0)})}}a.registerEventListenersBySelector=function registerEventListenersBySelector(a){document.querySelectorAll(a).forEach(function(a){p(a)})};var p=function(a){a.addEventListener("click",function(b){b.preventDefault();q(a,{focusOnClose:b.target})})};a.registerEventListeners=p;var q=function(){var a=n(regeneratorRuntime.mark(function a(l){var m,n,o,p,q,t,u,v,w,x,y,z=arguments;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:m=1<z.length&&z[1]!==void 0?z[1]:{},n=m.focusOnClose,o=void 0===n?null:n;a.t0=b.default;a.t1=k.default.TYPE;a.next=5;return(0,d.get_string)("selectpaymenttype","core_payment");case 5:a.t2=a.sent;a.next=8;return c.default.render("core_payment/gateways_modal",{});case 8:a.t3=a.sent;a.t4={type:a.t1,title:a.t2,body:a.t3};a.next=12;return a.t0.create.call(a.t0,a.t4);case 12:p=a.sent;(0,i.addToastRegion)(p.getRoot()[0]);p.show();p.getRoot().on(g.default.hidden,function(){p.destroy();try{o.focus()}catch(a){}});p.getRoot().on(h.default.proceed,function(a){var b=p.getRoot()[0],c=(b.querySelector(f.default.values.gateway)||{value:""}).value;if(c){s(c,l.dataset.amount,l.dataset.currency,l.dataset.component,l.dataset.componentid,l.dataset.description,function(a){var b=a.success,c=a.message,d=void 0===c?"":c;p.hide();if(b){j.default.addNotification({message:d,type:"success"});location.reload()}else{j.default.alert("",d)}})}else{(0,d.get_string)("nogatewayselected","core_payment").then(function(a){return(0,i.add)(a)})}a.preventDefault()});q=l.dataset.currency;a.next=20;return(0,e.getGatewaysSupportingCurrency)(q);case 20:t=a.sent;u={gateways:t};a.next=24;return c.default.renderForPromise("core_payment/gateways",u);case 24:v=a.sent;w=v.html;x=v.js;y=p.getRoot()[0];c.default.replaceNodeContents(y.querySelector(f.default.regions.gatewaysContainer),w,x);r(y,parseFloat(l.dataset.amount),l.dataset.currency);case 30:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}(),r=function(){var a=n(regeneratorRuntime.mark(function a(b,d,e){var g,h,i,j,k;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:a.next=2;return r.locale;case 2:g=a.sent;h=d.toLocaleString(g,{style:"currency",currency:e});a.next=6;return c.default.renderForPromise("core_payment/fee_breakdown",{fee:h});case 6:i=a.sent;j=i.html;k=i.js;c.default.replaceNodeContents(b.querySelector(f.default.regions.costContainer),j,k);case 10:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}();r.locale=(0,d.get_string)("localecldr","langconfig");var s=function(){var a=n(regeneratorRuntime.mark(function a(b,c,d,e,f,g,h){var i;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:a.next=2;return"function"==typeof o.define&&o.define.amd?new Promise(function(a,c){o.require(["pg_".concat(b,"/gateways_modal")],a,c)}):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&o.require&&"component"===o.require.loader?Promise.resolve(require(("pg_".concat(b,"/gateways_modal")))):Promise.resolve(o["pg_".concat(b,"/gateways_modal")]);case 2:i=a.sent;i.process(c,d,e,f,g,h);case 4:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}()});
|
||||
define ("core_payment/gateways_modal",["exports","core/modal_factory","core/templates","core/str","./repository","./selectors","core/modal_events","core_payment/events","core/toast","core/notification","./modal_gateways"],function(a,b,c,d,e,f,g,h,i,j,k){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.registerEventListeners=a.registerEventListenersBySelector=void 0;b=l(b);c=l(c);f=l(f);g=l(g);h=l(h);j=l(j);k=l(k);var o="undefined"!=typeof window?window:"undefined"!=typeof self?self:"undefined"!=typeof global?global:{};function l(a){return a&&a.__esModule?a:{default:a}}function m(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function n(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){m(h,d,e,f,g,"next",a)}function g(a){m(h,d,e,f,g,"throw",a)}f(void 0)})}}a.registerEventListenersBySelector=function registerEventListenersBySelector(a){document.querySelectorAll(a).forEach(function(a){p(a)})};var p=function(a){a.addEventListener("click",function(b){b.preventDefault();q(a,{focusOnClose:b.target})})};a.registerEventListeners=p;var q=function(){var a=n(regeneratorRuntime.mark(function a(l){var m,n,o,p,q,t,u,v,w,x,y,z=arguments;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:m=1<z.length&&z[1]!==void 0?z[1]:{},n=m.focusOnClose,o=void 0===n?null:n;a.t0=b.default;a.t1=k.default.TYPE;a.next=5;return(0,d.get_string)("selectpaymenttype","core_payment");case 5:a.t2=a.sent;a.next=8;return c.default.render("core_payment/gateways_modal",{});case 8:a.t3=a.sent;a.t4={type:a.t1,title:a.t2,body:a.t3};a.next=12;return a.t0.create.call(a.t0,a.t4);case 12:p=a.sent;q=p.getRoot()[0];(0,i.addToastRegion)(q);p.show();p.getRoot().on(g.default.hidden,function(){p.destroy();try{o.focus()}catch(a){}});p.getRoot().on(h.default.proceed,function(a){var b=(q.querySelector(f.default.values.gateway)||{value:""}).value;if(b){s(b,{value:parseFloat(l.dataset.amount),currency:l.dataset.currency,surcharge:parseInt((q.querySelector(f.default.values.gateway)||{dataset:{surcharge:0}}).dataset.surcharge)},l.dataset.component,l.dataset.componentid,l.dataset.description,function(a){var b=a.success,c=a.message,d=void 0===c?"":c;p.hide();if(b){j.default.addNotification({message:d,type:"success"});location.reload()}else{j.default.alert("",d)}})}else{(0,d.get_string)("nogatewayselected","core_payment").then(function(a){return(0,i.add)(a)})}a.preventDefault()});q.addEventListener("change",function(a){if(a.target.matches(f.default.elements.gateways)){r(q,parseFloat(l.dataset.amount),l.dataset.currency)}});t=l.dataset.currency;a.next=22;return(0,e.getGatewaysSupportingCurrency)(t);case 22:u=a.sent;v={gateways:u};a.next=26;return c.default.renderForPromise("core_payment/gateways",v);case 26:w=a.sent;x=w.html;y=w.js;c.default.replaceNodeContents(q.querySelector(f.default.regions.gatewaysContainer),x,y);a.next=32;return r(q,parseFloat(l.dataset.amount),l.dataset.currency);case 32:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}(),r=function(){var a=n(regeneratorRuntime.mark(function a(b,d,e){var g,h,i,j,k,l;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:a.next=2;return r.locale;case 2:g=a.sent;h=parseInt((b.querySelector(f.default.values.gateway)||{dataset:{surcharge:0}}).dataset.surcharge);d+=d*h/100;i=d.toLocaleString(g,{style:"currency",currency:e});a.next=8;return c.default.renderForPromise("core_payment/fee_breakdown",{fee:i,surcharge:h});case 8:j=a.sent;k=j.html;l=j.js;c.default.replaceNodeContents(b.querySelector(f.default.regions.costContainer),k,l);case 12:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}();r.locale=(0,d.get_string)("localecldr","langconfig");var s=function(){var a=n(regeneratorRuntime.mark(function a(b,c,d,e,f,g){var h,i,j,k,l;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:h=c.value,i=c.currency,j=c.surcharge,k=void 0===j?0:j;a.next=3;return"function"==typeof o.define&&o.define.amd?new Promise(function(a,c){o.require(["pg_".concat(b,"/gateways_modal")],a,c)}):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&o.require&&"component"===o.require.loader?Promise.resolve(require(("pg_".concat(b,"/gateways_modal")))):Promise.resolve(o["pg_".concat(b,"/gateways_modal")]);case 3:l=a.sent;h+=h*k/100;l.process(h,i,d,e,f,g);case 6:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}()});
|
||||
//# sourceMappingURL=gateways_modal.min.js.map
|
||||
|
File diff suppressed because one or more lines are too long
2
payment/amd/build/selectors.min.js
vendored
2
payment/amd/build/selectors.min.js
vendored
@ -1,2 +1,2 @@
|
||||
define ("core_payment/selectors",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;a.default={regions:{gatewaysContainer:"[data-region=\"gateways-container\"]",costContainer:"[data-region=\"fee-breakdown-container\"]"},values:{gateway:"[data-region=\"gateways-container\"] input[type=\"radio\"]:checked"}};return a.default});
|
||||
define ("core_payment/selectors",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;a.default={elements:{gateways:"[data-region=\"gateways-container\"] input[type=\"radio\"]"},regions:{gatewaysContainer:"[data-region=\"gateways-container\"]",costContainer:"[data-region=\"fee-breakdown-container\"]"},values:{gateway:"[data-region=\"gateways-container\"] input[type=\"radio\"]:checked"}};return a.default});
|
||||
//# sourceMappingURL=selectors.min.js.map
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"sources":["../src/selectors.js"],"names":["regions","gatewaysContainer","costContainer","values","gateway"],"mappings":"kJAwBe,CACXA,OAAO,CAAE,CACLC,iBAAiB,CAAE,sCADd,CAELC,aAAa,CAAE,2CAFV,CADE,CAKXC,MAAM,CAAE,CACJC,OAAO,CAAE,oEADL,CALG,C","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Define all of the selectors we will be using on the payment interface.\n *\n * @module core_payment/selectors\n * @package core_payment\n * @copyright 2019 Shamim Rezaie <shamim@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nexport default {\n regions: {\n gatewaysContainer: '[data-region=\"gateways-container\"]',\n costContainer: '[data-region=\"fee-breakdown-container\"]',\n },\n values: {\n gateway: '[data-region=\"gateways-container\"] input[type=\"radio\"]:checked',\n },\n};\n"],"file":"selectors.min.js"}
|
||||
{"version":3,"sources":["../src/selectors.js"],"names":["elements","gateways","regions","gatewaysContainer","costContainer","values","gateway"],"mappings":"kJAwBe,CACXA,QAAQ,CAAE,CACNC,QAAQ,CAAE,4DADJ,CADC,CAIXC,OAAO,CAAE,CACLC,iBAAiB,CAAE,sCADd,CAELC,aAAa,CAAE,2CAFV,CAJE,CAQXC,MAAM,CAAE,CACJC,OAAO,CAAE,oEADL,CARG,C","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Define all of the selectors we will be using on the payment interface.\n *\n * @module core_payment/selectors\n * @package core_payment\n * @copyright 2019 Shamim Rezaie <shamim@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nexport default {\n elements: {\n gateways: '[data-region=\"gateways-container\"] input[type=\"radio\"]',\n },\n regions: {\n gatewaysContainer: '[data-region=\"gateways-container\"]',\n costContainer: '[data-region=\"fee-breakdown-container\"]',\n },\n values: {\n gateway: '[data-region=\"gateways-container\"] input[type=\"radio\"]:checked',\n },\n};\n"],"file":"selectors.min.js"}
|
@ -72,7 +72,8 @@ const show = async(rootNode, {
|
||||
body: await Templates.render('core_payment/gateways_modal', {}),
|
||||
});
|
||||
|
||||
addToastRegion(modal.getRoot()[0]);
|
||||
const rootElement = modal.getRoot()[0];
|
||||
addToastRegion(rootElement);
|
||||
|
||||
modal.show();
|
||||
|
||||
@ -87,14 +88,17 @@ const show = async(rootNode, {
|
||||
});
|
||||
|
||||
modal.getRoot().on(PaymentEvents.proceed, (e) => {
|
||||
const root = modal.getRoot()[0];
|
||||
const gateway = (root.querySelector(Selectors.values.gateway) || {value: ''}).value;
|
||||
const gateway = (rootElement.querySelector(Selectors.values.gateway) || {value: ''}).value;
|
||||
|
||||
if (gateway) {
|
||||
processPayment(
|
||||
gateway,
|
||||
rootNode.dataset.amount,
|
||||
rootNode.dataset.currency,
|
||||
{
|
||||
value: parseFloat(rootNode.dataset.amount),
|
||||
currency: rootNode.dataset.currency,
|
||||
surcharge: parseInt((rootElement.querySelector(Selectors.values.gateway) || {dataset: {surcharge: 0}})
|
||||
.dataset.surcharge),
|
||||
},
|
||||
rootNode.dataset.component,
|
||||
rootNode.dataset.componentid,
|
||||
rootNode.dataset.description,
|
||||
@ -121,6 +125,13 @@ const show = async(rootNode, {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
// Re-calculate the cost when gateway is changed.
|
||||
rootElement.addEventListener('change', e => {
|
||||
if (e.target.matches(Selectors.elements.gateways)) {
|
||||
updateCostRegion(rootElement, parseFloat(rootNode.dataset.amount), rootNode.dataset.currency);
|
||||
}
|
||||
});
|
||||
|
||||
const currency = rootNode.dataset.currency;
|
||||
const gateways = await getGatewaysSupportingCurrency(currency);
|
||||
const context = {
|
||||
@ -128,9 +139,8 @@ const show = async(rootNode, {
|
||||
};
|
||||
|
||||
const {html, js} = await Templates.renderForPromise('core_payment/gateways', context);
|
||||
const root = modal.getRoot()[0];
|
||||
Templates.replaceNodeContents(root.querySelector(Selectors.regions.gatewaysContainer), html, js);
|
||||
updateCostRegion(root, parseFloat(rootNode.dataset.amount), rootNode.dataset.currency);
|
||||
Templates.replaceNodeContents(rootElement.querySelector(Selectors.regions.gatewaysContainer), html, js);
|
||||
await updateCostRegion(rootElement, parseFloat(rootNode.dataset.amount), rootNode.dataset.currency);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -143,9 +153,11 @@ const show = async(rootNode, {
|
||||
*/
|
||||
const updateCostRegion = async(root, amount, currency) => {
|
||||
const locale = await updateCostRegion.locale; // This only takes a bit the first time.
|
||||
const surcharge = parseInt((root.querySelector(Selectors.values.gateway) || {dataset: {surcharge: 0}}).dataset.surcharge);
|
||||
amount += amount * surcharge / 100;
|
||||
const localisedCost = amount.toLocaleString(locale, {style: "currency", currency: currency});
|
||||
|
||||
const {html, js} = await Templates.renderForPromise('core_payment/fee_breakdown', {fee: localisedCost});
|
||||
const {html, js} = await Templates.renderForPromise('core_payment/fee_breakdown', {fee: localisedCost, surcharge});
|
||||
Templates.replaceNodeContents(root.querySelector(Selectors.regions.costContainer), html, js);
|
||||
};
|
||||
updateCostRegion.locale = getString("localecldr", "langconfig");
|
||||
@ -154,18 +166,21 @@ updateCostRegion.locale = getString("localecldr", "langconfig");
|
||||
* Process payment using the selected gateway.
|
||||
*
|
||||
* @param {string} gateway The gateway to be used for payment
|
||||
* @param {number} amount Amount of payment
|
||||
* @param {string} currency The currency in the three-character ISO-4217 format
|
||||
* @param {Object} amount - Amount of payment
|
||||
* @param {number} amount.value The numerical part of the amount
|
||||
* @param {string} amount.currency The currency part of the amount in the three-character ISO-4217 format
|
||||
* @param {number} amount.surcharge The surcharge percentage that should be added to the amount
|
||||
* @param {string} component Name of the component that the componentid belongs to
|
||||
* @param {number} componentid An internal identifier that is used by the component
|
||||
* @param {string} description Description of the payment
|
||||
* @param {processPaymentCallback} callback The callback function to call when processing is finished
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
const processPayment = async(gateway, amount, currency, component, componentid, description, callback) => {
|
||||
const processPayment = async(gateway, {value, currency, surcharge = 0}, component, componentid, description, callback) => {
|
||||
const paymentMethod = await import(`pg_${gateway}/gateways_modal`);
|
||||
|
||||
paymentMethod.process(amount, currency, component, componentid, description, callback);
|
||||
value += value * surcharge / 100;
|
||||
paymentMethod.process(value, currency, component, componentid, description, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -23,6 +23,9 @@
|
||||
*/
|
||||
|
||||
export default {
|
||||
elements: {
|
||||
gateways: '[data-region="gateways-container"] input[type="radio"]',
|
||||
},
|
||||
regions: {
|
||||
gatewaysContainer: '[data-region="gateways-container"]',
|
||||
costContainer: '[data-region="fee-breakdown-container"]',
|
||||
|
@ -67,6 +67,7 @@ class get_gateways_for_currency extends external_api {
|
||||
'shortname' => $gateway,
|
||||
'name' => get_string('gatewayname', 'pg_' . $gateway),
|
||||
'description' => get_string('gatewaydescription', 'pg_' . $gateway),
|
||||
'surcharge' => \core_payment\helper::get_gateway_surcharge($gateway),
|
||||
];
|
||||
}
|
||||
|
||||
@ -84,6 +85,7 @@ class get_gateways_for_currency extends external_api {
|
||||
'shortname' => new external_value(PARAM_PLUGIN, 'Name of the plugin'),
|
||||
'name' => new external_value(PARAM_TEXT, 'Human readable name of the gateway'),
|
||||
'description' => new external_value(PARAM_TEXT, 'description of the gateway'),
|
||||
'surcharge' => new external_value(PARAM_INT, 'percentage of surcharge when using the gateway'),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
@ -76,6 +76,16 @@ class helper {
|
||||
return $gateways;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the percentage of surcharge that is applied when using a gateway
|
||||
*
|
||||
* @param string $gateway Name of the gateway
|
||||
* @return int
|
||||
*/
|
||||
public static function get_gateway_surcharge(string $gateway): int {
|
||||
return get_config('pg_' . $gateway, 'surcharge') ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the attributes to place on a pay button.
|
||||
*
|
||||
@ -164,4 +174,16 @@ class helper {
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* This functions adds the settings that are common for all payment gateways.
|
||||
*
|
||||
* @param \admin_settingpage $settings The settings object
|
||||
* @param string $gateway The gateway name prefic with pg_
|
||||
*/
|
||||
public static function add_common_gateway_settings(\admin_settingpage $settings, string $gateway): void {
|
||||
$settings->add(new \admin_setting_configtext($gateway . '/surcharge', get_string('surcharge', 'core_payment'),
|
||||
get_string('surcharge_desc', 'core_payment'), 0, PARAM_INT));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +77,11 @@ class transaction_complete extends external_api {
|
||||
'currency' => $currency
|
||||
] = payment_helper::get_cost($component, $componentid);
|
||||
|
||||
// Add surcharge if there is any.
|
||||
if ($config->surcharge) {
|
||||
$amount += $amount * $config->surcharge / 100;
|
||||
}
|
||||
|
||||
$paypalhelper = new paypal_helper($config->clientid, $config->secret, $sandbox);
|
||||
$orderdetails = $paypalhelper->get_order_details($orderid);
|
||||
|
||||
|
@ -41,4 +41,6 @@ if ($ADMIN->fulltree) {
|
||||
];
|
||||
$settings->add(new admin_setting_configselect('pg_paypal/environment', get_string('environment', 'pg_paypal'),
|
||||
get_string('environment_desc', 'pg_paypal'), 'live', $options));
|
||||
|
||||
\core_payment\helper::add_common_gateway_settings($settings, 'pg_paypal');
|
||||
}
|
||||
|
@ -31,8 +31,19 @@
|
||||
|
||||
}}
|
||||
<div class="core_payment_fee_breakdown">
|
||||
{{# str }} labelvalue, core, {
|
||||
"label": {{# quote }}{{# str }} cost {{/ str }}{{/ quote }},
|
||||
"value": "{{fee}}"
|
||||
} {{/ str }}
|
||||
{{#surcharge}}
|
||||
{{# str }} labelvalue, core, {
|
||||
"label": {{# quote }}{{# str }} cost {{/ str }}{{/ quote }},
|
||||
"value": {{# quote }}{{# str }} feeincludesurcharge, core_payment, {
|
||||
"fee": "{{fee}}",
|
||||
"surcharge": {{surcharge}}
|
||||
} {{/ str }}{{/ quote }}
|
||||
} {{/ str }}
|
||||
{{/surcharge}}
|
||||
{{^surcharge}}
|
||||
{{# str }} labelvalue, core, {
|
||||
"label": {{# quote }}{{# str }} cost {{/ str }}{{/ quote }},
|
||||
"value": "{{fee}}"
|
||||
} {{/ str }}
|
||||
{{/surcharge}}
|
||||
</div>
|
||||
|
@ -29,6 +29,7 @@
|
||||
* shortname
|
||||
* name
|
||||
* description
|
||||
* surcharge
|
||||
* image
|
||||
|
||||
Example context (json):
|
||||
@ -36,11 +37,12 @@
|
||||
"shortname": "paypal",
|
||||
"name": "PayPal",
|
||||
"description": "A description for PayPal.",
|
||||
"surcharge": "3"
|
||||
}
|
||||
|
||||
}}
|
||||
<div class="custom-control custom-radio {{shortname}}">
|
||||
<input class="custom-control-input" type="radio" name="payby" id="id-payby-{{uniqid}}-{{shortname}}" value="{{shortname}}" {{#checked}} checked="checked" {{/checked}} />
|
||||
<input class="custom-control-input" type="radio" name="payby" id="id-payby-{{uniqid}}-{{shortname}}" data-surcharge="{{surcharge}}" value="{{shortname}}" {{#checked}} checked="checked" {{/checked}} />
|
||||
<label class="custom-control-label bg-light border p-3 my-3" for="id-payby-{{uniqid}}-{{shortname}}">
|
||||
<p class="h3">{{name}}</p>
|
||||
<p class="content mb-2">{{description}}</p>
|
||||
|
Loading…
x
Reference in New Issue
Block a user