/**
  * Do payment action
  */
 public function doActionAction()
 {
     $transactionId = $this->Request()->getParam('transactionId');
     // Load the correct shop in order to use the correct api credentials
     $this->registerShopByTransactionId($transactionId);
     $config = $this->plugin->Config();
     $client = $this->get('paypalClient');
     $action = $this->Request()->getParam('paymentAction');
     $amount = $this->Request()->getParam('paymentAmount');
     $amount = str_replace(',', '.', $amount);
     $currency = $this->Request()->getParam('paymentCurrency');
     $orderNumber = $this->Request()->getParam('orderNumber');
     $full = $this->Request()->getParam('paymentFull') === 'true';
     $last = $this->Request()->getParam('paymentLast') === 'true';
     $note = $this->Request()->getParam('note');
     $invoiceId = null;
     if ($config->get('paypalSendInvoiceId') === true) {
         $prefix = $config->get('paypalPrefixInvoiceId');
         if (!empty($prefix)) {
             // Set prefixed invoice id - Remove special chars and spaces
             $prefix = str_replace(' ', '', $prefix);
             $prefix = preg_replace('/[^A-Za-z0-9\\-]/', '', $prefix);
             $invoiceId = $prefix . $orderNumber;
         } else {
             $invoiceId = $orderNumber;
         }
     }
     try {
         switch ($action) {
             case 'refund':
                 $data = array('TRANSACTIONID' => $transactionId, 'REFUNDTYPE' => $full ? 'Full' : 'Partial', 'AMT' => $full ? '' : $amount, 'CURRENCYCODE' => $full ? '' : $currency, 'NOTE' => $note);
                 if ($invoiceId) {
                     $data['INVOICEID'] = $invoiceId;
                 }
                 $result = $client->RefundTransaction($data);
                 break;
             case 'auth':
                 $result = $client->doReAuthorization(array('AUTHORIZATIONID' => $transactionId, 'AMT' => $amount, 'CURRENCYCODE' => $currency));
                 break;
             case 'capture':
                 $data = array('AUTHORIZATIONID' => $transactionId, 'AMT' => $amount, 'CURRENCYCODE' => $currency, 'COMPLETETYPE' => $last ? 'Complete' : 'NotComplete', 'NOTE' => $note);
                 if ($invoiceId) {
                     $data['INVOICEID'] = $invoiceId;
                 }
                 $result = $client->doCapture($data);
                 break;
             case 'void':
                 $result = $client->doVoid(array('AUTHORIZATIONID' => $transactionId, 'NOTE' => $note));
                 break;
             case 'book':
                 $result = $client->doAuthorization(array('TRANSACTIONID' => $transactionId, 'AMT' => $amount, 'CURRENCYCODE' => $currency));
                 if ($result['ACK'] == 'Success') {
                     $data = array('AUTHORIZATIONID' => $result['TRANSACTIONID'], 'AMT' => $amount, 'CURRENCYCODE' => $currency, 'COMPLETETYPE' => $last ? 'Complete' : 'NotComplete', 'NOTE' => $note);
                     if ($invoiceId) {
                         $data['INVOICEID'] = $invoiceId;
                     }
                     $result = $client->doCapture($data);
                 }
                 break;
             default:
                 return;
         }
         if ($result['ACK'] != 'Success') {
             throw new Exception('[' . $result['L_SEVERITYCODE0'] . '] ' . $result['L_SHORTMESSAGE0'] . " " . $result['L_LONGMESSAGE0'] . "<br>\n");
         }
         // Switch transaction id
         if ($action !== 'book' && $action !== 'capture' && (isset($result['TRANSACTIONID']) || isset($result['AUTHORIZATIONID']))) {
             $sql = '
                 UPDATE s_order SET transactionID=?
                 WHERE transactionID=? LIMIT 1
             ';
             $this->get('db')->query($sql, array(isset($result['TRANSACTIONID']) ? $result['TRANSACTIONID'] : $result['AUTHORIZATIONID'], $transactionId));
             $transactionId = $result['TRANSACTIONID'];
         }
         if ($action == 'void') {
             $paymentStatus = 'Voided';
         } elseif ($action == 'refund') {
             $paymentStatus = 'Refunded';
         } elseif (isset($result['PAYMENTSTATUS'])) {
             $paymentStatus = $result['PAYMENTSTATUS'];
         }
         if (isset($paymentStatus)) {
             try {
                 $this->plugin->setPaymentStatus($transactionId, $paymentStatus, $note);
             } catch (Exception $e) {
                 $result['SW_STATUS_ERROR'] = $e->getMessage();
             }
         }
         $this->View()->assign(array('success' => true, 'result' => $result));
     } catch (Exception $e) {
         $this->View()->assign(array('message' => $e->getMessage(), 'success' => false));
     }
 }
 /**
  * @param $details
  * @return array
  */
 protected function finishCheckout($details)
 {
     $client = $client = $this->get('paypalClient');
     $config = $this->plugin->Config();
     $router = $this->Front()->Router();
     $notifyUrl = $router->assemble(array('action' => 'notify', 'forceSecure' => true, 'appendSession' => true));
     if (!empty($details['REFERENCEID'])) {
         $params = array('REFERENCEID' => $details['REFERENCEID'], 'IPADDRESS' => $this->Request()->getClientIp(false), 'NOTIFYURL' => $notifyUrl, 'CUSTOM' => $this->createPaymentUniqueId(), 'BUTTONSOURCE' => 'Shopware_Cart_ECM');
     } else {
         $params = array('TOKEN' => $details['TOKEN'], 'PAYERID' => $details['PAYERID'], 'NOTIFYURL' => $notifyUrl, 'CUSTOM' => $details['CUSTOM'], 'BUTTONSOURCE' => 'Shopware_Cart_ECS');
     }
     if (Shopware::VERSION == '___VERSION___' || version_compare(Shopware::VERSION, '4.4.0') >= 0) {
         $params['BUTTONSOURCE'] = 'Shopware_Cart_5';
     }
     if (empty($params['TOKEN'])) {
         $params['PAYMENTACTION'] = 'Authorization';
     } else {
         $params['PAYMENTACTION'] = $config->get('paypalPaymentAction', 'Sale');
     }
     $params = array_merge($params, $this->getBasketParameter());
     $params = array_merge($params, $this->getCustomerParameter());
     if ($config->get('paypalSendInvoiceId')) {
         $orderNumber = $this->saveOrder(isset($params['TOKEN']) ? $params['TOKEN'] : $params['REFERENCEID'], $params['CUSTOM']);
         $prefix = $config->get('paypalPrefixInvoiceId');
         if (!empty($prefix)) {
             // Set prefixed invoice id - Remove special chars and spaces
             $prefix = str_replace(' ', '', $prefix);
             $prefix = preg_replace('/[^A-Za-z0-9\\-]/', '', $prefix);
             $params['INVNUM'] = $prefix . $orderNumber;
         } else {
             $params['INVNUM'] = $orderNumber;
         }
     }
     //$params['SOFTDESCRIPTOR'] = $orderNumber;
     if (!empty($params['REFERENCEID'])) {
         $result = $client->doReferenceTransaction($params);
     } else {
         $result = $client->doExpressCheckoutPayment($params);
     }
     $result['CUSTOM'] = $params['CUSTOM'];
     if ($result['ACK'] != 'Success') {
         return $result;
     }
     if (empty($orderNumber)) {
         $orderNumber = $this->saveOrder($result['TRANSACTIONID'], $result['CUSTOM']);
     }
     // Sets billing agreement id
     if (!empty($result['BILLINGAGREEMENTID'])) {
         try {
             $sql = '
                 INSERT INTO s_order_attributes (orderID, swag_payal_billing_agreement_id)
                 SELECT id, ? FROM s_order WHERE ordernumber = ?
                 ON DUPLICATE KEY UPDATE
                    swag_payal_billing_agreement_id = VALUES(swag_payal_billing_agreement_id)
             ';
             $this->get('db')->query($sql, array($result['BILLINGAGREEMENTID'], $orderNumber));
         } catch (Exception $e) {
         }
     }
     // Sets express flag
     if (!empty($params['TOKEN'])) {
         try {
             $sql = '
                 INSERT INTO s_order_attributes (orderID, swag_payal_express)
                 SELECT id, 1 FROM s_order WHERE ordernumber = ?
                 ON DUPLICATE KEY UPDATE swag_payal_express = 1
             ';
             $this->get('db')->query($sql, array($orderNumber));
         } catch (Exception $e) {
         }
     }
     // Stets transaction details
     $sql = '
         UPDATE `s_order`
         SET transactionID = ?, internalcomment = CONCAT(internalcomment, ?),
           customercomment = CONCAT(customercomment, ?)
         WHERE ordernumber = ?
     ';
     $this->get('db')->query($sql, array($result['TRANSACTIONID'], isset($details['EMAIL']) ? "{$details['EMAIL']} ({$details['PAYERSTATUS']})\r\n" : null, isset($details['NOTE']) ? $details['NOTE'] : '', $orderNumber));
     // Sets payment status
     $paymentStatus = $result['PAYMENTSTATUS'];
     $ppAmount = floatval($result['AMT']);
     $swAmount = $this->getAmount();
     if (abs($swAmount - $ppAmount) >= 0.01) {
         $paymentStatus = 'AmountMissMatch';
         //Überprüfung notwendig
     }
     $this->plugin->setPaymentStatus($result['TRANSACTIONID'], $paymentStatus);
     $result['INVNUM'] = $orderNumber;
     return $result;
 }
 /**
  * @param \Enlight_Controller_ActionEventArgs $args
  */
 public function onPreDispatchPaymentPaypal(\Enlight_Controller_ActionEventArgs $args)
 {
     $request = $args->getRequest();
     /** @var \Shopware_Controllers_Frontend_PaymentPaypal $controller */
     $controller = $args->getSubject();
     if ($request->getActionName() != 'return') {
         return;
     }
     $paymentId = $request->get('paymentId');
     if (!$paymentId) {
         return;
     }
     $payerId = $request->getParam('PayerID');
     $uri = 'payments/payment/' . $paymentId;
     $payment = array();
     try {
         $payment = $this->restClient->get($uri, array('payer_id' => $payerId));
     } catch (Exception $e) {
         $this->logException('An error occurred on getting the payment on returning from PayPal', $e);
     }
     if (!empty($payment['transactions'][0]['amount']['total'])) {
         $ppAmount = floatval($payment['transactions'][0]['amount']['total']);
         $ppCurrency = floatval($payment['transactions'][0]['amount']['currency']);
     } else {
         $ppAmount = 0;
         $ppCurrency = '';
     }
     $swAmount = $controller->getAmount();
     $swCurrency = $controller->getCurrencyShortName();
     if (abs($swAmount - $ppAmount) >= 0.01 || $ppCurrency != $swCurrency) {
         $controller->redirect(array('controller' => 'checkout', 'action' => 'confirm'));
         return;
     }
     $paypalConfig = $this->paypalBootstrap->Config();
     $orderNumber = null;
     if ($payment['state'] == 'created') {
         if ($paypalConfig->get('paypalSendInvoiceId')) {
             $orderNumber = $controller->saveOrder($payment['id'], sha1($payment['id']));
             $params = array(array('op' => 'add', 'path' => '/transactions/0/invoice_number', 'value' => $orderNumber));
             $prefix = $paypalConfig->get('paypalPrefixInvoiceId');
             if ($prefix) {
                 // Set prefixed invoice id - Remove special chars and spaces
                 $prefix = str_replace(' ', '', $prefix);
                 $prefix = preg_replace('/[^A-Za-z0-9\\_]/', '', $prefix);
                 $params[0]['value'] = $prefix . $orderNumber;
             }
             $uri = 'payments/payment/' . $paymentId;
             try {
                 $this->restClient->patch($uri, $params);
             } catch (Exception $e) {
                 $this->logException('An error occurred on patching the order number to the payment', $e);
             }
         }
         $uri = "payments/payment/{$paymentId}/execute";
         try {
             $payment = $this->restClient->create($uri, array('payer_id' => $payerId));
         } catch (Exception $e) {
             $this->logException('An error occurred on executing the payment', $e);
         }
     }
     if ($payment['state'] == 'approved') {
         if (!empty($payment['transactions'][0]['related_resources'][0]['sale']['id'])) {
             $transactionId = $payment['transactions'][0]['related_resources'][0]['sale']['id'];
         } else {
             $transactionId = $payment['id'];
         }
         if (!$orderNumber) {
             $orderNumber = $controller->saveOrder($transactionId, sha1($payment['id']));
         } else {
             $sql = 'UPDATE s_order
                     SET transactionID = ?
                     WHERE ordernumber = ?;';
             $controller->get('db')->query($sql, array($transactionId, $orderNumber));
         }
         if (!empty($payment['transactions'][0]['related_resources'][0]['sale']['state'])) {
             $paymentStatus = ucfirst($payment['transactions'][0]['related_resources'][0]['sale']['state']);
             $this->paypalBootstrap->setPaymentStatus($transactionId, $paymentStatus);
         }
         if ($payment['payment_instruction']) {
             $this->saveInvoiceInstructions($orderNumber, $payment);
         }
         try {
             $sql = '
                 INSERT INTO s_order_attributes (orderID, swag_payal_express)
                 SELECT id, 2 FROM s_order WHERE ordernumber = ?
                 ON DUPLICATE KEY UPDATE swag_payal_express = 2
             ';
             $controller->get('db')->query($sql, array($orderNumber));
         } catch (Exception $e) {
         }
         $controller->redirect(array('controller' => 'checkout', 'action' => 'finish', 'sUniqueID' => sha1($payment['id'])));
     }
 }