Skip to content

Instantly share code, notes, and snippets.

@cristinecula
Created June 8, 2012 18:10
Show Gist options
  • Select an option

  • Save cristinecula/2897346 to your computer and use it in GitHub Desktop.

Select an option

Save cristinecula/2897346 to your computer and use it in GitHub Desktop.
PayPal IPN Handler for CakePHP
<?php
App::uses('HttpSocket', 'Network/Http');
/* inside controller */
/**
* PayPal IPN Notification parser
* Checks if the notification is valid
* @see https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_admin_IPNIntro
* @see https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_IPNandPDTVariables
* @return mixed The data for verifying and updating the user purchase
*/
protected function _parse_paypal() {
$HttpSocket = new HttpSocket();
$validationArray = array(
'cmd' => '_notify-validate',
);
$validationArray = array_merge($validationArray, $this->request->data);
$HttpSocket->get(Configure::read('Paypal.url'), $validationArray);
if($HttpSocket->response['body'] !== 'VERIFIED') {
$this->log('PayPal IPN Error: '. RequestHandlerComponent::getClientIp() .' has sent an invalid notification', 'purchases');
die('The IPN notification is invalid');
}
if($validationArray['mc_currency'] !== 'USD') {
$this->log('PayPal IPN Error: '. $validationArray['invoice'] .' reported currency '. $validationArray['mc_currency'], 'purchases');
die;
}
switch(strtolower($validationArray['payment_status'])) {
case 'completed':
$status = PURCHASE_STATUS_OK;
break;
case 'failed':
$status = PURCHASE_STATUS_FAILED;
break;
case 'denied':
$status = PURCHASE_STATUS_DENIED;
break;
case 'pending':
$status = PURCHASE_STATUS_PENDING;
// TODO: check the pending_reason
break;
case 'refunded':
$status = PURCHASE_STATUS_REFUNDED;
break;
default:
$this->log('PayPal IPN Error: Received payment_status '. $validationArray['payment_status'] .' is not handled.', 'purchases');
die;
}
$paymentData = array(
'id' => $validationArray['invoice'],
'product_id' => $validationArray['item_number'],
'invoice_id' => $validationArray['txn_id'],
'price' => $validationArray['mc_gross'],
'payer_email' => $validationArray['payer_email'],
'status' => $status,
'ipn_data' => json_encode($validationArray),
);
return $paymentData;
}
<?php
$inputs = array(
'cmd' => '_xclick',
'txn_type' => 'web_accept',
'business' => $paypalVars['owner'],
'quantity' => '1',
'item_name' => $purchase['Product']['name'],
'item_number' => $purchase['Product']['id'],
'amount' => $purchase['Purchase']['price'],
'invoice' => $purchase['Purchase']['id'],
'notify_url' => Router::url(array('controller' => 'purchases', 'action' => 'notify', 'paypal'), true),
'return' => Router::url(array('controller' => 'purchases', 'action' => 'thanks', $purchase['Purchase']['id']), true),
'cancel_return' => Router::url(array('controller' => 'purchases', 'action' => 'cancel'), true),
);
echo $this->Form->create(false, array(
'url' => Configure::read('Paypal.url'),
));
foreach($inputs as $input => $value) {
echo $this->Form->hidden($input, array('name' => $input, 'value' => $value));
}
echo $this->Form->end('Submit');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment