Handles response for NotificationType = PaymentRefund

@param stdClass $oData

@return boolean
@throws oxConnectionException
@throws Exception
549790
protected function _paymentRefund($oData)
    {
        $sAmazonRefundId = $oData->RefundDetails->AmazonRefundId;
        $sSql = "SELECT COUNT(*)
            FROM bestitamazonrefunds 
            WHERE BESTITAMAZONREFUNDID = {$this->getDatabase()->quote($sAmazonRefundId)}
            LIMIT 1";
        $iMatches = (int)$this->getDatabase()->getOne($sSql);

        //Update Refund info
        if ($iMatches > 0 && isset($oData->RefundDetails->RefundStatus->State)) {
            $this->getClient()->updateRefund(
                $oData->RefundDetails->RefundStatus->State,
                $sAmazonRefundId
            );
            $this->logIPNResponse(Logger::INFO, 'OK', $oData);
            return true;
        }

        $this->logIPNResponse(Logger::ERROR, "Refund with Refund ID: {$sAmazonRefundId} not found", $oData);
        return false;
    }
851679
public function validatePaymentReference(Structure\RequestReferenceDetails $paymentData)
    {
        $this->response = parent::validatePaymentReference($this->entity, $paymentData);

        /**
         * Checks the state of the platform integration.
         */
        if (Exception\IntegrationState::check($this->response->integrationState)) {
            throw new Exception\IntegrationState($this->response->integrationState);
        }

        /**
         * In case an error code is returned not related to the integration state.
         * (eg.: maximum daily amount exceeded, maximum reference amount, etc.)
         */
        if (!empty($this->response->err_code)) {
            throw new Exception\IntegrationResponse(
                $this->response->err_msg,
                $this->response->err_code
            );
        }

        return $this->response;
    }
27907
public function execute($data) {

        $this->getDetailsTransaction(str_replace('-', '', $data));

        if(!empty($this->_detailsTransactionByCode) && $this->_needConciliate){
            throw new \Exception('need to conciliate');
        }

        if (empty($this->_detailsTransactionByCode)) {
            throw new \Exception('empty');
        }
        return $this->_detailsTransactionByCode;
    }
154609
public function onCallbackSuccess($order, $data = null)
    {
        try {

            $response = $this->omnipay->completePurchase([
                'transactionId'    => $order->transactionId,
            ])->send();

            if ($response->isSuccessful()) {

                $this->statusCode = 'completed';

                $this->transactionId = $this->omnipay->getTransactionId();

                $this->detail = 'Success';

            } else {

                throw new GatewayException($response->getMessage(), 1);

            }

        } catch (\Exception $e) {

            throw new GatewayException(
                $e->getMessage(),
                1000,
                $e
            );

        }
    }
699891
def void
            
      resp = StdClass.new
      t = InvoiceTransaction.where(:invoice_id => self.id, :transaction_type => InvoiceTransaction::TYPE_AUTHORIZE, :success => true).first
      
      if self.financial_status == Invoice::FINANCIAL_STATUS_CAPTURED
        resp.error = "This invoice has already been captured, you will need to refund instead"
      elsif t.nil?
        resp.error = "This invoice doesn't seem to be authorized."
      else
                
        sc = self.site.store_config
        ot = Caboose::InvoiceTransaction.new(
          :invoice_id => self.id,
          :date_processed => DateTime.now.utc,
          :transaction_type => InvoiceTransaction::TYPE_VOID,
          :payment_processor => sc.pp_name,
          :amount => self.total
        )
        
        case sc.pp_name
          when 'authorize.net'            
            response = AuthorizeNet::SIM::Transaction.new(
              sc.authnet_api_login_id, 
              sc.authnet_api_transaction_key,                      
              self.total,
              :transaction_type => InvoiceTransaction::TYPE_VOID,
              :transaction_id => t.transaction_id,
              :test => sc.pp_testing
            )                    
            self.update_attributes(
              :financial_status => Invoice::FINANCIAL_STATUS_VOIDED,
              :status => Invoice::STATUS_CANCELED
            )
            self.save          
            # TODO: Add the variant quantities invoiceed back        
            resp.success = "Invoice voided successfully"
                        
            ot.success        = response.response_code && response.response_code == '1'            
            ot.transaction_id = response.transaction_id
            #ot.auth_code      = response.authorization_code
            ot.response_code  = response.response_code            
            ot.save
          
          when 'stripe'
            # TODO: Implement void invoice for strip
            
          when 'payscape'
            # TODO: Implement void invoice for payscape
            
        end
        
      end
      return resp      
    end
258260
function _doRefund($oID, $amount = 'Full', $note = '') {
    global $db, $doPayPal, $messageStack;
    $new_order_status = (int)MODULE_PAYMENT_PAYPALDP_REFUNDED_STATUS_ID;
    $orig_order_amount = 0;
    $doPayPal = $this->paypal_init();
    $proceedToRefund = false;
    $refundNote = strip_tags(zen_db_input($_POST['refnote']));
    if (isset($_POST['fullrefund']) && $_POST['fullrefund'] == MODULE_PAYMENT_PAYPAL_ENTRY_REFUND_BUTTON_TEXT_FULL) {
      $refundAmt = 'Full';
      if (isset($_POST['reffullconfirm']) && $_POST['reffullconfirm'] == 'on') {
        $proceedToRefund = true;
      } else {
        $messageStack->add_session(MODULE_PAYMENT_PAYPALDP_TEXT_REFUND_FULL_CONFIRM_ERROR, 'error');
      }
    }
    if (isset($_POST['partialrefund']) && $_POST['partialrefund'] == MODULE_PAYMENT_PAYPAL_ENTRY_REFUND_BUTTON_TEXT_PARTIAL) {
      $refundAmt = (float)$_POST['refamt'];
      $proceedToRefund = true;
      if ($refundAmt == 0) {
        $messageStack->add_session(MODULE_PAYMENT_PAYPALDP_TEXT_INVALID_REFUND_AMOUNT, 'error');
        $proceedToRefund = false;
      }
    }

    // look up history on this order from PayPal table
    $sql = "select * from " . TABLE_PAYPAL . " where order_id = :orderID  AND parent_txn_id = '' ";
    $sql = $db->bindVars($sql, ':orderID', $oID, 'integer');
    $zc_ppHist = $db->Execute($sql);
    if ($zc_ppHist->RecordCount() == 0) return false;
    $txnID = $zc_ppHist->fields['txn_id'];
    $curCode = $zc_ppHist->fields['mc_currency'];
    $PFamt = $zc_ppHist->fields['mc_gross'];
    if ($doPayPal->_mode == 'payflow' && $refundAmt == 'Full') $refundAmt = $PFamt;

    /**
     * Submit refund request to PayPal
     */
    if ($proceedToRefund) {
       $response = $doPayPal->RefundTransaction($oID, $txnID, $refundAmt, $refundNote, $curCode);
      $error = $this->_errorHandler($response, 'DoRefund');
      $new_order_status = ($new_order_status > 0 ? $new_order_status : 1);
      if (!$error) {
        if (!isset($response['GROSSREFUNDAMT'])) $response['GROSSREFUNDAMT'] = $refundAmt;
        // Success, so save the results
        $sql_data_array = array('orders_id' => $oID,
                                'orders_status_id' => (int)$new_order_status,
                                'date_added' => 'now()',
                                'comments' => 'REFUND INITIATED. Trans ID:' . $response['REFUNDTRANSACTIONID'] . $response['PNREF']. "\n" . /*' Net Refund Amt:' . urldecode($response['NETREFUNDAMT']) . "\n" . ' Fee Refund Amt: ' . urldecode($response['FEEREFUNDAMT']) . "\n" . */' Gross Refund Amt: ' . urldecode($response['GROSSREFUNDAMT']) . (isset($response['PPREF']) ? "\nPPRef: " . $response['PPREF'] : '') . "\n" . $refundNote,
                                'customer_notified' => 0
                             );
        zen_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);
        $db->Execute("update " . TABLE_ORDERS  . "
                      set orders_status = '" . (int)$new_order_status . "'
                      where orders_id = '" . (int)$oID . "'");
        $messageStack->add_session(sprintf(MODULE_PAYMENT_PAYPALDP_TEXT_REFUND_INITIATED, urldecode($response['GROSSREFUNDAMT']), urldecode($response['REFUNDTRANSACTIONID']). $response['PNREF']), 'success');
        return true;
      }
    }
  }
1091150
public function callback($data)
    {
        $payload = $data;
        $this->logger->debug($payload);
        $decoded  = JWT::decode($payload, $this->payapiApiKey, ['HS256']);
        $jsonData = json_decode($decoded);
        $result   = null;

        if ($jsonData->payment->status == 'processing') {
            //Processing async payment
            $this->logger->debug("PROCESSING CALLBACK...");
            $order_id = $this->helper->createOrder($jsonData);
            $result   = ['platform' => 'magento', 'order_id' => $order_id];
        } else {
            $orderId = $this->getOrderId($jsonData);
            if ($orderId) {
                if ($jsonData->payment->status == 'successful') {
                    $this->logger->debug("SUCCESSFUL CALLBACK...");
                    //Payment success
                    $order_id = $this->helper->addPayment($orderId);
                    $result   = ['platform' => 'magento', 'order_id' => $order_id];
                } elseif ($jsonData->payment->status == 'failed') {
                    //Payment failure
                    $this->logger->debug("FAILED CALLBACK...");
                    $order_id = $this->helper->changeStatus($orderId, "canceled", "canceled", "failed");
                    $result   = ['platform' => 'magento', 'order_id' => $order_id];
                } elseif ($jsonData->payment->status == 'cancelled') {
                    //Payment failure
                    $this->logger->debug("CANCELLED CALLBACK...");
                    $order_id = $this->helper->changeStatus($orderId, "canceled", "canceled", "cancelled");
                    $result   = ['platform' => 'magento', 'order_id' => $order_id]; 
                } elseif ($jsonData->payment->status == 'chargeback') {
                    $this->logger->debug("CHARGEBACK CALLBACK...");
                    $order_id = $this->helper->changeStatus(
                        $orderId,
                        "payment_review",
                        "payment_review",
                        "chargeback"
                    );

                    $result = ['platform' => 'magento', 'order_id' => $order_id];
                } else {
                    //Payment cancelled
                    $this->logger->debug("STATUS CALLBACK: ".$jsonData->payment->status);
                    $order_id = $this->helper->changeStatus(
                        $orderId,
                        "payment_review",
                        "payment_review",
                        $jsonData->payment->status
                    );

                    $result = ['platform' => 'magento', 'order_id' => $order_id];
                }
            }
        }

        if (isset($result)) {
            $this->logger->debug(json_encode($result));
            return json_encode($result);
        } else {
            $this->logger->debug("KO. COULD NOT CREATE ORDER OR ADD PAYMENT");
            throw new \Magento\Framework\Exception\LocalizedException(__('Could not create the order correctly.'));
        }
    }
131594
final public function addStatus(TPkgShopOrderStatusData $oData)
    {
        $this->getShopLogger()->info('add status', array('oData' => $oData));
        $this->validateStatusData($oData);
        $this->getShopLogger()->info('status validated ok');
        $aData = $oData->getDataAsTdbArray();
        $oStatus = TdbShopOrderStatus::GetNewInstance($aData);
        $oStatus->AllowEditByAll(true);
        $oStatus->SaveFieldsFast($aData);
        $oStatus->AllowEditByAll(false);
        $this->getShopLogger()->info('status saved');

        $aItems = $oData->getItems();
        $itemCount = count($aItems);
        $count = 0;
        /** @var TPkgShopOrderStatusItemData $item */
        foreach ($aItems as $item) {
            ++$count;
            $this->getShopLogger()->info("process status  {$count}/{$itemCount}");
            $aItem = $item->getDataAsTdbArray();
            $aItem['shop_order_status_id'] = $oStatus->id;

            $oItem = TdbShopOrderStatusItem::GetNewInstance($aItem);
            $oItem->AllowEditByAll(true);
            $oItem->SaveFieldsFast($aItem);
            $oItem->AllowEditByAll(false);
        }

        $aExceptionList = $this->orderStatusAddedHook($oStatus);
        if (count($aExceptionList) > 0) {
            $orderId = $oData->getOrder()->id;
            $e = new TPkgShopOrderStatusException_PostOrderStatusAddedExceptions(
                "post order status added hook throw multiple exceptions for order {$orderId} with status {$oStatus->id}",
                array('oData' => $oData, 'status' => $oStatus->sqlData)
            );
            $e->setExceptionList($aExceptionList)->setOrderStatus($oStatus);
            throw $e;
        }

        return $oStatus;
    }
381222
public function objectCreate($oData)
    {
        $sBucket       = !empty($oData->bucket->slug) ? $oData->bucket->slug : '';
        $sFilenameOrig = !empty($oData->filename) ? $oData->filename : '';
        $sFilename     = strtolower(substr($sFilenameOrig, 0, strrpos($sFilenameOrig, '.')));
        $sExtension    = strtolower(substr($sFilenameOrig, strrpos($sFilenameOrig, '.')));
        $sSource       = !empty($oData->file) ? $oData->file : '';
        $sMime         = !empty($oData->mime) ? $oData->mime : '';
        $sName         = !empty($oData->name) ? $oData->name : 'file' . $sExtension;

        // --------------------------------------------------------------------------

        try {

            //  Create "normal" version
            $this->sdk()->putObject([
                'Bucket'      => $this->getBucket(),
                'Key'         => $sBucket . '/' . $sFilename . $sExtension,
                'SourceFile'  => $sSource,
                'ContentType' => $sMime,
                'ACL'         => 'public-read',
            ]);

            //  Create "download" version
            $this->sdk()->copyObject([
                'Bucket'             => $this->getBucket(),
                'CopySource'         => $this->getBucket() . '/' . $sBucket . '/' . $sFilename . $sExtension,
                'Key'                => $sBucket . '/' . $sFilename . '-download' . $sExtension,
                'ContentType'        => 'application/octet-stream',
                'ContentDisposition' => 'attachment; filename="' . str_replace('"', '', $sName) . '" ',
                'MetadataDirective'  => 'REPLACE',
                'ACL'                => 'public-read',
            ]);

            return true;

        } catch (\Exception $e) {
            $this->setError('AWS-SDK EXCEPTION: [objectCreate]: ' . $e->getMessage());
            return false;
        }
    }
165092
protected function _orderReferenceUpdate($oData)
    {
        $sId = $oData->OrderReference->AmazonOrderReferenceId;
        $oOrder = $this->_loadOrderById('BESTITAMAZONORDERREFERENCEID', $sId);

        if ($oOrder !== false && isset($oData->OrderReference->OrderReferenceStatus->State)) {
            $this->getClient()->processOrderReference($oOrder, $oData->OrderReference);
            $this->logIPNResponse(Logger::INFO, 'OK', $oData);
            return true;
        }

        $this->logIPNResponse(Logger::ERROR, "Order with Order Reference ID: {$sId} not found", $oData);
        return false;
    }
306664
private function matchRequest(&$classData)
    {
        if (!is_array($classData)) {
            throw new RestException("Invalid class cache data.");
        }

        // build the request url upon which we will do the matching
        try {
            $url = $this->getUrl();
        } catch (\Exception $e) {
            throw $e;
        }


        // get request method
        $method = $this->getMethod();
        if (!in_array($method, self::$supportedRequestTypes)) {
            throw new RestException('Unsupported request method: "' . $method . '"');
        }

        $callbacks = (empty($classData[$method])) ? [] : $classData[$method];

        // match array
        $matchedMethod = [
            'methodData'        => false,
            'matchedParameters' => false
        ];

        // validate that we have the ending class name in the url
        $classUrl = PathTransformations::classNameToUrl($this->class, $this->normalize);
        if (strpos($url, '/' . $classUrl . '/') !== false) {
            $matchedMethod = $this->matchMethod($callbacks, $url);

            // if method was not matched
            if (!$matchedMethod['methodData']) {
                // if no method was matched, let's try to match a default method
                $matchedMethod = $this->matchDefaultMethod($callbacks, $url, $classUrl);
            }
        }

        $methodData = (isset($matchedMethod['methodData'])) ? $matchedMethod['methodData'] : false;
        $matchedParameters = ($matchedMethod['matchedParameters']) ? $matchedMethod['matchedParameters'] : [];

        $requestBag = new RequestBag();
        $requestBag->setClassData($classData)
                   ->setMethodData($methodData)
                   ->setMethodParameters($matchedParameters)
                   ->setApi($this->api);

        $callback = new Callback($requestBag);

        return $callback->getCallbackResult();
    }
130253
public function addCalendar($jsonData)
    {
        if ($jsonData == '')
            throw new Exception('Data not specified');

        //build URI
        $strURI = Product::$baseProductUri . '/tasks/' . $this->getFileName() . '/calendars/';

        //sign URI
        $signedURI = Utils::sign($strURI);

        $responseStream = Utils::processCommand($signedURI, 'POST', 'json', $jsonData);

        $json = json_decode($responseStream);

        if ($json->Status == 'Created')
            return $json->CalendarItem;
        else
            return false;
    }
1361504
public function checkWebPayment($token, $transactionId)
    {
        $requestPayment = new Structure\RequestPaymentDetails($token, $transactionId);

        $this->response = parent::checkWebPayment($this->entity, $requestPayment);

        /**
         * Checks the state of the platform integration.
         */
        if (Exception\IntegrationState::check($this->response->requestState)) {
            throw new Exception\IntegrationState($this->response->requestState);
        }

        if ($this->response->requestState->state == 0) {
            throw new Exception\IntegrationResponse(
                $this->response->requestState->message,
                $this->response->requestState->code
            );
        }

        return $this->response;
    }
545795
function _doRefund($oID, $amount = 0) {
    global $db, $messageStack;
    $_POST['refamt'] = preg_replace('/[^0-9.%]/', '', $_POST['refamt']);
    $new_order_status = (int)MODULE_PAYMENT_LINKPOINT_API_REFUNDED_ORDER_STATUS_ID;
    if ($new_order_status == 0) $new_order_status = 1;
    $proceedToRefund = true;
    $refundNote = strip_tags(zen_db_input($_POST['refnote']));
    if (isset($_POST['refconfirm']) && $_POST['refconfirm'] != 'on') {
      $messageStack->add_session(MODULE_PAYMENT_LINKPOINT_API_TEXT_REFUND_CONFIRM_ERROR, 'error');
      $proceedToRefund = false;
    }
    if (isset($_POST['buttonrefund']) && $_POST['buttonrefund'] == MODULE_PAYMENT_LINKPOINT_API_ENTRY_REFUND_BUTTON_TEXT) {
      $refundAmt = (float)$_POST['refamt'];
      $new_order_status = (int)MODULE_PAYMENT_LINKPOINT_API_REFUNDED_ORDER_STATUS_ID;
      if ($refundAmt == 0) {
        $messageStack->add_session(MODULE_PAYMENT_LINKPOINT_API_TEXT_INVALID_REFUND_AMOUNT, 'error');
        $proceedToRefund = false;
      }
    }
    if (isset($_POST['cc_number']) && (int)trim($_POST['cc_number']) == 0) {
      $messageStack->add_session(MODULE_PAYMENT_LINKPOINT_API_TEXT_CC_NUM_REQUIRED_ERROR, 'error');
    }
    if (isset($_POST['trans_id']) && (int)trim($_POST['trans_id']) == 0) {
      $messageStack->add_session(MODULE_PAYMENT_LINKPOINT_API_TEXT_TRANS_ID_REQUIRED_ERROR, 'error');
      $proceedToRefund = false;
    }

    $sql = "select lp_trans_num, transaction_time from " . TABLE_LINKPOINT_API . " where order_id = " . (int)$oID . " and transaction_result = 'APPROVED' order by transaction_time DESC";
    $query = $db->Execute($sql);
    if ($query->RecordCount() < 1) {
      $messageStack->add_session(MODULE_PAYMENT_LINKPOINT_API_TEXT_NO_MATCHING_ORDER_FOUND, 'error');
      $proceedToRefund = false;
    }
    /**
     * Submit refund request to gateway
     */
    if ($proceedToRefund) {
      unset($myorder);
      $myorder["ordertype"] = 'CREDIT';
      $myorder["oid"] = $query->fields['lp_trans_num'];
      if ($_POST['trans_id'] != '') $myorder["tdate"] = $_POST['trans_id'];
      $myorder["chargetotal"] = number_format($refundAmt, 2, '.', '');
      $myorder["comments"]  = htmlentities($refundNote, ENT_QUOTES, 'UTF-8');

      $result = $this->_sendRequest($myorder);
      $response_alert = $result['r_approved'] . ' ' . $result['r_error'] . ($this->commError == '' ? '' : ' Communications Error - Please notify webmaster.');
      $this->reportable_submit_data['Note'] = $refundNote;
      $failure = ($result["r_approved"] != "APPROVED");
      if ($failure) {
        $messageStack->add_session($response_alert, 'error');
      } else {
        // Success, so save the results
        $this->_updateOrderStatus($oID, $new_order_status, 'REFUND INITIATED. Order ID:' . $result['r_ordernum'] . ' - ' . 'Trans ID: ' . $result['r_tdate'] . "\n" . 'Amount: ' . $myorder["chargetotal"] . "\n" . $refundNote);
        $messageStack->add_session(sprintf(MODULE_PAYMENT_LINKPOINT_API_TEXT_REFUND_INITIATED, $result['r_tdate'], $result['r_ordernum']), 'success');
        return true;
      }
    }
    return false;
  }
1070388
public function update($iPaymentId, array $aData = []): bool
    {
        $oDb = Factory::service('Database');

        try {

            $oDb->trans_begin();

            unset($aData['ref']);
            unset($aData['token']);

            if (array_key_exists('custom_data', $aData)) {
                $aData['custom_data'] = json_encode($aData['custom_data']);
            }

            $bResult = parent::update($iPaymentId, $aData);

            if (!$bResult) {
                throw new PaymentException('Failed to update payment.');
            }

            $oDb->trans_commit();
            $this->triggerEvent(
                Events::PAYMENT_UPDATED,
                [$this->getPaymentForEvent($iPaymentId)]
            );

            return $bResult;

        } catch (\Exception $e) {
            $oDb->trans_rollback();
            $this->setError($e->getMessage());
            return false;
        }
    }
390639
function execute(O $o) {
		if (df_is_checkout_multishipping()) {
			$p = $o['payment']; /** @var OP $p */
			/**
			 * 2017-08-28
			 * I intentionally do not use @see dfp_my() here, 
			 * because this function will instantiate a @see \Df\Payment\Method instance
			 * (or use a previously cached instance). 
			 */
			if (df_starts_with(($code = $p->getMethod()), 'dfe_')) { /** @var string $code */
				Method::sgReset();
				if ($cardId = Token::exchangedGet($code)) {  /** @var string|null $cardId */
					dfp_add_info($p, [Token::KEY => $cardId]);
				}
			}
		}
	}
1092590
public function initializeUserForCallBackPayPalUser($payPalData)
    {
        // setting mode..
        $this->callBackUser = true;

        // setting data..
        $street = $this->splitShipToStreetPayPalUser($payPalData['SHIPTOSTREET']);

        // setting object id as it is requested later while processing user object
        $this->setId(\OxidEsales\Eshop\Core\UtilsObject::getInstance()->generateUID());

        $this->oxuser__oxstreet = new \OxidEsales\Eshop\Core\Field($street['street']);
        $this->oxuser__oxstreetnr = new \OxidEsales\Eshop\Core\Field($street['streetnr']);
        $this->oxuser__oxcity = new \OxidEsales\Eshop\Core\Field($payPalData['SHIPTOCITY']);
        $this->oxuser__oxzip = new \OxidEsales\Eshop\Core\Field($payPalData['SHIPTOZIP']);

        $country = oxNew(\OxidEsales\Eshop\Application\Model\Country::class);
        $countryId = $country->getIdByCode($payPalData["SHIPTOCOUNTRY"]);
        $this->oxuser__oxcountryid = new \OxidEsales\Eshop\Core\Field($countryId);

        $stateId = '';
        if (isset($payPalData["SHIPTOSTATE"])) {
            $state = oxNew(\OxidEsales\Eshop\Application\Model\State::class);
            $stateId = $state->getIdByCode($payPalData["SHIPTOSTATE"], $countryId);
        }
        $this->oxuser__oxstateid = new \OxidEsales\Eshop\Core\Field($stateId);
    }