diff --git a/modules/adaptive/commerce_paypal_adaptive.module b/modules/adaptive/commerce_paypal_adaptive.module index 0049c8d..c6c0c63 100644 --- a/modules/adaptive/commerce_paypal_adaptive.module +++ b/modules/adaptive/commerce_paypal_adaptive.module @@ -219,30 +219,50 @@ function commerce_paypal_adaptive_chained_redirect_form($form, &$form_state, $or * Payment method callback: redirect form return validation. */ function commerce_paypal_adaptive_chained_redirect_form_validate($order, $payment_method) { - if (!empty($payment_method['settings']['ipn_logging']) && - $payment_method['settings']['ipn_logging'] == 'full_ipn') { - watchdog('commerce_paypal_wps', 'Customer returned from PayPal with the following POST data: !ipn_data', array('!ipn_data' => '
' . check_plain(print_r($_POST, TRUE)) . '
'), WATCHDOG_NOTICE); - } + // PayPal gives us absolutely nothing when the customer returns from checkout. + // What they what is for us to perform a PaymentDetails request for the + // transaction and then update accordingly. + + // Get all of the transactions that are pending for the order. + $transactions = commerce_payment_transaction_load_multiple(array(), array( + 'status' => COMMERCE_PAYMENT_STATUS_PENDING, + 'order_id' => $order->order_id, + 'remote_status' => 'CREATED', + )); - // This may be an unnecessary step, but if for some reason the user does end - // up returning at the success URL with a Failed payment, go back. - if (!empty($_POST['payment_status']) && $_POST['payment_status'] == 'Failed') { - return FALSE; + foreach ($transactions as $transaction) { + $response = commerce_paypal_adaptive_paymentdetails_request($transaction->remote_id, $payment_method['settings']); + if ($response !== FALSE) { + $transaction->payload[REQUEST_TIME] = $response; + $transaction->remote_status = $response['status']; + if ($response['status'] == 'COMPLETED') { + $transaction->status = COMMERCE_PAYMENT_STATUS_SUCCESS; + } + elseif (in_array($response['status'], array('PROCESSING', 'PENDING'))) { + // Don't do anything. + } + else { + $transaction->status = COMMERCE_PAYMENT_STATUS_FAILURE; + } + } + commerce_payment_transaction_save($transaction); } } /** - * Payment method callback: redirect form return submission. + * Implements hook_commerce_paypal_ipn_process(). */ -function commerce_paypal_adaptive_chained_redirect_form_submit($order, $payment_method) { - // Nothing here yet. +function commerce_paypal_adaptive_paypal_ipn_validate($order, $payment_method, $ipn) { + // @todo Implement. + watchdog('commerce_paypal_apc', 'IPN logged for Order @order_number.!ipn_data', array('@order_number' => $order->order_number, '!ipn_data' => $ipn_data), WATCHDOG_NOTICE); } /** * Implements hook_commerce_paypal_ipn_process(). */ -function commerce_paypal_adaptive_commerce_paypal_ipn_process($order, $payment_method, $ipn) { +function commerce_paypal_adaptive_paypal_ipn_process($order, $payment_method, $ipn) { // @todo Implement. + dpm($ipn); } /** @@ -322,30 +342,59 @@ function commerce_paypal_adaptive_chained_order_form($form, &$form_state, $order ); // Allow modules to alter parameters of the API request. - drupal_alter('commerce_paypal_apc_order_form_data', $data, $order); + drupal_alter('commerce_paypal_apc_order_form_data', $data, $order, $settings); $response = commerce_paypal_adaptive_payrequest($data, $settings); + // Create a transaction. The payment won't be completed until the customer + // explicitly makes a payment. + $transaction = commerce_payment_transaction_new('paypal_apc', $order->order_id); + $transaction->instance_id = $settings['payment_method']; + $transaction->payload[REQUEST_TIME] = $response; + $transaction->amount = $amount; + $transaction->currency_code = $currency_code; + $transaction->data['commerce_paypal_adaptive'] = $data; + if ($response !== FALSE) { - if ($response->responseEnvelope->ack == 'Success') { - $form['#action'] = commerce_paypal_adaptive_redirect_url($response->payKey, $settings); + if ($response['responseEnvelope']['ack'] == 'Success') { + $form['#action'] = commerce_paypal_adaptive_redirect_url($response['payKey'], $settings); $form['submit'] = array( '#type' => 'submit', '#value' => t('Proceed to PayPal'), ); + $transaction->remote_id = $response['payKey']; + $transaction->status = COMMERCE_PAYMENT_STATUS_PENDING; + $transaction->remote_status = $response['paymentExecStatus']; + $transaction->message = 'Created (@created_date)'; + $transaction->message_variables = array( + '@created_date' => format_date(REQUEST_TIME, 'short'), + ); } else { watchdog('commerce_paypal_adaptive', 'Error #!error_id creating transaction: !message
!error_object', array( - '!error_id' => $response->error[0]->errorId, - '!message' => $response->error[0]->message, - '!error_object' => '
' . print_r($response->error[0], TRUE) . '
', + '!error_id' => $response['error'][0]['errorId'], + '!message' => $response['error'][0]['message'], + '!error_object' => '
' . print_r($response['error'][0], TRUE) . '
', ), WATCHDOG_ERROR); + drupal_set_message(t('Unable to initialize transaction with PayPal.'), 'error'); + drupal_goto($settings['cancel_return']); + $transaction->status = COMMERCE_PAYMENT_STATUS_FAILURE; + $transaction->message = 'Error #@error_number (@error_message)'; + $transaction->message_variables = array( + '@error_number' => $response['error'][0]['errorId'], + '@error_message' => $response['error'][0]['message'], + ); } } else { drupal_set_message(t('Unable to initialize transaction with PayPal.'), 'error'); + drupal_goto($settings['cancel_return']); + $transaction->status = COMMERCE_PAYMENT_STATUS_FAILURE; } + // Save the transaction. + commerce_payment_transaction_save($transaction); + return $form; } @@ -466,3 +515,35 @@ function commerce_paypal_adaptive_redirect_url($pay_key, $settings) { ); return $server_url . '?' . http_build_query($params); } + + +/** + * Performs an Adaptive Payments PaymentDetails Request. + * + * @param string $pay_key + * The payKey returned from the original PayRequest. + * @param array $settings + * Payment method settings array. + * @return mixed + * A PayPal PaymentDetails response or FALSE if something bad happened. + */ +function commerce_paypal_adaptive_paymentdetails_request($pay_key, $settings) { + // Set up our request here since the requestEnvelope is required. + $params = array( + 'payKey' => $pay_key, + 'requestEnvelope' => array( + 'errorLanguage' => 'en_US', + ), + ); + if ($settings['ipn_logging'] == 'full_ipn') { + watchdog('commerce_paypal_adaptive', 'PayPal Adaptive PaymentDetails Request: !ipn_data', array('!ipn_data' => '
' . check_plain(print_r($params, TRUE)) . '
')); + } + + $response = commerce_paypal_adaptive_post($params, 'PaymentDetails', $settings); + + if ($settings['ipn_logging'] == 'full_ipn') { + watchdog('commerce_paypal_adaptive', 'PayPal Adaptive PaymentDetails Response: !ipn_data', array('!ipn_data' => '
' . check_plain(print_r($response, TRUE)) . '
')); + } + + return $response; +}