function uc_paypal_ipn in Ubercart 6.2
Same name and namespace in other branches
- 5 payment/uc_paypal/uc_paypal.module \uc_paypal_ipn()
- 7.3 payment/uc_paypal/uc_paypal.pages.inc \uc_paypal_ipn()
Process Instant Payment Notifiations from PayPal.
1 string reference to 'uc_paypal_ipn'
- uc_paypal_menu in payment/
uc_paypal/ uc_paypal.module - Implements hook_menu().
File
- payment/
uc_paypal/ uc_paypal.pages.inc, line 11 - Paypal administration menu items.
Code
function uc_paypal_ipn() {
if (!isset($_POST['invoice'])) {
watchdog('uc_paypal', 'IPN attempted with invalid order ID.', array(), WATCHDOG_ERROR);
return;
}
if (strpos($_POST['invoice'], '-') > 0) {
list($order_id, $cart_id) = explode('-', $_POST['invoice']);
// Sanitize order ID and cart ID
$order_id = intval($order_id);
$cart_id = check_plain($cart_id);
if (!empty($cart_id)) {
// Needed later by uc_complete_sale to empty the correct cart
$_SESSION['uc_cart_id'] = $cart_id;
}
}
else {
$order_id = intval($_POST['invoice']);
}
watchdog('uc_paypal', 'Receiving IPN at URL for order @order_id. <pre>@debug</pre>', array(
'@order_id' => $order_id,
'@debug' => variable_get('uc_paypal_wps_debug_ipn', FALSE) ? print_r($_POST, TRUE) : '',
));
$order = uc_order_load($order_id);
if ($order == FALSE) {
watchdog('uc_paypal', 'IPN attempted for non-existent order @order_id.', array(
'@order_id' => $order_id,
), WATCHDOG_ERROR);
return;
}
// Assign posted variables to local variables
$payment_status = check_plain($_POST['payment_status']);
$payment_amount = check_plain($_POST['mc_gross']);
$payment_currency = check_plain($_POST['mc_currency']);
$payment_fee = check_plain($_POST['mc_fee']);
$receiver_email = check_plain($_POST['business']);
if ($receiver_email == '') {
$receiver_email = check_plain($_POST['receiver_email']);
}
$txn_id = check_plain($_POST['txn_id']);
$txn_type = check_plain($_POST['txn_type']);
$payer_email = check_plain($_POST['payer_email']);
// Express Checkout IPNs may not have the WPS email stored. But if it is,
// make sure that the right account is being paid.
$uc_paypal_wps_email = variable_get('uc_paypal_wps_email', '');
if (!empty($uc_paypal_wps_email) && drupal_strtolower($receiver_email) != drupal_strtolower($uc_paypal_wps_email)) {
watchdog('uc_paypal', 'IPN for a different PayPal account attempted.', array(), WATCHDOG_ERROR);
return;
}
$req = '';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= $key . '=' . $value . '&';
}
$req .= 'cmd=_notify-validate';
if (variable_get('uc_paypal_wpp_server', '') == 'https://api-3t.paypal.com/nvp') {
$host = 'https://www.paypal.com/cgi-bin/webscr';
}
else {
$host = variable_get('uc_paypal_wps_server', 'https://www.sandbox.paypal.com/cgi-bin/webscr');
}
$response = drupal_http_request($host, array(), 'POST', $req);
// TODO: Change this to property_exists when we have a PHP requirement >= 5.1.
if (array_key_exists('error', $response)) {
watchdog('uc_paypal', 'IPN failed with HTTP error @error, code @code.', array(
'@error' => $response->error,
'@code' => $response->code,
), WATCHDOG_ERROR);
return;
}
if (strcmp($response->data, 'VERIFIED') == 0) {
watchdog('uc_paypal', 'IPN transaction verified.');
$duplicate = db_result(db_query("SELECT COUNT(*) FROM {uc_payment_paypal_ipn} WHERE txn_id = '%s' AND status <> 'Pending'", $txn_id));
if ($duplicate > 0) {
if ($order->payment_method != 'credit') {
watchdog('uc_paypal', 'IPN transaction ID has been processed before.', array(), WATCHDOG_NOTICE);
}
return;
}
db_query("INSERT INTO {uc_payment_paypal_ipn} (order_id, txn_id, txn_type, mc_gross, status, receiver_email, payer_email, received) VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', %d)", $order_id, $txn_id, $txn_type, $payment_amount, $payment_status, $receiver_email, $payer_email, time());
$context = array(
'revision' => 'formatted-original',
'type' => 'amount',
);
$options = array(
'sign' => FALSE,
);
switch ($payment_status) {
case 'Canceled_Reversal':
uc_order_comment_save($order_id, 0, t('PayPal has cancelled the reversal and returned !amount !currency to your account.', array(
'!amount' => uc_price($payment_amount, $context, $options),
'!currency' => $payment_currency,
)), 'admin');
break;
case 'Completed':
if (abs($payment_amount - $order->order_total) > 0.01) {
watchdog('uc_paypal', 'Payment @txn_id for order @order_id did not equal the order total.', array(
'@txn_id' => $txn_id,
'@order_id' => $order->order_id,
), WATCHDOG_WARNING, l(t('view'), 'admin/store/orders/' . $order->order_id));
}
$comment = t('PayPal transaction ID: @txn_id', array(
'@txn_id' => $txn_id,
));
uc_payment_enter($order_id, 'paypal_wps', $payment_amount, $order->uid, NULL, $comment);
uc_cart_complete_sale($order);
uc_order_comment_save($order_id, 0, t('PayPal IPN reported a payment of @amount @currency.', array(
'@amount' => uc_price($payment_amount, $context, $options),
'@currency' => $payment_currency,
)));
break;
case 'Denied':
uc_order_comment_save($order_id, 0, t("You have denied the customer's payment."), 'admin');
break;
case 'Expired':
uc_order_comment_save($order_id, 0, t('The authorization has failed and cannot be captured.'), 'admin');
break;
case 'Failed':
uc_order_comment_save($order_id, 0, t("The customer's attempted payment from a bank account failed."), 'admin');
break;
case 'Pending':
uc_order_update_status($order_id, 'paypal_pending');
uc_order_comment_save($order_id, 0, t('Payment is pending at PayPal: @reason', array(
'@reason' => _uc_paypal_pending_message(check_plain($_POST['pending_reason'])),
)), 'admin');
break;
// You, the merchant, refunded the payment.
case 'Refunded':
$comment = t('PayPal transaction ID: @txn_id', array(
'@txn_id' => $txn_id,
));
uc_payment_enter($order_id, 'paypal_wps', $payment_amount, $order->uid, NULL, $comment);
break;
case 'Reversed':
watchdog('uc_paypal', 'PayPal has reversed a payment!', array(), WATCHDOG_ERROR);
uc_order_comment_save($order_id, 0, t('Payment has been reversed by PayPal: @reason', array(
'@reason' => _uc_paypal_reversal_message(check_plain($_POST['reason_code'])),
)), 'admin');
break;
case 'Processed':
uc_order_comment_save($order_id, 0, t('A payment has been accepted.'), 'admin');
break;
case 'Voided':
uc_order_comment_save($order_id, 0, t('The authorization has been voided.'), 'admin');
break;
}
}
elseif (strcmp($response->data, 'INVALID') == 0) {
watchdog('uc_paypal', 'IPN transaction failed verification.', array(), WATCHDOG_ERROR);
uc_order_comment_save($order_id, 0, t('An IPN transaction failed verification for this order.'), 'admin');
}
}