Skip to content

Commit

Permalink
Add Paypal gateway
Browse files Browse the repository at this point in the history
  • Loading branch information
amiriun committed Sep 29, 2017
1 parent 288571c commit 96b8b3c
Show file tree
Hide file tree
Showing 6 changed files with 300 additions and 3 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
}
],
"require": {
"nesbot/carbon": "~1.20"
"nesbot/carbon": "~1.20",
"paypal/rest-api-sdk-php": "*"
},
"autoload": {
"psr-4": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ public function up()
Enum::PAYLINE,
Enum::SADAD,
Enum::ZARINPAL,
Enum::SAMAN
Enum::SAMAN,
Enum::PAYPAL,
]);
$table->decimal('price', 15, 2);
$table->string('ref_id', 100)->nullable();
Expand Down
1 change: 1 addition & 0 deletions src/Enum.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Enum
const PARSIAN = 'PARSIAN';
const PASARGAD = 'PASARGAD';
const SAMAN = 'SAMAN';
const PAYPAL = 'PAYPAL';

/**
* Status code for status field in poolport_transactions table
Expand Down
15 changes: 14 additions & 1 deletion src/GatewayResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Larabookir\Gateway;

use Larabookir\Gateway\Parsian\Parsian;
use Larabookir\Gateway\Paypal\Paypal;
use Larabookir\Gateway\Sadad\Sadad;
use Larabookir\Gateway\Mellat\Mellat;
use Larabookir\Gateway\Payline\Payline;
Expand Down Expand Up @@ -56,7 +57,17 @@ public function __construct($config = null, $port = null)
*/
public function getSupportedPorts()
{
return [Enum::MELLAT, Enum::SADAD, Enum::ZARINPAL, Enum::PAYLINE, Enum::JAHANPAY, Enum::PARSIAN, Enum::PASARGAD, Enum::SAMAN];
return [
Enum::MELLAT,
Enum::SADAD,
Enum::ZARINPAL,
Enum::PAYLINE,
Enum::JAHANPAY,
Enum::PARSIAN,
Enum::PASARGAD,
Enum::SAMAN,
Enum::PAYPAL,
];
}

/**
Expand Down Expand Up @@ -140,6 +151,8 @@ function make($port)
$name = Enum::JAHANPAY;
} elseif ($port InstanceOf Sadad) {
$name = Enum::SADAD;
} elseif ($port InstanceOf Paypal) {
$name = Enum::PAYPAL;
} elseif(in_array(strtoupper($port),$this->getSupportedPorts())){
$port=ucfirst(strtolower($port));
$name=strtoupper($port);
Expand Down
263 changes: 263 additions & 0 deletions src/Paypal/Paypal.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
<?php

namespace Larabookir\Gateway\Paypal;

use Larabookir\Gateway\Mellat\MellatException;
use Larabookir\Gateway\Enum;
use Larabookir\Gateway\Paypal\PaypalException;
use Larabookir\Gateway\PortAbstract;
use Larabookir\Gateway\PortInterface;
use PayPal\Api\Amount;
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\Exception\PayPalConnectionException;
use PayPal\Rest\ApiContext;

class Paypal extends PortAbstract implements PortInterface
{
private $_api_context;
protected $productName;
protected $shipmentPrice;
protected $redirectUrl;



/**
* {@inheritdoc}
*/
public function set($amount)
{
$this->amount = $amount;

return $this;
}


/**
* Sets callback url
* @param $url
*/
function setCallback($url)
{
$this->callbackUrl = $url;
return $this;
}

public function redirect()
{
return \Redirect::away($this->redirectUrl);
}

/**
* Gets callback url
* @return string
*/
function getCallback()
{
if (!$this->callbackUrl)
$this->callbackUrl = $this->config->get('gateway.paypal.settings.call_back_url');

return $this->makeCallback($this->callbackUrl, ['transaction_id' => $this->transactionId()]);
}

public function setApiContext()
{
$paypal_conf = $this->config->get('gateway.paypal');
$this->_api_context = new ApiContext(new OAuthTokenCredential($paypal_conf['client_id'], $paypal_conf['secret']));
$this->_api_context->setConfig($paypal_conf['settings']);
}

public function setShipmentPrice($shipmentPrice)
{
$this->shipmentPrice = $shipmentPrice;

return $this;
}

public function ready()
{
$this->sendPayRequest();

return $this;
}

public function setRedirectUrl($url)
{
$this->redirectUrl = $url;
}

/**
* {@inheritdoc}
*/
public function verify($transaction)
{
parent::verify($transaction);

$this->setApiContext();
$this->userPayment();
if ($this->verifyPayment()) {
$this->transactionSucceed();
$this->newLog(200, Enum::TRANSACTION_SUCCEED_TEXT);
}

return $this;
}

public function setProductName($name){
$this->productName = $name;

return $this;
}

public function sendPayRequest()
{
$this->setApiContext();
$this->newTransaction();
$payer = new Payer();
$payer->setPaymentMethod('paypal');
$item_1 = new Item();
$item_1->setName($this->getProductName())// item name
->setCurrency('USD')
->setQuantity(1)
->setPrice($this->amount); // unit price
$item_2 = new Item();
$item_2->setName('Shipment')
->setCurrency('USD')
->setQuantity(1)
->setPrice($this->getShipmentPrice());
// add item to list
$item_list = new ItemList();
$item_list->setItems([$item_1, $item_2]);
$amount = new Amount();
$amount->setCurrency('USD')
->setTotal($this->getShipmentPrice() + $this->amount);
$transaction = new Transaction();
$transaction->setAmount($amount)
->setItemList($item_list)
->setDescription('Your transaction description');
$redirect_urls = new RedirectUrls();
$redirect_urls->setReturnUrl($this->getCallback())
->setCancelUrl($this->getCallback());
$payment = new Payment();
$payment->setIntent('Sale')
->setPayer($payer)
->setRedirectUrls($redirect_urls)
->setTransactions([$transaction]);
try {
$payment->create($this->_api_context);
} catch (PayPalConnectionException $ex) {
if (\Config::get('app.debug')) {
echo "Exception: " . $ex->getMessage() . PHP_EOL;
$err_data = json_decode($ex->getData(), true);
exit;
} else {
die('Some error occur, sorry for inconvenient');
}
}
foreach ($payment->getLinks() as $link) {
if ($link->getRel() == 'approval_url') {
$redirect_url = $link->getHref();
break;
}
}
// add payment ID to session
\Session::put('paypal_payment_id', $payment->getId());

if (isset($redirect_url)) {
$this->setRedirectUrl($redirect_url);
} else {
$this->setRedirectUrl(\URL::route('original.route'));
}
}

/**
* Check user payment
*
* @return bool
*
* @throws MellatException
*/
protected function userPayment()
{
$this->refId = \Input::get('PayerID');
$this->transactionSetRefId();
$this->trackingCode = \Input::get('token');
// $this->cardNumber = \Input::get('CardHolderPan');
// $payRequestResCode = \Input::get('ResCode');

// if ($payRequestResCode == '0') {
return true;
// }

$this->transactionFailed();
$this->newLog($payRequestResCode, @MellatException::$errors[$payRequestResCode]);
throw new MellatException($payRequestResCode);
}

/**
* Verify user payment from paypal server
*
* @return bool
*/
protected function verifyPayment()
{
try {

/** Get the payment ID before session clear **/
$payment_id = \Session::get('paypal_payment_id');
/** clear the session payment ID **/
\Session::forget('paypal_payment_id');
if (!$this->refId() || !$this->trackingCode()) {
return false;
}
$payment = Payment::get($payment_id, $this->_api_context);
/** PaymentExecution object includes information necessary **/
/** to execute a PayPal account payment. **/
/** The payer_id is added to the request query parameters **/
/** when the user is redirected from paypal back to your site **/
$execution = new PaymentExecution();
$execution->setPayerId($this->refId);
/**Execute the payment **/
$result = $payment->execute($execution, $this->_api_context);
/** dd($result);exit; /** DEBUG RESULT, remove it later **/
if ($result->getState() == 'approved') {

/** it's all right **/
/** Here Write your database logic like that insert record or value in database if you want **/

// \Session::put('success','Payment success');
return true;
}

return false;
} catch (\Exception $e) {
$this->transactionFailed();
$this->newLog('PaypalException', $e->getMessage());
throw $e;
}
}

public function getProductName(){
if(!$this->productName){
return $this->config->get('gateway.paypal.default_product_name');
}

return $this->productName;
}

public function getShipmentPrice(){
if(!$this->shipmentPrice){
return $this->config->get('gateway.paypal.default_shipment_price');
}

return $this->shipmentPrice;
}


}
18 changes: 18 additions & 0 deletions src/Paypal/PaypalException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Larabookir\Gateway\Paypal;

use Larabookir\Gateway\Exceptions\BankException;

class PaypalException extends BankException
{
public static $errors = array(
);

public function __construct($errorId)
{
$this->errorId = intval($errorId);

parent::__construct(@self::$errors[$this->errorId].' #'.$this->errorId, $this->errorId);
}
}

0 comments on commit 96b8b3c

Please sign in to comment.