MDL-69166 core_payment: add payment accounts

This commit is contained in:
Marina Glancy
2020-10-27 14:40:49 +11:00
committed by Shamim Rezaie
parent 3c87455f4b
commit 6ff3087fe6
40 changed files with 1049 additions and 58 deletions
+9
View File
@@ -0,0 +1,9 @@
<?php
// This file defines settingpages and externalpages under the "Payment" category
$ADMIN->add('payment', new admin_externalpage(
'paymentaccounts',
new lang_string('paymentaccounts', 'payment'),
new moodle_url("/payment/accounts.php"),
['moodle/payment:manageaccounts', 'moodle/payment:viewpayments']));
+1
View File
@@ -39,6 +39,7 @@ $ADMIN->add('root', new admin_category('license', new lang_string('license')));
$ADMIN->add('root', new admin_category('location', new lang_string('location','admin')));
$ADMIN->add('root', new admin_category('language', new lang_string('language')));
$ADMIN->add('root', new admin_category('messaging', new lang_string('messagingcategory', 'admin')));
$ADMIN->add('root', new admin_category('payment', new lang_string('payments', 'payment')));
$ADMIN->add('root', new admin_category('modules', new lang_string('plugins', 'admin')));
$ADMIN->add('root', new admin_category('security', new lang_string('security','admin')));
$ADMIN->add('root', new admin_category('appearance', new lang_string('appearance','admin')));
+2 -1
View File
@@ -37,7 +37,7 @@ class provider implements \core_payment\local\callback\provider {
* Callback function that returns the enrolment cost for the course that $instanceid enrolment instance belongs to.
*
* @param int $instanceid The enrolment instance id
* @return array['amount' => float, 'currency' => string]
* @return array['amount' => float, 'currency' => string, 'accountid' => int]
*/
public static function get_cost(int $instanceid): array {
global $DB;
@@ -47,6 +47,7 @@ class provider implements \core_payment\local\callback\provider {
return [
'amount' => (float) $instance->cost,
'currency' => $instance->currency,
'accountid' => $instance->customint1,
];
}
+5
View File
@@ -210,6 +210,7 @@ class enrol_fee_plugin extends enrol_plugin {
'isguestuser' => isguestuser(),
'cost' => $localisedcost,
'currency' => $instance->currency,
'accountid' => $instance->customint1,
'amount' => $cost,
'instanceid' => $instance->id,
'description' => get_string('purchasedescription', 'enrol_fee',
@@ -309,6 +310,10 @@ class enrol_fee_plugin extends enrol_plugin {
$mform->addElement('select', 'status', get_string('status', 'enrol_fee'), $options);
$mform->setDefault('status', $this->get_config('status'));
$mform->addElement('select', 'customint1', get_string('paymentaccount', 'payment'),
['' => ''] + \core_payment\helper::get_payment_accounts_menu($context));
$mform->addRule('customint1', get_string('required'), 'required', null, 'client');
$mform->addElement('text', 'cost', get_string('cost', 'enrol_fee'), array('size' => 4));
$mform->setType('cost', PARAM_RAW);
$mform->setDefault('cost', format_float($this->get_config('cost'), 2, true));
@@ -41,6 +41,7 @@
"cost": "$108.50",
"amount": 108.50,
"currency": "AUD",
"accountid": 1,
"instanceid": 11,
"description": "Enrolment in course Introduction to algorithms",
"isguestuser": false
@@ -64,6 +65,7 @@
id="gateways-modal-trigger-{{ uniqid }}"
data-amount="{{amount}}"
data-currency="{{currency}}"
data-accountid="{{accountid}}"
data-component="enrol_fee"
data-componentid="{{instanceid}}"
data-description={{# quote }}{{description}}{{/ quote }}
+10
View File
@@ -22,11 +22,21 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['accountname'] = 'Account name';
$string['accountnotavailable'] = 'Not available';
$string['callbacknotimplemented'] = 'The callback is not implemented for component {$a}.';
$string['createaccount'] = 'Create payment account';
$string['feeincludesurcharge'] = '{$a->fee} (includes {$a->surcharge}% surcharge for using this payment type)';
$string['gatewaycannotbeenabled'] = 'The payment gateway cannot be enabled because the configuration is incomplete.';
$string['gatewaydisabled'] = 'Disabled';
$string['gatewayenabled'] = 'Enabled';
$string['gatewaynotfound'] = 'Gateway not found';
$string['nocurrencysupported'] = 'No payment in any currency is supported. Please make sure that at least one payment gateway is enabled.';
$string['nogateway'] = 'There is no payment gateway that can be used.';
$string['nogatewayselected'] = 'You first need to select a payment gateway.';
$string['payments'] = 'Payments';
$string['paymentaccount'] = 'Payment account';
$string['paymentaccounts'] = 'Payment accounts';
$string['selectpaymenttype'] = 'Select payment type';
$string['supportedcurrencies'] = 'Supported currencies';
$string['surcharge'] = 'Surcharge (percentage)';
+1
View File
@@ -166,6 +166,7 @@ $string['type_mnetservice_plural'] = 'MNet services';
$string['type_mod'] = 'Activity module';
$string['type_mod_plural'] = 'Activity modules';
$string['type_pgmanage'] = 'Manage payment gateways';
$string['type_pg'] = 'Payment gateway';
$string['type_pg_plural'] = 'Payment gateways';
$string['type_plagiarism'] = 'Plagiarism plugin';
$string['type_plagiarism_plural'] = 'Plagiarism plugins';
+1 -1
View File
@@ -268,7 +268,7 @@ abstract class persistent extends moodleform {
/**
* Return the persistent object associated with this form instance.
*
* @return core\persistent
* @return \core\persistent
*/
final protected function get_persistent() {
return $this->persistent;
+18
View File
@@ -2576,4 +2576,22 @@ $capabilities = array(
'editingteacher' => CAP_ALLOW,
]
],
// Allow to manage payment accounts.
'moodle/payment:manageaccounts' => [
'captype' => 'write',
'riskbitmask' => RISK_PERSONAL | RISK_CONFIG | RISK_DATALOSS,
'contextlevel' => CONTEXT_COURSE,
'archetypes' => [
]
],
// Allow to view payments.
'moodle/payment:viewpayments' => [
'captype' => 'read',
'riskbitmask' => RISK_PERSONAL,
'contextlevel' => CONTEXT_COURSE,
'archetypes' => [
]
],
);
+31
View File
@@ -4288,6 +4288,35 @@
<INDEX NAME="instance" UNIQUE="false" FIELDS="contextid, contenttype, instanceid"/>
</INDEXES>
</TABLE>
<TABLE NAME="payment_accounts" COMMENT="Payment accounts">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="idnumber" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="enabled" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="payment_gateways" COMMENT="Configuration for one gateway for one payment account">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="accountid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="gateway" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="enabled" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false"/>
<FIELD NAME="config" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="accountid" TYPE="foreign" FIELDS="accountid" REFTABLE="payment_accounts" REFFIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="payments" COMMENT="Stores information about payments">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
@@ -4296,6 +4325,7 @@
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="amount" TYPE="char" LENGTH="20" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="currency" TYPE="char" LENGTH="3" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="accountid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="gateway" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
@@ -4303,6 +4333,7 @@
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id"/>
<KEY NAME="accountid" TYPE="foreign" FIELDS="accountid" REFTABLE="payment_accounts" REFFIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="component" UNIQUE="false" FIELDS="component"/>
+63
View File
@@ -2896,5 +2896,68 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2021052500.32);
}
if ($oldversion < 2021052500.33) {
// Define table payment_accounts to be created.
$table = new xmldb_table('payment_accounts');
// Adding fields to table payment_accounts.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
$table->add_field('idnumber', XMLDB_TYPE_CHAR, '100', null, null, null, null);
$table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('enabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
$table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
$table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
// Adding keys to table payment_accounts.
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
// Conditionally launch create table for payment_accounts.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Define table payment_gateways to be created.
$table = new xmldb_table('payment_gateways');
// Adding fields to table payment_gateways.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('accountid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('gateway', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
$table->add_field('enabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1');
$table->add_field('config', XMLDB_TYPE_TEXT, null, null, null, null, null);
$table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
// Adding keys to table payment_gateways.
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
$table->add_key('accountid', XMLDB_KEY_FOREIGN, ['accountid'], 'payment_accounts', ['id']);
// Conditionally launch create table for payment_gateways.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Define field accountid to be added to payments.
$table = new xmldb_table('payments');
$field = new xmldb_field('accountid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'currency');
// Conditionally launch add field accountid.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Define key accountid (foreign) to be added to payments.
$table = new xmldb_table('payments');
$key = new xmldb_key('accountid', XMLDB_KEY_FOREIGN, ['accountid'], 'payment_accounts', ['id']);
// Launch add key accountid.
$dbman->add_key($table, $key);
// Main savepoint reached.
upgrade_main_savepoint(true, 2021052500.33);
}
return true;
}
+71
View File
@@ -0,0 +1,71 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Management of payment accounts
*
* @package core_payment
* @copyright 2020 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../config.php');
require_once($CFG->libdir . '/adminlib.php');
admin_externalpage_setup('paymentaccounts');
$PAGE->set_heading(get_string('paymentaccounts', 'payment'));
$enabledplugins = \core\plugininfo\pg::get_enabled_plugins();
echo $OUTPUT->header();
$accounts = \core_payment\helper::get_payment_accounts_to_manage(context_system::instance());
$table = new html_table();
$table->head = [get_string('accountname', 'payment'), get_string('type_pg', 'plugin'), ''];
$table->colclasses = ['', '', 'mdl-right'];
$table->data = [];
foreach ($accounts as $account) {
$gateways = [];
$canmanage = has_capability('moodle/payment:manageaccounts', $account->get_context());
foreach ($account->get_gateways() as $gateway) {
$status = $gateway->get('enabled') ? $OUTPUT->pix_icon('i/valid', get_string('gatewayenabled', 'payment')) :
$OUTPUT->pix_icon('i/invalid', get_string('gatewaydisabled', 'payment'));
$gateways[] = $status .
($canmanage ? html_writer::link($gateway->get_edit_url(), $gateway->get_display_name()) : $gateway->get_display_name());
}
$name = $account->get_formatted_name();
if (!$account->is_available()) {
$name .= ' ' . html_writer::span(get_string('accountnotavailable', 'payment'), 'badge badge-warning');
}
$menu = new action_menu();
$menu->set_alignment(action_menu::TL, action_menu::BL);
$menu->set_menu_trigger(get_string('edit'));
if ($canmanage) {
$menu->add(new action_menu_link_secondary($account->get_edit_url(), null, get_string('edit')));
$deleteurl = $account->get_edit_url(['delete' => 1, 'sesskey' => sesskey()]);
$deleteaction = new confirm_action(get_string('deleteconfirm', 'tool_recyclebin'));
$menu->add(new action_menu_link_secondary($deleteurl, null, get_string('delete')));
}
$table->data[] = [$name, join(', ', $gateways), $OUTPUT->render($menu)];
}
echo html_writer::table($table);
echo $OUTPUT->single_button(new moodle_url('/payment/manage_account.php'), get_string('createaccount', 'payment'), 'get');
echo $OUTPUT->footer();
+1 -1
View File
@@ -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,u,v,w,x,y,z,A=arguments;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:m=1<A.length&&A[1]!==void 0?A[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){t(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)){s(q,parseFloat(l.dataset.amount),l.dataset.currency)}});u=l.dataset.currency;a.next=22;return(0,e.getGatewaysSupportingCurrency)(u);case 22:v=a.sent;w={gateways:v};a.next=26;return c.default.renderForPromise("core_payment/gateways",w);case 26:x=a.sent;y=x.html;z=x.js;c.default.replaceNodeContents(q.querySelector(f.default.regions.gatewaysContainer),y,z);r(q);a.next=33;return s(q,parseFloat(l.dataset.amount),l.dataset.currency);case 33:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}(),r=function(a){var b=a.querySelectorAll(f.default.elements.gateways);if(1==b.length){b[0].checked=!0}},s=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 s.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)}}();s.locale=(0,d.get_string)("localecldr","langconfig");var t=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)}}()});
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,u,v,w,x,y,z,A,B=arguments;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:m=1<B.length&&B[1]!==void 0?B[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){t(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)){s(q,parseFloat(l.dataset.amount),l.dataset.currency)}});u=l.dataset.currency;v=l.dataset.accountid;a.next=23;return(0,e.getGatewaysSupportingCurrency)(u,v);case 23:w=a.sent;x={gateways:w};a.next=27;return c.default.renderForPromise("core_payment/gateways",x);case 27:y=a.sent;z=y.html;A=y.js;c.default.replaceNodeContents(q.querySelector(f.default.regions.gatewaysContainer),z,A);r(q);a.next=34;return s(q,parseFloat(l.dataset.amount),l.dataset.currency);case 34:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}(),r=function(a){var b=a.querySelectorAll(f.default.elements.gateways);if(1==b.length){b[0].checked=!0}},s=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 s.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)}}();s.locale=(0,d.get_string)("localecldr","langconfig");var t=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
+1 -1
View File
@@ -1,2 +1,2 @@
define ("core_payment/repository",["exports","core/ajax"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.getGatewaysSupportingCurrency=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);var c=function(a){return b.default.call([{methodname:"core_payment_get_gateways_for_currency",args:{currency:a}}])[0]};a.getGatewaysSupportingCurrency=c});
define ("core_payment/repository",["exports","core/ajax"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.getGatewaysSupportingCurrency=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);var c=function(a,c){return b.default.call([{methodname:"core_payment_get_gateways_for_currency",args:{currency:a,accountid:c}}])[0]};a.getGatewaysSupportingCurrency=c});
//# sourceMappingURL=repository.min.js.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["../src/repository.js"],"names":["getGatewaysSupportingCurrency","currency","Ajax","call","methodname","args"],"mappings":"6KAwBA,uDAQO,GAAMA,CAAAA,CAA6B,CAAG,SAAAC,CAAQ,CAAI,CAOrD,MAAOC,WAAKC,IAAL,CAAU,CAND,CACZC,UAAU,CAAE,wCADA,CAEZC,IAAI,CAAE,CACFJ,QAAQ,CAARA,CADE,CAFM,CAMC,CAAV,EAAqB,CAArB,CACV,CARM,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 * Repository for payment subsystem.\n *\n * @module core_payment/repository\n * @package core_payment\n * @copyright 2020 Shamim Rezaie <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Returns the list of gateways that can process payments in the given currency.\n *\n * @param {string} currency The currency in the three-character ISO-4217 format\n * @returns {Promise<{shortname: string, name: string, description: String}[]>}\n */\nexport const getGatewaysSupportingCurrency = currency => {\n const request = {\n methodname: 'core_payment_get_gateways_for_currency',\n args: {\n currency\n }\n };\n return Ajax.call([request])[0];\n};\n"],"file":"repository.min.js"}
{"version":3,"sources":["../src/repository.js"],"names":["getGatewaysSupportingCurrency","currency","accountid","Ajax","call","methodname","args"],"mappings":"6KAwBA,uDASO,GAAMA,CAAAA,CAA6B,CAAG,SAACC,CAAD,CAAWC,CAAX,CAAyB,CAQlE,MAAOC,WAAKC,IAAL,CAAU,CAPD,CACZC,UAAU,CAAE,wCADA,CAEZC,IAAI,CAAE,CACFL,QAAQ,CAARA,CADE,CAEFC,SAAS,CAATA,CAFE,CAFM,CAOC,CAAV,EAAqB,CAArB,CACV,CATM,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 * Repository for payment subsystem.\n *\n * @module core_payment/repository\n * @package core_payment\n * @copyright 2020 Shamim Rezaie <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Returns the list of gateways that can process payments in the given currency.\n *\n * @param {string} currency The currency in the three-character ISO-4217 format\n * @param {int} accountid\n * @returns {Promise<{shortname: string, name: string, description: String}[]>}\n */\nexport const getGatewaysSupportingCurrency = (currency, accountid) => {\n const request = {\n methodname: 'core_payment_get_gateways_for_currency',\n args: {\n currency,\n accountid\n }\n };\n return Ajax.call([request])[0];\n};\n"],"file":"repository.min.js"}
+2 -1
View File
@@ -133,7 +133,8 @@ const show = async(rootNode, {
});
const currency = rootNode.dataset.currency;
const gateways = await getGatewaysSupportingCurrency(currency);
const accountid = rootNode.dataset.accountid;
const gateways = await getGatewaysSupportingCurrency(currency, accountid);
const context = {
gateways
};
+4 -2
View File
@@ -28,13 +28,15 @@ import Ajax from 'core/ajax';
* Returns the list of gateways that can process payments in the given currency.
*
* @param {string} currency The currency in the three-character ISO-4217 format
* @param {int} accountid
* @returns {Promise<{shortname: string, name: string, description: String}[]>}
*/
export const getGatewaysSupportingCurrency = currency => {
export const getGatewaysSupportingCurrency = (currency, accountid) => {
const request = {
methodname: 'core_payment_get_gateways_for_currency',
args: {
currency
currency,
accountid
}
};
return Ajax.call([request])[0];
+152
View File
@@ -0,0 +1,152 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Class account
*
* @package core_payment
* @copyright 2020 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_payment;
use core\persistent;
/**
* Class account
*
* @package core_payment
* @copyright 2020 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class account extends persistent {
/**
* Database table.
*/
const TABLE = 'payment_accounts';
/** @var array */
protected $gateways;
/**
* Return the definition of the properties of this model.
*
* @return array
*/
protected static function define_properties() : array {
return array(
'name' => [
'type' => PARAM_TEXT,
],
'idnumber' => [
'type' => PARAM_RAW_TRIMMED,
],
'contextid' => [
'type' => PARAM_INT,
'default' => function() {
return \context_system::instance()->id;
}
],
'enabled' => [
'type' => PARAM_BOOL,
'default' => true
],
);
}
/**
* Account context
*
* @return \context
* @throws \coding_exception
*/
public function get_context(): \context {
return \context::instance_by_id($this->get('contextid'));
}
/**
* Account name ready for display
*
* @return string
* @throws \coding_exception
*/
public function get_formatted_name(): string {
return format_string($this->get('name'), true, ['context' => $this->get_context(), 'escape' => false]);
}
/**
* Manage account url
*
* @param array $extraparams
* @return \moodle_url
* @throws \coding_exception
* @throws \moodle_exception
*/
public function get_edit_url(array $extraparams = []): \moodle_url {
return new \moodle_url('/payment/manage_account.php',
($this->get('id') ? ['id' => $this->get('id')] : []) + $extraparams);
}
/**
* List of gateways configured (or possible) for this account
*
* @param bool $enabledpluginsonly only return payment plugins that are enabled
* @return account_gateway[]
* @throws \coding_exception
*/
public function get_gateways(bool $enabledpluginsonly = true): array {
$id = $this->get('id');
if (!$id) {
return [];
}
if ($this->gateways === null) {
\core_component::get_plugin_list('pg');
$this->gateways = [];
foreach (\core_component::get_plugin_list('pg') as $gatewayname => $unused) {
$gateway = account_gateway::get_record(['accountid' => $id, 'gateway' => $gatewayname]);
if (!$gateway) {
$gateway = new account_gateway(0, (object)['accountid' => $id, 'gateway' => $gatewayname,
'enabled' => false, 'config' => null]);
}
$this->gateways[$gatewayname] = $gateway;
}
}
if ($enabledpluginsonly) {
$enabledplugins = \core\plugininfo\pg::get_enabled_plugins();
return array_intersect_key($this->gateways, $enabledplugins);
}
return $this->gateways;
}
/**
* Is this account available (used in management interface)
*
* @return bool
* @throws \coding_exception
*/
public function is_available(): bool {
if (!$this->get('id') || !$this->get('enabled')) {
return false;
}
foreach ($this->get_gateways() as $gateway) {
if ($gateway->get('id') && $gateway->get('enabled')) {
return true;
}
}
return false;
}
}
+114
View File
@@ -0,0 +1,114 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Class account_gateway
*
* @package core_payment
* @copyright 2020 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_payment;
use core\persistent;
defined('MOODLE_INTERNAL') || die();
/**
* Class account_gateway
*
* @package core_payment
* @copyright 2020 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class account_gateway extends persistent {
/**
* Database table.
*/
const TABLE = 'payment_gateways';
/**
* Return the definition of the properties of this model.
*
* @return array
*/
protected static function define_properties() : array {
return array(
'accountid' => [
'type' => PARAM_INT,
],
'gateway' => [
'type' => PARAM_COMPONENT,
// TODO select with options?
],
'enabled' => [
'type' => PARAM_BOOL,
'default' => true
],
'config' => [
'type' => PARAM_RAW,
'optional' => true,
'null' => NULL_ALLOWED,
'default' => null
],
);
}
/**
* Return the gateway name ready for display
*
* @return string
* @throws \coding_exception
*/
public function get_display_name(): string {
return get_string('pluginname', 'pg_' . $this->get('gateway'));
}
/**
* Gateway management url
*
* @return \moodle_url
* @throws \coding_exception
* @throws \moodle_exception
*/
public function get_edit_url(): \moodle_url {
$params = $this->get('id') ? ['id' => $this->get('id')] :
['accountid' => $this->get('accountid'), 'gateway' => $this->get('gateway')];
return new \moodle_url('/payment/manage_gateway.php', $params);
}
/**
* Get corresponding account
*
* @return account
* @throws \coding_exception
*/
public function get_account(): account {
return new account($this->get('accountid'));
}
/**
* Parse configuration from the json-encoded stored value
*
* @return array
* @throws \coding_exception
*/
public function get_configuration(): array {
$config = @json_decode($this->get('config'), true);
return ($config && is_array($config)) ? $config : [];
}
}
+6 -3
View File
@@ -43,7 +43,8 @@ class get_gateways_for_currency extends external_api {
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters(
['currency' => new external_value(PARAM_ALPHA, 'Currency code')]
['currency' => new external_value(PARAM_ALPHA, 'Currency code'),
'accountid' => new external_value(PARAM_INT, 'Account id')]
);
}
@@ -51,16 +52,18 @@ class get_gateways_for_currency extends external_api {
* Returns the list of gateways that can process payments in the given currency.
*
* @param string $currency The currency in the three-character ISO-4217 format.
* @param int $accountid
* @return \stdClass[]
*/
public static function execute(string $currency): array {
public static function execute(string $currency, int $accountid): array {
$params = external_api::validate_parameters(self::execute_parameters(), [
'currency' => $currency,
'accountid' => $accountid,
]);
$list = [];
$gateways = \core_payment\helper::get_gateways_for_currency($params['currency']);
$gateways = \core_payment\helper::get_gateways_for_currency($params['currency'], $params['accountid']);
foreach ($gateways as $gateway) {
$list[] = (object)[
+64
View File
@@ -0,0 +1,64 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Class account
*
* @package core_payment
* @copyright 2020 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_payment\form;
use core\form\persistent;
defined('MOODLE_INTERNAL') || die();
/**
* Class account
*
* @package core_payment
* @copyright 2020 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class account extends persistent {
/** @var string The persistent class. */
protected static $persistentclass = 'core_payment\account';
/**
* Define the form - called by parent constructor
*/
public function definition() {
$mform = $this->_form;
$mform->addElement('hidden', 'id');
$mform->addElement('hidden', 'contextid');
$mform->addElement('text', 'name', get_string('accountname', 'payment'), 'maxlength="255"');
$mform->setType('name', PARAM_TEXT);
$mform->addRule('name', get_string('required'), 'required', null, 'client');
$mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'server');
$mform->addElement('text', 'idnumber', get_string('idnumber'), 'maxlength="100"');
$mform->setType('idnumber', PARAM_RAW_TRIMMED);
$mform->addRule('idnumber', get_string('maximumchars', '', 100), 'maxlength', 100, 'server');
$mform->addElement('advcheckbox', 'enabled', get_string('enable'));
$this->add_action_buttons();
}
}
+150
View File
@@ -0,0 +1,150 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Class account_gateway
*
* @package core_payment
* @copyright 2020 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_payment\form;
use core\form\persistent;
use core_payment\gateway;
defined('MOODLE_INTERNAL') || die();
/**
* Class account_gateway
*
* @package core_payment
* @copyright 2020 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class account_gateway extends persistent {
/** @var string The persistent class. */
protected static $persistentclass = \core_payment\account_gateway::class;
protected static $fieldstoremove = ['accountname', 'gatewayname', 'submitbutton'];
/**
* Define the form - called by parent constructor
*/
public function definition() {
$mform = $this->_form;
$mform->addElement('hidden', 'id');
$mform->addElement('hidden', 'accountid');
$mform->addElement('hidden', 'gateway');
$mform->addElement('static', 'accountname', get_string('accountname', 'payment'),
$this->get_gateway_persistent()->get_account()->get_formatted_name());
$mform->addElement('static', 'gatewayname', get_string('type_pg', 'plugin'),
$this->get_gateway_persistent()->get_display_name());
$mform->addElement('advcheckbox', 'enabled', get_string('enable'));
/** @var \core_payment\gateway $classname */
$classname = '\pg_' . $this->get_gateway_persistent()->get('gateway') . '\gateway';
if (class_exists($classname)) {
$classname::add_configuration_to_gateway_form($this);
}
$this->add_action_buttons();
}
/**
* Form validation
*
* @param \stdClass $data
* @param array $files
* @param array $errors
*/
protected function extra_validation($data, $files, array &$errors) {
/** @var \core_payment\gateway $classname */
$classname = '\pg_' . $this->get_gateway_persistent()->get('gateway') . '\gateway';
if (class_exists($classname)) {
$classname::validate_gateway_form($this, $data, $files, $errors);
}
}
/**
* Exposes the protected attribute to be accessed by the \core_payment\gateway callback
*
* @return \MoodleQuickForm
*/
public function get_mform(): \MoodleQuickForm {
return $this->_form;
}
/**
* Exposes the protected attribute to be accessed by the \core_payment\gateway callback
*
* @return \core_payment\account_gateway
*/
public function get_gateway_persistent(): \core_payment\account_gateway {
return $this->get_persistent();
}
/**
* Filter out the foreign fields of the persistent.
*
* This can be overridden to filter out more complex fields.
*
* @param \stdClass $data The data to filter the fields out of.
* @return \stdClass.
*/
protected function filter_data_for_persistent($data) {
$data = parent::filter_data_for_persistent($data);
return (object) array_intersect_key((array)$data, \core_payment\account_gateway::properties_definition());
}
/**
* Overwrite parent method to json encode config
*
* @return object|\stdClass|null
* @throws \coding_exception
*/
public function get_data() {
if (!$data = parent::get_data()) {
return $data;
}
// Everything that is not a property of the account_gateway class is a gateway config.
$data = (array)$data;
$properties = \core_payment\account_gateway::properties_definition() + ['id' => 1];
$config = array_diff_key($data, $properties, ['timemodified' => 1, 'timecreated' => 1]);
$data = array_intersect_key($data, $properties);
$data['config'] = json_encode($config);
return (object)$data;
}
/**
* Overwrite parent method to json decode config
*
* @param array|\stdClass $values
*/
public function set_data($values) {
if (($config = isset($values->config) ? @json_decode($values->config, true) : null) && is_array($config)) {
$values = (object)((array)$values + $config);
}
unset($values->config);
parent::set_data($values);
}
}
+26
View File
@@ -39,4 +39,30 @@ abstract class gateway {
* @return string[] An array of the currency codes in the three-character ISO-4217 format
*/
public abstract static function get_supported_currencies(): array;
/**
* Configuration form for the gateway instance
*
* Use $form->get_mform() to access the \MoodleQuickForm instance
*
* @param \core_payment\form\account_gateway $form
*/
public abstract static function add_configuration_to_gateway_form(\core_payment\form\account_gateway $form): void;
/**
* Validates the gateway configuration form.
*
* Needs to be overridden to make sure the incomplete configuration can not be enabled.
*
* @param \core_payment\form\account_gateway $form
* @param \stdClass $data
* @param array $files
* @param array $errors form errors (passed by reference)
*/
public static function validate_gateway_form(\core_payment\form\account_gateway $form,
\stdClass $data, array $files, array &$errors): void {
if ($data->enabled) {
$errors['enabled'] = get_string('gatewaycannotbeenabled', 'payment');
}
}
}
+116 -5
View File
@@ -44,6 +44,7 @@ class helper {
$plugins = \core_plugin_manager::instance()->get_enabled_plugins('pg');
foreach ($plugins as $plugin) {
/** @var \pg_paypal\gateway $classname */
$classname = '\pg_' . $plugin . '\gateway';
$currencies += $classname::get_supported_currencies();
@@ -58,13 +59,22 @@ class helper {
* Returns the list of gateways that can process payments in the given currency.
*
* @param string $currency The currency in the three-character ISO-4217 format.
* @param int $accountid
* @return string[]
*/
public static function get_gateways_for_currency(string $currency): array {
public static function get_gateways_for_currency(string $currency, int $accountid): array {
$gateways = [];
$plugins = \core_plugin_manager::instance()->get_enabled_plugins('pg');
foreach ($plugins as $plugin) {
$account = new account($accountid);
if (!$account->get('id') || !$account->get('enabled')) {
return $gateways;
}
foreach ($account->get_gateways() as $plugin => $gateway) {
if (!$gateway->get('enabled')) {
continue;
}
/** @var gateway $classname */
$classname = '\pg_' . $plugin . '\gateway';
$currencies = $classname::get_supported_currencies();
@@ -114,19 +124,42 @@ class helper {
*
* @param string $component Name of the component that the componentid belongs to
* @param int $componentid An internal identifier that is used by the component
* @return array['amount' => float, 'currency' => string]
* @return array['amount' => float, 'currency' => string, 'accountid' => int]
* @throws \moodle_exception
*/
public static function get_cost(string $component, int $componentid): array {
$cost = component_class_callback("$component\\payment\\provider", 'get_cost', [$componentid]);
if ($cost === null) {
if ($cost === null || !is_array($cost) || !array_key_exists('amount', $cost)
|| !array_key_exists('currency', $cost) || !array_key_exists('accountid', $cost) ) {
throw new \moodle_exception('callbacknotimplemented', 'core_payment', '', $component);
}
return $cost;
}
/**
* Returns the gateway configuration for given component and gateway
*
* @param string $component
* @param int $componentid
* @param string $gatewayname
* @return array
* @throws \moodle_exception
*/
public static function get_gateway_configuration(string $component, int $componentid, string $gatewayname): array {
$x = self::get_cost($component, $componentid);
$gateway = null;
$account = new account($x['accountid']);
if ($account && $account->get('enabled')) {
$gateway = $account->get_gateways()[$gatewayname] ?? null;
}
if (!$gateway) {
throw new \moodle_exception('gatewaynotfound', 'payment');
}
return $gateway->get_configuration();
}
/**
* Delivers what the user paid for.
*
@@ -186,4 +219,82 @@ class helper {
get_string('surcharge_desc', 'core_payment'), 0, PARAM_INT));
}
/**
* Save a new or edited payment account (used in management interface)
*
* @param \stdClass $data
*/
public static function save_payment_account(\stdClass $data) {
if (empty($data->id)) {
$account = new account(0, $data);
} else {
$account = new account($data->id);
$account->from_record($data);
}
$account->save();
// TODO trigger event.
}
/**
* Delete a payment account (used in management interface)
*
* @param account $account
*/
public static function delete_payment_account(account $account) {
foreach ($account->get_gateways(false) as $gateway) {
if ($gateway->get('id')) {
$gateway->delete();
}
}
$account->delete();
// TODO trigger event.
}
/**
* Save a payment gateway linked to an existing account (used in management interface)
*
* @param \stdClass $data
*/
public static function save_payment_gateway(\stdClass $data) {
if (empty($data->id)) {
$gateway = new account_gateway(0, $data);
} else {
$gateway = new account_gateway($data->id);
unset($data->accountid, $data->gateway, $data->id);
$gateway->from_record($data);
}
$gateway->save();
// TODO trigger event.
}
/**
* Returns the list of payment accounts in the given context (used in management interface)
*
* @param \context $context
* @return account[]
*/
public static function get_payment_accounts_to_manage(\context $context): array {
return account::get_records(['contextid' => $context->id]);
}
/**
* Get list of accounts available in the given context
*
* @param \context $context
* @return array
*/
public static function get_payment_accounts_menu(\context $context): array {
global $DB;
[$sql, $params] = $DB->get_in_or_equal($context->get_parent_context_ids(true));
$accounts = array_filter(account::get_records_select('contextid '.$sql, $params), function($account) {
return $account->is_available();
});
return array_map(function($account) {
return $account->get_formatted_name();
}, $accounts);
}
}
+1 -1
View File
@@ -38,7 +38,7 @@ interface provider {
/**
* @param int $identifier An identifier that is known to the plugin
* @return array['amount' => float, 'currency' => string]
* @return array['amount' => float, 'currency' => string, 'accountid' => int]
*/
public static function get_cost(int $identifier): array;
+1 -1
View File
@@ -1,2 +1,2 @@
function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("pg_paypal/gateways_modal",["exports","./repository","core/templates","core/truncate","core/ajax","core/modal_factory","core/modal_events","core/str"],function(a,b,c,d,e,f,g,h){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.process=void 0;b=k(b);c=i(c);d=i(d);e=i(e);f=i(f);g=i(g);function i(a){return a&&a.__esModule?a:{default:a}}function j(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;j=function(){return a};return a}function k(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=j();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var e in a){if(Object.prototype.hasOwnProperty.call(a,e)){var f=d?Object.getOwnPropertyDescriptor(a,e):null;if(f&&(f.get||f.set)){Object.defineProperty(c,e,f)}else{c[e]=a[e]}}}c.default=a;if(b){b.set(a,c)}return c}function l(a,b){return r(a)||q(a,b)||n(a,b)||m()}function m(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function n(a,b){if(!a)return;if("string"==typeof a)return p(a,b);var c=Object.prototype.toString.call(a).slice(8,-1);if("Object"===c&&a.constructor)c=a.constructor.name;if("Map"===c||"Set"===c)return Array.from(c);if("Arguments"===c||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c))return p(a,b)}function p(a,b){if(null==b||b>a.length)b=a.length;for(var c=0,d=Array(b);c<b;c++){d[c]=a[c]}return d}function q(a,b){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(a)))return;var c=[],d=!0,e=!1,f=void 0;try{for(var g=a[Symbol.iterator](),h;!(d=(h=g.next()).done);d=!0){c.push(h.value);if(b&&c.length===b)break}}catch(a){e=!0;f=a}finally{try{if(!d&&null!=g["return"])g["return"]()}finally{if(e)throw f}}return c}function r(a){if(Array.isArray(a))return a}function s(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 t(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){s(h,d,e,f,g,"next",a)}function g(a){s(h,d,e,f,g,"throw",a)}f(void 0)})}}var u=function(){var a=t(regeneratorRuntime.mark(function a(){var b;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:a.t0=f.default;a.next=3;return c.default.render("pg_paypal/paypal_button_placeholder",{});case 3:a.t1=a.sent;a.t2={body:a.t1};a.next=7;return a.t0.create.call(a.t0,a.t2);case 7:b=a.sent;b.show();return a.abrupt("return",b);case 10:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}(),v=function(){var a=t(regeneratorRuntime.mark(function a(c,f,i,j,k,m){var n,o,p,q,r;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:a.next=2;return Promise.all([u(),b.getConfigForJs()]);case 2:n=a.sent;o=l(n,2);p=o[0];q=o[1];p.getRoot().on(g.default.hidden,function(){p.destroy()});r="https://www.paypal.com/sdk/js?client-id=".concat(q.clientid,"&currency=").concat(f);w(r,function(){p.setBody("");paypal.Buttons({createOrder:function createOrder(a,b){return b.order.create({purchase_units:[{amount:{currency_code:f,value:c},description:d.default.truncate(k,{length:127,stripTags:!0})}],application_context:{shipping_preference:"NO_SHIPPING",brand_name:d.default.truncate(q.brandname,{length:127,stripTags:!0})}})},onApprove:function onApprove(a){p.getRoot().on(g.default.outsideClick,function(a){a.preventDefault()});p.setBody((0,h.get_string)("authorising","pg_paypal"));return e.default.call([{methodname:"pg_paypal_create_transaction_complete",args:{component:i,componentid:j,orderid:a.orderID}}])[0].then(function(a){p.hide();return m(a)})}}).render(p.getBody()[0])});case 9:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}();a.process=v;var w=function(a,b){if(w.currentlyloaded==a){b();return}if(w.currentlyloaded){var d=document.querySelector("script[src=\"".concat(w.currentlyloaded,"\"]"));if(d){d.parentNode.removeChild(d)}}var c=document.createElement("script");if(c.readyState){c.onreadystatechange=function(){if("complete"==this.readyState||"loaded"==this.readyState){this.onreadystatechange=null;b()}}}else{c.onload=function(){b()}}c.setAttribute("src",a);document.head.appendChild(c);w.currentlyloaded=a};w.currentlyloaded=""});
function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("pg_paypal/gateways_modal",["exports","./repository","core/templates","core/truncate","core/ajax","core/modal_factory","core/modal_events","core/str"],function(a,b,c,d,e,f,g,h){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.process=void 0;b=k(b);c=i(c);d=i(d);e=i(e);f=i(f);g=i(g);function i(a){return a&&a.__esModule?a:{default:a}}function j(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;j=function(){return a};return a}function k(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=j();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var e in a){if(Object.prototype.hasOwnProperty.call(a,e)){var f=d?Object.getOwnPropertyDescriptor(a,e):null;if(f&&(f.get||f.set)){Object.defineProperty(c,e,f)}else{c[e]=a[e]}}}c.default=a;if(b){b.set(a,c)}return c}function l(a,b){return r(a)||q(a,b)||n(a,b)||m()}function m(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function n(a,b){if(!a)return;if("string"==typeof a)return p(a,b);var c=Object.prototype.toString.call(a).slice(8,-1);if("Object"===c&&a.constructor)c=a.constructor.name;if("Map"===c||"Set"===c)return Array.from(c);if("Arguments"===c||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c))return p(a,b)}function p(a,b){if(null==b||b>a.length)b=a.length;for(var c=0,d=Array(b);c<b;c++){d[c]=a[c]}return d}function q(a,b){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(a)))return;var c=[],d=!0,e=!1,f=void 0;try{for(var g=a[Symbol.iterator](),h;!(d=(h=g.next()).done);d=!0){c.push(h.value);if(b&&c.length===b)break}}catch(a){e=!0;f=a}finally{try{if(!d&&null!=g["return"])g["return"]()}finally{if(e)throw f}}return c}function r(a){if(Array.isArray(a))return a}function s(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 t(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){s(h,d,e,f,g,"next",a)}function g(a){s(h,d,e,f,g,"throw",a)}f(void 0)})}}var u=function(){var a=t(regeneratorRuntime.mark(function a(){var b;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:a.t0=f.default;a.next=3;return c.default.render("pg_paypal/paypal_button_placeholder",{});case 3:a.t1=a.sent;a.t2={body:a.t1};a.next=7;return a.t0.create.call(a.t0,a.t2);case 7:b=a.sent;b.show();return a.abrupt("return",b);case 10:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}(),v=function(){var a=t(regeneratorRuntime.mark(function a(c,f,i,j,k,m){var n,o,p,q,r;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:a.next=2;return Promise.all([u(),b.getConfigForJs(i,j)]);case 2:n=a.sent;o=l(n,2);p=o[0];q=o[1];p.getRoot().on(g.default.hidden,function(){p.destroy()});r="https://www.paypal.com/sdk/js?client-id=".concat(q.clientid,"&currency=").concat(f);w(r,function(){p.setBody("");paypal.Buttons({createOrder:function createOrder(a,b){return b.order.create({purchase_units:[{amount:{currency_code:f,value:c},description:d.default.truncate(k,{length:127,stripTags:!0})}],application_context:{shipping_preference:"NO_SHIPPING",brand_name:d.default.truncate(q.brandname,{length:127,stripTags:!0})}})},onApprove:function onApprove(a){p.getRoot().on(g.default.outsideClick,function(a){a.preventDefault()});p.setBody((0,h.get_string)("authorising","pg_paypal"));return e.default.call([{methodname:"pg_paypal_create_transaction_complete",args:{component:i,componentid:j,orderid:a.orderID}}])[0].then(function(a){p.hide();return m(a)})}}).render(p.getBody()[0])});case 9:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}();a.process=v;var w=function(a,b){if(w.currentlyloaded==a){b();return}if(w.currentlyloaded){var d=document.querySelector("script[src=\"".concat(w.currentlyloaded,"\"]"));if(d){d.parentNode.removeChild(d)}}var c=document.createElement("script");if(c.readyState){c.onreadystatechange=function(){if("complete"==this.readyState||"loaded"==this.readyState){this.onreadystatechange=null;b()}}}else{c.onload=function(){b()}}c.setAttribute("src",a);document.head.appendChild(c);w.currentlyloaded=a};w.currentlyloaded=""});
//# sourceMappingURL=gateways_modal.min.js.map
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,2 +1,2 @@
define ("pg_paypal/repository",["exports","core/ajax"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.getConfigForJs=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);var c=function(){return b.default.call([{methodname:"pg_paypal_get_config_for_js",args:{}}])[0]};a.getConfigForJs=c});
define ("pg_paypal/repository",["exports","core/ajax"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.getConfigForJs=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);var c=function(a,c){return b.default.call([{methodname:"pg_paypal_get_config_for_js",args:{component:a,componentid:c}}])[0]};a.getConfigForJs=c});
//# sourceMappingURL=repository.min.js.map
@@ -1 +1 @@
{"version":3,"sources":["../src/repository.js"],"names":["getConfigForJs","Ajax","call","methodname","args"],"mappings":"2JAwBA,uDAOO,GAAMA,CAAAA,CAAc,CAAG,UAAM,CAMhC,MAAOC,WAAKC,IAAL,CAAU,CALD,CACZC,UAAU,CAAE,6BADA,CAEZC,IAAI,CAAE,EAFM,CAKC,CAAV,EAAqB,CAArB,CACV,CAPM,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 * PayPal repository module to encapsulate all of the AJAX requests that can be sent for PayPal.\n *\n * @module pg_paypal/repository\n * @package pg_paypal\n * @copyright 2020 Shamim Rezaie <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Return the PayPal JavaScript SDK URL.\n *\n * @returns {Promise<{clientid: String, brandname: String}>}\n */\nexport const getConfigForJs = () => {\n const request = {\n methodname: 'pg_paypal_get_config_for_js',\n args: {},\n };\n\n return Ajax.call([request])[0];\n};\n"],"file":"repository.min.js"}
{"version":3,"sources":["../src/repository.js"],"names":["getConfigForJs","component","componentid","Ajax","call","methodname","args"],"mappings":"2JAwBA,uDAOO,GAAMA,CAAAA,CAAc,CAAG,SAACC,CAAD,CAAYC,CAAZ,CAA4B,CAMtD,MAAOC,WAAKC,IAAL,CAAU,CALD,CACZC,UAAU,CAAE,6BADA,CAEZC,IAAI,CAAE,CAACL,SAAS,CAATA,CAAD,CAAYC,WAAW,CAAXA,CAAZ,CAFM,CAKC,CAAV,EAAqB,CAArB,CACV,CAPM,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 * PayPal repository module to encapsulate all of the AJAX requests that can be sent for PayPal.\n *\n * @module pg_paypal/repository\n * @package pg_paypal\n * @copyright 2020 Shamim Rezaie <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Return the PayPal JavaScript SDK URL.\n *\n * @returns {Promise<{clientid: String, brandname: String}>}\n */\nexport const getConfigForJs = (component, componentid) => {\n const request = {\n methodname: 'pg_paypal_get_config_for_js',\n args: {component, componentid},\n };\n\n return Ajax.call([request])[0];\n};\n"],"file":"repository.min.js"}
@@ -60,7 +60,7 @@ export const process = async(amount, currency, component, componentid, descripti
paypalConfig,
] = await Promise.all([
showModalWithPlaceholder(),
Repository.getConfigForJs(),
Repository.getConfigForJs(component, componentid),
]);
modal.getRoot().on(ModalEvents.hidden, () => {
+2 -2
View File
@@ -29,10 +29,10 @@ import Ajax from 'core/ajax';
*
* @returns {Promise<{clientid: String, brandname: String}>}
*/
export const getConfigForJs = () => {
export const getConfigForJs = (component, componentid) => {
const request = {
methodname: 'pg_paypal_get_config_for_js',
args: {},
args: {component, componentid},
};
return Ajax.call([request])[0];
@@ -26,6 +26,7 @@ declare(strict_types=1);
namespace pg_paypal\external;
use core_payment\helper;
use external_api;
use external_function_parameters;
use external_value;
@@ -43,7 +44,10 @@ class get_config_for_js extends external_api {
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([]);
return new external_function_parameters([
'component' => new external_value(PARAM_COMPONENT, ''),
'componentid' => new external_value(PARAM_INT, ''),
]);
}
/**
@@ -51,12 +55,17 @@ class get_config_for_js extends external_api {
*
* @return string[]
*/
public static function execute(): array {
$config = get_config('pg_paypal');
public static function execute($component, $componentid): array {
self::validate_parameters(self::execute_parameters(), [
'component' => $component,
'componentid' => $componentid,
]);
$config = helper::get_gateway_configuration($component, $componentid, 'paypal');
return [
'clientid' => $config->clientid,
'brandname' => $config->brandname,
'clientid' => $config['clientid'],
'brandname' => $config['brandname'],
];
}
@@ -26,6 +26,7 @@ declare(strict_types=1);
namespace pg_paypal\external;
use core_payment\helper;
use external_api;
use external_function_parameters;
use external_value;
@@ -69,12 +70,13 @@ class transaction_complete extends external_api {
'orderid' => $orderid,
]);
$config = get_config('pg_paypal');
$config = (object)helper::get_gateway_configuration($component, $componentid, 'paypal');
$sandbox = $config->environment == 'sandbox';
[
'amount' => $amount,
'currency' => $currency
'currency' => $currency,
'accountid' => $accountid,
] = payment_helper::get_cost($component, $componentid);
// Add surcharge if there is any.
@@ -41,4 +41,51 @@ class gateway extends \core_payment\gateway {
'MXN', 'MYR', 'NOK', 'NZD', 'PHP', 'PLN', 'RUB', 'SEK', 'SGD', 'THB', 'TRY', 'TWD', 'USD'
];
}
/**
* Configuration form for the gateway instance
*
* Use $form->get_mform() to access the \MoodleQuickForm instance
*
* @param \core_payment\form\account_gateway $form
*/
public static function add_configuration_to_gateway_form(\core_payment\form\account_gateway $form): void {
$mform = $form->get_mform();
$mform->addElement('text', 'brandname', get_string('brandname', 'pg_paypal'));
$mform->setType('brandname', PARAM_TEXT);
$mform->addHelpButton('brandname', 'brandname', 'pg_paypal');
$mform->addElement('text', 'clientid', get_string('clientid', 'pg_paypal'));
$mform->setType('clientid', PARAM_TEXT);
$mform->addHelpButton('clientid', 'clientid', 'pg_paypal');
$mform->addElement('text', 'secret', get_string('secret', 'pg_paypal'));
$mform->setType('secret', PARAM_TEXT);
$mform->addHelpButton('secret', 'secret', 'pg_paypal');
$options = [
'live' => get_string('live', 'pg_paypal'),
'sandbox' => get_string('sandbox', 'pg_paypal'),
];
$mform->addElement('select', 'environment', get_string('environment', 'pg_paypal'), $options);
$mform->addHelpButton('environment', 'environment', 'pg_paypal');
}
/**
* Validates the gateway configuration form.
*
* @param \core_payment\form\account_gateway $form
* @param \stdClass $data
* @param array $files
* @param array $errors form errors (passed by reference)
*/
public static function validate_gateway_form(\core_payment\form\account_gateway $form,
\stdClass $data, array $files, array &$errors): void {
if ($data->enabled &&
(empty($data->brandname) || empty($data->clientid) || empty($data->secret))) {
$errors['enabled'] = get_string('gatewaycannotbeenabled', 'payment');
}
}
}
-8
View File
@@ -33,14 +33,6 @@ $functions = [
'type' => 'read',
'ajax' => true,
],
'pg_paypal_get_sdk_url' => [
'classname' => 'pg_paypal\external\get_sdk_url',
'methodname' => 'execute',
'classpath' => '',
'description' => 'Generates and returns the URL of the PayPal JavaScript SDK',
'type' => 'read',
'ajax' => true,
],
'pg_paypal_create_transaction_complete' => [
'classname' => 'pg_paypal\external\transaction_complete',
'methodname' => 'execute',
+4 -4
View File
@@ -25,12 +25,12 @@
$string['amountmismatch'] = 'The amount you attempted to pay does not match the required fee. Your account has not been debited.';
$string['authorising'] = 'Authorising the payment. Please wait...';
$string['brandname'] = 'Brand name';
$string['brandname_desc'] = 'The optional label that overrides the business name in the PayPal account on the PayPal site.';
$string['brandname_help'] = 'An optional label that overrides the business name for the PayPal account on the PayPal site.';
$string['cannotfetchorderdatails'] = 'Could not fetch payment details from PayPal. Your account has not been debited.';
$string['clientid'] = 'Client ID';
$string['clientid_desc'] = 'The client ID that PayPal generated for your application.';
$string['clientid_help'] = 'The client ID that PayPal generated for your application.';
$string['environment'] = 'Environment';
$string['environment_desc'] = 'You can set this to Sandbox if you are using sandbox accounts (for testing purpose only).';
$string['environment_help'] = 'You can set this to Sandbox if you are using sandbox accounts (for testing purpose only).';
$string['gatewaydescription'] = 'PayPal is an authorised payment gateway provider for processing credit card transactions.';
$string['gatewayname'] = 'PayPal';
$string['internalerror'] = 'An internal error has occurred. Please contact us.';
@@ -41,4 +41,4 @@ $string['pluginname_desc'] = 'The PayPal plugin allows you to receive payments v
$string['repeatedorder'] = 'This order has already been processed earlier.';
$string['sandbox'] = 'Sandbox';
$string['secret'] = 'Secret';
$string['secret_desc'] = 'The secret thatPayPal generated for your application.';
$string['secret_help'] = 'The secret thatPayPal generated for your application.';
-14
View File
@@ -28,19 +28,5 @@ if ($ADMIN->fulltree) {
$settings->add(new admin_setting_heading('pg_paypal_settings', '', get_string('pluginname_desc', 'pg_paypal')));
$settings->add(new admin_setting_configtext('pg_paypal/brandname', get_string('brandname', 'pg_paypal'),
get_string('brandname', 'pg_paypal'), '', PARAM_TEXT));
$settings->add(new admin_setting_configtext('pg_paypal/clientid', get_string('clientid', 'pg_paypal'),
get_string('clientid_desc', 'pg_paypal'), '', PARAM_TEXT));
$settings->add(new admin_setting_configtext('pg_paypal/secret', get_string('secret', 'pg_paypal'),
get_string('secret_desc', 'pg_paypal'), '', PARAM_TEXT));
$options = [
'live' => get_string('live', 'pg_paypal'),
'sandbox' => get_string('sandbox', 'pg_paypal'),
];
$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');
}
+57
View File
@@ -0,0 +1,57 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Manage one payment accounts
*
* @package core_payment
* @copyright 2020 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../config.php');
require_once($CFG->libdir . '/adminlib.php');
$id = optional_param('id', 0, PARAM_INT);
$delete = optional_param('delete', false, PARAM_BOOL);
$pageurl = new moodle_url('/payment/manage_account.php');
admin_externalpage_setup('paymentaccounts', '', [], $pageurl);
$enabledplugins = \core\plugininfo\pg::get_enabled_plugins();
$account = new \core_payment\account($id);
require_capability('moodle/payment:manageaccounts', $account->get_context());
if ($delete && confirm_sesskey()) {
\core_payment\helper::delete_payment_account($account);
redirect(new moodle_url('/payment/accounts.php'));
}
$PAGE->set_heading($id ? format_string($account->get('name')) : get_string('createaccount', 'payment'));
$form = new \core_payment\form\account($pageurl->out(false), ['persistent' => $account]);
if ($form->is_cancelled()) {
redirect(new moodle_url('/payment/accounts.php'));
} else if ($data = $form->get_data()) {
\core_payment\helper::save_payment_account($data);
redirect(new moodle_url('/payment/accounts.php'));
}
echo $OUTPUT->header();
$form->display();
echo $OUTPUT->footer();
+63
View File
@@ -0,0 +1,63 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Manage one payment gateway
*
* @package core_payment
* @copyright 2020 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../config.php');
require_once($CFG->libdir . '/adminlib.php');
$id = optional_param('id', 0, PARAM_INT);
$accountid = optional_param('accountid', 0, PARAM_INT);
$gatewayname = optional_param('gateway', null, PARAM_COMPONENT);
$pageurl = new moodle_url('/payment/manage_gateway.php');
admin_externalpage_setup('paymentaccounts', '', [], $pageurl);
$enabledplugins = \core\plugininfo\pg::get_enabled_plugins();
if ($id) {
$gateway = new \core_payment\account_gateway($id);
$account = new \core_payment\account($gateway->get('accountid'));
} else if ($accountid) {
$account = new \core_payment\account($accountid);
$gateway = $account->get_gateways()[$gatewayname] ?? null;
}
if (empty($account) || empty($gateway)) {
throw new moodle_exception('gatewaynotfound', 'payment');
}
require_capability('moodle/payment:manageaccounts', $account->get_context());
$PAGE->set_heading($id ? format_string($account->get('name')) : get_string('createaccount', 'payment'));
$form = new \core_payment\form\account_gateway($pageurl->out(false), ['persistent' => $gateway]);
if ($form->is_cancelled()) {
redirect(new moodle_url('/payment/accounts.php'));
} else if ($data = $form->get_data()) {
\core_payment\helper::save_payment_gateway($data);
redirect(new moodle_url('/payment/accounts.php'));
}
echo $OUTPUT->header();
$form->display();
echo $OUTPUT->footer();