oshirowanen
oshirowanen

Reputation: 15965

Paypal IPN not returning VERIFIED

I am trying to get IPN from PayPal to work, but it keeps returning INVALID instead of VERIFIED and I can't see what I've done wrong.

At the moment, I have 2 php files using the sample code from paypal's developer site. The code seem to run fine, I am using the sandbox so I can see the payment being transfered, so I don't understand why I am getting INVALID.

Can someone have a look at the code as I can't see what I've done wrong.

1. basic_payment.php (the file which sends the payment data to paypal)

<?php
  require_once ("paypalplatform.php");

  $actionType = "PAY";
  $cancelUrl = "http://[my server details go here]/cancel.php";
  $returnUrl = "http://[my server details go here]/success.php";  
  $currencyCode = "GBP";
  $receiverEmailArray = array( '[email protected]' );
  $receiverAmountArray = array( '2' );
  $receiverPrimaryArray = array();
  $senderEmail = "";      
  $feesPayer = "";
  $ipnNotificationUrl = "http://[my server details go here]/ipn.php";
  $memo = "";     
  $pin = "";      
  $preapprovalKey = "";       
  $reverseAllParallelPaymentsOnError = "";        
  $trackingId = generateTrackingID(); 
  $receiverInvoiceIdArray = array( $trackingId );
  $resArray = CallPay ($actionType, $cancelUrl, $returnUrl, $currencyCode, $receiverEmailArray,
                          $receiverAmountArray, $receiverPrimaryArray, $receiverInvoiceIdArray,
                          $feesPayer, $ipnNotificationUrl, $memo, $pin, $preapprovalKey,
                          $reverseAllParallelPaymentsOnError, $senderEmail, $trackingId
  );
  $ack = strtoupper($resArray["responseEnvelope.ack"]);
  if($ack=="SUCCESS")
  {
      if ("" == $preapprovalKey)
      {
          $cmd = "cmd=_ap-payment&paykey=" . urldecode($resArray["payKey"]);
          RedirectToPayPal ( $cmd );
      }
      else
      {
          $payKey = urldecode($resArray["payKey"]);
          $paymentExecStatus = urldecode($resArray["paymentExecStatus"]);
      }
  } 
?>

2. ipn.php (the file which listens for paypals response)

<?php

    $ipn_post_data = $_POST;

    $url = 'https://www.sandbox.paypal.com/cgi-bin/webscr';

    $request = curl_init();
    curl_setopt_array($request, array
    (
        CURLOPT_URL => $url,
        CURLOPT_POST => TRUE,
        CURLOPT_POSTFIELDS => http_build_query(array('cmd' => '_notify-validate') + $ipn_post_data),
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_HEADER => FALSE,
    ));

    $response = curl_exec($request);
    $status   = curl_getinfo($request, CURLINFO_HTTP_CODE);

    curl_close($request);

    $to = "[email protected]";
    $from = "[email protected]";
    $subject = "response";
    $message = "<pre>".print_r($status,true)." - ".print_r($response,true)."</pre>\n";

    $header = 'To: Oshirowanen <[email protected]>' . "\r\n";
    $header .= 'From: Me <[email protected]>' . "\r\n";

    mail($to,$subject,$message,$header);

?>

The error messages:

Apache error log - No errors

Which is why I added the email stuff in ipn.php to try to capture something, and it is returning:

<pre>200 - INVALID</pre>

Can anyone see what I am doing wrong?

Upvotes: 0

Views: 2439

Answers (2)

mirsilstan
mirsilstan

Reputation: 11

This caused a confusion at first for me too. What you are talking about are 2 different kinds of IPTN messages:

  1. The first, the one from your question, its url is configured in ipnNotificationUrl, goes to site that intermediates the transaction. This one cannot be verified by sending the parameters back to Paypal; as you can add parameters yourself to that url, you can implement a HMAC mechanism for security.

  2. The second, the one from your solution, goes to the account that receives the money, if IPTN is enabled in the settings. This one can be verified by sending the parameters back to Paypal.

If you set the same URL for the both messages, you get them both, but just one can be validated using Paypal. If the seller and the site are different entities, in other words if the site just intermediates a transaction between a buyer and a seller, the site receives the first one and the seller the second one.

Upvotes: 1

oshirowanen
oshirowanen

Reputation: 15965

  1. Got it working using the basic sample code 4b,

  2. Cleared $ipnNotificationUrl = ""; from the basic sample code as I had a value in there which I added myself,

  3. Created a seller account instead of a business pro account in sandbox,

  4. Set the seller account to enable the ipn url,

  5. Used the following PHP 5.2 sample code for the ipn listener

  6. Added the 2 lines into the listener, as described here, the 2 lines can be seen below:

  7. Downloaded the cacert.pem certificate to my server from here and put it in the same directory as the ipn listener:

The 2 lines mentioned in point 6:

CURLOPT_SSL_VERIFYPEER => TRUE,
CURLOPT_CAINFO => 'cacert.pem',

I have no idea why the sandbox business pro account does not let me set an ipn url, but the seller account does.

Upvotes: 1

Related Questions