<?php
class paypal extends Payment_Provider_Base
{
	function __construct()
	{
		$this->conf['PaymentDirectory'] = 'paypal';
		$this->conf['PaymentMethod'] 	= 'paypal';
		
		// Load parent constructor
		parent::__construct();
		
		// Load configuration
		$this->loadConf();
		
		//$this->conf['paypal_url']	= "https://api-m.sandbox.paypal.com";
		$this->conf['paypal_url']	= "https://api-m.paypal.com";
		$this->conf['return_url'] 	= IDEAL_EMAIL . 'paypal/return.php';
	}
	
	public function startTransaction()
	{

		if($this->Type == 'invoice')
		{
			$orderID		= $this->InvoiceCode;
			$description	= __('description prefix invoice').' '.$this->InvoiceCode; 
			
			$_SESSION['paypal']['id'] = $this->InvoiceID;
			$_SESSION['paypal']['type'] = $this->Type;
		}
		else
		{
			$orderID		= $this->OrderCode;
			$description	= __('description prefix order').' '.$this->OrderCode; 
			
			$_SESSION['paypal']['id'] = $this->OrderID;
			$_SESSION['paypal']['type'] = $this->Type;
		}
		
		$amount					= number_format($this->Amount,2,'.','');

		// Get customer data
		$customer_data = $this->getCustomerData();

        $ch = curl_init();
        curl_setopt($ch,CURLOPT_URL, sprintf('%s/v2/checkout/orders', $this->conf['paypal_url']));
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(sprintf('Authorization: Bearer %s', $this->getAccessToken()), "Content-Type: application/json"));
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST , 'POST');
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array(
            'intent' => 'CAPTURE',
            'purchase_units' => [
                array(
                    'description' => $description,
                    'amount' => array(
                            'value' => $amount,
                            'currency_code' => CURRENCY_CODE
                    ),
                    'invoice_id' => $orderID
                )
            ],
            'payment_source' => array(
                'paypal' => array(
                    'experience_context' => array(
                        'payment_method_preference' => 'IMMEDIATE_PAYMENT_REQUIRED',
                        'user_action' => 'PAY_NOW',
                        'return_url' => $this->conf['return_url'],
                        'cancel_url' => $this->conf['return_url']
                    ),
                    'name' => array(
                        'given_name' => $customer_data->Initials,
                        'surname' => $customer_data->SurName
                    ),
                    'address' => array(
                        'address_line_1' => $customer_data->Address,
                        'admin_area_2' => $customer_data->City,
                        'postal_code' => $customer_data->ZipCode,
                        'country_code' => $customer_data->Country
                    )
                )
            )
        )));

        $curlResp = curl_exec($ch);
        $curlHTTPCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        if ($curlHTTPCode == 200 && json_decode($curlResp, true)) {
            $result = json_decode($curlResp, true);
            $this->updateTransactionID($result['id']);
            $_SESSION['paypal']['transaction_id'] = $result['id'];

            foreach($result['links'] as $link) {
                if ($link['rel'] == 'payer-action') {
                    // Redirect
                    header("Location: " . $link['href']);
                    exit;
                }
            }
        } else {
            $this->paymentStatusUnknown('Failed to start PayPal order');
            exit;
        }
	}
	
	public function validateTransaction($transactionID)
	{
        if($transactionID){
            $this->getType($transactionID);
        }

        // Retrieve payment status from PayPal.
        if (!$this->Paid) {
            $accessToken = $this->getAccessToken();

            $ch = curl_init();
            curl_setopt($ch,CURLOPT_URL, sprintf('%s/v2/checkout/orders/%s', $this->conf['paypal_url'], $transactionID));
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(sprintf('Authorization: Bearer %s', $accessToken)));
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_TIMEOUT, 10);

            $curlResp = curl_exec($ch);
            $curlHTTPCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

            if ($curlHTTPCode == 200 && json_decode($curlResp, true)) {
                $result = json_decode($curlResp, true);
                if ($result['status'] == 'COMPLETED' || $result['status'] == 'APPROVED') {
                    // Capture the order to actually retrieve the payment.
                    $ch_capture = curl_init();
                    curl_setopt($ch_capture,CURLOPT_URL, sprintf('%s/v2/checkout/orders/%s/capture', $this->conf['paypal_url'], $transactionID));
                    curl_setopt($ch_capture, CURLOPT_HTTPHEADER, array(sprintf('Authorization: Bearer %s', $accessToken), "Content-Type: application/json"));
                    curl_setopt($ch_capture, CURLOPT_SSL_VERIFYHOST, 0);
                    curl_setopt($ch_capture, CURLOPT_SSL_VERIFYPEER, FALSE);
                    curl_setopt($ch_capture, CURLOPT_RETURNTRANSFER, 1);
                    curl_setopt($ch_capture, CURLOPT_TIMEOUT, 10);
                    curl_setopt($ch_capture, CURLOPT_CUSTOMREQUEST , 'POST');

                    $captureResp = curl_exec($ch_capture);
                    $curlHTTPCodeCapture = curl_getinfo($ch_capture, CURLINFO_HTTP_CODE);

                    if ($curlHTTPCodeCapture == 200 || $curlHTTPCodeCapture == 201) {
                        $captureResult = json_decode($captureResp, true);

                        if (isset($captureResult['purchase_units'][0]['payments']['captures'][0]['id'])) {
                            $this->paymentProcessed($transactionID, $captureResult['purchase_units'][0]['payments']['captures'][0]['id']);
                        } else {
                            $this->paymentProcessed($transactionID);
                        }
                    } else {
                        $this->paymentStatusUnknown();
                    }
                } else if ($result['status'] == 'PAYER_ACTION_REQUIRED') {
                    $this->paymentStatusUnknown();
                }
            }
        }

        // For consumer.
        if($this->Paid)
        {
            if($this->Type 	== 'invoice')
            {
                $_SESSION['payment']['type'] 			= 'invoice';
                $_SESSION['payment']['id'] 				= $this->InvoiceID;
            }
            elseif($this->Type 	== 'order')
            {
                $_SESSION['payment']['type'] 			= 'order';
                $_SESSION['payment']['id'] 				= $this->OrderID;
            }

            // Because type is found, we know it is paid
            $_SESSION['payment']['status'] 			= 'paid';
            $_SESSION['payment']['paymentmethod'] 	= $this->conf['PaymentMethod'];
            $_SESSION['payment']['transactionid'] 	= $transactionID;
            $_SESSION['payment']['date'] 			= date('Y-m-d H:i:s');
        }
        else
        {
            $_SESSION['payment']['status'] 			= 'pending';
            $_SESSION['payment']['paymentmethod'] 	= $this->conf['PaymentMethod'];
            $_SESSION['payment']['transactionid'] 	= $transactionID;
            $_SESSION['payment']['date'] 			= date('Y-m-d H:i:s');
        }

        header("Location: ".IDEAL_EMAIL);
        exit;
	}
	
	public static function getBackofficeSettings()
	{
		$settings = array();
		
		$settings['MerchantID']['Title'] = "API client ID";
		$settings['MerchantID']['Value'] = "";

        $settings['ExtraID']['Title'] = "API secret";
        $settings['MerchantID']['Value'] = "";

		$settings['Advanced']['Title'] = "PayPal";
		$settings['Advanced']['Image'] = "paypal.jpg";
		$settings['Advanced']['Description'] = "Met PayPal betaalt u snel en veilig online.";
		
		$settings['Advanced']['FeeType'] = "";
		$settings['Advanced']['FeeAmount'] = "0";
		$settings['Advanced']['FeeDesc'] = "Transactiekosten";
		
		$settings['Advanced']['Testmode'] = "0";
		
		return $settings;
	}

    private function getAccessToken(): string {
        $ch = curl_init();
        curl_setopt_array($ch, array(
            CURLOPT_URL => sprintf('%s/v1/oauth2/token', $this->conf['paypal_url']),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => 'grant_type=client_credentials',
            CURLOPT_HTTPHEADER => array(
                'Content-Type: application/x-www-form-urlencoded',
                sprintf('Authorization: Basic %s', base64_encode($this->conf['MerchantID'].":".$this->conf['ExtraID']))
            ),
        ));

        $response = curl_exec($ch);

        if (!curl_errno($ch)) {
            $content = json_decode($response, true);
            if (!empty($content['access_token'])) {
                return $content['access_token'];
            }
        }

        $this->paymentStatusUnknown('Failed to connect to PayPal');
        exit;
    }
}