diff --git a/README.md b/README.md
index 29c9914a..55a809d3 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,7 @@
- [Introduction](#introduction)
- [Installation](#installation)
- [Usage](#usage)
+- [Handling PayPal IPN](#paypalipn)
- [Support](#support)
@@ -10,7 +11,7 @@
**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.**
@@ -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);
+```
+
+
+## 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
+ }
+}
+```
+
## 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.
+
\ No newline at end of file
diff --git a/config/config.php b/config/config.php
index dbc04827..98d31cee 100644
--- a/config/config.php
+++ b/config/config.php
@@ -4,7 +4,7 @@
* Created by Raza Mehdi
*/
-return array(
+return [
'mode' => 'sandbox', // Can only be 'sandbox' Or 'live'. If empty or invalid, 'live' will be used.
'sandbox' => [
'username' => '',
@@ -21,4 +21,5 @@
'payment_action' => 'Sale', // Can Only Be 'Sale', 'Authorization', 'Order'
'currency' => 'USD',
-);
\ No newline at end of file
+ 'notify_url' => url('paypal/notify'), // Change this accordingly for your application.
+];
\ No newline at end of file
diff --git a/src/ExpressCheckout.php b/src/ExpressCheckout.php
index 4d1384fc..3b7028ba 100644
--- a/src/ExpressCheckout.php
+++ b/src/ExpressCheckout.php
@@ -1,68 +1,17 @@
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();
}
/**
@@ -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) {
@@ -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;
- }
}
diff --git a/src/PayPalIPNController.php b/src/PayPalIPNController.php
new file mode 100644
index 00000000..bf5df1af
--- /dev/null
+++ b/src/PayPalIPNController.php
@@ -0,0 +1,31 @@
+all();
+
+ foreach($request_params as $key=>$value)
+ $post[$key] = $value;
+
+ $post['cmd'] = '_notify-validate';
+
+ $response = self::verifyIPN($post);
+
+ Session::put('paypal_ipn_response', $response);
+ }
+
+}
diff --git a/src/PayPalRequestTrait.php b/src/PayPalRequestTrait.php
new file mode 100644
index 00000000..abaf7b2e
--- /dev/null
+++ b/src/PayPalRequestTrait.php
@@ -0,0 +1,165 @@
+$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);
+ }
+
+ /**
+ * Verify IPNDetails
+ */
+ private static function verifyIPN($post)
+ {
+ $response = self::doPayPalRequest('verifyipn',$post);
+
+ return $response;
+ }
+
+ /**
+ * Refund PayPal Transaction
+ */
+ private static function refundTransaction($transaction)
+ {
+ $post = [
+ 'TRANSACTIONID' => $transaction
+ ];
+
+ $response = self::doPayPalRequest('RefundTransaction',$post);
+
+ 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;
+ }
+
+}
\ No newline at end of file