ÿØÿà JFIF    ÿÛ „  ( %!1"%)+...383-7(-.+  -%%--------+------------/----------------------------ÿÀ  ¶" ÿÄ     ÿÄ @    !1AQaq‘¡"±ÁÑð2’BRráS‚ñ3b¢CT²Ò #cÿÄ    ÿÄ '   1!AQ2a"‘±#ÿÚ   ? ò(/p‘—–¢·,M|¯G»R£üešT. ôŸEoCFñ‡ 4ÔkåóxR|µÁ¨ÓDà!Ç´µ˜‡p ÍQ‹§!þž^õWsŒy  åÁ§$á«%ºq˜™JyyË0y«^Ϗ -3ÃÏËÈ£Æ\P’ä„s&•‹Üs üô'àWt¹pñCp$bÚF`·7.^)¾!)ÒÙ˜–ÅÏš^h¾ø³·ìe±ŒaeÖ—Í,e=B}Jéߦ$$½—šÙÜCC¯¶è8β–Åkèwx LÉngT±æ¹£Ócœ¿Í/©Éÿ ‰ÚCÒ­mq;Tt¶–}0"zÖPcd1š­¤tˆ„ÐÓâqú[™öUCŠ2޿د­É(¸ßúçšmW,Ò ºf‹Ån™ÄLêÁ8üÁkÁ€L¥ÍuJ1œôrÂSŒÓöt!7EUíïb)AËi¬â-ÙHk8òÁiXYwÅ)O^"ÇØriÛô{»wRUKÙÏÚlÓ¬€‚’שT ] ªb—ÊîKC^×M“xùäñz¬zJ× {4[¹M'IÆeH1LCWÕ]œûº WDæà°OÅ‚¹c²ÞuA–rL`HšpCez‡V’— Ž‚Ë„–ñ­'µR0ÕÖ=À:±G»C\nÆÉ5*¢ †3šhQ4ýÒi$Õ1"Ü]¢p-q3zcQ$ªö¨¥æf›‘»´ÝÚHá„e²JÇ–iÊ:·à¬Øc5Åk»Laª*wi [0Ówk ¦a¦0Õ²ÅÅ‚T¸’³q:Æ<¹ú Ò˜Æ}2VE•Ѐp¡Ô3Úº …h³^LJºçì¥Ánó|˜ÖˆÎˆ+« ¦dø‘Mº–d\ªDðÛ„Ì×LÝ——Ð9Ç|•FèçVm™¨€™3õS–9Äå¢<̉Ìm¢±`·º˜&Z²ž Ë®D«¶»6™‰©­HÈ Àá«h­i³04æ’hxœi3ï¨(ÓL·†‹¶ËpŒ ƒÜÒ? :õdsÀ –3æÓ·Üjâ¬9—]8n¼&]I F£¼…ì–—Œ0v°LǐÅfÛ2TÖ’aµ˜N@ÖBSÏ^à´4-±°b×nÈÈœÆD=KdŒø…ÄÈK,›ÖR§fjü$^ÔÎ!„6^ s:Üun\ôkCÞò÷<—Lúl Í›G¹ÀPá¼Nc¡šÒ…ÙWͳœ±vÊáЄ×9‹P‰cEØ‘™›µŸP<×g1 º©Ø¬wiÁ^l5× I/';Ë+´Z‡ÓÄFÕp[Èð’ HÄ ó 9¬Dl4“é±Ï”V=^Hð;žLädÉa‚°Ë,#/Ž~²BÔÛ QãñQtIeórVB,ÏÂf‹4#Μc‹É3ZIÖ Œ¢¥·üxa‡Ãçè„jŠ[5 Ä!U?,3žÎ×…ðdÓ÷háŠA‰ìÄ4÷ÃÜZÃE{‰®+W\ZÍE[‰»µk»MÝ­`¢©†˜ÃV‹-f¢¡†¢a«eŠ%«Y¨©q%jâd,Ôq`) ¤¦…šˆ ¦E>0Ùb²t–Ÿ  ÷jsςҒKÈcø(é›;k(’#ôŒQ ™C> õ³M9óºÆµ¤çâ;uÀ)5>RÔ¸fÓ~Ȧ—’-$fe«"FâUˆÊwµPÏu w+"åÉó¨6s™Û9(À¨ù©hE°½†n`m~“@©›p!Vkhµ Á1šbEqqÊ@ºèl›2 –Yã%‘‚hÛ{a¶‡ÅÞM²¬çL34®Çl]®‹ŽØŒm'RÜe35æöˆ­Á­ cP9šeÁköo´L³Ì=p8]”‡B¶,šº|ɏdzXˆØk*ÇÚ{#ñ‰pã(€¶‡9ý'šÜ³½¯kƒ†Â’ëSOƒ•Å®H6+a¢µˆ‹Y¨b˜b+XˆÖ!°u!¢"µˆˆn2ˆ Å0Ä`Å Ô®c(ÓÜGº•Ä»Œ âWî%q.áÐÄ÷î%umÍ£+ÜQ,Vn¦-GphU¸¢X­&,Gt ·K¢ÅÅ·¥RÄÊÉbKn N­R2g$VµÕó Qr#–ÓZUÏð0ÎtÙÀœz ëöo“Îk¯n„T°"SÞ+³/…€½"ižãO%Í%&Δâ‘ËØ´IˆÓ°Ë‰ÞM3.™yçÁzit›`4C`k¢¼á!álÄï sÂ[×!¤l¾æo"ƒIÔ'@ªu)3›ô®“@Z à¾] üœ'‡4¸PÞkÁ-qÄH‰ÓÍBd´ÿ —¹°ÄA&ÊUC„öz‚‚RæŠtf¬>˜ÑidšEçÑL÷áý¡V±h§­c¿¥¨ƒ@g¼…Ýö^ÞËc.ž„æ“I[ ª+·zÐÒÚ,½Ð»¶€C›7jk$๖€Ž¾ÅÙpp¶ÍþéΤ ½ØÎŒq ñpæžÅ¥#Øâ49ÃÂK^MYV“,¶Éz_òæ:…;Õ«¦I3âJ£¤û5$7Èxün\â]Êe¯(Ÿ&Ž‹¶2<6Ćf× æ¢ƱqWı[(ÙÂŽç‚T7¨@ÈÉÍß‚ïÙ"&3TYlGށ†)†#5ŠA©^T2ÆÁ†)©†©†¤yGXÁ†©"†)©¼ÅV WS†#©]R–r‹q5ÕbâWþBh¯u+ªÅÄ×ü„nÑ^êkªÁj‰jeœWˆÕÕ`µDµ2Ì+Ä µDµµ5Ô{¤Þ0RF’H÷AÛ<ÊÁ§ ƈæ0Ñ£ê4 öÚµ[¬/1²€â<-¬šö²r×0o×w ´xÐÒË„ g01¬„åEM蛇Ã\6µE›‘fÙO k÷CºnÓ1`iîÒ² áÂ!ÑLÄÿ ³¬\õ*:M=Ç»c‹2[‰ØsÕLò\ŒK L^™üÄN\¶#» Ç\……ßïIœÉ$¸ÎñÍ®ÔHÇ Ûí/´>Li”„†g^$ 7NÍÑÑ2M2ªNg=k½Ð}Ÿl6‡ —JWˆ”ÞéT·+µ¦üÂFè¢Vs6ýÆ4»2+2IÝ9ô9®ÇGÙÇ1+Ä8;*Õ§ž½D*îÑWÚçá3Ma¤·ˆ¥t}š²Ü…Q+Æüµ8HíS”üxGéÁˆ¦Ël„éÈ 5 µÄƒ6äÜ(kIš¯S†fÖ&¸®×v|Äyˆ*禌Éù@7-®Ä[]ÎÖ¿ê`º…=:…žJVnݳvðÖKE¼‚ »mà ÷f®:Ë ™–4rð¡4` ܹçž~‹C=œ…¾Ïj|VDtK.ƒ"9 Ï ­–éXá³6WÒïIL-Ї Ç PKJ\]iVrQQpaypal/styles.cssnu[.core_payment_gateways_modal .paypal .icon { height: 40px; width: auto; }PKJ\[{{paypal/db/services.phpnu[. /** * External functions and service definitions for the PayPal payment gateway plugin. * * @package paygw_paypal * @copyright 2020 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $functions = [ 'paygw_paypal_get_config_for_js' => [ 'classname' => 'paygw_paypal\external\get_config_for_js', 'classpath' => '', 'description' => 'Returns the configuration settings to be used in js', 'type' => 'read', 'ajax' => true, ], 'paygw_paypal_create_transaction_complete' => [ 'classname' => 'paygw_paypal\external\transaction_complete', 'classpath' => '', 'description' => 'Takes care of what needs to be done when a PayPal transaction comes back as complete.', 'type' => 'write', 'ajax' => true, 'loginrequired' => false, ], ]; PKJ\ paypal/db/install.phpnu[. /** * paygw_paypal installer script. * * @package paygw_paypal * @copyright 2020 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ function xmldb_paygw_paypal_install() { global $CFG; // Enable the Paypal payment gateway on installation. It still needs to be configured and enabled for accounts. $order = (!empty($CFG->paygw_plugins_sortorder)) ? explode(',', $CFG->paygw_plugins_sortorder) : []; set_config('paygw_plugins_sortorder', join(',', array_merge($order, ['paypal']))); } PKJ\ݗvvpaypal/db/upgrade.phpnu[. /** * Upgrade script for paygw_paypal. * * @package paygw_paypal * @copyright 2021 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ /** * Upgrade the plugin. * * @param int $oldversion the version we are upgrading from * @return bool always true */ function xmldb_paygw_paypal_upgrade(int $oldversion): bool { global $DB; $dbman = $DB->get_manager(); if ($oldversion < 2021052501) { // Define key paymentid (foreign-unique) to be added to paygw_paypal. $table = new xmldb_table('paygw_paypal'); $key = new xmldb_key('paymentid', XMLDB_KEY_FOREIGN_UNIQUE, ['paymentid'], 'payments', ['id']); // Launch add key paymentid. $dbman->add_key($table, $key); // Paypal savepoint reached. upgrade_plugin_savepoint(true, 2021052501, 'paygw', 'paypal'); } // Automatically generated Moodle v4.2.0 release upgrade line. // Put any upgrade step following this. // Automatically generated Moodle v4.3.0 release upgrade line. // Put any upgrade step following this. // Automatically generated Moodle v4.4.0 release upgrade line. // Put any upgrade step following this. // Automatically generated Moodle v4.5.0 release upgrade line. // Put any upgrade step following this. // Automatically generated Moodle v5.0.0 release upgrade line. // Put any upgrade step following this. return true; } PKJ\㻠paypal/db/install.xmlnu[
PKJ\R^ paypal/lang/en/paygw_paypal.phpnu[. /** * Strings for component 'paygw_paypal', language 'en' * * @package paygw_paypal * @copyright 2019 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ $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_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_help'] = 'The client ID that PayPal generated for your application.'; $string['environment'] = 'Environment'; $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['live'] = 'Live'; $string['paymentnotcleared'] = 'payment not cleared by PayPal.'; $string['pluginname'] = 'PayPal'; $string['pluginname_desc'] = 'The PayPal plugin allows you to receive payments via PayPal.'; $string['privacy:metadata'] = 'The PayPal plugin does not store any personal data.'; $string['repeatedorder'] = 'This order has already been processed earlier.'; $string['sandbox'] = 'Sandbox'; $string['secret'] = 'Secret'; $string['secret_help'] = 'The secret that PayPal generated for your application.'; PKJ\R7҃҃paypal/pix/img.svgnu[ PKJ\<Zpaypal/version.phpnu[. /** * Version information * * @package paygw_paypal * @copyright 2019 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX). $plugin->requires = 2025040800; // Requires this Moodle version. $plugin->component = 'paygw_paypal'; // Full name of the plugin (used for diagnostics). PKJ\y0paypal/classes/external/transaction_complete.phpnu[. /** * This class contains a list of webservice functions related to the PayPal payment gateway. * * @package paygw_paypal * @copyright 2020 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ declare(strict_types=1); namespace paygw_paypal\external; use core_external\external_api; use core_external\external_value; use core_external\external_function_parameters; use core_payment\helper; use core_payment\helper as payment_helper; use paygw_paypal\paypal_helper; class transaction_complete extends external_api { /** * Returns description of method parameters. * * @return external_function_parameters */ public static function execute_parameters() { return new external_function_parameters([ 'component' => new external_value(PARAM_COMPONENT, 'The component name'), 'paymentarea' => new external_value(PARAM_AREA, 'Payment area in the component'), 'itemid' => new external_value(PARAM_INT, 'The item id in the context of the component area'), 'orderid' => new external_value(PARAM_TEXT, 'The order id coming back from PayPal'), ]); } /** * Perform what needs to be done when a transaction is reported to be complete. * This function does not take cost as a parameter as we cannot rely on any provided value. * * @param string $component Name of the component that the itemid belongs to * @param string $paymentarea * @param int $itemid An internal identifier that is used by the component * @param string $orderid PayPal order ID * @return array */ public static function execute(string $component, string $paymentarea, int $itemid, string $orderid): array { global $USER, $DB; self::validate_parameters(self::execute_parameters(), [ 'component' => $component, 'paymentarea' => $paymentarea, 'itemid' => $itemid, 'orderid' => $orderid, ]); $config = (object)helper::get_gateway_configuration($component, $paymentarea, $itemid, 'paypal'); $sandbox = $config->environment == 'sandbox'; $payable = payment_helper::get_payable($component, $paymentarea, $itemid); $currency = $payable->get_currency(); // Add surcharge if there is any. $surcharge = helper::get_gateway_surcharge('paypal'); $amount = helper::get_rounded_cost($payable->get_amount(), $currency, $surcharge); $paypalhelper = new paypal_helper($config->clientid, $config->secret, $sandbox); $orderdetails = $paypalhelper->get_order_details($orderid); $success = false; $message = ''; if ($orderdetails) { if ($orderdetails['status'] == paypal_helper::ORDER_STATUS_APPROVED && $orderdetails['intent'] == paypal_helper::ORDER_INTENT_CAPTURE) { $item = $orderdetails['purchase_units'][0]; if ($item['amount']['value'] == $amount && $item['amount']['currency_code'] == $currency) { $capture = $paypalhelper->capture_order($orderid); if ($capture && $capture['status'] == paypal_helper::CAPTURE_STATUS_COMPLETED) { $success = true; // Everything is correct. Let's give them what they paid for. try { $paymentid = payment_helper::save_payment($payable->get_account_id(), $component, $paymentarea, $itemid, (int) $USER->id, $amount, $currency, 'paypal'); // Store PayPal extra information. $record = new \stdClass(); $record->paymentid = $paymentid; $record->pp_orderid = $orderid; $DB->insert_record('paygw_paypal', $record); payment_helper::deliver_order($component, $paymentarea, $itemid, $paymentid, (int) $USER->id); } catch (\Exception $e) { debugging('Exception while trying to process payment: ' . $e->getMessage(), DEBUG_DEVELOPER); $success = false; $message = get_string('internalerror', 'paygw_paypal'); } } else { $success = false; $message = get_string('paymentnotcleared', 'paygw_paypal'); } } else { $success = false; $message = get_string('amountmismatch', 'paygw_paypal'); } } else { $success = false; $message = get_string('paymentnotcleared', 'paygw_paypal'); } } else { // Could not capture authorization! $success = false; $message = get_string('cannotfetchorderdatails', 'paygw_paypal'); } return [ 'success' => $success, 'message' => $message, ]; } /** * Returns description of method result value. * * @return external_function_parameters */ public static function execute_returns() { return new external_function_parameters([ 'success' => new external_value(PARAM_BOOL, 'Whether everything was successful or not.'), 'message' => new external_value(PARAM_RAW, 'Message (usually the error message).'), ]); } } PKJ\0 0 -paypal/classes/external/get_config_for_js.phpnu[. /** * This class contains a list of webservice functions related to the PayPal payment gateway. * * @package paygw_paypal * @copyright 2020 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ declare(strict_types=1); namespace paygw_paypal\external; use core_payment\helper; use core_external\external_api; use core_external\external_function_parameters; use core_external\external_value; use core_external\external_single_structure; class get_config_for_js extends external_api { /** * Returns description of method parameters. * * @return external_function_parameters */ public static function execute_parameters(): external_function_parameters { return new external_function_parameters([ 'component' => new external_value(PARAM_COMPONENT, 'Component'), 'paymentarea' => new external_value(PARAM_AREA, 'Payment area in the component'), 'itemid' => new external_value(PARAM_INT, 'An identifier for payment area in the component'), ]); } /** * Returns the config values required by the PayPal JavaScript SDK. * * @param string $component * @param string $paymentarea * @param int $itemid * @return string[] */ public static function execute(string $component, string $paymentarea, int $itemid): array { self::validate_parameters(self::execute_parameters(), [ 'component' => $component, 'paymentarea' => $paymentarea, 'itemid' => $itemid, ]); $config = helper::get_gateway_configuration($component, $paymentarea, $itemid, 'paypal'); $payable = helper::get_payable($component, $paymentarea, $itemid); $surcharge = helper::get_gateway_surcharge('paypal'); return [ 'clientid' => $config['clientid'], 'brandname' => $config['brandname'], 'cost' => helper::get_rounded_cost($payable->get_amount(), $payable->get_currency(), $surcharge), 'currency' => $payable->get_currency(), ]; } /** * Returns description of method result value. * * @return external_single_structure */ public static function execute_returns(): external_single_structure { return new external_single_structure([ 'clientid' => new external_value(PARAM_TEXT, 'PayPal client ID'), 'brandname' => new external_value(PARAM_TEXT, 'Brand name'), 'cost' => new external_value(PARAM_FLOAT, 'Cost with gateway surcharge'), 'currency' => new external_value(PARAM_TEXT, 'Currency'), ]); } } PKJ\ȭ  #paypal/classes/privacy/provider.phpnu[. /** * Privacy Subsystem implementation for paygw_paypal. * * @package paygw_paypal * @category privacy * @copyright 2020 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace paygw_paypal\privacy; use core_payment\privacy\paygw_provider; use core_privacy\local\request\writer; /** * Privacy Subsystem implementation for paygw_paypal. * * @copyright 2020 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class provider implements \core_privacy\local\metadata\null_provider, paygw_provider { /** * Get the language string identifier with the component's language * file to explain why this plugin stores no data. * * @return string */ public static function get_reason(): string { return 'privacy:metadata'; } /** * Export all user data for the specified payment record, and the given context. * * @param \context $context Context * @param array $subcontext The location within the current context that the payment data belongs * @param \stdClass $payment The payment record */ public static function export_payment_data(\context $context, array $subcontext, \stdClass $payment) { global $DB; $subcontext[] = get_string('gatewayname', 'paygw_paypal'); $record = $DB->get_record('paygw_paypal', ['paymentid' => $payment->id]); $data = (object) [ 'orderid' => $record->pp_orderid, ]; writer::with_context($context)->export_data( $subcontext, $data ); } /** * Delete all user data related to the given payments. * * @param string $paymentsql SQL query that selects payment.id field for the payments * @param array $paymentparams Array of parameters for $paymentsql */ public static function delete_data_for_payment_sql(string $paymentsql, array $paymentparams) { global $DB; $DB->delete_records_select('paygw_paypal', "paymentid IN ({$paymentsql})", $paymentparams); } } PKJ\? paypal/classes/paypal_helper.phpnu[. /** * Contains helper class to work with PayPal REST API. * * @package core_payment * @copyright 2020 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace paygw_paypal; use curl; defined('MOODLE_INTERNAL') || die(); require_once($CFG->libdir . '/filelib.php'); class paypal_helper { /** * @var string The payment was authorized or the authorized payment was captured for the order. */ public const CAPTURE_STATUS_COMPLETED = 'COMPLETED'; /** * @var string The merchant intends to capture payment immediately after the customer makes a payment. */ public const ORDER_INTENT_CAPTURE = 'CAPTURE'; /** * @var string The customer approved the payment. */ public const ORDER_STATUS_APPROVED = 'APPROVED'; /** * @var string The base API URL */ private $baseurl; /** * @var string Client ID */ private $clientid; /** * @var string PayPal App secret */ private $secret; /** * @var string The oath bearer token */ private $token; /** * helper constructor. * * @param string $clientid The client id. * @param string $secret PayPal secret. * @param bool $sandbox Whether we are working with the sandbox environment or not. */ public function __construct(string $clientid, string $secret, bool $sandbox) { $this->clientid = $clientid; $this->secret = $secret; $this->baseurl = $sandbox ? 'https://api.sandbox.paypal.com' : 'https://api.paypal.com'; $this->token = $this->get_token(); } /** * Captures an authorized payment, by ID. * * @param string $authorizationid The PayPal-generated ID for the authorized payment to capture. * @param float $amount The amount to capture. * @param string $currency The currency code for the amount. * @param bool $final Indicates whether this is the final captures against the authorized payment. * @return array|null Formatted API response. */ public function capture_authorization(string $authorizationid, float $amount, string $currency, bool $final = true): ?array { $location = "{$this->baseurl}/v2/payments/authorizations/{$authorizationid}/capture"; $options = [ 'CURLOPT_RETURNTRANSFER' => true, 'CURLOPT_TIMEOUT' => 30, 'CURLOPT_HTTP_VERSION' => CURL_HTTP_VERSION_1_1, 'CURLOPT_SSLVERSION' => CURL_SSLVERSION_TLSv1_2, 'CURLOPT_HTTPHEADER' => [ 'Content-Type: application/json', "Authorization: Bearer {$this->token}", ], ]; $command = [ 'amount' => [ 'value' => (string) $amount, 'currency_code' => $currency, ], 'final_capture' => $final, ]; $command = json_encode($command); $curl = new curl(); $result = $curl->post($location, $command, $options); return json_decode($result, true); } /** * Captures order details from PayPal. * * @param string $orderid The order we want to capture. * @return array|null Formatted API response. */ public function capture_order(string $orderid): ?array { $location = "{$this->baseurl}/v2/checkout/orders/{$orderid}/capture"; $options = [ 'CURLOPT_RETURNTRANSFER' => true, 'CURLOPT_TIMEOUT' => 30, 'CURLOPT_HTTP_VERSION' => CURL_HTTP_VERSION_1_1, 'CURLOPT_SSLVERSION' => CURL_SSLVERSION_TLSv1_2, 'CURLOPT_HTTPHEADER' => [ 'Content-Type: application/json', "Authorization: Bearer {$this->token}", ], ]; $command = '{}'; $curl = new curl(); $result = $curl->post($location, $command, $options); return json_decode($result, true); } public function get_order_details(string $orderid): ?array { $location = "{$this->baseurl}/v2/checkout/orders/{$orderid}"; $options = [ 'CURLOPT_RETURNTRANSFER' => true, 'CURLOPT_TIMEOUT' => 30, 'CURLOPT_HTTP_VERSION' => CURL_HTTP_VERSION_1_1, 'CURLOPT_SSLVERSION' => CURL_SSLVERSION_TLSv1_2, 'CURLOPT_HTTPHEADER' => [ 'Content-Type: application/json', "Authorization: Bearer {$this->token}", ], ]; $curl = new curl(); $result = $curl->get($location, [], $options); return json_decode($result, true); } /** * Request for PayPal REST oath bearer token. * * @return string */ private function get_token(): string { $location = "{$this->baseurl}/v1/oauth2/token"; $options = [ 'CURLOPT_RETURNTRANSFER' => true, 'CURLOPT_TIMEOUT' => 30, 'CURLOPT_HTTP_VERSION' => CURL_HTTP_VERSION_1_1, 'CURLOPT_SSLVERSION' => CURL_SSLVERSION_TLSv1_2, 'CURLOPT_USERPWD' => "{$this->clientid}:{$this->secret}", ]; $command = 'grant_type=client_credentials'; $curl = new curl(); $result = $curl->post($location, $command, $options); $result = json_decode($result, true); return $result['access_token']; } }PKJ\!!paypal/classes/gateway.phpnu[. /** * Contains class for PayPal payment gateway. * * @package paygw_paypal * @copyright 2019 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace paygw_paypal; /** * The gateway class for PayPal payment gateway. * * @copyright 2019 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class gateway extends \core_payment\gateway { public static function get_supported_currencies(): array { // See https://developer.paypal.com/docs/api/reference/currency-codes/, // 3-character ISO-4217: https://en.wikipedia.org/wiki/ISO_4217#Active_codes. return [ 'AUD', 'BRL', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD', 'HUF', 'ILS', 'INR', 'JPY', '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', 'paygw_paypal')); $mform->setType('brandname', PARAM_TEXT); $mform->addHelpButton('brandname', 'brandname', 'paygw_paypal'); $mform->addElement('text', 'clientid', get_string('clientid', 'paygw_paypal')); $mform->setType('clientid', PARAM_TEXT); $mform->addHelpButton('clientid', 'clientid', 'paygw_paypal'); $mform->addElement('text', 'secret', get_string('secret', 'paygw_paypal')); $mform->setType('secret', PARAM_TEXT); $mform->addHelpButton('secret', 'secret', 'paygw_paypal'); $options = [ 'live' => get_string('live', 'paygw_paypal'), 'sandbox' => get_string('sandbox', 'paygw_paypal'), ]; $mform->addElement('select', 'environment', get_string('environment', 'paygw_paypal'), $options); $mform->addHelpButton('environment', 'environment', 'paygw_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'); } } } PKJ\ 3paypal/templates/paypal_button_placeholder.mustachenu[{{! 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 . }} {{! @template paygw_paypal/paypal_button_placeholder Classes required for JS: * none Data attributes required for JS: * none Context variables required for this template: * none Example context (json): {} }}
PKJ\! paypal/amd/src/gateways_modal.jsnu[// 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 . /** * This module is responsible for PayPal content in the gateways modal. * * @module paygw_paypal/gateways_modal * @copyright 2020 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ import * as Repository from './repository'; import Templates from 'core/templates'; import Truncate from 'core/truncate'; import Modal from 'core/modal'; import ModalEvents from 'core/modal_events'; import {getString} from 'core/str'; /** * Creates and shows a modal that contains a placeholder. * * @returns {Promise} */ const showModalWithPlaceholder = async() => await Modal.create({ body: await Templates.render('paygw_paypal/paypal_button_placeholder', {}), show: true, removeOnClose: true, }); /** * Process the payment. * * @param {string} component Name of the component that the itemId belongs to * @param {string} paymentArea The area of the component that the itemId belongs to * @param {number} itemId An internal identifier that is used by the component * @param {string} description Description of the payment * @returns {Promise} */ export const process = (component, paymentArea, itemId, description) => { return Promise.all([ showModalWithPlaceholder(), Repository.getConfigForJs(component, paymentArea, itemId), ]) .then(([modal, paypalConfig]) => { return Promise.all([ modal, paypalConfig, switchSdk(paypalConfig.clientid, paypalConfig.currency), ]); }) .then(([modal, paypalConfig]) => { // We have to clear the body. The render method in paypal.Buttons will render everything. modal.setBody(''); return new Promise(resolve => { window.paypal.Buttons({ // Set up the transaction. createOrder: function(data, actions) { return actions.order.create({ purchase_units: [{ // eslint-disable-line amount: { currency_code: paypalConfig.currency_code, // eslint-disable-line value: paypalConfig.cost, }, description: Truncate.truncate(description, {length: 127, stripTags: true}), }], application_context: { // eslint-disable-line shipping_preference: 'NO_SHIPPING', // eslint-disable-line brand_name: Truncate.truncate(paypalConfig.brandname, {length: 127, stripTags: true}), // eslint-disable-line }, }); }, // Finalise the transaction. onApprove: function(data) { modal.getRoot().on(ModalEvents.outsideClick, (e) => { // Prevent closing the modal when clicking outside of it. e.preventDefault(); }); modal.setBody(getString('authorising', 'paygw_paypal')); Repository.markTransactionComplete(component, paymentArea, itemId, data.orderID) .then(res => { modal.hide(); return res; }) .then(resolve); } }).render(modal.getBody()[0]); }); }) .then(res => { if (res.success) { return Promise.resolve(res.message); } return Promise.reject(res.message); }); }; /** * Unloads the previously loaded PayPal JavaScript SDK, and loads a new one. * * @param {string} clientId PayPal client ID * @param {string} currency The currency * @returns {Promise} */ const switchSdk = (clientId, currency) => { const sdkUrl = `https://www.paypal.com/sdk/js?client-id=${clientId}¤cy=${currency}`; // Check to see if this file has already been loaded. If so just go straight to the func. if (switchSdk.currentlyloaded === sdkUrl) { return Promise.resolve(); } // PayPal can only work with one currency at the same time. We have to unload the previously loaded script // if it was loaded for a different currency. Weird way indeed, but the only way. // See: https://github.com/paypal/paypal-checkout-components/issues/1180 if (switchSdk.currentlyloaded) { const suspectedScript = document.querySelector(`script[src="${switchSdk.currentlyloaded}"]`); if (suspectedScript) { suspectedScript.parentNode.removeChild(suspectedScript); } } const script = document.createElement('script'); return new Promise(resolve => { if (script.readyState) { script.onreadystatechange = function() { if (this.readyState == 'complete' || this.readyState == 'loaded') { this.onreadystatechange = null; resolve(); } }; } else { script.onload = function() { resolve(); }; } script.setAttribute('src', sdkUrl); document.head.appendChild(script); switchSdk.currentlyloaded = sdkUrl; }); }; /** * Holds the full url of loaded PayPal JavaScript SDK. * * @static * @type {string} */ switchSdk.currentlyloaded = ''; PKJ\8U paypal/amd/src/repository.jsnu[// 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 . /** * PayPal repository module to encapsulate all of the AJAX requests that can be sent for PayPal. * * @module paygw_paypal/repository * @copyright 2020 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ import Ajax from 'core/ajax'; /** * Return the PayPal JavaScript SDK URL. * * @param {string} component Name of the component that the itemId belongs to * @param {string} paymentArea The area of the component that the itemId belongs to * @param {number} itemId An internal identifier that is used by the component * @returns {Promise<{clientid: string, brandname: string, cost: number, currency: string}>} */ export const getConfigForJs = (component, paymentArea, itemId) => { const request = { methodname: 'paygw_paypal_get_config_for_js', args: { component, paymentarea: paymentArea, itemid: itemId, }, }; return Ajax.call([request])[0]; }; /** * Call server to validate and capture payment for order. * * @param {string} component Name of the component that the itemId belongs to * @param {string} paymentArea The area of the component that the itemId belongs to * @param {number} itemId An internal identifier that is used by the component * @param {string} orderId The order id coming back from PayPal * @returns {*} */ export const markTransactionComplete = (component, paymentArea, itemId, orderId) => { const request = { methodname: 'paygw_paypal_create_transaction_complete', args: { component, paymentarea: paymentArea, itemid: itemId, orderid: orderId, }, }; return Ajax.call([request])[0]; }; PKJ\\<<"paypal/amd/build/repository.min.jsnu[define("paygw_paypal/repository",["exports","core/ajax"],(function(_exports,_ajax){var obj; /** * PayPal repository module to encapsulate all of the AJAX requests that can be sent for PayPal. * * @module paygw_paypal/repository * @copyright 2020 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.markTransactionComplete=_exports.getConfigForJs=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};_exports.getConfigForJs=(component,paymentArea,itemId)=>{const request={methodname:"paygw_paypal_get_config_for_js",args:{component:component,paymentarea:paymentArea,itemid:itemId}};return _ajax.default.call([request])[0]};_exports.markTransactionComplete=(component,paymentArea,itemId,orderId)=>{const request={methodname:"paygw_paypal_create_transaction_complete",args:{component:component,paymentarea:paymentArea,itemid:itemId,orderid:orderId}};return _ajax.default.call([request])[0]}})); //# sourceMappingURL=repository.min.js.mapPKJ\)&paypal/amd/build/gateways_modal.min.jsnu[define("paygw_paypal/gateways_modal",["exports","./repository","core/templates","core/truncate","core/modal","core/modal_events","core/str"],(function(_exports,Repository,_templates,_truncate,_modal,_modal_events,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.process=void 0,Repository=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj} /** * This module is responsible for PayPal content in the gateways modal. * * @module paygw_paypal/gateways_modal * @copyright 2020 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */(Repository),_templates=_interopRequireDefault(_templates),_truncate=_interopRequireDefault(_truncate),_modal=_interopRequireDefault(_modal),_modal_events=_interopRequireDefault(_modal_events);const showModalWithPlaceholder=async()=>await _modal.default.create({body:await _templates.default.render("paygw_paypal/paypal_button_placeholder",{}),show:!0,removeOnClose:!0});_exports.process=(component,paymentArea,itemId,description)=>Promise.all([showModalWithPlaceholder(),Repository.getConfigForJs(component,paymentArea,itemId)]).then((_ref=>{let[modal,paypalConfig]=_ref;return Promise.all([modal,paypalConfig,switchSdk(paypalConfig.clientid,paypalConfig.currency)])})).then((_ref2=>{let[modal,paypalConfig]=_ref2;return modal.setBody(""),new Promise((resolve=>{window.paypal.Buttons({createOrder:function(data,actions){return actions.order.create({purchase_units:[{amount:{currency_code:paypalConfig.currency_code,value:paypalConfig.cost},description:_truncate.default.truncate(description,{length:127,stripTags:!0})}],application_context:{shipping_preference:"NO_SHIPPING",brand_name:_truncate.default.truncate(paypalConfig.brandname,{length:127,stripTags:!0})}})},onApprove:function(data){modal.getRoot().on(_modal_events.default.outsideClick,(e=>{e.preventDefault()})),modal.setBody((0,_str.getString)("authorising","paygw_paypal")),Repository.markTransactionComplete(component,paymentArea,itemId,data.orderID).then((res=>(modal.hide(),res))).then(resolve)}}).render(modal.getBody()[0])}))})).then((res=>res.success?Promise.resolve(res.message):Promise.reject(res.message)));const switchSdk=(clientId,currency)=>{const sdkUrl="https://www.paypal.com/sdk/js?client-id=".concat(clientId,"¤cy=").concat(currency);if(switchSdk.currentlyloaded===sdkUrl)return Promise.resolve();if(switchSdk.currentlyloaded){const suspectedScript=document.querySelector('script[src="'.concat(switchSdk.currentlyloaded,'"]'));suspectedScript&&suspectedScript.parentNode.removeChild(suspectedScript)}const script=document.createElement("script");return new Promise((resolve=>{script.readyState?script.onreadystatechange=function(){"complete"!=this.readyState&&"loaded"!=this.readyState||(this.onreadystatechange=null,resolve())}:script.onload=function(){resolve()},script.setAttribute("src",sdkUrl),document.head.appendChild(script),switchSdk.currentlyloaded=sdkUrl}))};switchSdk.currentlyloaded=""})); //# sourceMappingURL=gateways_modal.min.js.mapPKJ\铊 &paypal/amd/build/repository.min.js.mapnu[{"version":3,"file":"repository.min.js","sources":["../src/repository.js"],"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 .\n\n/**\n * PayPal repository module to encapsulate all of the AJAX requests that can be sent for PayPal.\n *\n * @module paygw_paypal/repository\n * @copyright 2020 Shamim Rezaie \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 * @param {string} component Name of the component that the itemId belongs to\n * @param {string} paymentArea The area of the component that the itemId belongs to\n * @param {number} itemId An internal identifier that is used by the component\n * @returns {Promise<{clientid: string, brandname: string, cost: number, currency: string}>}\n */\nexport const getConfigForJs = (component, paymentArea, itemId) => {\n const request = {\n methodname: 'paygw_paypal_get_config_for_js',\n args: {\n component,\n paymentarea: paymentArea,\n itemid: itemId,\n },\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Call server to validate and capture payment for order.\n *\n * @param {string} component Name of the component that the itemId belongs to\n * @param {string} paymentArea The area of the component that the itemId belongs to\n * @param {number} itemId An internal identifier that is used by the component\n * @param {string} orderId The order id coming back from PayPal\n * @returns {*}\n */\nexport const markTransactionComplete = (component, paymentArea, itemId, orderId) => {\n const request = {\n methodname: 'paygw_paypal_create_transaction_complete',\n args: {\n component,\n paymentarea: paymentArea,\n itemid: itemId,\n orderid: orderId,\n },\n };\n\n return Ajax.call([request])[0];\n};\n"],"names":["component","paymentArea","itemId","request","methodname","args","paymentarea","itemid","Ajax","call","orderId","orderid"],"mappings":";;;;;;;yMAiC8B,CAACA,UAAWC,YAAaC,gBAC7CC,QAAU,CACZC,WAAY,iCACZC,KAAM,CACFL,UAAAA,UACAM,YAAaL,YACbM,OAAQL,gBAITM,cAAKC,KAAK,CAACN,UAAU,qCAYO,CAACH,UAAWC,YAAaC,OAAQQ,iBAC9DP,QAAU,CACZC,WAAY,2CACZC,KAAM,CACFL,UAAAA,UACAM,YAAaL,YACbM,OAAQL,OACRS,QAASD,iBAIVF,cAAKC,KAAK,CAACN,UAAU"}PKJ\:7!!*paypal/amd/build/gateways_modal.min.js.mapnu[{"version":3,"file":"gateways_modal.min.js","sources":["../src/gateways_modal.js"],"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 .\n\n/**\n * This module is responsible for PayPal content in the gateways modal.\n *\n * @module paygw_paypal/gateways_modal\n * @copyright 2020 Shamim Rezaie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport * as Repository from './repository';\nimport Templates from 'core/templates';\nimport Truncate from 'core/truncate';\nimport Modal from 'core/modal';\nimport ModalEvents from 'core/modal_events';\nimport {getString} from 'core/str';\n\n/**\n * Creates and shows a modal that contains a placeholder.\n *\n * @returns {Promise}\n */\nconst showModalWithPlaceholder = async() => await Modal.create({\n body: await Templates.render('paygw_paypal/paypal_button_placeholder', {}),\n show: true,\n removeOnClose: true,\n});\n\n/**\n * Process the payment.\n *\n * @param {string} component Name of the component that the itemId belongs to\n * @param {string} paymentArea The area of the component that the itemId belongs to\n * @param {number} itemId An internal identifier that is used by the component\n * @param {string} description Description of the payment\n * @returns {Promise}\n */\nexport const process = (component, paymentArea, itemId, description) => {\n return Promise.all([\n showModalWithPlaceholder(),\n Repository.getConfigForJs(component, paymentArea, itemId),\n ])\n .then(([modal, paypalConfig]) => {\n return Promise.all([\n modal,\n paypalConfig,\n switchSdk(paypalConfig.clientid, paypalConfig.currency),\n ]);\n })\n .then(([modal, paypalConfig]) => {\n // We have to clear the body. The render method in paypal.Buttons will render everything.\n modal.setBody('');\n\n return new Promise(resolve => {\n window.paypal.Buttons({\n // Set up the transaction.\n createOrder: function(data, actions) {\n return actions.order.create({\n purchase_units: [{ // eslint-disable-line\n amount: {\n currency_code: paypalConfig.currency_code, // eslint-disable-line\n value: paypalConfig.cost,\n },\n description: Truncate.truncate(description, {length: 127, stripTags: true}),\n }],\n application_context: { // eslint-disable-line\n shipping_preference: 'NO_SHIPPING', // eslint-disable-line\n brand_name: Truncate.truncate(paypalConfig.brandname, {length: 127, stripTags: true}), // eslint-disable-line\n },\n });\n },\n // Finalise the transaction.\n onApprove: function(data) {\n modal.getRoot().on(ModalEvents.outsideClick, (e) => {\n // Prevent closing the modal when clicking outside of it.\n e.preventDefault();\n });\n\n modal.setBody(getString('authorising', 'paygw_paypal'));\n\n Repository.markTransactionComplete(component, paymentArea, itemId, data.orderID)\n .then(res => {\n modal.hide();\n return res;\n })\n .then(resolve);\n }\n }).render(modal.getBody()[0]);\n });\n })\n .then(res => {\n if (res.success) {\n return Promise.resolve(res.message);\n }\n\n return Promise.reject(res.message);\n });\n};\n\n/**\n * Unloads the previously loaded PayPal JavaScript SDK, and loads a new one.\n *\n * @param {string} clientId PayPal client ID\n * @param {string} currency The currency\n * @returns {Promise}\n */\nconst switchSdk = (clientId, currency) => {\n const sdkUrl = `https://www.paypal.com/sdk/js?client-id=${clientId}¤cy=${currency}`;\n\n // Check to see if this file has already been loaded. If so just go straight to the func.\n if (switchSdk.currentlyloaded === sdkUrl) {\n return Promise.resolve();\n }\n\n // PayPal can only work with one currency at the same time. We have to unload the previously loaded script\n // if it was loaded for a different currency. Weird way indeed, but the only way.\n // See: https://github.com/paypal/paypal-checkout-components/issues/1180\n if (switchSdk.currentlyloaded) {\n const suspectedScript = document.querySelector(`script[src=\"${switchSdk.currentlyloaded}\"]`);\n if (suspectedScript) {\n suspectedScript.parentNode.removeChild(suspectedScript);\n }\n }\n\n const script = document.createElement('script');\n\n return new Promise(resolve => {\n if (script.readyState) {\n script.onreadystatechange = function() {\n if (this.readyState == 'complete' || this.readyState == 'loaded') {\n this.onreadystatechange = null;\n resolve();\n }\n };\n } else {\n script.onload = function() {\n resolve();\n };\n }\n\n script.setAttribute('src', sdkUrl);\n document.head.appendChild(script);\n\n switchSdk.currentlyloaded = sdkUrl;\n });\n};\n\n/**\n * Holds the full url of loaded PayPal JavaScript SDK.\n *\n * @static\n * @type {string}\n */\nswitchSdk.currentlyloaded = '';\n"],"names":["showModalWithPlaceholder","async","Modal","create","body","Templates","render","show","removeOnClose","component","paymentArea","itemId","description","Promise","all","Repository","getConfigForJs","then","_ref","modal","paypalConfig","switchSdk","clientid","currency","_ref2","setBody","resolve","window","paypal","Buttons","createOrder","data","actions","order","purchase_units","amount","currency_code","value","cost","Truncate","truncate","length","stripTags","application_context","shipping_preference","brand_name","brandname","onApprove","getRoot","on","ModalEvents","outsideClick","e","preventDefault","markTransactionComplete","orderID","res","hide","getBody","success","message","reject","clientId","sdkUrl","currentlyloaded","suspectedScript","document","querySelector","parentNode","removeChild","script","createElement","readyState","onreadystatechange","this","onload","setAttribute","head","appendChild"],"mappings":";;;;;;;4MAmCMA,yBAA2BC,eAAiBC,eAAMC,OAAO,CAC3DC,WAAYC,mBAAUC,OAAO,yCAA0C,IACvEC,MAAM,EACNC,eAAe,qBAYI,CAACC,UAAWC,YAAaC,OAAQC,cAC7CC,QAAQC,IAAI,CACfd,2BACAe,WAAWC,eAAeP,UAAWC,YAAaC,UAErDM,MAAKC,WAAEC,MAAOC,0BACJP,QAAQC,IAAI,CACfK,MACAC,aACAC,UAAUD,aAAaE,SAAUF,aAAaG,eAGrDN,MAAKO,YAAEL,MAAOC,2BAEXD,MAAMM,QAAQ,IAEP,IAAIZ,SAAQa,UACfC,OAAOC,OAAOC,QAAQ,CAElBC,YAAa,SAASC,KAAMC,gBACjBA,QAAQC,MAAM9B,OAAO,CACxB+B,eAAgB,CAAC,CACbC,OAAQ,CACJC,cAAehB,aAAagB,cAC5BC,MAAOjB,aAAakB,MAExB1B,YAAa2B,kBAASC,SAAS5B,YAAa,CAAC6B,OAAQ,IAAKC,WAAW,MAEzEC,oBAAqB,CACjBC,oBAAqB,cACrBC,WAAYN,kBAASC,SAASpB,aAAa0B,UAAW,CAACL,OAAQ,IAAKC,WAAW,QAK3FK,UAAW,SAAShB,MAChBZ,MAAM6B,UAAUC,GAAGC,sBAAYC,cAAeC,IAE1CA,EAAEC,oBAGNlC,MAAMM,SAAQ,kBAAU,cAAe,iBAEvCV,WAAWuC,wBAAwB7C,UAAWC,YAAaC,OAAQoB,KAAKwB,SACvEtC,MAAKuC,MACFrC,MAAMsC,OACCD,OAEVvC,KAAKS,YAEXpB,OAAOa,MAAMuC,UAAU,UAGjCzC,MAAKuC,KACEA,IAAIG,QACG9C,QAAQa,QAAQ8B,IAAII,SAGxB/C,QAAQgD,OAAOL,IAAII,iBAW5BvC,UAAY,CAACyC,SAAUvC,kBACnBwC,yDAAoDD,8BAAqBvC,aAG3EF,UAAU2C,kBAAoBD,cACvBlD,QAAQa,aAMfL,UAAU2C,gBAAiB,OACrBC,gBAAkBC,SAASC,oCAA6B9C,UAAU2C,uBACpEC,iBACAA,gBAAgBG,WAAWC,YAAYJ,uBAIzCK,OAASJ,SAASK,cAAc,iBAE/B,IAAI1D,SAAQa,UACX4C,OAAOE,WACPF,OAAOG,mBAAqB,WACD,YAAnBC,KAAKF,YAA+C,UAAnBE,KAAKF,kBACjCC,mBAAqB,KAC1B/C,YAIR4C,OAAOK,OAAS,WACZjD,WAIR4C,OAAOM,aAAa,MAAOb,QAC3BG,SAASW,KAAKC,YAAYR,QAE1BjD,UAAU2C,gBAAkBD,WAUpC1C,UAAU2C,gBAAkB"}PKJ\}Rpaypal/settings.phpnu[. /** * Settings for the PayPal payment gateway * * @package paygw_paypal * @copyright 2019 Shamim Rezaie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); if ($ADMIN->fulltree) { $settings->add(new admin_setting_heading('paygw_paypal_settings', '', get_string('pluginname_desc', 'paygw_paypal'))); \core_payment\helper::add_common_gateway_settings($settings, 'paygw_paypal'); } PKJ\]iVrQQpaypal/styles.cssnu[PKJ\[{{paypal/db/services.phpnu[PKJ\ Spaypal/db/install.phpnu[PKJ\ݗvvn paypal/db/upgrade.phpnu[PKJ\㻠)paypal/db/install.xmlnu[PKJ\R^ paypal/lang/en/paygw_paypal.phpnu[PKJ\R7҃҃"paypal/pix/img.svgnu[PKJ\<Zpaypal/version.phpnu[PKJ\y0իpaypal/classes/external/transaction_complete.phpnu[PKJ\0 0 -paypal/classes/external/get_config_for_js.phpnu[PKJ\ȭ  #\paypal/classes/privacy/provider.phpnu[PKJ\? paypal/classes/paypal_helper.phpnu[PKJ\!!paypal/classes/gateway.phpnu[PKJ\ 3Kpaypal/templates/paypal_button_placeholder.mustachenu[PKJ\!  paypal/amd/src/gateways_modal.jsnu[PKJ\8U !paypal/amd/src/repository.jsnu[PKJ\\<<"+paypal/amd/build/repository.min.jsnu[PKJ\)&70paypal/amd/build/gateways_modal.min.jsnu[PKJ\铊 &A@paypal/amd/build/repository.min.js.mapnu[PKJ\:7!!*hLpaypal/amd/build/gateways_modal.min.js.mapnu[PKJ\}Rnpaypal/settings.phpnu[PKs