Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Contains helper class to work with PayPal REST API.
  19   *
  20   * @package    core_payment
  21   * @copyright  2020 Shamim Rezaie <shamim@moodle.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace paygw_paypal;
  26  
  27  use curl;
  28  
  29  defined('MOODLE_INTERNAL') || die();
  30  
  31  require_once($CFG->libdir . '/filelib.php');
  32  
  33  class paypal_helper {
  34  
  35      /**
  36       * @var string The payment was authorized or the authorized payment was captured for the order.
  37       */
  38      public const CAPTURE_STATUS_COMPLETED = 'COMPLETED';
  39  
  40      /**
  41       * @var string The merchant intends to capture payment immediately after the customer makes a payment.
  42       */
  43      public const ORDER_INTENT_CAPTURE = 'CAPTURE';
  44  
  45      /**
  46       * @var string The customer approved the payment.
  47       */
  48      public const ORDER_STATUS_APPROVED = 'APPROVED';
  49  
  50      /**
  51       * @var string The base API URL
  52       */
  53      private $baseurl;
  54  
  55      /**
  56       * @var string Client ID
  57       */
  58      private $clientid;
  59  
  60      /**
  61       * @var string PayPal App secret
  62       */
  63      private $secret;
  64  
  65      /**
  66       * @var string The oath bearer token
  67       */
  68      private $token;
  69  
  70      /**
  71       * helper constructor.
  72       *
  73       * @param string $clientid The client id.
  74       * @param string $secret PayPal secret.
  75       * @param bool $sandbox Whether we are working with the sandbox environment or not.
  76       */
  77      public function __construct(string $clientid, string $secret, bool $sandbox) {
  78          $this->clientid = $clientid;
  79          $this->secret = $secret;
  80          $this->baseurl = $sandbox ? 'https://api.sandbox.paypal.com' : 'https://api.paypal.com';
  81  
  82          $this->token = $this->get_token();
  83      }
  84  
  85      /**
  86       * Captures an authorized payment, by ID.
  87       *
  88       * @param string $authorizationid The PayPal-generated ID for the authorized payment to capture.
  89       * @param float $amount The amount to capture.
  90       * @param string $currency The currency code for the amount.
  91       * @param bool $final Indicates whether this is the final captures against the authorized payment.
  92       * @return array|null Formatted API response.
  93       */
  94      public function capture_authorization(string $authorizationid, float $amount, string $currency, bool $final = true): ?array {
  95          $location = "{$this->baseurl}/v2/payments/authorizations/{$authorizationid}/capture";
  96  
  97          $options = [
  98              'CURLOPT_RETURNTRANSFER' => true,
  99              'CURLOPT_TIMEOUT' => 30,
 100              'CURLOPT_HTTP_VERSION' => CURL_HTTP_VERSION_1_1,
 101              'CURLOPT_SSLVERSION' => CURL_SSLVERSION_TLSv1_2,
 102              'CURLOPT_HTTPHEADER' => [
 103                  'Content-Type: application/json',
 104                  "Authorization: Bearer {$this->token}",
 105              ],
 106          ];
 107  
 108          $command = [
 109              'amount' => [
 110                  'value' => (string) $amount,
 111                  'currency_code' => $currency,
 112              ],
 113              'final_capture' => $final,
 114          ];
 115          $command = json_encode($command);
 116  
 117          $curl = new curl();
 118          $result = $curl->post($location, $command, $options);
 119  
 120          return json_decode($result, true);
 121      }
 122  
 123      /**
 124       * Captures order details from PayPal.
 125       *
 126       * @param string $orderid The order we want to capture.
 127       * @return array|null Formatted API response.
 128       */
 129      public function capture_order(string $orderid): ?array {
 130          $location = "{$this->baseurl}/v2/checkout/orders/{$orderid}/capture";
 131  
 132          $options = [
 133              'CURLOPT_RETURNTRANSFER' => true,
 134              'CURLOPT_TIMEOUT' => 30,
 135              'CURLOPT_HTTP_VERSION' => CURL_HTTP_VERSION_1_1,
 136              'CURLOPT_SSLVERSION' => CURL_SSLVERSION_TLSv1_2,
 137              'CURLOPT_HTTPHEADER' => [
 138                  'Content-Type: application/json',
 139                  "Authorization: Bearer {$this->token}",
 140              ],
 141          ];
 142  
 143          $command = '{}';
 144  
 145          $curl = new curl();
 146          $result = $curl->post($location, $command, $options);
 147  
 148          return json_decode($result, true);
 149      }
 150  
 151      public function get_order_details(string $orderid): ?array {
 152          $location = "{$this->baseurl}/v2/checkout/orders/{$orderid}";
 153  
 154          $options = [
 155              'CURLOPT_RETURNTRANSFER' => true,
 156              'CURLOPT_TIMEOUT' => 30,
 157              'CURLOPT_HTTP_VERSION' => CURL_HTTP_VERSION_1_1,
 158              'CURLOPT_SSLVERSION' => CURL_SSLVERSION_TLSv1_2,
 159              'CURLOPT_HTTPHEADER' => [
 160                  'Content-Type: application/json',
 161                  "Authorization: Bearer {$this->token}",
 162              ],
 163          ];
 164  
 165          $curl = new curl();
 166          $result = $curl->get($location, [], $options);
 167  
 168          return json_decode($result, true);
 169      }
 170  
 171      /**
 172       * Request for PayPal REST oath bearer token.
 173       *
 174       * @return string
 175       */
 176      private function get_token(): string {
 177          $location = "{$this->baseurl}/v1/oauth2/token";
 178  
 179          $options = [
 180              'CURLOPT_RETURNTRANSFER' => true,
 181              'CURLOPT_TIMEOUT' => 30,
 182              'CURLOPT_HTTP_VERSION' => CURL_HTTP_VERSION_1_1,
 183              'CURLOPT_SSLVERSION' => CURL_SSLVERSION_TLSv1_2,
 184              'CURLOPT_USERPWD' => "{$this->clientid}:{$this->secret}",
 185          ];
 186  
 187          $command = 'grant_type=client_credentials';
 188  
 189          $curl = new curl();
 190          $result = $curl->post($location, $command, $options);
 191  
 192          $result = json_decode($result, true);
 193  
 194          return $result['access_token'];
 195      }
 196  }