function commerce_paypal_wps_paypal_ipn_process in Commerce PayPal 7
Same name and namespace in other branches
- 7.2 modules/wps/commerce_paypal_wps.module \commerce_paypal_wps_paypal_ipn_process()
Payment method callback: process an IPN once it's been validated.
File
- modules/
wps/ commerce_paypal_wps.module, line 238 - Implements PayPal Website Payments Standard in Drupal Commerce checkout.
Code
function commerce_paypal_wps_paypal_ipn_process($order, $payment_method, &$ipn) {
// Do not perform any processing on WPS transactions here that do not have
// transaction IDs, indicating they are non-payment IPNs such as those used
// for subscription signup requests.
if (empty($ipn['txn_id'])) {
return FALSE;
}
// Exit when we don't get a payment status we recognize.
if (!in_array($ipn['payment_status'], array(
'Failed',
'Voided',
'Pending',
'Completed',
'Refunded',
))) {
commerce_payment_redirect_pane_previous_page($order);
return FALSE;
}
// If this is a prior authorization capture IPN for which we've already
// created a transaction...
if (in_array($ipn['payment_status'], array(
'Voided',
'Completed',
)) && !empty($ipn['auth_id']) && ($auth_ipn = commerce_paypal_ipn_load($ipn['auth_id']))) {
// Load the prior IPN's transaction and update that with the capture values.
$transaction = commerce_payment_transaction_load($auth_ipn['transaction_id']);
}
else {
// Create a new payment transaction for the order.
$transaction = commerce_payment_transaction_new('paypal_wps', $order->order_id);
$transaction->instance_id = $payment_method['instance_id'];
}
$transaction->remote_id = $ipn['txn_id'];
$transaction->amount = commerce_currency_decimal_to_amount($ipn['mc_gross'], $ipn['mc_currency']);
$transaction->currency_code = $ipn['mc_currency'];
$transaction->payload[REQUEST_TIME] = $ipn;
// Set the transaction's statuses based on the IPN's payment_status.
$transaction->remote_status = $ipn['payment_status'];
// If we didn't get an approval response code...
switch ($ipn['payment_status']) {
case 'Failed':
$transaction->status = COMMERCE_PAYMENT_STATUS_FAILURE;
$transaction->message = t("The payment has failed. This happens only if the payment was made from your customer’s bank account.");
break;
case 'Voided':
$transaction->status = COMMERCE_PAYMENT_STATUS_FAILURE;
$transaction->message = t('The authorization was voided.');
break;
case 'Pending':
$transaction->status = COMMERCE_PAYMENT_STATUS_PENDING;
$transaction->message = commerce_paypal_ipn_pending_reason($ipn['pending_reason']);
break;
case 'Completed':
$transaction->status = COMMERCE_PAYMENT_STATUS_SUCCESS;
$transaction->message = t('The payment has completed.');
break;
case 'Refunded':
$transaction->status = COMMERCE_PAYMENT_STATUS_SUCCESS;
$transaction->message = t('Refund for transaction @txn_id', array(
'@txn_id' => $ipn['parent_txn_id'],
));
break;
}
// Save the transaction information.
commerce_payment_transaction_save($transaction);
$ipn['transaction_id'] = $transaction->transaction_id;
// Create a billing profile based on the IPN if enabled.
if (!empty($payment_method['settings']['ipn_create_billing_profile']) && isset($order->commerce_customer_billing)) {
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
// If this order does not have a billing profile yet...
if ($order_wrapper->commerce_customer_billing
->value() === NULL) {
// Ensure we have the required data in the IPN.
if (empty($ipn['residence_country']) || empty($ipn['first_name']) || empty($ipn['last_name'])) {
$data = array_intersect_key($ipn, drupal_map_assoc(array(
'residence_country',
'first_name',
'last_name',
)));
watchdog('commerce_paypal_wps', 'A billing profile for Order @order_number could not be created due to insufficient data in the IPN:!data', array(
'@order_number' => $order->order_number,
'!data' => '<pre>' . check_plain(print_r($data, TRUE)) . '</pre>',
), WATCHDOG_WARNING);
}
else {
// Create the new profile now.
$profile = commerce_customer_profile_new('billing', $order->uid);
// Add the address value.
$profile_wrapper = entity_metadata_wrapper('commerce_customer_profile', $profile);
$profile_wrapper->commerce_customer_address = array_merge(addressfield_default_values(), array(
'country' => $ipn['residence_country'],
'name_line' => $ipn['first_name'] . ' ' . $ipn['last_name'],
'first_name' => $ipn['first_name'],
'last_name' => $ipn['last_name'],
));
// Save the profile, reference it from the order, and save the order.
$profile_wrapper
->save();
$order_wrapper->commerce_customer_billing = $profile_wrapper;
$order_wrapper
->save();
watchdog('commerce_paypal_wps', 'Billing profile created for Order @order_number containing the first and last names and residence country of the customer based on IPN data.', array(
'@order_number' => $order->order_number,
));
}
}
}
commerce_payment_redirect_pane_next_page($order);
watchdog('commerce_paypal_wps', 'IPN processed for Order @order_number with ID @txn_id.', array(
'@txn_id' => $ipn['txn_id'],
'@order_number' => $order->order_number,
), WATCHDOG_INFO);
}