<?php
    /**
    *
    * copyright (c) 2013-2024 Heliac Technologies
    * license https://opensource.org/licenses/gpl-license.php GNU GPL v3 
    *
    * linee guida per l'utilizzo del logo https://www.geecom.org/index.php?alias=linee-guida-per-l%27uso-del-logo-geecom
    *
    */
    
    class ConnettorePayPal {
        private $clientId;
        private $secret;
        private $sandbox;
        private $urlRichieste;
        private $accessToken;
        
        public function __construct($clientId, $secret, $sandbox=false) {
            $this->clientId = $clientId;
            $this->secret   = $secret;
            $this->sandbox  = $sandbox;
            $this->urlRichieste = ($this->sandbox) ? "https://api-m.sandbox.paypal.com/" : "https://api-m.paypal.com/";
            $this->accessToken = "";
        }

        function creaOrdine($paypalRequestId,$paginaPagamentoEffettuato,$paginaPagamentoNonEffettuato,$prezzo,$nomeCartaDiCredito,$lingua = "it-IT") {
            $curl = curl_init();

            $richiestaJson = '{
                "intent": "CAPTURE",
                "purchase_units": [
                  {
                    "reference_id": "'.time().'",
                    "amount": {
                      "currency_code": "EUR",
                      "value": "'.$prezzo.'"
                    }
                  }
                ],
                "payment_source": {
                  "paypal": {
                    "experience_context": {
                      "payment_method_preference": "IMMEDIATE_PAYMENT_REQUIRED",
                      "brand_name": "'.$nomeCartaDiCredito.'",
                      "locale": "'.$lingua.'",
                      "landing_page": "LOGIN",
                      "user_action": "PAY_NOW",
                      "return_url": "'.$paginaPagamentoEffettuato.'",
                      "cancel_url": "'.$paginaPagamentoNonEffettuato.'"
                    }
                  }
                }
              }';
            
            curl_setopt_array(
                $curl,
                array(
                    CURLOPT_URL => $this->urlRichieste."v2/checkout/orders",
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_SSL_VERIFYHOST => false,
                    CURLOPT_SSL_VERIFYPEER => false,
                    CURLOPT_CUSTOMREQUEST => "POST",
                    CURLOPT_HEADER => false,
                    CURLOPT_HTTPHEADER => array(
                        "Content-Type: application/json",
                        "Authorization: Bearer " . $this->accessToken,
                        "PayPal-Request-Id: " . $paypalRequestId,
                        "Prefer: return=representation"
                    ),
                    CURLOPT_POSTFIELDS => $richiestaJson,
                )
            );

            $risultatoRichiesta       = curl_exec($curl);
            curl_close($curl);
            return $risultatoRichiesta;
        }

	/*
	 * Questo metodo crea un ordine con carta di credito
	 */
        function creaOrdineCarta($paypalRequestId,$paginaPagamentoEffettuato,$paginaPagamentoNonEffettuato,$prezzo,$nomeCartaDiCredito,$lingua = "it-IT") {
            $curl = curl_init();

            $richiestaJson = '{
                "intent": "CAPTURE",
                "purchase_units": [
                  {
                    "reference_id": "'.time().'",
                    "amount": {
                      "currency_code": "EUR",
                      "value": "'.$prezzo.'"
                    }
                  }
                ],
                "payment_source": {
                  "card": {
                    "attributes": {
                      "verification": {
                        "method": "SCA_ALWAYS"
                      }
                    }
                  }
                }
              }';
            
            curl_setopt_array(
                $curl,
                array(
                    CURLOPT_URL => $this->urlRichieste."v2/checkout/orders",
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_SSL_VERIFYHOST => false,
                    CURLOPT_SSL_VERIFYPEER => false,
                    CURLOPT_CUSTOMREQUEST => "POST",
                    CURLOPT_HEADER => false,
                    CURLOPT_HTTPHEADER => array(
                        "Content-Type: application/json",
                        "Authorization: Bearer " . $this->accessToken,
                        "PayPal-Request-Id: " . $paypalRequestId,
                        "Prefer: return=representation"
                    ),
                    CURLOPT_POSTFIELDS => $richiestaJson,
                )
            );

            $risultatoRichiesta       = curl_exec($curl);
            curl_close($curl);
            return $risultatoRichiesta;
        }
                
        function recuperaRisultato3DS($idOrdine) {
            $curl = curl_init();
            
            curl_setopt_array($curl, array(
		    CURLOPT_URL => $this->urlRichieste."v2/checkout/orders/$idOrdine?fields=payment_source",
		    CURLOPT_RETURNTRANSFER => true,
		    CURLOPT_SSL_VERIFYHOST => false,
		    CURLOPT_SSL_VERIFYPEER => false,
		    CURLOPT_CUSTOMREQUEST => "GET",
		    CURLOPT_HEADER => false,
		    CURLOPT_HTTPHEADER => array(
			"Content-Type: application/json",
			"Authorization: Bearer " . $this->accessToken,
		    ),
		)
            );

            $response = curl_exec($curl);

            curl_close($curl);

            return $this->azioniResponso3ds($response);
        }
        
        public function azioniResponso3ds($tds) {
		$json_3ds = json_decode($tds);

		isset($json_3ds->payment_source->card->authentication_result->liability_shift) ? $LS = $json_3ds->payment_source->card->authentication_result->liability_shift : $LS = "X";
		isset($json_3ds->payment_source->card->authentication_result->three_d_secure->enrollment_status) ? $ES = $json_3ds->payment_source->card->authentication_result->three_d_secure->enrollment_status : $ES = "X";
		isset($json_3ds->payment_source->card->authentication_result->three_d_secure->authentication_status) ? $AS = $json_3ds->payment_source->card->authentication_result->three_d_secure->authentication_status : $AS = "X";

		$result = array('ES' => $ES, 'AS' => $AS, 'LS' => $LS);

		// We turned the table of recommended actions into arrays for easier verification and simpler reading.
		
		// Continue with authorization.
		$CWA = [
		    array('ES' => 'Y', 'AS' => 'Y', 'LS' => 'POSSIBLE'),
		    array('ES' => 'Y', 'AS' => 'Y', 'LS' => 'YES'),
		    array('ES' => 'Y', 'AS' => 'A', 'LS' => 'POSSIBLE'),
		    array('ES' => 'N', 'AS' => 'X', 'LS' => 'NO'),
		    array('ES' => 'U', 'AS' => 'X', 'LS' => 'NO'),
		    array('ES' => 'B', 'AS' => 'X', 'LS' => 'NO')
		];

		// Do not continue with authorization.
		$DNCWA = [
		    array('ES' => 'Y', 'AS' => 'N', 'LS' => 'NO'),
		    array('ES' => 'Y', 'AS' => 'R', 'LS' => 'NO')
		];

		// Do not continue with authorization. Request cardholder to retry.
		$DNCWARCHTR = [
		    array('ES' => 'Y', 'AS' => 'U', 'LS' => 'UNKNOWN'),
		    array('ES' => 'Y', 'AS' => 'U', 'LS' => 'NO'),
		    array('ES' => 'Y', 'AS' => 'C', 'LS' => 'UNKNOWN'),
		    array('ES' => 'Y', 'AS' => 'X', 'LS' => 'NO'),
		    array('ES' => 'U', 'AS' => 'X', 'LS' => 'UNKNOWN'),
		    array('ES' => 'X', 'AS' => 'X', 'LS' => 'UNKNOWN')
		];

		if (in_array($result, $CWA)) {
		    $res = ["result" => "capture"];
		} elseif (in_array($result, $DNCWA)) {
		    $res = ["result" => "unknown"];
		} elseif (in_array($result, $DNCWARCHTR)) {
		    $res = ["result" => "retry"];
		} else {
		    $res = ["result" => "genericIssue"];
		}

		$res = json_encode($res);
		return $res;
        }    
    
        function catturaPagamento($paypalAuthorizationId) {
            $curl = curl_init();
            
            curl_setopt_array(
                $curl,
                array(
                    CURLOPT_URL => $this->urlRichieste."v2/checkout/orders/$paypalAuthorizationId/capture",
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_SSL_VERIFYHOST => false,
                    CURLOPT_SSL_VERIFYPEER => false,
                    CURLOPT_CUSTOMREQUEST => "POST",
                    CURLOPT_HEADER => false,
                    CURLOPT_HTTPHEADER => array(
                        "Content-Type: application/json",
                        "Authorization: Bearer " . $this->accessToken,
                        "PayPal-Request-Id: " . $paypalAuthorizationId,
                        "Prefer: return=representation"
                    )
                )
            );

            $risultatoRichiesta = curl_exec($curl);
            curl_close($curl);
            return $risultatoRichiesta;
        }
        
        function richiediAccessToken() {
            $curl = curl_init($this->urlRichieste."v1/oauth2/token");
            
            curl_setopt($curl, CURLOPT_HTTPHEADER, ["Content-Type"=>"application/x-www-form-urlencoded"]);
            curl_setopt($curl, CURLOPT_USERPWD, "$this->clientId:$this->secret");
            curl_setopt($curl, CURLOPT_POST, true);
            curl_setopt($curl, CURLOPT_POSTFIELDS, "grant_type=client_credentials");
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            
            $risultatoRichiesta = json_decode(curl_exec($curl));
            curl_close($curl);

            $this->accessToken  = $risultatoRichiesta->access_token;
        }
        
        // getter & setter
        public function getClientId() {
            return $this->clientId;
        }

        public function getSecret() {
            return $this->secret;
        }
        
        public function getSandbox() {
            return $this->sandbox;
        }

        public function getAccessToken() {
            return $this->accessToken;
        }

        public function setClientId($clientId): void {
            $this->clientId = $clientId;
        }

        public function setSecret($secret): void {
            $this->secret = $secret;
        }
        
        public function setSandbox($sandbox): void {
            $this->sandbox = $sandbox;
        }
        
        public function setAccessToken($accessToken): void {
            $this->accessToken = $accessToken;
        }
    }
