commerce_authnet.acceptjs.inc in Commerce Authorize.Net 7
Includes the Accept.js payment method callbacks.
File
includes/commerce_authnet.acceptjs.incView source
<?php
/**
* @file
* Includes the Accept.js payment method callbacks.
*/
/**
* Returns the default settings for the Authorize.Net AIM payment method.
*/
function commerce_authnet_acceptjs_default_settings() {
return array(
'login' => '',
'tran_key' => '',
'client_key' => '',
'txn_mode' => AUTHNET_TXN_MODE_LIVE_TEST,
'txn_type' => COMMERCE_CREDIT_AUTH_CAPTURE,
'cardonfile' => FALSE,
'continuous' => FALSE,
'email_customer' => FALSE,
'log' => array(
'request' => '0',
'response' => '0',
),
'card_types' => array(),
);
}
/**
* Payment method callback: settings form.
*/
function commerce_authnet_acceptjs_settings_form($settings = NULL) {
// Merge default settings into the stored settings array.
$settings = (array) $settings + commerce_authnet_acceptjs_default_settings();
$form = array();
$form['login'] = array(
'#type' => 'textfield',
'#title' => t('API Login ID'),
'#description' => t('Your API Login ID is different from the username you use to login to your Authorize.Net account. Once you login, browse to your Account tab and click the <em>API Login ID and Transaction Key</em> link to find your API Login ID. If you are using a new Authorize.Net account, you may still need to generate an ID.'),
'#default_value' => $settings['login'],
'#required' => TRUE,
);
$form['tran_key'] = array(
'#type' => 'textfield',
'#title' => t('Transaction Key'),
'#description' => t('Your Transaction Key can be found on the same screen as your API Login ID. However, it will not be readily displayed. You must answer your security question and submit a form to see your Transaction Key.'),
'#default_value' => $settings['tran_key'],
'#required' => TRUE,
);
$form['client_key'] = array(
'#type' => 'textfield',
'#title' => t('Client Key'),
'#description' => t('Follow the instructions <a href="https://developer.authorize.net/api/reference/features/acceptjs.html#Obtaining_a_Public_Client_Key">here</a> to get a client key.'),
'#default_value' => $settings['client_key'],
'#required' => TRUE,
);
$form['txn_mode'] = array(
'#type' => 'radios',
'#title' => t('Transaction mode'),
'#description' => t('Adjust to live transactions when you are ready to start processing real payments.') . '<br />' . t('Only specify a developer test account if you login to your account through https://test.authorize.net.'),
'#options' => array(
AUTHNET_TXN_MODE_LIVE => t('Live transactions in a live account'),
AUTHNET_TXN_MODE_LIVE_TEST => t('Test transactions in a live account'),
AUTHNET_TXN_MODE_DEVELOPER => t('Developer test account transactions'),
),
'#default_value' => $settings['txn_mode'],
);
$form['txn_type'] = array(
'#type' => 'radios',
'#title' => t('Default credit card transaction type'),
'#description' => t('The default will be used to process transactions during checkout.'),
'#options' => array(
COMMERCE_CREDIT_AUTH_CAPTURE => t('Authorization and capture'),
COMMERCE_CREDIT_AUTH_ONLY => t('Authorization only (requires manual or automated capture after checkout)'),
),
'#default_value' => $settings['txn_type'],
);
// A requires the Card on File module.
if (module_exists('commerce_cardonfile')) {
$form['cardonfile'] = array(
'#type' => 'checkbox',
'#title' => t('Enable Card on File functionality with this payment method using Authorize.Net CIM.'),
'#description' => t('This requires an Authorize.Net account upgraded to include support for CIM (Customer Information Manager).'),
'#default_value' => $settings['cardonfile'],
);
$form['continuous'] = array(
'#type' => 'checkbox',
'#title' => t('Use continuous authority transactions.'),
'#description' => t('A continuous authority merchant account will be required.'),
'#default_value' => $settings['continuous'],
);
}
else {
$form['cardonfile'] = array(
'#type' => 'markup',
'#markup' => t('To enable Card on File funcitionality download and install the Card on File module.'),
);
}
$form['email_customer'] = array(
'#type' => 'checkbox',
'#title' => t('Tell Authorize.net to e-mail the customer a receipt based on your account settings.'),
'#default_value' => $settings['email_customer'],
);
$form['log'] = array(
'#type' => 'checkboxes',
'#title' => t('Log the following messages for debugging'),
'#options' => array(
'request' => t('API request messages'),
'response' => t('API response messages'),
),
'#default_value' => $settings['log'],
);
return $form;
}
/**
* Payment method callback: checkout form.
*/
function commerce_authnet_acceptjs_submit_form($payment_method, $pane_values, $checkout_pane, $order) {
return commerce_authnet_acceptjs_form_elements($payment_method);
}
/**
* Payment method callback: checkout form validation.
*/
function commerce_authnet_acceptjs_submit_form_validate($payment_method, $pane_form, $pane_values, $order, $form_parents = array()) {
// If the customer specified a card on file, skip the normal validation.
if (module_exists('commerce_cardonfile') && !empty($payment_method['settings']['cardonfile']) && !empty($pane_values['cardonfile']) && $pane_values['cardonfile'] !== 'new') {
return;
}
$values = $pane_values['credit_card']['cc'];
if (empty($pane_values['credit_card']['cc']['data_descriptor']) || empty($pane_values['credit_card']['cc']['data_value'])) {
drupal_set_message('There was an error', 'error');
return FALSE;
}
return TRUE;
}
/**
* Payment method callback: checkout form submission.
*/
function commerce_authnet_acceptjs_submit_form_submit($payment_method, $pane_form, $pane_values, $order, $charge) {
// If txn_type has been specified in the pane values array, such as through
// the special select element we alter onto the payment terminal form, use
// that instead.
if (!empty($pane_values['txn_type'])) {
$payment_method['settings']['txn_type'] = $pane_values['txn_type'];
}
if (module_exists('commerce_cardonfile') && $payment_method['settings']['cardonfile'] && !empty($pane_values['cardonfile'])) {
// @TODO SUPPORT COF!
if (!empty($pane_values['cardonfile']) && $pane_values['cardonfile'] !== 'new') {
// We're using a stored payment profile. Pass it along to CIM.
return commerce_authnet_cim_submit_form_submit($payment_method, $pane_form, $pane_values, $order, $charge);
}
else {
if (!empty($pane_values['credit_card']['cardonfile_store']) && $pane_values['credit_card']['cardonfile_store']) {
// We've got a request to store a new card.
return commerce_authnet_acceptjs_submit_new_card_form_submit($payment_method, $pane_form, $pane_values, $order, $charge);
}
}
}
$values = $pane_values['credit_card']['cc'];
$data_descriptor = $values['data_descriptor'];
$data_value = $values['data_value'];
// https://developer.authorize.net/api/reference/#payment-transactions-create-an-accept-payment-transaction
$request = array(
'createTransactionRequest' => array(
'merchantAuthentication' => array(
'name' => $payment_method['settings']['login'],
'transactionKey' => $payment_method['settings']['tran_key'],
),
'clientId' => 'CG-PHP-SDK',
'refId' => 'ref' . time(),
'transactionRequest' => array(
'transactionType' => $payment_method['settings']['txn_type'] == COMMERCE_CREDIT_AUTH_CAPTURE ? 'authCaptureTransaction' : 'authOnlyTransaction',
'amount' => number_format(commerce_currency_amount_to_decimal($charge['amount'], $charge['currency_code']), 2, '.', ''),
'payment' => array(
'opaqueData' => array(
'dataDescriptor' => $data_descriptor,
'dataValue' => $data_value,
),
),
'solution' => array(
'id' => 'A1000009',
),
),
),
);
if (!empty($order)) {
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$request['createTransactionRequest']['transactionRequest']['order']['invoiceNumber'] = $order->order_number;
$description = array();
// Descriptions come from products, though not all environments have them.
// So check first.
if (function_exists('commerce_product_line_item_types')) {
foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
if (in_array($line_item_wrapper->type
->value(), commerce_product_line_item_types())) {
$description[] = round($line_item_wrapper->quantity
->value(), 2) . 'x ' . $line_item_wrapper->line_item_label
->value();
$request['createTransactionRequest']['transactionRequest']['lineItems']['lineItem'][] = array(
'itemId' => drupal_substr($line_item_wrapper->line_item_label
->value(), 0, 31),
'name' => drupal_substr($line_item_wrapper->commerce_product->title
->value(), 0, 31),
'quantity' => round($line_item_wrapper->quantity
->value(), 2),
'unitPrice' => commerce_currency_amount_to_decimal($line_item_wrapper->commerce_unit_price->amount
->value(), $line_item_wrapper->commerce_unit_price->currency_code
->value()),
);
}
}
}
$request['createTransactionRequest']['transactionRequest']['order']['description'] = substr(implode(', ', $description), 0, 255);
$request['createTransactionRequest']['transactionRequest']['customer'] = array(
'id' => substr($order->uid, 0, 20),
'email' => substr($order->mail, 0, 255),
);
if (isset($order->commerce_customer_billing)) {
$request['createTransactionRequest']['transactionRequest']['billTo'] = commerce_authnet_cim_billto_array($order);
}
if (isset($order->commerce_customer_shipping)) {
$request['createTransactionRequest']['transactionRequest']['shipTo'] = commerce_authnet_cim_shipto_array($order);
}
$request['createTransactionRequest']['transactionRequest']['customerIP'] = substr(ip_address(), 0, 15);
}
$request_json = drupal_json_encode($request);
if ($payment_method['settings']['txn_mode'] == AUTHNET_TXN_MODE_DEVELOPER) {
$api_url = 'https://apitest.authorize.net/xml/v1/request.api';
}
else {
$api_url = 'https://api.authorize.net/xml/v1/request.api';
}
// Setup the cURL request.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_url);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_NOPROGRESS, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($request_json),
));
$result_json = curl_exec($ch);
// Log any errors to the watchdog.
if ($error = curl_error($ch)) {
watchdog('commerce_authnet', 'cURL error: @error', array(
'@error' => $error,
), WATCHDOG_ERROR);
curl_close($ch);
return FALSE;
}
curl_close($ch);
// The API returns hidden Byte Order Mark characters, causing the
// JSON decoding to fail.
$result_json = preg_replace('/[\\x00-\\x1F\\x80-\\xFF]/', '', $result_json);
$result = drupal_json_decode($result_json);
// Prepare a transaction object to log the API response.
$transaction = commerce_payment_transaction_new('authnet_acceptjs', $order->order_id);
$transaction->instance_id = $payment_method['instance_id'];
$transaction->remote_id = $result['transactionResponse']['transId'];
$transaction->amount = $charge['amount'];
$transaction->currency_code = $charge['currency_code'];
$transaction->payload[REQUEST_TIME] = $result_json;
if (empty($result['messages']['resultCode']) || $result['messages']['resultCode'] != 'Ok') {
$transaction->status = COMMERCE_PAYMENT_STATUS_FAILURE;
$transaction_message = array();
foreach ($result['messages']['message'] as $message) {
$transaction_message[] = t('Authorize.net error: @code - @error', array(
'@code' => $message['code'],
'@error' => $message['text'],
));
watchdog('commerce_authnet', 'Authorize.net error: @code - @error', array(
'@code' => $message['code'],
'@error' => $message['text'],
), WATCHDOG_ERROR);
$transaction->message = implode('<br />', $transaction_message);
}
commerce_payment_transaction_save($transaction);
return FALSE;
}
elseif (!empty($result['transactionResponse']['errors'])) {
$transaction->status = COMMERCE_PAYMENT_STATUS_FAILURE;
$transaction_message = array();
foreach ($result['transactionResponse']['errors'] as $message) {
$transaction_message[] = t('Authorize.net error: @code - @error', array(
'@code' => $message['errorCode'],
'@error' => $message['errorText'],
));
watchdog('commerce_authnet', 'Authorize.net error: @code - @error', array(
'@code' => $message['errorCode'],
'@error' => $message['errorText'],
), WATCHDOG_ERROR);
$transaction->message = implode('<br />', $transaction_message);
drupal_set_message(check_plain($message['errorText']), 'error');
}
commerce_payment_transaction_save($transaction);
return FALSE;
}
// Set the transaction status based on the type of transaction this was.
switch ($payment_method['settings']['txn_type']) {
case COMMERCE_CREDIT_AUTH_ONLY:
$transaction->status = COMMERCE_PAYMENT_STATUS_PENDING;
break;
case COMMERCE_CREDIT_AUTH_CAPTURE:
$transaction->status = COMMERCE_PAYMENT_STATUS_SUCCESS;
break;
case COMMERCE_CREDIT_CAPTURE_ONLY:
$transaction->status = COMMERCE_PAYMENT_STATUS_SUCCESS;
break;
}
$transaction->remote_status = commerce_authnet_txn_type($payment_method['settings']['txn_type']);
// Build a meaningful response message.
$message = array(
'<b>' . commerce_authnet_reverse_txn_type($transaction->remote_status) . '</b>',
'<b>' . ($result['transactionResponse']['messages'][0]['code'] != '1' ? t('REJECTED') : t('ACCEPTED')) . ':</b> ' . check_plain($result['transactionResponse']['messages'][0]['description']),
t('AVS response: @avs', array(
'@avs' => commerce_authnet_avs_response($result['transactionResponse']['avsResultCode']),
)),
);
// Add the CVV response if enabled.
if (isset($result['transactionResponse']['cvvResultCode'])) {
$message[] = t('CVV match: @cvv', array(
'@cvv' => commerce_authnet_cvv_response($result['transactionResponse']['cvvResultCode']),
));
}
$transaction->message = implode('<br />', $message);
commerce_payment_transaction_save($transaction);
return TRUE;
}
/**
* Handles advanced logic relating to creating AcceptJS orders with new card data.
*
* @see commerce_authnet_aim_submit_form_submit()
*/
function commerce_authnet_acceptjs_submit_new_card_form_submit($payment_method, $pane_form, $pane_values, $order, $charge) {
// At this point, we have a few choices to make. We know the user is logged in
// and so we know if they have any existing card on file profiles. If they do
// not, then we can assume that they need a new profile. If they do have one,
// then we need take appropriate steps to add the CC info to the existing
// profile and process the payment based on their profile.
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$payment_details = array(
'opaqueData' => array(
'dataDescriptor' => $pane_values['credit_card']['cc']['data_descriptor'],
'dataValue' => $pane_values['credit_card']['cc']['data_value'],
),
);
// Prepare the billing address for use in the request.
if (isset($order->commerce_customer_billing) && $order_wrapper->commerce_customer_billing
->value()) {
$billing_address = $order_wrapper->commerce_customer_billing->commerce_customer_address
->value();
if (empty($billing_address['first_name'])) {
$name_parts = explode(' ', $billing_address['name_line']);
$billing_address['first_name'] = array_shift($name_parts);
$billing_address['last_name'] = implode(' ', $name_parts);
}
}
$remote_id = FALSE;
// First look to see if we already have cards on file for the user.
$stored_cards = array();
if (!user_is_anonymous()) {
$stored_cards = commerce_cardonfile_load_multiple_by_uid($order->uid, $payment_method['instance_id']);
}
$customer_profile_id = NULL;
if (empty($stored_cards)) {
// We do not, create the profile (which includes the payment details).
$response = commerce_authnet_acceptjs_create_customer_profile_request($payment_method, $order);
// If the Customer Profile creation was a success, store the new card on
// file data locally.
if ((string) $response->messages->resultCode == 'Ok') {
$customer_profile_id = (string) $response->customerProfileId;
}
elseif ((string) $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) $response->messages->message->text), 'is_numeric');
$customer_profile_id = reset($result);
}
else {
return FALSE;
}
}
else {
// Extract the user's Customer Profile ID from the first card's remote ID.
$card_data = reset($stored_cards);
list($customer_profile_id) = explode('|', $card_data->remote_id);
}
// Attempt to add the card to an existing Customer Profile if specified.
if (!empty($customer_profile_id)) {
$response = commerce_authnet_acceptjs_create_customer_payment_profile_request($payment_method, $customer_profile_id, $order, $payment_details);
if ((string) $response->messages->resultCode == 'Ok') {
$payment_profile_id = (string) $response->customerPaymentProfileId;
}
elseif ((string) $response->messages->message->code == 'E00039') {
if (empty($response->customerPaymentProfileId)) {
return FALSE;
}
$payment_profile_id = $response->customerPaymentProfileId;
}
elseif ($response->messages->message->code == 'E00040') {
// But if we could not find a customer profile, create a new one.
$response = commerce_authnet_acceptjs_create_customer_profile_request($payment_method, $order, $payment_details);
// If the Customer Profile creation was a success, store the new card on
// file data locally.
if ((string) $response->messages->resultCode == 'Ok') {
// Build a remote ID that includes the Customer Profile ID and the
// Payment Profile ID.
$customer_profile_id = (string) $response->customerProfileId;
$payment_profile_id = (string) $response->customerPaymentProfileIdList->numericString;
}
else {
return FALSE;
}
}
else {
return FALSE;
}
$remote_id = $customer_profile_id . '|' . $payment_profile_id;
}
// Build our card for storing with card on file.
/** @var \stdClass $card_data */
$card_data = commerce_cardonfile_new();
$card_data->uid = $order->uid;
$card_data->payment_method = $payment_method['method_id'];
$card_data->instance_id = $payment_method['instance_id'];
$card_data->remote_id = $remote_id;
$card_data->card_type = !empty($card_type) ? $card_type : 'card';
$card_data->card_name = !empty($billing_address['name_line']) ? $billing_address['name_line'] : '';
$card_data->card_number = $pane_values['credit_card']['cc']['last4'];
$card_data->card_exp_month = $pane_values['credit_card']['cc']['expiration_month'];
$card_data->card_exp_year = substr(date('Y'), 0, 2) . $pane_values['credit_card']['cc']['expiration_year'];
$card_data->status = 1;
if (isset($pane_values['cardonfile_instance_default'])) {
$card_data->instance_default = $pane_values['cardonfile_instance_default'];
}
// Save and log the creation of the new card on file.
commerce_cardonfile_save($card_data);
if ($customer_profile_id) {
watchdog('commerce_authnet', 'CIM Payment Profile added to Customer Profile @profile_id for user @uid.', array(
'@profile_id' => $customer_profile_id,
'@uid' => $order->uid,
));
}
else {
watchdog('commerce_authnet', 'CIM Customer Profile @profile_id created and saved to user @uid.', array(
'@profile_id' => (string) $response->customerProfileId,
'@uid' => $order->uid,
));
}
// Process the payment.
return commerce_authnet_cim_cardonfile_charge($payment_method, $card_data, $order, $charge);
}
/**
* Submits a createCustomerProfileRequest XML CIM API request to Authorize.Net.
*
* This function will attempt to create a CIM Customer Profile and a default
* Payment Profile for it using the given payment details.
*
* @param $payment_method
* The payment method instance array containing the API credentials for a CIM
* enabled Authorize.Net account.
* @param $order
* The order object containing the billing address and e-mail to use for the
* customer profile.
* @param $payment_details
* An array of payment details to use in the default payment profile. See the
* respective helper array functions for possible keys.
*
* @return
* A SimpleXMLElement containing the API response.
*
* @see commerce_authnet_cim_credit_card_array()
*/
function commerce_authnet_acceptjs_create_customer_profile_request($payment_method, $order, $payment_details = array()) {
$billto = commerce_authnet_cim_billto_array($order);
// Build the base profile request data.
$api_request_data = array(
'profile' => array(
'merchantCustomerId' => $order->uid,
'description' => $billto['firstName'] . ' ' . $billto['lastName'],
'email' => $order->mail,
),
);
if (!empty($payment_details)) {
$api_request_data['profile']['paymentProfiles'] = array(
'billTo' => $billto,
'payment' => array(),
);
}
// Add the shipping address if available.
if (isset($order->commerce_customer_shipping)) {
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
if ($order_wrapper->commerce_customer_shipping
->value()) {
$api_request_data['profile']['shipToList'] = commerce_authnet_cim_shipto_array($order);
}
}
// If the order is anonymous, unset the merchantCustomerId from the request.
if (empty($api_request_data['profile']['merchantCustomerId'])) {
unset($api_request_data['profile']['merchantCustomerId']);
}
if (!empty($payment_details['opaqueData'])) {
$api_request_data['profile']['paymentProfiles']['payment'] = $payment_details;
}
return commerce_authnet_cim_request($payment_method, 'createCustomerProfileRequest', $api_request_data);
}
/**
* Submits a createCustomerPaymentProfileRequest XML CIM API request.
*
* @param $payment_method
* The payment method instance array containing the API credentials for a CIM
* enabled Authorize.Net account.
* @param $cim_customer_profile_id
* A numerical CIM Customer Profile ID.
* @param $order
* The order object containing the billing address and e-mail to use for the
* payment profile.
* @param $payment_details
* An array of payment details to use in the default payment profile. See the
* respective helper array functions for possible keys.
*
* @return
* A SimpleXMLElement containing the API response.
*
* @see commerce_authnet_cim_credit_card_array()
*/
function commerce_authnet_acceptjs_create_customer_payment_profile_request($payment_method, $cim_customer_profile_id, $order, $payment_details) {
$billto = commerce_authnet_cim_billto_array($order);
// Build the base profile request data.
$api_request_data = array(
'customerProfileId' => $cim_customer_profile_id,
'paymentProfile' => array(
'billTo' => $billto,
'payment' => array(),
),
);
if (!empty($payment_details['opaqueData'])) {
$api_request_data['paymentProfile']['payment'] = $payment_details;
}
return commerce_authnet_cim_request($payment_method, 'createCustomerPaymentProfileRequest', $api_request_data);
}
/**
* Return the form elements for Accept.js.
*
* @param array $payment_method
* The payment method.
*
* @return array
* The form elements.
*/
function commerce_authnet_acceptjs_form_elements(array $payment_method) {
$form = array();
// @todo change to proper library.
if ($payment_method['settings']['txn_mode'] == AUTHNET_TXN_MODE_DEVELOPER) {
$form['#attached']['library'][] = array(
'commerce_authnet',
'commerce_authnet.acceptjs.sandbox',
);
}
else {
$form['#attached']['library'][] = array(
'commerce_authnet',
'commerce_authnet.acceptjs.production',
);
}
$form['#attached']['library'][] = array(
'commerce_authnet',
'commerce_authnet.acceptjs.accept',
);
$form['#attached']['css'][] = drupal_get_path('module', 'commerce_payment') . '/theme/commerce_payment.theme.css';
$js_settings = array(
'clientKey' => $payment_method['settings']['client_key'],
'apiLoginID' => $payment_method['settings']['login'],
'paymentMethodType' => 'credit_card',
);
// Allow other modules to alter the JS settings.
drupal_alter('commerce_authnet_acceptjs_settings', $js_settings, $payment_method);
$form['#attached']['js'][] = array(
'data' => array(
'commerceAuthorizeNet' => $js_settings,
),
'type' => 'setting',
);
$form['credit_card'] = array(
'#type' => 'container',
);
$form['credit_card']['#attributes']['class'][] = 'acceptjs-form';
$form['credit_card']['errors'] = array(
'#type' => 'hidden',
);
$form['credit_card']['cc'] = array(
'#type' => 'container',
);
// Fields placeholder to be built by the JS.
$form['credit_card']['cc']['credit_card_number'] = array(
'#type' => 'textfield',
'#title' => t('Card number'),
'#attributes' => array(
'placeholder' => '•••• •••• •••• ••••',
'autocomplete' => 'off',
'autocorrect' => 'off',
'autocapitalize' => 'none',
'id' => 'credit-card-number',
'required' => 'required',
),
'#label_attributes' => array(
'class' => array(
'js-form-required',
'form-required',
),
),
'#maxlength' => 20,
'#size' => 20,
);
$form['credit_card']['cc']['expiration'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'credit-card-form__expiration',
'container-inline',
),
),
);
$form['credit_card']['cc']['expiration']['month'] = array(
'#type' => 'textfield',
'#title' => t('Month'),
'#attributes' => array(
'placeholder' => 'MM',
'autocomplete' => 'off',
'autocorrect' => 'off',
'autocapitalize' => 'none',
'id' => 'expiration-month',
'required' => 'required',
),
'#label_attributes' => array(
'class' => array(
'js-form-required',
'form-required',
),
),
'#maxlength' => 2,
'#size' => 3,
);
$form['credit_card']['cc']['expiration']['divider'] = array(
'#type' => 'item',
'#title' => '',
'#markup' => '<span class="credit-card-form__divider">/</span>',
);
$form['credit_card']['cc']['expiration']['year'] = array(
'#type' => 'textfield',
'#title' => t('Year'),
'#attributes' => array(
'placeholder' => 'YY',
'autocomplete' => 'off',
'autocorrect' => 'off',
'autocapitalize' => 'none',
'id' => 'expiration-year',
'required' => 'required',
),
'#label_attributes' => array(
'class' => array(
'js-form-required',
'form-required',
),
),
'#maxlength' => 2,
'#size' => 3,
);
$form['credit_card']['cc']['security_code'] = array(
'#type' => 'textfield',
'#title' => t('CVV'),
'#attributes' => array(
'placeholder' => '•••',
'autocomplete' => 'off',
'autocorrect' => 'off',
'autocapitalize' => 'none',
'id' => 'cvv',
'required' => 'required',
),
'#label_attributes' => array(
'class' => array(
'js-form-required',
'form-required',
),
),
'#maxlength' => 4,
'#size' => 4,
);
// To display validation errors.
$form['credit_card']['cc']['payment_errors'] = array(
'#type' => 'markup',
'#markup' => '<div id="payment-errors"></div>',
'#weight' => -200,
);
// Populated by the JS library after receiving a response from AuthorizeNet.
$form['credit_card']['cc']['data_descriptor'] = array(
'#type' => 'hidden',
'#attributes' => array(
'class' => array(
'accept-js-data-descriptor',
),
),
);
$form['credit_card']['cc']['data_value'] = array(
'#type' => 'hidden',
'#attributes' => array(
'class' => array(
'accept-js-data-value',
),
),
);
$form['credit_card']['cc']['last4'] = array(
'#type' => 'hidden',
'#attributes' => array(
'class' => array(
'accept-js-data-last4',
),
),
);
$form['credit_card']['cc']['expiration_month'] = array(
'#type' => 'hidden',
'#attributes' => array(
'class' => array(
'accept-js-data-month',
),
),
);
$form['credit_card']['cc']['expiration_year'] = array(
'#type' => 'hidden',
'#attributes' => array(
'class' => array(
'accept-js-data-year',
),
),
);
return $form;
}
Functions
Name | Description |
---|---|
commerce_authnet_acceptjs_create_customer_payment_profile_request | Submits a createCustomerPaymentProfileRequest XML CIM API request. |
commerce_authnet_acceptjs_create_customer_profile_request | Submits a createCustomerProfileRequest XML CIM API request to Authorize.Net. |
commerce_authnet_acceptjs_default_settings | Returns the default settings for the Authorize.Net AIM payment method. |
commerce_authnet_acceptjs_form_elements | Return the form elements for Accept.js. |
commerce_authnet_acceptjs_settings_form | Payment method callback: settings form. |
commerce_authnet_acceptjs_submit_form | Payment method callback: checkout form. |
commerce_authnet_acceptjs_submit_form_submit | Payment method callback: checkout form submission. |
commerce_authnet_acceptjs_submit_form_validate | Payment method callback: checkout form validation. |
commerce_authnet_acceptjs_submit_new_card_form_submit | Handles advanced logic relating to creating AcceptJS orders with new card data. |