<?php
require_once "./config/db_config.php";
class PayUPaymentGateway
{
    public $domainURL;
    CONST API_VERSION = 'ONE_ZERO';
    CONST TRANSACTION_TYPE = 'PAYMENT';
    CONST RETURN_URL = '/paymentResponse.php';
    CONST DEMO_MODE = false;
    CONST REDIRECT_CHANNEL = 'responsive';
    CONST COUNTRY_CODE = '254';
    CONST REGIONAL_ID = 'KE';
    CONST IS_SECURE_3D = 'true';
    CONST DESCRIPTION = 'Payment';
    CONST MERCHANT_USER_ID = '7';
    CONST SOAP_WDS_URL = '/service/PayUAPI?wsdl';
    CONST PAYU_RPP_URL = '/rpp.do?PayUReference=';    

    public function __construct()
    {
        $this->domainURL = domainURL;
    }

    public function createOrder($data)
    {
        $gatewayJson = json_decode($data['gatewayConfig'], true);

        $requiredKeys = ['supportedPaymentMethods', 'safekey', 'currencyCode', 'username', 'password', 'environment'];
        foreach ($requiredKeys as $key) {
            if (empty($gatewayJson[$key])) {
                return ['status' => 'ERROR', 'message' => "Missing required gateway parameter: $key"];
            }
        }

        $username = $gatewayJson['username'];
        $password = $gatewayJson['password'];
        $environment = $gatewayJson['environment'];
        $safeKey = $gatewayJson['safekey'];
        $currencyCode = $gatewayJson['currencyCode'];
        $supportedPaymentMethods = $gatewayJson['supportedPaymentMethods'];       
        try{
            $setTransactionArray = array();
            $setTransactionArray['Api'] = self::API_VERSION;
            $setTransactionArray['Safekey'] = $safeKey;
            $setTransactionArray['TransactionType'] = self::TRANSACTION_TYPE;
            $setTransactionArray['AdditionalInformation']['merchantReference'] = $data['id'];
            if(isset($data['requestUrl']) && !empty($data['requestUrl']))
            {
                
                $parsedUrl = parse_url($data['requestUrl']);
                $newUrl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'];
                $failureUrl = rtrim($newUrl, '/') . '/paymentprocess/' . self::RETURN_URL;
                $successUrl = rtrim($newUrl, '/') . '/paymentprocess/' . self::RETURN_URL;
            }
            $setTransactionArray['AdditionalInformation']['cancelUrl'] = isset($failureUrl)?$failureUrl:$this->domainURL.self::RETURN_URL;
            $setTransactionArray['AdditionalInformation']['returnUrl'] = isset($successUrl)?$successUrl:$this->domainURL.self::RETURN_URL;
            if ($currencyCode == "KES") 
            {
                $setTransactionArray['AdditionalInformation']['demoMode'] = self::DEMO_MODE;
                $setTransactionArray['AdditionalInformation']['redirectChannel'] = self::REDIRECT_CHANNEL;
                $setTransactionArray['Customer']['countryCode'] = self::COUNTRY_CODE;
                $setTransactionArray['Customer']['regionalId'] = self::REGIONAL_ID;
                $setTransactionArray['Basket']['description'] = self::DESCRIPTION;
                $setTransactionArray['AdditionalInformation']['secure3d'] = self::IS_SECURE_3D;                
                // $setTransactionArray['AdditionalInformation']['notificationUrl'] = "";
                $setTransactionArray['AdditionalInformation']['supportedPaymentMethods'] = $supportedPaymentMethods;
                $setTransactionArray['Customer']['mobile'] = $data['phoneNo'];
            }
            $setTransactionArray['AdditionalInformation']['supportedPaymentMethods'] = $supportedPaymentMethods;
            $setTransactionArray['Basket']['amountInCents'] = $data['amount'] * 100;
            $setTransactionArray['Basket']['currencyCode'] = $currencyCode;
            $setTransactionArray['Customer']['merchantUserId'] = self::MERCHANT_USER_ID;
            $setTransactionArray['Customer']['email'] = $data['email'];
            $fullname = explode(" ", $data['name'], 2);                                
            $setTransactionArray['Customer']['firstName'] = isset($fullname[0]) ? $fullname[0] : $data['name'];
            $setTransactionArray['Customer']['lastName'] = isset($fullname[1]) ? $fullname[1] : $data['name'];

             // 2. Creating a XML header for sending in the soap heaeder (creating it raw a.k.a xml mode)
             $headerXml = '<wsse:Security SOAP-ENV:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">';
             $headerXml .= '<wsse:UsernameToken wsu:Id="UsernameToken-9" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">';
             $headerXml .= '<wsse:Username>' . $username . '</wsse:Username>';
             $headerXml .= '<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">' . $password . '</wsse:Password>';
             $headerXml .= '</wsse:UsernameToken>';
             $headerXml .= '</wsse:Security>';
             
             $headerbody = new SoapVar($headerXml, XSD_ANYXML, null, null, null);
             
             // 3. Create Soap Header.        
             $ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'; //Namespace of the WS. 
             $header = new SOAPHeader($ns, 'Security', $headerbody, true);

             // 4. Make new instance of the PHP Soap client
             $soap_client = new SoapClient($environment.self::SOAP_WDS_URL, array("trace" => 1, "exception" => 0));

             // 5. Set the Headers of soap client. 
             $soap_client->__setSoapHeaders($header);

             // 6. Do the setTransaction soap call to PayU
             $soapCallResult = $soap_client->setTransaction($setTransactionArray);

             // 7. Decode the Soap Call Result
             $returnData = json_decode(json_encode($soapCallResult), true);

             if ((isset($returnData['return']['successful']) && ($returnData['return']['successful'] === true) && isset($returnData['return']['payUReference'])))
             {
                return [
                    'status' => 'SUCCESS',
                    'url' => $environment.self::PAYU_RPP_URL.$returnData['return']['payUReference'],
                    'txnId' => $returnData['return']['payUReference']
                ];
             }
             else{
                return ['status' => 'ERROR',
            'data' => $returnData];
             }
            

        }catch(Exception $e)
        {
            return ['status' => 'ERROR', 'message' => $e->getMessage()];
        }
    }

    function fetchOrder($data){
        $gatewayJson = json_decode($data['gatewayConfig'], true);

        $requiredKeys = ['supportedPaymentMethods', 'safekey', 'currencyCode', 'username', 'password', 'environment'];
        foreach ($requiredKeys as $key) {
            if (empty($gatewayJson[$key])) {
                return ['status' => 'ERROR', 'message' => "Missing required gateway parameter: $key"];
            }
        }

        $username = $gatewayJson['username'];
        $password = $gatewayJson['password'];
        $environment = $gatewayJson['environment'];
        $safeKey = $gatewayJson['safekey'];
        $currencyCode = $gatewayJson['currencyCode'];
        $supportedPaymentMethods = $gatewayJson['supportedPaymentMethods'];
        $payUReference = $data['txnId'];

        $soapDataArray = array();
        $soapDataArray['Api'] = self::API_VERSION;
        $soapDataArray['Safekey'] = $safeKey;
        $soapDataArray['AdditionalInformation']['payUReference'] = $payUReference;

        // 2. Creating a XML header for sending in the soap heaeder (creating it raw a.k.a xml mode)
        $headerXml = '<wsse:Security SOAP-ENV:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">';
        $headerXml .= '<wsse:UsernameToken wsu:Id="UsernameToken-9" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">';
        $headerXml .= '<wsse:Username>' . $username . '</wsse:Username>';
        $headerXml .= '<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">' . $password . '</wsse:Password>';
        $headerXml .= '</wsse:UsernameToken>';
        $headerXml .= '</wsse:Security>';
        $headerbody = new SoapVar($headerXml, XSD_ANYXML, null, null, null);

        // 3. Create Soap Header.        
        $ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'; //Namespace of the WS. 
        $header = new SOAPHeader($ns, 'Security', $headerbody, true);

        // 4. Make new instance of the PHP Soap client
        $soap_client = new SoapClient($environment.self::SOAP_WDS_URL, array("trace" => 1, "exception" => 0));

        // 5. Set the Headers of soap client. 
        $soap_client->__setSoapHeaders($header);

        // 6. Do the setTransaction soap call to PayU
        $soapCallResult = $soap_client->getTransaction($soapDataArray);

        // 7. Decode the Soap Call Result
        $returnData = json_decode(json_encode($soapCallResult), true);

        if(isset($returnData['return']['payUReference']) && isset($returnData['return']['transactionState']))
        {
            return [
                'status' => 'SUCCESS',
                'payUReference' => $returnData['return']['payUReference'],
                'transactionState' => $returnData['return']['transactionState'],
                'jsonResponse' => $returnData,
            ];
        }else
        {
            return [
                'status' => 'SUCCESS',                
                'jsonResponse' => $returnData,
            ];
        }
    }


}