Skip to content

Commit

Permalink
Added following features:
Browse files Browse the repository at this point in the history
1. Added trait for setting PayPal config & performing API requests.
2. Added functionality to refund PayPal transactions.
3. Added functionality to handle PayPal IPN.
4. Created demo controller showing procedure on handling PayPal IPN.
  • Loading branch information
srmklive committed Oct 16, 2015
1 parent 7325cc0 commit 34b64c8
Show file tree
Hide file tree
Showing 5 changed files with 245 additions and 139 deletions.
45 changes: 42 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
- [Introduction](#introduction)
- [Installation](#installation)
- [Usage](#usage)
- [Handling PayPal IPN](#paypalipn)
- [Support](#support)

<a name="introduction"></a>
## Introduction

**This is an experimental release.!**

Laravel plugin For Processing Payments Through Paypal.
Laravel plugin For Processing Payments Through Paypal. Using this plugin you can process or refund payments and handle IPN (Instant Payment Notification) from PayPal in your Laravel application.

**Currently only PayPal Express Checkout Is Supported.**

Expand Down Expand Up @@ -91,12 +92,50 @@ $response = PayPal::getExpressCheckoutDetails($token);

* DoExpressCheckoutPayment
```
$response = PayPal::doExpressCheckoutPayment($token,$PayerID);
$response = PayPal::doExpressCheckoutPayment($data, $token, $PayerID);
// Note that 'token', 'PayerID' are values returned by PayPal when it redirects to success page after successful verification of user's PayPal info.
```

* RefundTransaction
```
$response = PayPal::refundTransaction($transactionid);
```

<a name="paypalipn"></a>
## Handling PayPal IPN

Included in this package is controller **PayPalIPNController**. This demo controller includes code on handling Instant Payment Notifications from PayPal, and saves the IPN response in session as **paypal_ipn_response**.
You can use this in your application like this:

* Open **App\Http\Middleware\VerifyCsrfToken.php** and add your IPN route to **$excluded** routes variable.
```
'notify'
```

* You can also extend it using your own controller like this:

```
class IPNController extends PayPalIPNController
{
public function postNotify(Request $request)
{
parent::postNotify($request);
$response = Session::get('paypal_ipn_response');
// Do your processing on IPN response
}
}
```

<a name="support"></a>
## Support

This plugin only supports Laravel 5 & Laravel 5.1
This plugin only supports Laravel 5 & Laravel 5.1.
* In case of any issues, kindly create one on the [Issues](https://github.com/srmklive/laravel-paypal/issues) section.
* If you would like to contribute:
* Fork this repository.
* Implement your features.
* Generate pull request.

5 changes: 3 additions & 2 deletions config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Created by Raza Mehdi <[email protected]>
*/

return array(
return [
'mode' => 'sandbox', // Can only be 'sandbox' Or 'live'. If empty or invalid, 'live' will be used.
'sandbox' => [
'username' => '',
Expand All @@ -21,4 +21,5 @@

'payment_action' => 'Sale', // Can Only Be 'Sale', 'Authorization', 'Order'
'currency' => 'USD',
);
'notify_url' => url('paypal/notify'), // Change this accordingly for your application.
];
138 changes: 4 additions & 134 deletions src/ExpressCheckout.php
Original file line number Diff line number Diff line change
@@ -1,68 +1,17 @@
<?php namespace Srmklive\PayPal;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;

class ExpressCheckout
{

/**
* @var Client
*/
private static $client;

/**
* @var Array
*/
private static $config;
// Integrate PayPal Request trait
use PayPalRequestTrait;

/**
* PayPal Processor Constructor
*/
public function __construct()
{
// Setting Http Client
self::$client = new Client();

// Setting PayPal API Credentials
$this->setConfig();
}

/**
* Function To Set PayPal API Configuration
*/
private static function setConfig()
{
$paypal = config('paypal');

// Setting Default PayPal Mode If not set
if (empty($paypal['mode']) || !in_array($paypal['mode'], ['sandbox', 'live'])) {
$paypal['mode'] = 'live';
}

$mode = $paypal['mode'];

// Getting PayPal API Credentials
foreach ($paypal[$mode] as $key=>$value) {
self::$config[$key] = $value;
}

// Setting API Endpoints
if ($paypal['mode'] == 'sandbox') {
self::$config['api_url'] = !empty(self::$config['secret']) ?
'https://api-3t.sandbox.paypal.com/nvp' : 'https://api.sandbox.paypal.com/nvp';

self::$config['gateway_url'] = 'https://www.sandbox.paypal.com';
} else {
self::$config['api_url'] = !empty(self::$config['secret']) ?
'https://api-3t.paypal.com/nvp' : 'https://api.paypal.com/nvp';

self::$config['gateway_url'] = 'https://www.paypal.com';
}

unset($paypal);
$this->setConfig();
}

/**
Expand Down Expand Up @@ -162,7 +111,7 @@ public static function doExpressCheckoutPayment($data, $token, $payerid)
'PAYMENTREQUEST_0_CURRENCYCODE' => !empty(self::$config['currency']) ? self::$config['currency'] : 'USD',
'PAYMENTREQUEST_0_DESC' => $data['invoice_description'],
'PAYMENTREQUEST_0_INVNUM' => $data['invoice_id'],
'PAYMENTREQUEST_0_NOTIFYURL' => $data['notify_url']
'PAYMENTREQUEST_0_NOTIFYURL' => config('paypal.notify_url')
];

foreach ($tmp as $k=>$v) {
Expand All @@ -174,83 +123,4 @@ public static function doExpressCheckoutPayment($data, $token, $payerid)
return $response;
}

/**
* Function To Perform PayPal API Request
*
* @param $method
* @param $params
* @return array
*/
private static function doPayPalRequest($method, $params)
{
if (empty(self::$config))
self::setConfig();

// Setting API Credentials, Version & Method
$post = [
'USER' => self::$config['username'],
'PWD' => self::$config['password'],
'SIGNATURE' => self::$config['secret'],
'VERSION' => 123,
'METHOD' => $method,
];

// Checking Whether The Request Is PayPal IPN Response
if ($method == 'verifyipn') {
unset($post['method']);

$post_url = self::$config['gateway_url'].'/cgi-bin/webscr';
} else {
$post_url = self::$config['api_url'];
}

foreach ($params as $key=>$value) {
$post[$key] = $value;
}

try {
$request = self::$client->post($post_url, [
'form_params' => $post
]);

$response = $request->getBody(true);
$response = self::retrieveData($response);

if ($method == 'SetExpressCheckout') {
if (!empty($response['TOKEN'])) {
$response['paypal_link'] = self::$config['gateway_url'] .
'/webscr?cmd=_express-checkout&token=' . $response['TOKEN'];
} else {
return [
'type' => 'error',
'message' => trans('paypal::error.paypal_connection_error')
];
}
}

return $response;

} catch (ClientException $e) {
$message = $e->getRequest() . " " . $e->getResponse();
} catch (ServerException $e) {
$message = $e->getRequest(). " " . $e->getResponse();
} catch (BadResponseException $e) {
$message = $e->getRequest(). " " . $e->getResponse();
}

return [
'type' => 'error',
'message' => $message
];
}

/**
* Parse PayPal NVP Response
*/
private static function retrieveData($string)
{
$response = array();
parse_str($string, $response);
return $response;
}
}
31 changes: 31 additions & 0 deletions src/PayPalIPNController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php namespace Srmklive\PayPal;

/**
* Demo code to Handle IPN(Instant Payment Notification) from PayPal.
*/

use App\Order;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Session;

class PayPalIPNController extends Controller {

use PayPalRequestTrait;

public function postNotify(Request $request)
{
$post = [];
$request_params = $request->all();

foreach($request_params as $key=>$value)
$post[$key] = $value;

$post['cmd'] = '_notify-validate';

$response = self::verifyIPN($post);

Session::put('paypal_ipn_response', $response);
}

}
Loading

0 comments on commit 34b64c8

Please sign in to comment.