<?php
/**
 * Created by JetBrains PhpStorm.
 * User: mindblast
 * Date: 13.02.14
 * Time: 11:23
 * To change this template use File | Settings | File Templates.
 */

define('MCP__CREDITCARDSERVICE_INTERFACE', 'IMcpCreditcardService_v1_5');


include_once(DATEIPFAD . 'plugins/lib/micropaymentServiceClient/lib/init.php');
include_once(DATEIPFAD . 'plugins/lib/micropaymentServiceClient/services/' . MCP__CREDITCARDSERVICE_INTERFACE . '.php');
require_once( MCP__SERVICELIB_DISPATCHER . 'TNvpServiceDispatcher.php');

class MicropaymentCCAPI extends PaymentInterface
{
    // some constants
    const WEBSERVICE_URL_CH = 'https://webservices.micropayment.ch/public/creditcard/v1.5/nvp/';
    const WEBSERVICE_URL_DE = 'https://webservices.micropayment.de/public/creditcard/v1.5/nvp/';

    // Language Strings
    private $strings = array(
        'de_DE' => array(
            'displayName' => 'Micropayment Kreditkarte (API)',
            'testMode' => 'Test Modus',
            'accessKey' => 'Access Key',
            'project' => 'Projektkürzel',
            'server' => 'Server',
            'deutschland' => 'Deutschland',
            'schweiz' => 'Schweiz',
            'ownerName' => 'Kreditkarten Inhaber',
            'cardNumber' => 'Kreditkarten Nummer',
            'expirationDateMonth' => 'gültig bis (Monat)',
            'expirationDateYear' => 'gültig bis (Jahr)',
            'january' => 'Januar',
            'february' => 'Februar',
            'march' => 'März',
            'april' => 'April',
            'may' => 'Mai',
            'june' => 'Juni',
            'july' => 'Juli',
            'august' => 'August',
            'september' => 'September',
            'oktober' => 'Oktober',
            'november' => 'November',
            'december' => 'Dezember',
            'cvvNumber' => 'CVV / CVC',
            'errorOwnerName' => 'Bitte geben sie Namen des Kreditkarten Inhabers an',
            'errorCardNumber' => 'Bitte geben sie die Nummer der Kreditkarte an',
            'errorCvvNumber' => 'Bitte geben sie die CVV/CVC Nummer an',
            'errorCouldntConnectToServer' => 'Es konnte keine Verbindung zum Server des Zahlungsanbieters hergestellt werden.',
            'errNoAccessKey' => 'Bitte geben Sie den AccessKey an.',
            'errNoProject' => 'Bitte geben Sie das Projektkürzel an.',
            'auftrag' => 'Auftrag'
        ),
        'en_UK' => array(
            'displayName' => 'Micropayment Creditcard',
            'testMode' => 'test mode',
            'accessKey' => 'access key',
            'project' => 'project short',
            'server' => 'Server',
            'deutschland' => 'Germany',
            'schweiz' => 'Switzerland',
            'ownerName' => 'Creditcard owner',
            'cardNumber' => 'Creditcard number',
            'expirationDateMonth' => 'valid until (month)',
            'expirationDateYear' => 'valid until (year)',
            'january' => 'January',
            'february' => 'February',
            'march' => 'March',
            'april' => 'April',
            'may' => 'May',
            'june' => 'June',
            'july' => 'July',
            'august' => 'August',
            'september' => 'September',
            'oktober' => 'Oktober',
            'november' => 'November',
            'december' => 'December',
            'cvvNumber' => 'CVV / CVC',
            'errorOwnerName' => 'Please enter the name of the credit card owner',
            'errorCardNumber' => 'Please enter the number of the credit card',
            'errorCvvNumber' => 'Please enter the CVV/CVC number',
            'errorCouldntConnectToServer' => 'The connection to the server of the payment provider failed.',
            'auftrag' => 'order'
        )
    );
    private $localeStrings;
    private $locale;

    // Config Parameters
    private $testMode;
    private $accessKey;
    private $project;
    private $webserviceURL;

    // Input Parameters
    private $ownerName;
    private $cardNumber;
    private $expirationDateMonth;
    private $expirationDateYear;
    private $cvvNumber;

    // status of the payment sequence
    private $paymentStep = 'tryPayment';

    static $stdPluginCaps = array(
        'createInvoice' => false,
        'checkPending' => false,
        'changeOrder' => false,
        'cancelPayment' => false,
        'plugin_version' => '1.2'
    );

    static public function getPluginCaps($feature = false) {
        if($feature) {
            return self::$stdPluginCaps[$feature];
        } else {
            return self::$stdPluginCaps;
        }
    }

    public function setLocale($locale)
    {
        $this->locale = $locale;
        if(isset($this->strings[$locale])) {
            $this->localeStrings = $this->strings[$locale];
        } else {
            $this->localeStrings = $this->strings['en_UK'];
        }
    }

    public function getDisplayName()
    {
        return $this->localeStrings['displayName'];
    }

    public function getConfigParams()
    {
        return array(
            new ParamCfg('testMode', $this->localeStrings['testMode'], ParamCfg::TYPE_CHECK),
            new ParamCfg('accessKey', $this->localeStrings['accessKey'], ParamCfg::TYPE_STRING),
            new ParamCfg('project', $this->localeStrings['project'], ParamCfg::TYPE_STRING),
            new ParamCfg('server', $this->localeStrings['server'], ParamCfg::TYPE_SELECT, array('de' => $this->localeStrings['deutschland'], 'ch' => $this->localeStrings['schweiz']))
        );
    }

    public function setConfig($arrConfig)
    {
        $this->testMode = $arrConfig['testMode']?1:0;
        $this->accessKey = $arrConfig['accessKey'];
        $this->project = $arrConfig['project'];
        if($arrConfig['server'] == 'de') {
            $this->webserviceURL = self::WEBSERVICE_URL_DE;
        } else {
            $this->webserviceURL = self::WEBSERVICE_URL_CH;
        }
    }

    public function validateConfig($arrConfig)
    {
        if(trim($arrConfig['accessKey']) == '' && trim($arrConfig['project']) == '') {
            return true;
        }

        if(trim($arrConfig['accessKey']) == '') {
            $errors['accessKey'] = $this->localeStrings['errNoAccessKey'];
        }
        if(trim($arrConfig['project']) == '') {
            $errors['project'] = $this->localeStrings['errNoProject'];
        }
        if($errors) {
            return $errors;
        } else {
            return true;
        }
    }

    public function getPaymentChoiceTemplate()
    {
        return array(
            new ParamCfg('ownerName', $this->localeStrings['ownerName'], ParamCfg::TYPE_STRING),
            new ParamCfg('cardNumber', $this->localeStrings['cardNumber'], ParamCfg::TYPE_STRING),
            new ParamCfg('expirationDateMonth', $this->localeStrings['expirationDateMonth'], ParamCfg::TYPE_SELECT,
                array(  '01' => $this->localeStrings['january'],
                        '02' => $this->localeStrings['february'],
                        '03' => $this->localeStrings['march'],
                        '04' => $this->localeStrings['april'],
                        '05' => $this->localeStrings['may'],
                        '06' => $this->localeStrings['june'],
                        '07' => $this->localeStrings['july'],
                        '08' => $this->localeStrings['august'],
                        '09' => $this->localeStrings['september'],
                        '10' => $this->localeStrings['oktober'],
                        '11' => $this->localeStrings['november'],
                        '12' => $this->localeStrings['december']
                )
            ),
            new ParamCfg('expirationDateYear', $this->localeStrings['expirationDateYear'], ParamCfg::TYPE_SELECT,
                array(  '2012' => '2012',
                    '2013' => '2013',
                    '2014' => '2014',
                    '2015' => '2015',
                    '2016' => '2016',
                    '2017' => '2017',
                    '2018' => '2018',
                    '2019' => '2019',
                    '2020' => '2020',
                    '2021' => '2021',
                    '2022' => '2022',
                    '2023' => '2023',
                    '2024' => '2024',
                    '2025' => '2025',
                    '2026' => '2026',
                    '2027' => '2027',
                    '2028' => '2028',
                    '2029' => '2029',
                    '2030' => '2030'
                )
            ),
            new ParamCfg('cvvNumber', $this->localeStrings['cvvNumber'], ParamCfg::TYPE_STRING)
        );
    }

    public function validateAndSetPaymentChoice($arrParams)
    {
        if(trim($arrParams['ownerName']) == '') {
            $errors['ownerName'] = $this->localeStrings['errorOwnerName'];
        }
        if(trim($arrParams['cardNumber']) == '') {
            $errors['cardNumber'] = $this->localeStrings['errorCardNumber'];
        }
        if(trim($arrParams['cvvNumber']) == '') {
            $errors['cvvNumber'] = $this->localeStrings['errorCvvNumber'];
        }
        if(!$errors)
        {
            $this->ownerName = $arrParams['ownerName'];
            $this->cardNumber = $arrParams['cardNumber'];
            $this->expirationDateMonth = $arrParams['expirationDateMonth'];
            $this->expirationDateYear = $arrParams['expirationDateYear'];
            $this->cvvNumber = $arrParams['cvvNumber'];
            return true;
        }
        else
            return $errors;
    }

    /**
     *
     * @param $cart
     * @param $customer
     * @param $requestParams
     * @return \PaymentResult
     */
    public function doPayment(OrderData $order, array $requestParams)
    {
        $dispatcher = new TNvpServiceDispatcher(MCP__CREDITCARDSERVICE_INTERFACE, $this->webserviceURL);

        try {
            $result = $dispatcher->customerGet($this->accessKey, $this->testMode, $order->customer->customerID);
        } catch(Exception $e) {
            if($e->getCode() == 3110) {
                $result = false;
            }
        }

        try {
            if(!$result) {
                $dispatcher->customerCreate($this->accessKey, $this->testMode, $order->customer->customerID, null, $order->customer->invoiceAddress->firstName, $order->customer->invoiceAddress->lastName, $order->customer->email, 'de');
            }

            $dispatcher->customerSet($this->accessKey, $this->testMode, $order->customer->customerID, null, $order->customer->invoiceAddress->firstName, $order->customer->invoiceAddress->lastName, $order->customer->email, 'de');
            $dispatcher->addressSet($this->accessKey, $this->testMode, $order->customer->customerID,
                $order->customer->invoiceAddress->street . $order->customer->invoiceAddress->houseNumber,
                $order->customer->invoiceAddress->zipCode,
                $order->customer->invoiceAddress->city,
                $order->customer->invoiceAddress->country->isocode
            );
        } catch (Exception $e) {
            return new PaymentResult(PaymentResult::PAYMENT_FAILED, '', array(), $e->getMessage() . ' (' . $e->getCode() . ')');
        }

        try {
            $dispatcher->creditcardDataSet($this->accessKey, $this->testMode, $order->customer->customerID, $this->cardNumber, $this->expirationDateYear, $this->expirationDateMonth);
        } catch (Exception $e) {
            return new PaymentResult(PaymentResult::PAYMENT_FAILED, '', array(), $e->getMessage() . ' (' . $e->getCode() . ')');
        }

        try {
            $session = $dispatcher->sessionCreate($this->accessKey, $this->testMode, $order->customer->customerID, $_SESSION['sessionId'], $this->project, null, null, null, $order->totalAmount * 100, $order->currency->ISOCode, $this->localeStrings['auftrag'] . ': ' . $order->orderNumber, null, '95.91.241.81' /* $_SERVER['REMOTE_ADDR'] */ );
        } catch (Exception $e) {
            if($e->getCode() == 3111) {
                $session=array();
                $session['sessionId'] = $_SESSION['sessionId'];
            } else {
                return new PaymentResult(PaymentResult::PAYMENT_FAILED, '', array(), $e->getMessage() . ' (' . $e->getCode() . ')');
            }
        }

        try {
            $result = $dispatcher->transactionPurchase($this->accessKey, $this->testMode, $session['sessionId'], $this->cvvNumber);
        } catch (Exception $e) {
            return new PaymentResult(PaymentResult::PAYMENT_FAILED, '', array(), $e->getMessage() . ' (' . $e->getCode() . ')');
        }

        if($result['transactionStatus'] == 'FAILED') {
            return new PaymentResult(PaymentResult::PAYMENT_FAILED, '', array(), $result->transactionResultMessage);
        } else if($result['transactionStatus'] == 'SUCCESS') {
            return new PaymentResult(PaymentResult::PAYMENT_COMPLETE);
        } else {
            return new PaymentResult(PaymentResult::PAYMENT_FAILED, '', array(), $result->transactionResultMessage);
        }

    }
}
