Hi all,
I’ve a site that sells virtual currency through PayPal. Testing through PayPal’s IPN sandbox works fine for this script. But when the script goes live (non-sandbox), it’s not updating people’s virtual currency balance for transactions that are “Completed” at PayPal. This is CodeIgniter, btw.
Error logging with the live script has been tough, but here’s what I do know:
[list][]I know that PayPal is physically hitting the IPN script (it’s being called)
[]Within the while() loop, $res always evaluates to blank when I flag the variable for error logging (i.e. var_dump($res) == “”)
[*]MySQL table cashshop_invalid_transactions
is where invalid transactions (from the IPN) go and this table isn’t being populated with anything, which means that INVALID isn’t the response being returned by PayPal[/list]
Any reasons why users might not be getting their virtual currency? Did I miss something about the API? I don’t get why this script stopped working. I know PayPal changed to HTTP 1.1 protocol and this is correct.
function notify()
{
// --------------------------------------
// Read post from PayPal system, add cmd
// --------------------------------------
$req = 'cmd=_notify-validate';
// --------------------------------------
// Get the POST request to us, to make ours back
// --------------------------------------
foreach ($_POST as $key => $value)
{
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// --------------------------------------
// Post back to PayPal system to validate
// --------------------------------------
$header = "POST /cgi-bin/webscr HTTP/1.1\\r\
";
$header .= "Content-Type: application/x-www-form-urlencoded\\r\
";
$header .= "Host: www.paypal.com\\r\
";
$header .= "Connection: close\\r\
";
$header .= "Content-Length: " . strlen($req) . "\\r\
\\r\
";
// --------------------------------------
// Open handler
// --------------------------------------
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
// --------------------------------------
// Error connecting to paypal
// --------------------------------------
if (!$fp)
{
// Something died
}
// --------------------------------------
// Incoming post variables
// --------------------------------------
// We put user ID in this PayPal field user id
$user_id = $this->input->post('item_number');
// Paypal txn information
$payer_id = $this->input->post('payer_id');
$payment_date = $this->input->post('payment_date');
$txn_id = $this->input->post('txn_id');
$first_name = $this->input->post('first_name');
$last_name = $this->input->post('last_name');
$payer_email = $this->input->post('payer_email');
$payer_status = $this->input->post('payer_status');
$payment_type = $this->input->post('payment_type');
$memo = $this->input->post('memo');
$item_name = $this->input->post('item_name');
$quantity = $this->input->post('quantity');
$mc_gross = $this->input->post('mc_gross');
$mc_currency = $this->input->post('mc_currency');
$address_name = $this->input->post('address_name');
$address_street = $this->input->post('address_street');
$address_city = $this->input->post('address_city');
$address_state = $this->input->post('address_state');
$address_zip = $this->input->post('address_zip');
$address_country = $this->input->post('address_country');
$address_status = $this->input->post('address_status');
$payer_business_name = $this->input->post('payer_business_name');
$payment_status = $this->input->post('payment_status');
$pending_reason = $this->input->post('pending_reason');
$reason_code = $this->input->post('reason_code');
$txn_type = $this->input->post('txn_type');
// Make sure that this payment came to us
$receiver_email = $this->input->post('receiver_email');
// --------------------------------------
// Successful connection
// --------------------------------------
if ($fp)
{
// --------------------------------------
// Puts the request
// --------------------------------------
fputs ($fp, $header . $req);
// --------------------------------------
// Load necessary
// --------------------------------------
$this->load->library('event');
// --------------------------------------
// Loop through what we've got
// --------------------------------------
while (!feof($fp))
{
$res = fgets ($fp, 1024);
$res = trim($res); //NEW & IMPORTANT
// ------------------------------------------------------------------------------------------------------------------
// VERIFIED
// ------------------------------------------------------------------------------------------------------------------
if (strcmp($res, "VERIFIED") == 0)
{
// --------------------------------------
// Payment status Completed?
// --------------------------------------
if ($payment_status == 'Completed' && $receiver_email == 'my@email.com')
{
$data = array(
'user_id' => $user_id,
'payer_id' => $payer_id,
'payment_date' => $payment_date,
'txn_id' => $txn_id,
'first_name' => $first_name,
'last_name' => $last_name,
'payer_email' => $payer_email,
'payer_status' => $payer_status,
'payment_type' => $payment_type,
'memo' => $memo,
'item_name' => $item_name,
'quantity' => $quantity,
'mc_gross' => $mc_gross,
'mc_currency' => $mc_currency,
'address_name' => $address_name,
'address_street' => $address_street,
'address_city' => $address_city,
'address_state' => $address_state,
'address_zip' => $address_zip,
'address_country' => $address_country,
'address_status' => $address_status,
'payer_business_name' => $payer_business_name,
'payment_status' => $payment_status,
'pending_reason' => $pending_reason,
'reason_code' => $reason_code,
'txn_type' => $txn_type
);
$this->db->insert('cashshop_txn', $data);
// --------------------------------------
// Calculate how much virtual currency purchased
// --------------------------------------
$cc = $mc_gross / 0.01;
if ($cc == 4500)
{
$cc = 5000;
}
$this->db->query('UPDATE users SET currency = currency + '.$cc.' WHERE id = '.$this->db->escape($user_id));
// --------------------------------------
// Notify user of new currency available
// --------------------------------------
// Notification event
}
else if ($payment_status != 'Completed' && $receiver_email == 'my@email.com')
{
// --------------------------------------
// Not completed, manual verification
// --------------------------------------
// Flag for manual verification
}
}
// ------------------------------------------------------------------------------------------------------------------
// INVALID
// ------------------------------------------------------------------------------------------------------------------
if (strcmp ($res, "INVALID") == 0)
{
// --------------------------------------
// Insert transaction ID
// Flag for manual verification
// --------------------------------------
$insert_arr = array(
'txn_id' => $txn_id,
'user_id' => $user_id,
'amount' => $mc_gross,
'time' => time()
);
$this->db->insert('cashshop_invalid_transactions', $insert_arr);
}
}
// Close
fclose($fp);
} //end if ($fp)
} // end function notify