--- /dev/null
+<?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']));
$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')));
* 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;
return [
'amount' => (float) $instance->cost,
'currency' => $instance->currency,
+ 'accountid' => $instance->customint1,
];
}
'isguestuser' => isguestuser(),
'cost' => $localisedcost,
'currency' => $instance->currency,
+ 'accountid' => $instance->customint1,
'amount' => $cost,
'instanceid' => $instance->id,
'description' => get_string('purchasedescription', 'enrol_fee',
$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));
"cost": "$108.50",
"amount": 108.50,
"currency": "AUD",
+ "accountid": 1,
"instanceid": 11,
"description": "Enrolment in course Introduction to algorithms",
"isguestuser": false
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 }}
* @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)';
$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';
/**
* Return the persistent object associated with this form instance.
*
- * @return core\persistent
+ * @return \core\persistent
*/
final protected function get_persistent() {
return $this->persistent;
'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' => [
+ ]
+ ],
);
<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"/>
<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"/>
<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"/>
upgrade_main_savepoint(true, 2020102700.00);
}
+ if ($oldversion < 2020102700.01) {
+
+ // 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, 2020102700.01);
+ }
+
return true;
}
--- /dev/null
+<?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();
});
const currency = rootNode.dataset.currency;
- const gateways = await getGatewaysSupportingCurrency(currency);
+ const accountid = rootNode.dataset.accountid;
+ const gateways = await getGatewaysSupportingCurrency(currency, accountid);
const context = {
gateways
};
* 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];
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?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 : [];
+ }
+}
*/
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')]
);
}
* 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)[
--- /dev/null
+<?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();
+ }
+}
--- /dev/null
+<?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);
+ }
+}
* @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');
+ }
+ }
}
$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();
* 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();
*
* @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.
*
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);
+ }
}
/**
* @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;
paypalConfig,
] = await Promise.all([
showModalWithPlaceholder(),
- Repository.getConfigForJs(),
+ Repository.getConfigForJs(component, componentid),
]);
modal.getRoot().on(ModalEvents.hidden, () => {
*
* @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];
namespace pg_paypal\external;
+use core_payment\helper;
use external_api;
use external_function_parameters;
use external_value;
* @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, ''),
+ ]);
}
/**
*
* @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'],
];
}
namespace pg_paypal\external;
+use core_payment\helper;
use external_api;
use external_function_parameters;
use external_value;
'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.
'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');
+ }
+ }
}
'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',
$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.';
$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.';
$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');
}
--- /dev/null
+<?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();
--- /dev/null
+<?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();
defined('MOODLE_INTERNAL') || die();
-$version = 2020102700.00; // YYYYMMDD = weekly release date of this DEV branch.
+$version = 2020102700.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '3.10dev+ (Build: 20201023)';// Human-friendly version name