Skip to content

Commit

Permalink
MDL-69166 pg_paypal: Process after payment
Browse files Browse the repository at this point in the history
  • Loading branch information
rezaies committed Oct 27, 2020
1 parent 52ed139 commit 16099e4
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 0 deletions.
144 changes: 144 additions & 0 deletions payment/gateway/paypal/classes/external/transaction_complete.php
@@ -0,0 +1,144 @@
<?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/>.

/**
* This class contains a list of webservice functions related to the PayPal payment gateway.
*
* @package pg_paypal
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

declare(strict_types=1);

namespace pg_paypal\external;

use external_api;
use external_function_parameters;
use external_value;

defined('MOODLE_INTERNAL') || die();

require_once($CFG->libdir . '/externallib.php');

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'),
'componentid' => new external_value(PARAM_INT, 'The item id in the context of the component'),
'orderid' => new external_value(PARAM_TEXT, 'The order id coming back from PayPal'),
'authorizationid' => new external_value(PARAM_TEXT, 'The authorization 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 componentid belongs to
* @param int $componentid An internal identifier that is used by the component
* @param string $orderid PayPal order ID
* @param string $authorizationid The PayPal-generated ID for the authorized payment
* @return array
*/
public static function execute(string $component, int $componentid, string $orderid,
string $authorizationid): array {
global $USER, $DB;

self::validate_parameters(self::execute_parameters(), [
'component' => $component,
'componentid' => $componentid,
'orderid' => $orderid,
'authorizationid' => $authorizationid,
]);

$config = get_config('pg_paypal');

[
'amount' => $amount,
'currency' => $currency
] = \core_payment\helper::get_cost($component, $componentid);

$paypalhelper = new paypal_helper($config->clientid, $config->secret, false);
$authorization = $paypalhelper->capture_authorization($authorizationid, $amount, $currency);

$success = false;
$message = '';

if ($authorization) {
switch ($authorization['status']) {
case 'COMPLETED':
$success = true;
// Everything is correct. Let's give them what they paid for.
try {
\core_payment\helper::deliver_order($component, $componentid);

$paymentid = \core_payment\helper::save_payment($component, $componentid, (int)$USER->id, $amount, $currency,
'paypal');

// Store PayPal extra information.
$record = new \stdClass();
$record->paymentid = $paymentid;
$record->pp_orderid = $orderid;
$record->pp_authorizationid = $authorizationid;
$record->pp_paymentid = $authorization->id; // The PayPal-generated ID for the captured payment.
$record->pp_status = 'COMPLETED';

$DB->insert_record('pg_paypal', $record);
} catch (\Exception $e) {
debugging('Exception while trying to process payment: ' . $e->getMessage(), DEBUG_DEVELOPER);
$success = false;
$message = get_string('internalerror', 'pg_paypal');
}
break;
case 'PENDING':
$success = false;
$message = get_string('echecknotsupported', 'pg_paypal');
break;
default:
$success = false;
$message = get_string('paymentnotcleared', 'pg_paypal');
}
} else {
// Could not capture authorization!
$success = false;
$message = get_string('captureauthorizationfailed', 'pg_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_TEXT, 'Message (usually the error message).', VALUE_OPTIONAL),
]);
}
}
22 changes: 22 additions & 0 deletions payment/gateway/paypal/db/install.xml
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="payment/gateway/paypal/db" VERSION="20200110" COMMENT="XMLDB file for PayPal payment gateway plugin"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="pg_paypal" COMMENT="Stores PayPal related information">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="paymentid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="pp_orderid" TYPE="char" LENGTH="255" NOTNULL="true" DEFAULT="The ID of the order in PayPal" SEQUENCE="false"/>
<FIELD NAME="pp_authorizationid" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="pp_paymentid" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" COMMENT="The PayPal-generated ID for the captured payment."/>
<FIELD NAME="pp_status" TYPE="char" LENGTH="32" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="paymentid" TYPE="foreign-unique" FIELDS="paymentid" REFTABLE="payment" REFFIELDS="id"/>
</KEYS>
</TABLE>
</TABLES>
</XMLDB>
17 changes: 17 additions & 0 deletions payment/gateway/paypal/db/services.php
Expand Up @@ -33,4 +33,21 @@
'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',
'classpath' => '',
'description' => 'Takes care of what needs to be done when a PayPal transaction comes back as complete.',
'type' => 'write',
'ajax' => true,
'loginrequired' => false,
],
];
8 changes: 8 additions & 0 deletions payment/gateway/paypal/lang/en/pg_paypal.php
Expand Up @@ -24,9 +24,17 @@

$string['brandname'] = 'Brand name';
$string['brandname_desc'] = 'The optional label that overrides the business name in the PayPal account on the PayPal site.';
$string['captureauthorizationfailed'] = 'Could not capture authorization.';
$string['clientid'] = 'Client ID';
$string['clientid_desc'] = 'The client ID that PayPal generated for your application.';
$string['echecknotsupported'] = 'E-check is not supported.';
$string['gatewaydescription'] = 'PayPal is an authorised payment gateway provider for processing credit card transactions.';
$string['gatewayname'] = 'PayPal';
$string['internalerror'] = 'Internal error.';
$string['paymentauthorizationwarning'] = 'For PayPal payment authorizations, you must enable this feature on your PayPal account.';
$string['paymentnotcleared'] = 'payment not cleared by PayPal.';
$string['pluginname'] = 'PayPal';
$string['pluginname_desc'] = 'The PayPal plugin allows you to receive payments via PayPal.';
$string['repeatedorder'] = 'This order has already been processed earlier.';
$string['secret'] = 'Secret';
$string['secret_desc'] = 'The secret thatPayPal generated for your application.';
6 changes: 6 additions & 0 deletions payment/gateway/paypal/settings.php
Expand Up @@ -25,10 +25,16 @@
defined('MOODLE_INTERNAL') || die();

if ($ADMIN->fulltree) {

$settings->add(new admin_setting_heading('pg_paypal_settings', '', get_string('pluginname_desc', 'pg_paypal')));

$warning = $OUTPUT->notification(get_string('paymentauthorizationwarning', 'pg_paypal'), 'warning');
$settings->add(new admin_setting_heading('pg_paypal/warning', '', $warning));

$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));
}

0 comments on commit 16099e4

Please sign in to comment.