[guadec-web] Adding the Payment Gateway Files-Test-1



commit db2db93b6a4ce45a909a338b8207e749edc58680
Author: Saumya Dwivedi <saumya zero gmail com>
Date:   Sun Jul 6 20:19:14 2014 +0530

    Adding the Payment Gateway Files-Test-1

 guadec/confirm-payment.php |   41 +++---
 guadec/ipn.php             |   98 ++++++++++++++
 guadec/ipnlistener.php     |  310 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 429 insertions(+), 20 deletions(-)
---
diff --git a/guadec/confirm-payment.php b/guadec/confirm-payment.php
index e705348..b9da6bb 100644
--- a/guadec/confirm-payment.php
+++ b/guadec/confirm-payment.php
@@ -122,10 +122,10 @@ if (!empty($_POST)) {
 
 <div>
 <?php if(!($application_submitted == true)): ?>
-       <div> "Invalid Submission. Please go through registration page first."</div>
+       <div class="section group"> "Invalid Submission. Please go through registration page first."</div>
 <?php else: ?>
        <?php if ($errors == true): ?>
-       <div> "Invalid name or email. Please check."<a href="http://localhost/wordpress/?page_id=4787";> Go 
back to Registration </a>
+       <div class="section group"> "Invalid name or email. Please check."<a 
href="https://www.guadec.org/registration-form/";> Go back to Registration </a></div>
        <?php else: ?>
                <?php //echo $registerInfo; ?>
                <div class="section group">
@@ -182,26 +182,27 @@ if (!empty($_POST)) {
                </div>
                
                <?php if ($tamount > 0): ?>
-                       <div>Your details have been stored. Proceed to pay €<?php echo $tamount;?>.</div>
-                               
-                       <form name="_xclick" action="https://www.sandbox.paypal.com/cgi-bin/webscr"; 
method="post">
-                   <input type="hidden" name="cmd" value="_xclick">
-                   <input type="hidden" name="business" value="saumya zero-facilitator gmail com">
-                   <input type="hidden" name="currency_code" value="EUR">
-                   <input type="hidden" name="item_name" value="Digital Download">
-                   <input type="hidden" name="amount" value="<?php echo $tamount; ?>">
-                   <!-- Redirect to thank you after successful payment -->
-                   <input type="hidden" name="return" value=" https://www.guadec.org/thank-you";>
-                   <input type="hidden" name="custom" value="<?php echo $registerInfo; ?>">
+                       <div class="section_group>">Your details have been stored. Proceed to pay €<?php echo 
$tamount;?>.</div>
+                       <div class="col span_1_of_2">   
+                               <form name="_xclick" action="https://www.sandbox.paypal.com/cgi-bin/webscr"; 
method="post">
+                           <input type="hidden" name="cmd" value="_xclick">
+                           <input type="hidden" name="business" value="saumya zero-facilitator gmail com">
+                           <input type="hidden" name="currency_code" value="EUR">
+                           <input type="hidden" name="item_name" value="Digital Download">
+                           <input type="hidden" name="amount" value="<?php echo $tamount; ?>">
+                           <!-- Redirect to thank you after successful payment -->
+                           <input type="hidden" name="return" value=" https://www.guadec.org/thank-you";>
+                           <input type="hidden" name="custom" value="<?php echo $registerInfo; ?>">
 
-                       <!-- <Address of notification url. Can not be localhost      -->
-                   <input type="hidden" name="notify_url" 
value="http://web.iiit.ac.in/~saumya.dwivedi/test/ipn.php";>
+                               <!-- <Address of notification url. Can not be localhost      -->
+                           <input type="hidden" name="notify_url" 
value="http://www.guadec.org/wp-content/themes/guadec/ipn.php";>
 
-                   <!-- Redirect to thank you after cancelled payment -->
-                   <input type="hidden" name="cancel_return" 
value="https://www.guadec.org/cancel-registration/";>
-                   
-                   <input type="image" src="http://www.paypal.com/en_US/i/btn/btn_buynow_LG.gif"; border="0" 
name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
-                       </form>
+                           <!-- Redirect to thank you after cancelled payment -->
+                           <input type="hidden" name="cancel_return" 
value="https://www.guadec.org/cancel-registration/";>
+                           
+                           <input type="image" src="http://www.paypal.com/en_US/i/btn/btn_buynow_LG.gif"; 
border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
+                               </form>
+                       </div>
                <?php else: ?>
                        <div>Your details have been stored. An email confirming your registration will be 
sent to you shortly. Thank you.</div>
                        <!-- Send a confirm registration mail to the registered -->
diff --git a/guadec/ipn.php b/guadec/ipn.php
new file mode 100644
index 0000000..db959b9
--- /dev/null
+++ b/guadec/ipn.php
@@ -0,0 +1,98 @@
+<?php
+/*
+PayPal Instant Notification Receiver Page
+GUADEC 2014 Registration
+*/
+?>
+
+<?php
+// tell PHP to log errors to ipn_errors.log in this directory
+ini_set('log_errors', true);
+//ini_set('error_log', dirname(__FILE__).'/ipn_errors.log');
+
+ini_set('error_log', 'ipn_errors.log');
+
+// intantiate the IPN listener
+include('ipnlistener.php');
+$listener = new IpnListener();
+
+// tell the IPN listener to use the PayPal test sandbox
+$listener->use_sandbox = true;
+
+// try to process the IPN POST
+try {
+    $listener->requirePostMethod();
+    $verified = $listener->processIpn();
+} catch (Exception $e) {
+    error_log($e->getMessage());
+    exit(0);
+}
+
+// TODO: Handle IPN Response here
+
+if ($verified) {
+    // TODO: Implement additional fraud checks and MySQL storage
+
+    $errmsg = '';   // stores errors from fraud checks
+    
+    // 1. Make sure the payment status is "Completed" 
+    if ($_POST['payment_status'] != 'Completed') { 
+        $errmsg .= "'Payment status' does not match: ";
+        $errmsg .= $_POST['receiver_email']."\n";
+        // simply ignore any IPN that is not completed
+        exit(0); 
+    }
+
+    // 2. Make sure seller email matches your primary account email.
+    if ($_POST['receiver_email'] !='saumya zero-facilitator gmail com') {
+        $errmsg .= "'receiver_email' does not match: ";
+        $errmsg .= $_POST['receiver_email']."\n";
+    }
+    
+    // 3. Make sure the amount(s) paid match
+    if ($_POST['mc_gross'] <= '0.0') {
+        $errmsg .= "'mc_gross' does not match: ";
+        $errmsg .= $_POST['mc_gross']."\n";
+    }
+    
+    // 4. Make sure the currency code matches
+    if ($_POST['mc_currency'] != 'EUR') {
+        $errmsg .= "'mc_currency' does not match: ";
+        $errmsg .= $_POST['mc_currency']."\n";
+    }
+
+    // TODO: Check for duplicate user_id
+    
+    if (!empty($errmsg)) {
+    
+        // manually investigate errors from the fraud checking
+        $body = "IPN failed fraud checks: \n$errmsg\n\n";
+        $body .= $listener->getTextReport();
+
+        $body .= "Registration Payment--Detected Fraud--To be verified\n";
+        $body .= "If not verified, payment is refunded in full amounts to the account of the holder\n";
+        //append with the real payment details
+        $body .= $_POST['custom'];
+        error_log($body);
+        mail($_POST['receiver_email'], 'IPN Fraud Warning', $body);
+        mail($_POST['payer_email'], 'GUADEC 2014 Registration-Payment to be verified', $body);
+        
+        
+    } else {
+        $body .= $listener->getTextReport();
+        $body .= "Registration Payment Successful for ";
+        $body .= $_POST['custom'];
+        error_log($body);
+        mail($_POST['receiver_email'], 'GUADEC 2014 Registration Successful', $body);
+        mail($_POST['payer_email'], 'GUADEC 2014 Registration Successful', $body);
+    
+    }
+} 
+else {
+    // manually investigate the invalid IPN
+
+    error_log($listener->getTextReport());
+    mail($_POST['receiver_email'], 'Invalid IPN', $listener->getTextReport());
+}
+
+?>
diff --git a/guadec/ipnlistener.php b/guadec/ipnlistener.php
new file mode 100644
index 0000000..140a8ff
--- /dev/null
+++ b/guadec/ipnlistener.php
@@ -0,0 +1,310 @@
+<?php
+/**
+ *  PayPal IPN Listener
+ *
+ *  A class to listen for and handle Instant Payment Notifications (IPN) from 
+ *  the PayPal server.
+ *
+ *  https://github.com/Quixotix/PHP-PayPal-IPN
+ *
+ *  @package    PHP-PayPal-IPN
+ *  @author     Micah Carrick
+ *  @copyright  (c) 2012 - Micah Carrick
+ *  @version    2.1.0
+ */
+class IpnListener {
+    
+    /**
+     *  If true, the recommended cURL PHP library is used to send the post back 
+     *  to PayPal. If flase then fsockopen() is used. Default true.
+     *
+     *  @var boolean
+     */
+    public $use_curl = false;     
+    
+    /**
+     *  If true, explicitly sets cURL to use SSL version 3. Use this if cURL
+     *  is compiled with GnuTLS SSL.
+     *
+     *  @var boolean
+     */
+    public $force_ssl_v3 = false;     
+   
+    /**
+     *  If true, cURL will use the CURLOPT_FOLLOWLOCATION to follow any 
+     *  "Location: ..." headers in the response.
+     *
+     *  @var boolean
+     */
+    public $follow_location = false;     
+    
+    /**
+     *  If true, an SSL secure connection (port 443) is used for the post back 
+     *  as recommended by PayPal. If false, a standard HTTP (port 80) connection
+     *  is used. Default true.
+     *
+     *  @var boolean
+     */
+    public $use_ssl = true;      
+    
+    /**
+     *  If true, the paypal sandbox URI www.sandbox.paypal.com is used for the
+     *  post back. If false, the live URI www.paypal.com is used. Default false.
+     *
+     *  @var boolean
+     */
+    public $use_sandbox = true; 
+    
+    /**
+     *  The amount of time, in seconds, to wait for the PayPal server to respond
+     *  before timing out. Default 30 seconds.
+     *
+     *  @var int
+     */
+    public $timeout = 30;       
+    
+    private $post_data = array();
+    private $post_uri = '';     
+    private $response_status = '';
+    private $response = '';
+
+    const PAYPAL_HOST = 'www.paypal.com';
+    const SANDBOX_HOST = 'www.sandbox.paypal.com';
+    
+    /**
+     *  Post Back Using cURL
+     *
+     *  Sends the post back to PayPal using the cURL library. Called by
+     *  the processIpn() method if the use_curl property is true. Throws an
+     *  exception if the post fails. Populates the response, response_status,
+     *  and post_uri properties on success.
+     *
+     *  @param  string  The post data as a URL encoded string
+     */
+    protected function curlPost($encoded_data) {
+
+        if ($this->use_ssl) {
+            $uri = 'https://'.$this->getPaypalHost().'/cgi-bin/webscr';
+            $this->post_uri = $uri;
+        } else {
+            $uri = 'http://'.$this->getPaypalHost().'/cgi-bin/webscr';
+            $this->post_uri = $uri;
+        }
+        
+        $ch = curl_init();
+
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
+        curl_setopt($ch, CURLOPT_CAINFO, 
+                    dirname(__FILE__)."/cert/api_cert_chain.crt");
+        curl_setopt($ch, CURLOPT_URL, $uri);
+        curl_setopt($ch, CURLOPT_POST, true);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded_data);
+        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $this->follow_location);
+        curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_HEADER, true);
+        
+        if ($this->force_ssl_v3) {
+            curl_setopt($ch, CURLOPT_SSLVERSION, 3);
+        }
+        
+        $this->response = curl_exec($ch);
+        $this->response_status = strval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
+        
+        if ($this->response === false || $this->response_status == '0') {
+            $errno = curl_errno($ch);
+            $errstr = curl_error($ch);
+            throw new Exception("cURL error: [$errno] $errstr");
+        }
+    }
+    
+    /**
+     *  Post Back Using fsockopen()
+     *
+     *  Sends the post back to PayPal using the fsockopen() function. Called by
+     *  the processIpn() method if the use_curl property is false. Throws an
+     *  exception if the post fails. Populates the response, response_status,
+     *  and post_uri properties on success.
+     *
+     *  @param  string  The post data as a URL encoded string
+     */
+    protected function fsockPost($encoded_data) {
+    
+        if ($this->use_ssl) {
+            $uri = 'ssl://'.$this->getPaypalHost();
+            $port = '443';
+            $this->post_uri = $uri.'/cgi-bin/webscr';
+        } else {
+            $uri = $this->getPaypalHost(); // no "http://"; in call to fsockopen()
+            $port = '80';
+            $this->post_uri = 'http://'.$uri.'/cgi-bin/webscr';
+        }
+
+        $fp = fsockopen($uri, $port, $errno, $errstr, $this->timeout);
+        
+        if (!$fp) { 
+            // fsockopen error
+            throw new Exception("fsockopen error: [$errno] $errstr");
+        } 
+
+        $header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
+        $header .= "Host: ".$this->getPaypalHost()."\r\n";
+        $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
+        $header .= "Content-Length: ".strlen($encoded_data)."\r\n";
+        $header .= "Connection: Close\r\n\r\n";
+        
+        fputs($fp, $header.$encoded_data."\r\n\r\n");
+        
+        while(!feof($fp)) { 
+            if (empty($this->response)) {
+                // extract HTTP status from first line
+                $this->response .= $status = fgets($fp, 1024); 
+                $this->response_status = trim(substr($status, 9, 4));
+            } else {
+                $this->response .= fgets($fp, 1024); 
+            }
+        } 
+        
+        fclose($fp);
+    }
+    
+    private function getPaypalHost() {
+        if ($this->use_sandbox) return self::SANDBOX_HOST;
+        else return self::PAYPAL_HOST;
+    }
+    
+    /**
+     *  Get POST URI
+     *
+     *  Returns the URI that was used to send the post back to PayPal. This can
+     *  be useful for troubleshooting connection problems. The default URI
+     *  would be "ssl://www.sandbox.paypal.com:443/cgi-bin/webscr"
+     *
+     *  @return string
+     */
+    public function getPostUri() {
+        return $this->post_uri;
+    }
+    
+    /**
+     *  Get Response
+     *
+     *  Returns the entire response from PayPal as a string including all the
+     *  HTTP headers.
+     *
+     *  @return string
+     */
+    public function getResponse() {
+        return $this->response;
+    }
+    
+    /**
+     *  Get Response Status
+     *
+     *  Returns the HTTP response status code from PayPal. This should be "200"
+     *  if the post back was successful. 
+     *
+     *  @return string
+     */
+    public function getResponseStatus() {
+        return $this->response_status;
+    }
+    
+    /**
+     *  Get Text Report
+     *
+     *  Returns a report of the IPN transaction in plain text format. This is
+     *  useful in emails to order processors and system administrators. Override
+     *  this method in your own class to customize the report.
+     *
+     *  @return string
+     */
+    public function getTextReport() {
+        
+        $r = '';
+        
+        // date and POST url
+        for ($i=0; $i<80; $i++) { $r .= '-'; }
+        $r .= "\n[".date('m/d/Y g:i A').'] - '.$this->getPostUri();
+        if ($this->use_curl) $r .= " (curl)\n";
+        else $r .= " (fsockopen)\n";
+        
+        // HTTP Response
+        for ($i=0; $i<80; $i++) { $r .= '-'; }
+        $r .= "\n{$this->getResponse()}\n";
+        
+        // POST vars
+        for ($i=0; $i<80; $i++) { $r .= '-'; }
+        $r .= "\n";
+        
+        foreach ($this->post_data as $key => $value) {
+            $r .= str_pad($key, 25)."$value\n";
+        }
+        $r .= "\n\n";
+        return $r;
+    }
+    
+    /**
+     *  Process IPN
+     *
+     *  Handles the IPN post back to PayPal and parsing the response. Call this
+     *  method from your IPN listener script. Returns true if the response came
+     *  back as "VERIFIED", false if the response came back "INVALID", and 
+     *  throws an exception if there is an error.
+     *
+     *  @param array
+     *
+     *  @return boolean
+     */    
+    public function processIpn($post_data=null) {
+
+        $encoded_data = 'cmd=_notify-validate';
+        
+        if ($post_data === null) { 
+            // use raw POST data 
+            if (!empty($_POST)) {
+                $this->post_data = $_POST;
+                $encoded_data .= '&'.file_get_contents('php://input');
+            } else {
+                throw new Exception("No POST data found.");
+            }
+        } else { 
+            // use provided data array
+            $this->post_data = $post_data;
+            
+            foreach ($this->post_data as $key => $value) {
+                $encoded_data .= "&$key=".urlencode($value);
+            }
+        }
+
+        if ($this->use_curl) $this->curlPost($encoded_data); 
+        else $this->fsockPost($encoded_data);
+        
+        if (strpos($this->response_status, '200') === false) {
+            throw new Exception("Invalid response status: ".$this->response_status);
+        }
+        
+        if (strpos($this->response, "VERIFIED") !== false) {
+            return true;
+        } elseif (strpos($this->response, "INVALID") !== false) {
+            return false;
+        } else {
+            throw new Exception("Unexpected response from PayPal.");
+        }
+    }
+    
+    /**
+     *  Require Post Method
+     *
+     *  Throws an exception and sets a HTTP 405 response header if the request
+     *  method was not POST. 
+     */    
+    public function requirePostMethod() {
+        // require POST requests
+        if ($_SERVER['REQUEST_METHOD'] && $_SERVER['REQUEST_METHOD'] != 'POST') {
+            header('Allow: POST', true, 405);
+            throw new Exception("Invalid HTTP request method.");
+        }
+    }
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]