/** * Take the response XML from Litle and does the account updater stuff. * * @param DOMDocument $response * The XML response document. * @param object $order * The order object that has just been charged. * This will be used as the template to create additional donations * if needed. * * @return bool * TRUE if an account update was detected and attempted. * FALSE if nothing changed or we don't have enough info * to perform the update. */ public function processResponseXML(DOMDocument $response, $order) { $list = $response->getElementsByTagName('accountUpdater'); if ($list->length == 0) { // No Account Updater tags. return FALSE; } $data = $this->getDataFromXML($list->item(0)); // Do some error checking. if (!isset($data['originalCardTokenInfo']) || !isset($data['newCardTokenInfo'])) { return FALSE; } $changed = $this->cardHasChanged($data['originalCardTokenInfo'], $data['newCardTokenInfo']); if ($changed) { // Load the card on file card. $old_exp_date = $this->convertExpDateString($data['originalCardTokenInfo']['expDate']); $card = $this->findMatchingCardonfile($data['originalCardTokenInfo']['litleToken'], $old_exp_date, $order->uid); if (!$card) { // No card with a matching remote id or exp date or uid. // Do nothing even though we have new data. return FALSE; } // Save the new token info to the card on file. // A new token implies a new last 4 digits of the card number. $new_token = $data['newCardTokenInfo']['litleToken']; $new_number = substr($new_token, -4); $new_type = _commerce_litle_litle_card_type_to_cc($data['newCardTokenInfo']['type']); $card->remote_id = $new_token; // The long form of the card_type. $card->card_type = $new_type; // The card_number, which is the last 4 of the token for credit cards. $card->card_number = $new_number; // Convert the date format Litle uses to the one we use, and save it. $new_exp_date = $this->convertExpDateString($data['newCardTokenInfo']['expDate']); $card->card_exp_month = $new_exp_date['month']; $card->card_exp_year = $new_exp_date['year']; $card->changed = REQUEST_TIME; // Update billing info on existing future donations. // and create recurring donations through the new expiration date. $donation = fundraiser_donation_get_donation($order->order_id); if (isset($donation->recurring->master_did)) { $master_donation = fundraiser_donation_get_donation($donation->recurring->master_did); $submission_fields = $this->formatSubmissionFields($new_number, $new_type, $new_exp_date); // Only save the card on file if we are able to update the billing info // as well. commerce_cardonfile_save($card); $this->updateBillingInfo($master_donation, $submission_fields, $donation); return TRUE; } } return FALSE; }
/** * Save a card on file object */ public function saveCard($card, $billing_profile = NULL, $new_values = array()) { // Remove metadata values if (!empty($new_values)) { unset($new_values['no_store']); } // If new card ... if (empty($card->card_id)) { if (!empty($new_values)) { foreach ($new_values as $prop => $new_value) { $card->{$prop} = $new_value; } } // Ensure number is always sanitized $card->card_number = !empty($card->card_number) ? substr($card->card_number, -4) : 'XXXX'; // Save the new card return commerce_cardonfile_save($card, $billing_profile); } // Update to an existing card if (empty($new_values)) { return 3; } // Load original card $card_original = entity_load_unchanged('commerce_cardonfile', $card->card_id); // Detect property changes $changes = array(); foreach ($new_values as $prop => $new_value) { if ($card_original->{$prop} != $new_value) { $card->{$prop} = $new_value; $changes[] = $prop; } } // Detect if billing address changed $billing_updated = FALSE; if (!empty($billing_profile) && !empty($card->commerce_cardonfile_profile[LANGUAGE_NONE][0]['profile_id'])) { if (empty($billing_profile->profile_id) || $billing_profile->profile_id != $card->commerce_cardonfile_profile[LANGUAGE_NONE][0]['profile_id']) { $billing_updated = TRUE; } } // No changes if (empty($changes) && !$billing_updated) { return 3; } // Create new card if immutable property changed or billing updated if (array_intersect($changes, $this->cardImmutableProperties()) || $billing_updated) { // Disable the original card $card_original->status = 0; $card_original->changed = REQUEST_TIME; commerce_cardonfile_save($card_original); // Save the new card unset($card->card_id); $card->created = REQUEST_TIME; $card->changed = REQUEST_TIME; } // Ensure number is always sanitized $card->card_number = !empty($card->card_number) ? substr($card->card_number, -4) : 'XXXX'; // Save the updated card if ($billing_updated) { return commerce_cardonfile_save($card, $billing_profile); } return commerce_cardonfile_save($card); }
/** * This function will process payment for pending orders * @return array|bool */ public static function runCron($order, $check_pass = FALSE) { module_load_include('inc', 'commerce_recurring', 'commerce_recurring.rules'); module_load_include('inc', 'mp_order', 'mp_order.rules'); if ($check_pass == FALSE) { $payment_method = commerce_payment_method_instance_load('commerce_stripe|commerce_payment_commerce_stripe'); $card_details = commerce_cardonfile_load_multiple_by_uid($order->uid, $payment_method['instance_id'], TRUE); foreach ($card_details as $key) { $card_data = commerce_cardonfile_load($key->card_id); $card_data->remote_id = ''; commerce_cardonfile_save($card_data); } } $card_response = commerce_cardonfile_rules_action_order_select_default_card($order); $order_total = field_get_items('commerce_order', $order, 'commerce_order_total'); $response = commerce_cardonfile_rules_action_order_charge_card($order, $order_total[0], $card_response['select_card_response']); return new Response(TRUE, $response, ""); }