Model/Transactions/Method.php
<?php
/**
* 2007-2016 [PagSeguro Internet Ltda.]
*
* NOTICE OF LICENSE
*
*Licensed under the Apache License, Version 2.0 (the "License");
*you may not use this file except in compliance with the License.
*You may obtain a copy of the License at
*
*http://www.apache.org/licenses/LICENSE-2.0
*
*Unless required by applicable law or agreed to in writing, software
*distributed under the License is distributed on an "AS IS" BASIS,
*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*See the License for the specific language governing permissions and
*limitations under the License.
*
* @author PagSeguro Internet Ltda.
* @copyright 2016 PagSeguro Internet Ltda.
* @license http://www.apache.org/licenses/LICENSE-2.0
*/
namespace UOL\PagSeguro\Model\Transactions;
abstract class Method
{
/**
* Sanitize configuration
*
* @param $data
* @return mixed
*/
protected function sanitizeConfig($data)
{
$config = $this->_crypt->decrypt('!QAWRRR$HU%W34tyh59yh544%', $data);
$config = filter_var($config, FILTER_SANITIZE_URL);
return json_decode($config);
}
/**
* Get PagSeguro payments
*
* @param null $page
* @return \PagSeguro\Parsers\Transaction\Search\Date\Response|string
* @throws \Exception
*/
protected function getTransactions($page = null)
{
//check if has a page, if doesn't have one then start at the first.
if ($page===null) $page = 1;
try {
//check if is the first step, if is just add the response object to local var
if ($this->_PagSeguroPaymentList===null) {
$this->_PagSeguroPaymentList = $this->requestPagSeguroPayments($page);
} else {
$response = $this->requestPagSeguroPayments($page);
//update some important data
$this->_PagSeguroPaymentList->setDate($response->getDate());
$this->_PagSeguroPaymentList->setCurrentPage($response->getCurrentPage());
$this->_PagSeguroPaymentList->setResultsInThisPage(
$response->getResultsInThisPage() + $this->_PagSeguroPaymentList->getResultsInThisPage()
);
//add new transactions
$this->_PagSeguroPaymentList->addTransactions($response->getTransactions());
}
//check if was more pages
if ($this->_PagSeguroPaymentList->getTotalPages() > $page) {
$this->getPagSeguroPayments(++$page);
}
} catch (\Exception $exception) {
throw $exception;
}
return $this->_PagSeguroPaymentList;
}
/**
* Get all transactions where there is a pagseguro transaction code
* @return array
* @throws \Exception
*/
public function searchTransactions()
{
try {
$connection = $this->getConnection();
$select = $connection->select()
->from( ['order' => 'sales_order'], ['status', 'created_at', 'increment_id', 'store_id', 'entity_id'] )
->join( ['ps' => 'pagseguro_orders'], 'order.entity_id = ps.order_id')
->where('ps.transaction_code !== ?', '')
->order('order.created_at DESC');
if (!is_null($this->_session->getData('store_id'))) {
$select = $select->where('order.store_id = ?', $this->_session->getData('store_id'));
}
if ($this->_scopeConfig->getValue('payment/pagseguro/environment')) {
$select = $select->where('ps.environment = ?', $this->_scopeConfig->getValue('payment/pagseguro/environment'));
}
if (!empty($this->_idMagento)) {
$select = $select->where('order.increment_id = ?', $this->_idMagento);
}
if (!empty($this->_idPagseguro)) {
$select = $select->where('ps.transaction_code = ?', $this->_idPagseguro);
}
if (!empty($this->_status)) {
$select = $this->getStatusFromPaymentKey($this->_status)=== 'partially_refunded'
? $select->where('ps.partially_refunded = ?', 1)
: $select->where('order.status = ?', $this->getStatusFromPaymentKey($this->_status));
}
if (!empty($this->_dateBegin) && !empty($this->_dateEnd)) {
$startDate = date('Y-m-d H:i:s', strtotime(str_replace("/", "-", $this->_dateBegin)));
$endDate = date('Y-m-d'.' 23:59:59', strtotime(str_replace("/", "-", $this->_dateEnd)));
$select = $select->where('order.created_at >= ?', $startDate)->where('order.created_at <= ?', $endDate);
}
$connection->prepare($select);
return $connection->fetchAll($select);
} catch (\Exception $exception) {
throw $exception;
}
}
/** Get and formats transaction details
* @param $transactionCode
* @throws Exception
*/
public function getDetailsTransaction($transactionCode)
{
$this->_detailsTransactionByCode = $this->getTransactionsByCode($transactionCode);
if(!empty($this->_detailsTransactionByCode)){
$order = $this->decryptOrderById($this->_detailsTransactionByCode);
if ($this->getStoreReference()=== $this->decryptReference($this->_detailsTransactionByCode)) {
if ($this->_detailsTransactionByCode->getStatus()=== $this->getKeyFromOrderStatus($order->getStatus())) {
$this->_detailsTransactionByCode = $this->buildDetailsTransaction();
$this->_needConciliate = false;
}
}
}
}
/**
* Request PagSeguroTransaction details by code
* @param $code
*
* @return null|object
* @throws Exception
*/
public function getTransactionsByCode($code)
{
$this->_library->setEnvironment();
$this->_library->setCharset();
$this->_library->setLog();
$response = null;
try {
$response = \PagSeguro\Services\Transactions\Search\Code::search(
$this->_library->getPagSeguroCredentials(),
$code
);
return $response;
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
}
/**
* Request all PagSeguroTransaction in this _date interval
*
* @param $page
* @return string
* @throws \Exception
*/
protected function requestPagSeguroPayments($page)
{
$date = $this->getDates();
$options = [
'initial_date' => $date['initial'],
'final_date' => $date['final'],
'page' => $page,
'max_per_page' => 1000,
];
try {
$this->_library->setEnvironment();
$this->_library->setCharset();
$this->_library->setLog();
return \PagSeguro\Services\Transactions\Search\Date::search(
$this->_library->getPagSeguroCredentials(),
$options
);
} catch (Exception $exception) {
throw $exception;
}
}
/**
* Get date interval from days qty.
*
* @return array
*/
protected function getDates()
{
$date = new \DateTime ( "now" );
$date->setTimezone ( new \DateTimeZone ( "America/Sao_Paulo" ) );
$final = $date->format ( "Y-m-d\TH:i:s" );
$dateInterval = "P" . ( string ) $this->_days . "D";
$date->sub ( new \DateInterval ( $dateInterval ) );
$date->setTime ( 00, 00, 00 );
$initial = $date->format ( "Y-m-d\TH:i:s" );
return [
'initial' => $initial,
'final' => $final
];
}
/**
* @param $payment
* @return mixed
*/
protected function decryptOrderById($payment)
{
return $this->_order->load(\UOL\PagSeguro\Helper\Data::getReferenceDecryptOrderID($payment->getReference()));
}
/**
* @param $status
* @return bool|string
*/
protected function getStatusFromPaymentKey($status)
{
return \UOL\PagSeguro\Helper\Data::getStatusFromKey($status);
}
/**
* @param $status
* @return bool|string
*/
protected function getStatusString($status)
{
return \UOL\PagSeguro\Helper\Data::getPaymentStatusToString($status);
}
/**
* @param $order
* @return mixed
*/
protected function getKeyFromOrderStatus($status)
{
$param = is_object($status) ? $status->getStatus() : $status;
return \UOL\PagSeguro\Helper\Data::getKeyFromStatus($param);
}
/**
* @param $payment
* @return bool|string
*/
protected function formatPagSeguroStatus($payment)
{
return $this->getStatusString($payment->getStatus());
}
/**
* @param string $status
* @param integer $isPartiallyRefunded
* @return bool|string
*/
protected function formatMagentoStatus($status, $isPartiallyRefunded = 0)
{
return $isPartiallyRefunded
? $this->getStatusString($this->getKeyFromOrderStatus($status)) . ' (estornada parcialmente)'
: $this->getStatusString($this->getKeyFromOrderStatus($status));
}
/**
* @param $order
* @return string
*/
protected function formatMagentoId($order)
{
return sprintf('#%s', $order->getIncrementId());
}
/**
* @param $order
* @return false|string
*/
protected function formatDate($order)
{
$param = is_object($order) ? $order->getCreatedAt() : $order;
return date("d/m/Y H:i:s", strtotime($param));
}
/**
* @param $payment
* @return string
*/
protected function decryptReference($payment)
{
return \UOL\PagSeguro\Helper\Data::getReferenceDecrypt($payment->getReference());
}
/**
* Get store reference
*
* @return mixed
*/
protected function getStoreReference()
{
return $this->_scopeConfig->getValue('pagseguro/store/reference');
}
/**
* Update the sales_order_grid table transaction code
*
* @param int $orderId
* @param string $transactionCode
*/
protected function updateSalesOrder($orderId, $transactionCode)
{
$this->updateOrders('sales_order_grid', $orderId, $transactionCode);
}
/**
* Update the `pagseguro_orders` table
*
* @param int $orderId
* @param string $transactionCode
* @return void
*/
protected function updatePagSeguroOrders($orderId, $transactionCode)
{
$this->updateOrders('pagseguro_orders', $orderId, $transactionCode);
}
/**
* @param $table
* @param $orderId
* @param $transactionCode
*/
private function updateOrders($table, $orderId, $transactionCode)
{
$this->getConnection()
->query(sprintf(
"UPDATE `%s` SET transaction_code='%s' WHERE entity_id='%s'",
$this->getPrefixTableName($table),
$transactionCode,
$orderId
));
}
/**
* @return mixed
*/
private function getConnection()
{
return $this->_resource->getConnection();
}
/**
* @param $table
* @return mixed
*/
private function getPrefixTableName($table)
{
return $this->_resource->getTableName($table);
}
/**
* Update column 'partially_refunded' the `pagseguro_orders` table
*
* @param int $orderId
* @return void
*/
protected function updatePartiallyRefundedPagSeguro($orderId)
{
$this->getConnection()
->query(sprintf(
"UPDATE `%s` SET partially_refunded = 1 WHERE entity_id='%s'",
$this->getPrefixTableName('pagseguro_orders'),
$orderId
));
}
/**
* Get all pagseguro partially refunded orders id
*
* @return array
*/
protected function getPartiallyRefundedOrders()
{
$pagseguroOrdersIdArray = array();
$connection = $this->getConnection();
$select = $connection->select()
->from( ['ps' => $this->getPrefixTableName('pagseguro_orders')], ['order_id'] )
->where('ps.partially_refunded = ?', '1');
if ($this->_scopeConfig->getValue('payment/pagseguro/environment')) {
$select = $select->where('ps.environment = ?', $this->_scopeConfig->getValue('payment/pagseguro/environment'));
}
$connection->prepare($select);
foreach ($connection->fetchAll($select) as $value) {
$pagseguroOrdersIdArray[] = $value['order_id'];
}
return $pagseguroOrdersIdArray;
}
/**
* @param $order
* @param $payment
* @param $options
* @return mixed
*/
abstract protected function details($order, $payment, $options);
/**
* @param $data
* @return mixed
*/
abstract public function execute($data);
/**
* @param $payment
* @param $order
* @return mixed
*/
abstract protected function build($payment, $order);
/**
* Build and format the transaction data for the listing
* @return array
*/
public function buildDetailsTransaction()
{
return array(
'date' => $this->formatDate($this->_detailsTransactionByCode->getDate()),
'code' => $this->_detailsTransactionByCode->getCode(),
'reference' => $this->_detailsTransactionByCode->getReference(),
'type' => \UOL\PagSeguro\Helper\Data::getTransactionTypeName($this->_detailsTransactionByCode->getType()),
'status' => \UOL\PagSeguro\Helper\Data::getPaymentStatusToString($this->_detailsTransactionByCode->getStatus()),
'lastEventDate' => $this->formatDate($this->_detailsTransactionByCode->getLastEventDate()),
'installmentCount' => $this->_detailsTransactionByCode->getInstallmentCount(),
'cancelationSource' => \UOL\PagSeguro\Helper\Data::getTitleCancellationSourceTransaction($this->_detailsTransactionByCode->getCancelationSource()),
'discountAmount' => $this->_detailsTransactionByCode->getDiscountAmount(),
'escrowEndDate' => $this->formatDate($this->_detailsTransactionByCode->getEscrowEndDate()),
'extraAmount' => $this->_detailsTransactionByCode->getExtraAmount(),
'feeAmount' => $this->_detailsTransactionByCode->getFeeAmount(),
'grossAmount' => $this->_detailsTransactionByCode->getGrossAmount(),
'netAmount' => $this->_detailsTransactionByCode->getNetAmount(),
'creditorFees' => $this->prepareCreditorFees(),
'itemCount' => $this->_detailsTransactionByCode->getItemCount(),
'items' => $this->prepareItems(),
'paymentMethod' => $this->preparePaymentMethod(),
'sender' => $this->prepareSender(),
'shipping' => $this->prepareShipping(),
'paymentLink' => $this->_detailsTransactionByCode->getPaymentLink(),
'promoCode' => $this->_detailsTransactionByCode->getPromoCode()
);
}
/**
* Format transaction CreditorFees
* @return array|string
*/
private function prepareCreditorFees()
{
$creditorFees = "";
if(!empty($this->_detailsTransactionByCode->getCreditorFees()))
{
$creditorFees = array(
'intermediationRateAmount' => $this->_detailsTransactionByCode->getCreditorFees()->getIntermediationRateAmount(),
'intermediationFeeAmount' => $this->_detailsTransactionByCode->getCreditorFees()->getIntermediationFeeAmount(),
'installmentFeeAmount' => $this->_detailsTransactionByCode->getCreditorFees()->getInstallmentFeeAmount(),
'operationalFeeAmount' => $this->_detailsTransactionByCode->getCreditorFees()->getOperationalFeeAmount(),
'commissionFeeAmount' => $this->_detailsTransactionByCode->getCreditorFees()->getCommissionFeeAmount()
);
}
return $creditorFees;
}
/**
* Format transaction Items
* @return array
*/
private function prepareItems()
{
$itens = array();
if($this->_detailsTransactionByCode->getItemCount() > 0) {
foreach ($this->_detailsTransactionByCode->getItems() as $item)
{
$itens[] = array(
'id' => $item->getId(),
'description' => $item->getDescription(),
'quantity' => $item->getQuantity(),
'amount' => $item->getAmount(),
'weight' => $item->getWeight(),
'shippingCost' => $item->getShippingCost()
);
}
}
return $itens;
}
/**
* Format transaction PaymentMethod
* @return array|string
*/
private function preparePaymentMethod()
{
$paymentMethod = "";
if(!empty($this->_detailsTransactionByCode->getPaymentMethod()))
{
$paymentMethod = array(
'code' => $this->_detailsTransactionByCode->getPaymentMethod()->getCode(),
'type' => $this->_detailsTransactionByCode->getPaymentMethod()->getType(),
'titleType' => \UOL\PagSeguro\Helper\Data::getTitleTypePaymentMethod($this->_detailsTransactionByCode->getPaymentMethod()->getType()),
'titleCode' => \UOL\PagSeguro\Helper\Data::getTitleCodePaymentMethod($this->_detailsTransactionByCode->getPaymentMethod()->getCode())
);
}
return $paymentMethod;
}
/**
* Format transaction Sender
* @return array
*/
private function prepareSender()
{
$documents = array();
if(count($this->_detailsTransactionByCode->getSender()->getDocuments()) > 0) {
foreach ($this->_detailsTransactionByCode->getSender()->getDocuments() as $doc)
{
$documents[] = array(
'type' => $doc->getType(),
'identifier' => $doc->getIdentifier()
);
}
}
$sender = array();
if(!empty($this->_detailsTransactionByCode->getSender())){
$sender = array(
'name' => $this->_detailsTransactionByCode->getSender()->getName(),
'email' => $this->_detailsTransactionByCode->getSender()->getEmail(),
'phone' => array(
'areaCode' => $this->_detailsTransactionByCode->getSender()->getPhone()->getAreaCode(),
'number' => $this->_detailsTransactionByCode->getSender()->getPhone()->getNumber()
),
'documents' => $documents
);
}
return $sender;
}
/**
* Format transaction Shipping
* @return array
*/
private function prepareShipping()
{
$shipping = array();
if(!empty($this->_detailsTransactionByCode->getShipping())){
$shipping = array(
'addres' => array(
'street' => $this->_detailsTransactionByCode->getShipping()->getAddress()->getStreet(),
'number' => $this->_detailsTransactionByCode->getShipping()->getAddress()->getNumber(),
'complement' => $this->_detailsTransactionByCode->getShipping()->getAddress()->getComplement(),
'district' => $this->_detailsTransactionByCode->getShipping()->getAddress()->getDistrict(),
'postalCode' => $this->_detailsTransactionByCode->getShipping()->getAddress()->getPostalCode(),
'city' => $this->_detailsTransactionByCode->getShipping()->getAddress()->getCity(),
'state' => $this->_detailsTransactionByCode->getShipping()->getAddress()->getState(),
'country' => $this->_detailsTransactionByCode->getShipping()->getAddress()->getCountry()
),
'type' => $this->_detailsTransactionByCode->getShipping()->getType()->getType(),
'cost' => $this->_detailsTransactionByCode->getShipping()->getCost()->getCost()
);
}
return $shipping;
}
}