function commerce_authnet_cim_cardonfile_create in Commerce Authorize.Net 7
Commerce Card on File create callback.
Parameters
array $form: The card on file create form.
array $form_state: The card on file create form state.
array $payment_method: The payment method for the card on file request.
object $card_data: The commerce_cardonfile entity.
Return value
object|bool A new commerce_cardonfile entity or FALSE if there was an error.
1 string reference to 'commerce_authnet_cim_cardonfile_create'
File
- ./
commerce_authnet.module, line 947 - Implements Authorize.Net payment services for use in Drupal Commerce.
Code
function commerce_authnet_cim_cardonfile_create($form, &$form_state, $payment_method, $card_data) {
$account = user_load($card_data->uid);
// Submit the profile to the field attach handlers.
$profile = $form_state['commerce_customer_profile'];
field_attach_submit('commerce_customer_profile', $profile, $form['commerce_customer_profile'], $form_state);
commerce_customer_profile_save($profile);
// Format the address into the Auth.net schema.
$profile_wrapper = entity_metadata_wrapper('commerce_customer_profile', $profile);
$billto = commerce_authnet_cim_billto_array(NULL, $profile_wrapper->commerce_customer_address
->value());
// Build the card data to submit to Auth.net.
$number = $form_state['values']['credit_card']['number'];
$card_data->card_exp_month = $form_state['values']['credit_card']['exp_month'];
$card_data->card_exp_year = $form_state['values']['credit_card']['exp_year'];
$card_expire = $card_data->card_exp_year . '-' . $card_data->card_exp_month;
$card_code = $form_state['values']['credit_card']['code'];
$card_type = $form_state['values']['credit_card']['type'];
// Attempt to load and existing profile id from the customers card data.
$existing_cards = commerce_cardonfile_load_multiple_by_uid($account->uid, $payment_method['instance_id']);
// Check for a remote ID.
$remote_id = NULL;
if (!empty($existing_cards)) {
$existing_card = reset($existing_cards);
$remote_id = $existing_card->remote_id;
}
if ($remote_id) {
// Extract the profile id from the remote id.
list($cim_customer_profile_id, $cim_customer_payment_id) = explode('|', $remote_id);
// Build a request to add a new payment method to an existing profile.
$api_request_data = array(
'customerProfileId' => $cim_customer_profile_id,
'paymentProfile' => array(
'billTo' => $billto,
'payment' => array(
'creditCard' => array(
'cardNumber' => $number,
'expirationDate' => $card_expire,
'cardCode' => $card_code,
),
),
),
);
$xml_response = commerce_authnet_cim_request($payment_method, 'createCustomerPaymentProfileRequest', $api_request_data);
}
else {
// There isn't a profile ID to extract.
$cim_customer_profile_id = NULL;
// Build a request to create a profile and add payment method to it.
$api_request_data = array(
'profile' => array(
'merchantCustomerId' => $account->uid,
'description' => $billto['firstName'] . ' ' . $billto['lastName'],
'email' => $account->mail,
'paymentProfiles' => array(
'billTo' => $billto,
'payment' => array(
'creditCard' => array(
'cardNumber' => $number,
'expirationDate' => $card_expire,
'cardCode' => $card_code,
),
),
),
),
);
$xml_response = commerce_authnet_cim_request($payment_method, 'createCustomerProfileRequest', $api_request_data);
}
if ((string) $xml_response->messages->resultCode == 'Ok') {
// Build a remote ID that includes the Customer Profile ID and the
// Payment Profile ID.
if ($cim_customer_profile_id) {
$remote_id = $cim_customer_profile_id . '|' . (string) $xml_response->customerPaymentProfileId;
}
else {
$remote_id = (string) $xml_response->customerProfileId . '|' . (string) $xml_response->customerPaymentProfileIdList->numericString;
}
$card_data_wrapper = entity_metadata_wrapper('commerce_cardonfile', $card_data);
$card_data->uid = $account->uid;
$card_data->remote_id = $remote_id;
$card_data->card_type = $card_type;
$card_data->card_name = $billto['firstName'] . ' ' . $billto['lastName'];
$card_data->card_number = substr($number, -4);
$card_data->status = 1;
$card_data_wrapper->commerce_cardonfile_profile = $profile;
return $card_data;
}
elseif ((string) $xml_response->messages->message->code == 'E00039') {
// But if a Customer Profile already existed for this user, attempt
// instead to add this card as a new Payment Profile to it.
$result = array_filter(explode(' ', (string) $xml_response->messages->message->text), 'is_numeric');
$add_to_profile = reset($result);
// Build a request to add a new payment method to an existing profile.
$api_request_data = array(
'customerProfileId' => $add_to_profile,
'paymentProfile' => array(
'billTo' => $billto,
'payment' => array(
'creditCard' => array(
'cardNumber' => $number,
'expirationDate' => $card_expire,
'cardCode' => $card_code,
),
),
),
);
$xml_response = commerce_authnet_cim_request($payment_method, 'createCustomerPaymentProfileRequest', $api_request_data);
if ((string) $xml_response->messages->resultCode == 'Ok' || (string) $xml_response->messages->message->code == 'E00039') {
// If we got a duplicate code, then the payment profile already exists
// at Authorize.Net and needs to be represented locally.
if ((string) $xml_response->messages->message->code == 'E00039') {
$cim_profile_response = commerce_authnet_cim_get_customer_profile_request($payment_method, $add_to_profile);
if ((string) $cim_profile_response->messages->resultCode == 'Ok') {
// Inspect the returned payment profiles to find the one that
// generated the duplicate error code.
$cim_payment_profiles = $cim_profile_response->profile->paymentProfiles;
if (!is_array($cim_payment_profiles)) {
$cim_payment_profiles = array(
$cim_payment_profiles,
);
}
foreach ($cim_payment_profiles as $key => $payment_profile) {
// We match the submitted values against the existing payment
// profiles using the last 4 digits of the card number. This could
// potentially create a conflict if the same customer has two
// different cards that end in the same four digits, but that is
// highly unlikely.
if (substr($number, -4) == substr($payment_profile->payment->creditCard->cardNumber, -4)) {
$payment_profile_id = (string) $payment_profile->customerPaymentProfileId;
break;
}
}
}
}
else {
$payment_profile_id = (string) $xml_response->customerPaymentProfileId;
}
// Build a remote ID that includes the customer profile ID and the new
// or existing payment profile ID. We don't do any check here to ensure
// we found a payment profile ID, as we shouldn't have got a duplicate
// error if it didn't actually exist.
$remote_id = $add_to_profile . '|' . $payment_profile_id;
$card_data_wrapper = entity_metadata_wrapper('commerce_cardonfile', $card_data);
$card_data->uid = $account->uid;
$card_data->remote_id = $remote_id;
$card_data->card_type = $card_type;
$card_data->card_name = $billto['firstName'] . ' ' . $billto['lastName'];
$card_data->card_number = substr($number, -4);
$card_data->status = 1;
$card_data_wrapper->commerce_cardonfile_profile = $profile;
return $card_data;
}
else {
// Provide the user with information on the failure if it exists.
if (!empty($xml_response->messages->message->text)) {
drupal_set_message(t('Error: @error', array(
'@error' => (string) $xml_response->messages->message->text,
)), 'error');
}
}
}
return FALSE;
}