Skip to content

Instantly share code, notes, and snippets.

@aldoanizio
Created October 15, 2016 18:24
Show Gist options
  • Save aldoanizio/3ca08a254ef55da89161e9f449b258d4 to your computer and use it in GitHub Desktop.
Save aldoanizio/3ca08a254ef55da89161e9f449b258d4 to your computer and use it in GitHub Desktop.
Classe de Pagamento PayPal
<?php
// PayPal Library
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\PaymentExecution;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Transaction;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Rest\ApiContext;
use PayPal\Exception\PayPalConnectionException;
// Monolog
use \Monolog\Logger;
/**
* Classe de Pagamento PayPal
*
* @author Aldo Anizio Lugão Camacho
* @copyright (c) 2015 Aldo Anizio Lugão Camacho
*/
class PayPalWrapper
{
//---------------------------------------------
// Class properties
//---------------------------------------------
/**
* PagSeguroPaymentRequest instance
*
* @var \PayPal\Api\Payment
*/
private $logger;
/**
* PayPal API Context
*
* @var PayPal\Rest\ApiContext
*/
protected $apiContext;
/**
* PagSeguroPaymentRequest instance
*
* @var \PayPal\Api\Payment
*/
private $paymentRequest;
/**
* Descrição dos tipos de status
*
* @var array
*/
protected $paymentStates =
[
'created' => 'Criado',
'approved' => 'Aprovado',
'failed' => 'Falha',
'canceled' => 'Cancelado',
'expired' => 'Expirado',
];
//---------------------------------------------
// Class constructor, destructor etc ...
//---------------------------------------------
/**
* Metodo Construtor
*
* @param string $email Email do vendedor
* @param array $token Token de segurança
* @access protected
*/
public function __construct($email, $token, Logger $logger)
{
// Inicializar a ApiContext
$this->apiContext = new ApiContext(new OAuthTokenCredential($email, $token));
// SDK configuration
$this->apiContext->setConfig
([
'mode' => 'live',
'http.ConnectionTimeOut' => 30,
'log.LogEnabled' => true,
'log.FileName' => APP_PATH . '/storage/logs/PayPal.log',
'log.LogLevel' => 'ERROR'
]);
// Log handler
$this->logger = $logger;
}
//---------------------------------------------
// Class methods
//---------------------------------------------
/**
* Criar nova transação
*
* @access public
* @param array $data Dados da transação
* @return void
*/
public function createPayment($data = [])
{
// Inicializar pagador
$payer = new Payer();
$payer->setPaymentMethod('paypal');
// Produtos
$itemsArray = [];
foreach($this->arrGet($data, 'itens', []) as $produto)
{
// Objeto do Item
$novoItem = new Item();
// Dados do Item
$novoItem->setCurrency('BRL')
->setName($this->arrGet($produto, 'titulo'))
->setQuantity($this->arrGet($produto, 'quantidade'))
->setPrice(number_format($this->arrGet($produto, 'valor'), 2, '.', ''));
// Adicionar ao array
$itemsArray[] = $novoItem;
}
// Objeto Lista de Itens
$itemList = new ItemList();
$itemList->setItems($itemsArray);
// Detalhes do Pagamento
$details = new Details();
// Valor do Frete
$details->setShipping($this->arrGet($data, 'shipping_cost', 0.00));
// Valor do Subtotal
$details->setSubtotal(number_format($this->arrGet($data, 'subtotal', 0.00), 2, '.', ''));
// Total do Pagamento
$amount = new Amount();
$amount->setCurrency('BRL')->setTotal(number_format($this->arrGet($data, 'total', 0.00), 2, '.', ''))->setDetails($details);
// Objeto da Transação
$transaction = new Transaction();
$transaction->setAmount($amount)
->setItemList($itemList)
->setDescription($this->arrGet($produto, 'description'))
->setCustom($this->arrGet($data, 'reference'))
->setInvoiceNumber($this->arrGet($data, 'reference'));
// Objeto de Redirecionamento de URLs
$requestUrls = new RedirectUrls();
$requestUrls->setReturnUrl($this->arrGet($data, 'redirect_url'))->setCancelUrl($this->arrGet($data, 'redirect_url'));
// Objeto do Pagamento
$this->payment = new Payment();
$this->payment->setIntent('sale')->setPayer($payer)->setRedirectUrls($requestUrls)->setTransactions(array($transaction));
}
/**
* Capturar URL de requisição do pagamento
*
* @access public
* @return string
*/
public function getPaymentData()
{
$data = [];
// Fazer chamada para a API e retorna o código (url) de requisição para este pagamento.
try
{
// Solicitar pagamento na API
$this->payment->create($this->apiContext);
}
catch(PayPalConnectionException $ex)
{
// Menesagem de erro
$this->logger->addError($ex->getMessage());
// Empty value
return [];
}
// Capturar URL de redirecionamento
foreach($this->payment->getLinks() as $link)
{
if($link->getRel() == 'approval_url')
{
$requestUrl = $link->getHref();
break;
}
}
// Response
return
[
'payment_id' => $this->payment->getId(),
'request_url' => $requestUrl,
];
}
/**
* Executar segunda parte ou capturar o pagamento
*
* @access public
* @param string $paymentId Payment Id
* @param string $payerId Payer Id
* @return array
*/
public function getPaymentByCode($paymentId, $payerId = '')
{
// Verificar se pedido existe e não está aprovado
if($paymentId)
{
// Fazer chamada para a API e retorna o código (url) de requisição para este pagamento.
try
{
// Objeto do Pagamento
$payment = Payment::get($paymentId, $this->apiContext);
}
catch(PayPalConnectionException $ex)
{
// Menesagem de erro
$this->logger->addError($ex->getData());
// Get error data to array
$errorData = json_decode($ex->getData(), true);
$errorData['transaction_id'] = $paymentId;
// Empty value
return $this->sanitizeErrorData($errorData);
}
// Check if payment has been created (avoid execute twice)
if($payment->getState() == 'created' && empty($payerId) == false)
{
// Objeto PaymentExecution
$paymentExecution = new PaymentExecution();
// Definir pagador
$paymentExecution->setPayerId($payerId);
// Execute payment
$payment->execute($paymentExecution, $this->apiContext);
}
// Return data
return $this->sanitizePaymentData($payment);
}
}
/**
* Definir tipo de ambiente (live / sandbox)
*
* @access public
* @param string $ambiente Tipo de ambiente
* @return void
*/
public function setEnvironment($ambiente)
{
if(in_array($ambiente, ['live', 'sandbox']) == false)
{
throw new \InvalidArgumentException('O tipo de ambiente a ser configurado deve ser "live" ou "sandbox". Valor informado: ' . $ambiente);
}
// SDK configuration
$apiContextConfig = $this->apiContext->getConfig();
$apiContextConfig['mode'] = $ambiente;
$apiContextConfig = $this->apiContext->setConfig($apiContextConfig);
}
/**
* Extrair dados do pagamento
*
* @access private
* @param \PayPal\Api\Payment $payment Payment Object
* @return array
*/
private function sanitizePaymentData(Payment $payment)
{
// Dados da transacao
return
[
'transaction_id' => $payment->getId(),
'reference' => $payment->getTransactions()[0]->getCustom(),
'comentario' => '',
'payment_status' => $payment->getState(),
];
}
/**
* Extrair dados do erro
*
* @access private
* @param array $data Error data
* @return array
*/
private function sanitizeErrorData(array $data)
{
// Get status
switch($data['name'])
{
case 'PAYMENT_APPROVAL_EXPIRED':
case 'PAYMENT_EXPIRED':
$paymentStatus = 'expired';
break;
default:
$paymentStatus = 'pending';
break;
}
// Dados da transacao
return
[
'transaction_id' => $data['transaction_id'],
'reference' => '',
'comentario' => '',
'payment_status' => $paymentStatus,
];
}
/**
* Returns value from array using "dot notation".
*
* @access private
* @param array $array Array we're going to search
* @param string $path Array path
* @param mixed $default (optional) Default return value
* @return mixed
*/
private function arrGet(array $array, $path, $default = null)
{
$segments = explode('.', $path);
foreach($segments as $segment)
{
if(!is_array($array) || !isset($array[$segment]))
{
return $default;
}
$array = $array[$segment];
}
return $array;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment