Google Checkout Merchant Center, enter %url as the callback URL for this site. This will allow Ubercart to communicate with Google Checkout.', array('!checkout_url' => $checkout_url, '%url' => url('google_checkout', array('absolute' => TRUE))));
break;
}
return $output;
}
/**
* Implements hook_menu().
*/
function uc_google_checkout_menu() {
$items = array();
$items['admin/store/settings/google_checkout'] = array(
'title' => 'Google Checkout settings',
'description' => 'Set merchant ID and key for Google Checkout.',
'page callback' => 'drupal_get_form',
'page arguments' => array('uc_google_checkout_settings'),
'access arguments' => array('administer store'),
'file' => 'uc_google_checkout.admin.inc',
);
$items['admin/store/settings/google_checkout/account'] = array(
'title' => 'Account',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/store/settings/google_checkout/shipping'] = array(
'title' => 'Shipping',
'description' => 'Calculate shipping charges for orders through Google Checkout.',
'page callback' => 'drupal_get_form',
'page arguments' => array('uc_google_checkout_shipping_settings'),
'access arguments' => array('administer store'),
'type' => MENU_LOCAL_TASK,
'file' => 'uc_google_checkout.admin.inc',
);
$items['admin/store/settings/google_checkout/taxes'] = array(
'title' => 'Taxes',
'description' => 'Calculate taxes for orders through Google Checkout.',
'page callback' => 'drupal_get_form',
'page arguments' => array('uc_google_checkout_taxes_settings'),
'access arguments' => array('administer store'),
'type' => MENU_LOCAL_TASK,
'file' => 'uc_google_checkout.admin.inc',
);
$items['google_checkout'] = array(
'page callback' => 'uc_google_checkout_callback',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'file' => 'uc_google_checkout.pages.inc',
);
$items['admin/store/orders/%uc_order/google_checkout'] = array(
'title callback' => 'uc_google_checkout_terminal_title',
'title arguments' => array(3),
'description' => 'Process a credit card payment or refund through Google Checkout.',
'page callback' => 'uc_google_checkout_terminal',
'page arguments' => array(3),
'access arguments' => array('manual payments'),
'file' => 'uc_google_checkout.admin.inc',
);
return $items;
}
/**
* Menu title callback function.
*/
function uc_google_checkout_terminal_title($order) {
return t('Google Checkout terminal: Order @order_id', array('@order_id' => $order->order_id));
}
/**
* Implements hook_init().
*/
function uc_google_checkout_init() {
// When an order comes in from Google Checkout, we need to unset some
// $_SESSION data. Since this isn't done under the customer's user, we
// do it when they next load a page.
global $user;
$users = variable_get('uc_google_checkout_order_users', array());
if (isset($users[$user->uid])) {
unset($_SESSION['cart_order'], $_SESSION['do_complete'], $_SESSION['new_user'], $users[$user->uid]);
variable_set('uc_google_checkout_order_users', $users);
}
global $conf;
$conf['i18n_variables'][] = 'uc_google_checkout_order_cancel_reason';
}
/**
* Implements hook_theme().
*/
function uc_google_checkout_theme() {
return array(
'uc_google_checkout_shipping_settings' => array(
'render element' => 'form',
'file' => 'uc_google_checkout.admin.inc',
),
'uc_google_checkout_taxes_settings' => array(
'render element' => 'form',
'file' => 'uc_google_checkout.admin.inc',
),
);
}
/**
* Implements hook_form_alter().
*/
function uc_google_checkout_form_alter(&$form, &$form_state, $form_id) {
if (uc_product_is_product_form($form)) {
$node = $form['#node'];
if (is_object($node) && $form_id == $node->type . '_node_form' && uc_product_is_product($node->type)) {
$policy_url = 'https://checkout.google.com/support/sell/bin/answer.py?answer=75724';
$form['base']['gc_salable'] = array(
'#type' => 'checkbox',
'#title' => t('Product conforms to Google Checkout content policies.'),
'#default_value' => isset($node->gc_salable) ? $node->gc_salable : TRUE,
'#description' => t('To be a Google Checkout approved merchant, your items must conform to the Google Checkout content policies.', array('!url' => $policy_url)),
'#weight' => 40,
);
}
}
}
/**
* Implements hook_form_FORM_ID_alter() for uc_payment_methods_form().
*/
function uc_google_checkout_form_uc_payment_methods_form_alter(&$form, &$form_state) {
// Make sure no one enables this for Ubercart checkout.
$form['pmtable']['google_checkout']['uc_payment_method_google_checkout_checkout']['#disabled'] = TRUE;
$form['pmtable']['google_checkout']['uc_payment_method_google_checkout_checkout']['#value'] = FALSE;
}
/**
* Implements hook_form_FORM_ID_alter() for uc_payment_by_order_form().
*/
function uc_google_checkout_form_uc_payment_by_order_form_alter(&$form, &$form_state) {
unset($form['payments']['new']['method']['#options']['google_checkout']);
}
/**
* Implements hook_form_FORM_ID_alter() for uc_order_view_update_form().
*/
function uc_google_checkout_form_uc_order_view_update_form_alter(&$form, &$form_state) {
$form['#submit'][] = 'uc_google_checkout_notify_update';
}
/**
* Implements hook_form_FORM_ID_alter() for uc_store_format_settings_form().
*/
function uc_google_checkout_form_uc_store_format_settings_form_alter(&$form, &$form_state) {
$form['currency']['uc_currency_code']['#description'] .= ' ' . t('Google Checkout only accepts the following currencies: @list', array('@list' => implode(', ', _uc_google_checkout_currency_codes())));
}
/**
* Implements hook_node_insert().
*/
function uc_google_checkout_node_insert($node) {
uc_google_checkout_node_update($node);
}
/**
* Implements hook_node_update().
*/
function uc_google_checkout_node_update($node) {
if (uc_product_is_product($node->type)) {
if (isset($node->gc_salable)) {
if (!$node->revision) {
db_delete('uc_gc_products')
->condition('vid', $node->vid)
->execute();
}
db_insert('uc_gc_products')
->fields(array(
'vid' => $node->vid,
'nid' => $node->nid,
'gc_salable' => $node->gc_salable,
))
->execute();
}
}
}
/**
* Implements hook_node_load().
*/
function uc_google_checkout_node_load($nodes, $types) {
$vids = array();
$product_types = uc_product_types();
foreach ($nodes as &$node) {
if (in_array($node->type, $product_types)) {
$vids[$node->nid] = $node->vid;
// Set default value.
$node->gc_salable = TRUE;
}
}
if ($vids) {
$result = db_query("SELECT nid, gc_salable FROM {uc_gc_products} WHERE vid IN (:vids)", array(':vids' => $vids));
foreach ($result as $salable) {
$nodes[$node->nid]->gc_salable = $salable->gc_salable;
}
}
}
/**
* Implements hook_node_delete().
*/
function uc_google_checkout_node_delete($node) {
db_delete('uc_gc_products')
->condition('nid', $node->nid)
->execute();
}
/**
* Implements hook_node_revision_delete().
*/
function uc_google_checkout_node_revision_delete($node) {
db_delete('uc_gc_products')
->condition('vid', $node->vid)
->execute();
}
/******************************************************************************
* Hook Functions (Ubercart) *
******************************************************************************/
/**
* Implements hook_uc_cart_pane().
*/
function uc_google_checkout_uc_cart_pane() {
$panes[] = array(
'id' => 'uc_google_checkout',
'title' => t('Google Checkout'),
'enabled' => TRUE,
'weight' => 1,
'body' => drupal_get_form('uc_google_checkout_cart_form') + array(
'#prefix' => '
',
'#suffix' => '
',
),
);
return $panes;
}
/**
* Implements hook_uc_order_pane().
*/
function uc_google_checkout_uc_order_pane() {
$panes[] = array(
'id' => 'email_allowed',
'callback' => 'uc_google_checkout_pane_email_allowed',
'title' => t('Marketing preferences'),
'desc' => t("Display the customer's preferences about mass-marketing."),
'class' => 'pos-left',
'weight' => 4,
'show' => array('view', 'customer'),
);
return $panes;
}
/**
* Implements hook_uc_line_item().
*/
function uc_google_checkout_uc_line_item() {
$items[] = array(
'id' => 'gc_coupon',
'title' => t('Google Checkout Coupon'),
'stored' => TRUE,
'calculated' => TRUE,
'weight' => 2,
);
$items[] = array(
'id' => 'gc_gift_certificate',
'title' => t('Google Checkout Gift Certificate'),
'stored' => TRUE,
'calculated' => TRUE,
'weight' => 2,
);
return $items;
}
/**
* Implements hook_uc_order().
*/
function uc_google_checkout_uc_order($op, &$order, $arg2) {
switch ($op) {
case 'load':
$result = db_query("SELECT * FROM {uc_gc_orders} WHERE order_id = :id", array(':id' => $order->order_id));
if ($gc = $result->fetchObject()) {
$order->google_order_number = $gc->gc_order_number;
$order->financial_state = $gc->financial_state;
$order->fulfillment_state = $gc->fulfillment_state;
$order->gc_total = $gc->gc_total;
}
break;
case 'can_update':
if (!isset($order->google_order_number) || isset($_SESSION['google_updates']) && $_SESSION['google_updates']) {
return TRUE;
}
switch ($arg2) {
case 'canceled':
if (uc_google_checkout_cancel_order($order)) {
drupal_set_message(t('Cancel order request sent to Google Checkout. The order will be updated momentarily.'));
}
else {
drupal_set_message(t('Order is not canceled in Google Checkout.'));
}
return FALSE;
}
break;
}
}
/**
* Implements hook_uc_payment_method().
*/
function uc_google_checkout_uc_payment_method() {
$methods[] = array(
'id' => 'google_checkout',
'name' => t('Google Checkout'),
'title' => t('Google Checkout'),
'desc' => t('Express payment with Google Checkout.'),
'callback' => 'uc_payment_method_google_checkout',
'weight' => 1,
'checkout' => FALSE,
'backend' => FALSE,
);
return $methods;
}
/**
* Implements hook_uc_payment_gateway().
*/
function uc_google_checkout_uc_payment_gateway() {
$gateways[] = array(
'id' => 'google_checkout',
'title' => t('Google Checkout'),
'description' => t('Express payment with Google Checkout.'),
'google_checkout' => 'uc_google_checkout_charge',
);
return $gateways;
}
/**
* Implements hook_uc_shipment().
*/
function uc_google_checkout_uc_shipment($op, $shipment) {
switch ($op) {
case 'save':
$google_order_number = uc_google_checkout_get_google_number($shipment->order_id);
if ($google_order_number && $shipment->is_new) {
$xml_data = '';
foreach ($shipment->packages as $package) {
if ($package->tracking_number) {
$tracking_number = $package->tracking_number;
}
elseif ($shipment->tracking_number) {
$tracking_number = $shipment->tracking_number;
}
if ($tracking_number) {
foreach ($package->products as $product) {
$xml_data .= '';
$xml_data .= '';
$xml_data .= '' . check_plain($product->nid . '|' . $product->model) . '';
$xml_data .= '';
$xml_data .= '';
$xml_data .= '';
$xml_data .= '' . check_plain($shipment->carrier) . '';
$xml_data .= '' . check_plain($tracking_number) . '';
$xml_data .= '';
$xml_data .= '';
$xml_data .= '';
}
}
}
if ($xml_data) {
$request = '';
$request .= "\n";
$request .= '';
$request .= '';
$request .= $xml_data;
$request .= '';
$request .= 'true';
$request .= '';
$response = uc_google_checkout_send_request('request', $request);
}
}
break;
case 'delete':
$google_order_number = uc_google_checkout_get_google_number($shipment->order_id);
if ($google_order_number) {
foreach ($shipment->packages as $package) {
foreach ($package->products as $product) {
$reset_ids[] = check_plain($product->nid . '|' . $product->model);
}
}
$request = '';
$request .= "\n";
$request .= '';
$request .= '';
foreach (array_unique($reset_ids) as $item_id) {
$request .= '';
$request .= '' . $item_id . '';
$request .= '';
}
$request .= '';
$request .= 'false';
$request .= '';
}
$response = uc_google_checkout_send_request('request', $request);
break;
}
}
/******************************************************************************
* Callback Functions, Forms, and Tables *
******************************************************************************/
/**
* Form builder for uc_google_checkout_cart_form().
*
* @see uc_google_checkout_cart_form_submit()
* @ingroup forms
*/
function uc_google_checkout_cart_form($form, &$form_state) {
if (variable_get('uc_google_checkout_mode', 'checkout') == 'checkout') {
$merchant_id = variable_get('uc_google_checkout_merchant_id', '');
$checkout_url = 'https://checkout.google.com';
}
else {
$merchant_id = variable_get('uc_google_checkout_test_merchant_id', '');
$checkout_url = 'https://sandbox.google.com/checkout';
}
if (!$merchant_id) {
watchdog('google', 'Google Checkout is enabled, but no Merchant ID found.', array(), WATCHDOG_ERROR, 'admin/store/settings/google_checkout');
return;
}
$disable = FALSE;
foreach (uc_cart_get_contents() as $item) {
$product = node_load($item->nid);
if (!$product->gc_salable) {
$disable = TRUE;
break;
}
}
switch (variable_get('uc_google_checkout_button_size', 'large')) {
case 'large':
$width = 180;
$height = 46;
break;
case 'medium':
$width = 168;
$height = 44;
break;
case 'small':
$width = 160;
$height = 43;
break;
}
$form['submit'] = array(
'#type' => 'image_button',
'#src' => $checkout_url . '/buttons/checkout.gif?merchant_id=' . $merchant_id . '&w=' . $width . '&h=' . $height . '&style=' . variable_get('uc_google_checkout_button_color', 'trans') . '&variant=' . ($disable ? 'disabled' : 'text') . '&loc=en_US',
'#disabled' => $disable,
'#attributes' => array(
'alt' => t('Google Checkout'),
'title' => t('Fast checkout through Google.'),
'height' => $height,
'width' => $width,
),
'#description' => '' . t('What is Google Checkout?') . '',
);
return $form;
}
/**
* Form submission handler for uc_google_checkout_cart_form().
*
* @see uc_google_checkout_cart_form()
*/
function uc_google_checkout_cart_form_submit($form, &$form_state) {
global $user;
$items = uc_cart_get_contents();
if (!is_array($items) || count($items) == 0) {
drupal_set_message(t('You do not have any items in your shopping cart.'));
return;
}
if (empty($_SESSION['cart_order'])) {
$order = uc_order_new($user->uid);
$_SESSION['cart_order'] = $order->order_id;
}
else {
$order = new stdClass();
$order->uid = $user->uid;
$order->order_id = $_SESSION['cart_order'];
$order->primary_email = $user->mail;
$order->order_status = uc_order_state_default('in_checkout');
}
$order->products = $items;
uc_order_save($order);
uc_order_update_status($order->order_id, 'in_google_checkout');
$order->order_status = 'in_google_checkout';
$request = uc_google_checkout_cart_request($order);
if ($response = uc_google_checkout_send_request('merchantCheckout', $request)) {
$redirect = (string) $response->{'redirect-url'};
drupal_goto($redirect);
}
}
function uc_google_checkout_cart_request($order) {
if (variable_get('uc_google_checkout_mode', 'checkout') == 'checkout') {
$merchant_id = variable_get('uc_google_checkout_merchant_id', '');
}
else {
$merchant_id = variable_get('uc_google_checkout_test_merchant_id', '');
}
$output = '';
$output .= "\n";
if (count($order->products)) {
$output .= '';
$output .= '';
$output .= '';
foreach ($order->products as $product) {
$output .= '- ';
$output .= '' . check_plain($product->model) . '';
$output .= '' . check_plain($product->title) . '';
$output .= '' . $product->price . '';
$output .= '';
if (!uc_cart_product_is_shippable($product)) {
$output .= '';
$output .= 'PESSIMISTIC';
$output .= 'true';
$output .= '';
}
$output .= '' . $product->qty . '';
$output .= '' . $product->nid . '|' . $product->model . '';
$output .= '
';
}
$output .= '';
$output .= '';
$output .= '' . uc_cart_get_id() . '';
$output .= '' . $order->order_id . '';
$output .= '';
$output .= '';
$output .= '';
$output .= '';
if (uc_order_is_shippable($order)) {
$companies = uc_google_checkout_shipping_companies();
$services = uc_google_checkout_shipping_services();
$shipping_options = '';
foreach ($services as $key => $title) {
$settings = variable_get('uc_google_checkout_shipping_' . $key, array());
if ($settings['enable']) {
$shipping_options .= '';
$shipping_options .= '' . $settings['default'] . '';
$temp = explode('_', $key, 2);
$shipping_options .= '' . $companies[$temp[0]] . '';
$shipping_options .= '' . $settings['pickup'] . '';
$shipping_options .= '' . $services[$key] . '';
if ($settings['fixed_charge']) {
$shipping_options .= '' . uc_currency_format($settings['fixed_charge'], FALSE, FALSE, '.') . '';
}
if ($settings['percent_adjustment']) {
$shipping_options .= '' . (float)$settings['percent_adjustment'] . '';
}
$shipping_options .= '';
}
}
if ($shipping_options) {
$output .= '';
$output .= '';
$output .= '';
$output .= $shipping_options;
$output .= '';
$address = variable_get('uc_quote_store_default_address');
if (empty($address)) {
$address = new UcAddress();
$address->city = variable_get('uc_store_city', NULL);
$address->zone = uc_get_zone_code(variable_get('uc_store_zone', NULL));
$address->postal_code = variable_get('uc_store_postal_code', NULL);
$address->country = uc_store_default_country();
}
$country = uc_get_country_data(array('country_id' => $address->country));
$address->country_code = $country[0]['country_iso_code_2'];
$output .= '';
$output .= '';
$output .= '';
$output .= '' . $address->city . '';
$output .= '' . $address->zone . '';
$output .= '' . $address->country_code . '';
$output .= '' . $address->postal_code . '';
$output .= '';
$output .= '';
$output .= '';
$output .= '';
$output .= '';
}
}
$tax_table = '';
$result = db_query("SELECT zone, rate, tax_shipping FROM {uc_gc_taxes}");
foreach ($result as $tax) {
$tax_table .= '';
if ($tax->tax_shipping) {
$tax_table .= 'true';
}
$tax_table .= '' . (float)$tax->rate . '';
$tax_table .= '';
$tax_table .= '';
$tax_table .= '' . $tax->zone . '';
$tax_table .= '';
$tax_table .= '';
$tax_table .= '';
}
if ($tax_table) {
$output .= '';
$output .= '';
$output .= '';
$output .= $tax_table;
$output .= '';
$output .= '';
$output .= '';
}
$output .= '' . url('cart', array('absolute' => TRUE)) . '';
if (($page = variable_get('uc_continue_shopping_url', '')) != '') {
$output .= '' . url($page, array('absolute' => TRUE)) . '';
}
$output .= '218752253180456';
$output .= '';
$output .= '';
$output .= '';
}
return $output;
}
function uc_google_checkout_headers() {
if (variable_get('uc_google_checkout_mode', 'checkout') == 'checkout') {
$merchant_id = variable_get('uc_google_checkout_merchant_id', '');
$merchant_key = variable_get('uc_google_checkout_merchant_key', '');
}
else {
$merchant_id = variable_get('uc_google_checkout_test_merchant_id', '');
$merchant_key = variable_get('uc_google_checkout_test_merchant_key', '');
}
$headers = array();
$authorization = $merchant_id . ':' . $merchant_key;
if ($authorization != ':') {
$headers['Authorization'] = 'Basic ' . base64_encode($authorization);
}
$headers['Content-Type'] = 'application/xml; charset=UTF-8';
$headers['Accept'] = 'application/xml; charset=UTF-8';
return $headers;
}
function uc_google_checkout_send_request($api, $request) {
if (variable_get('uc_google_checkout_mode', 'checkout') == 'checkout') {
$merchant_id = variable_get('uc_google_checkout_merchant_id', '');
$checkout_url = 'https://checkout.google.com';
}
else {
$merchant_id = variable_get('uc_google_checkout_test_merchant_id', '');
$checkout_url = 'https://sandbox.google.com/checkout';
}
if (!$merchant_id) {
return;
}
// Google's XML parser doesn't like named entities apparently.
str_replace(array('&', '<', '>'), array('&', '<', '>'), $request);
$response_obj = drupal_http_request($checkout_url . '/api/checkout/v2/' . $api . '/Merchant/' . $merchant_id, array(
'headers' => uc_google_checkout_headers(),
'method' => 'POST',
'data' => $request,
));
if ($response_obj->error) {
watchdog('google', '@error', array('@error' => $response_obj->error), WATCHDOG_ERROR);
}
$response = new SimpleXMLElement($response_obj->data);
if ($response->getName() == 'error') {
$error = (string) $response->{'error-message'};
drupal_set_message($error, 'error');
watchdog('google', '@error', array('@error' => $error), WATCHDOG_ERROR);
return NULL;
}
/**
* Ugly hack to work around PHP bug, details here:
* http://bugs.php.net/bug.php?id=23220
* We strip out errors that look something like:
* warning: fread() [function.fread]: SSL fatal protocol error in...
* Copied from http://drupal.org/node/70915.
*/
$messages = drupal_set_message();
$errors = $messages['error'];
$total = count($errors);
for ($i = 0; $i <= $total; $i++) {
if (strpos($errors[$i], 'SSL: fatal protocol error in')) {
unset($_SESSION['messages']['error'][$i]);
}
}
if (empty($_SESSION['messages']['error'])) {
unset($_SESSION['messages']['error']);
}
db_delete('watchdog')
->condition('type', 'php')
->condition('variables', '%SSL: fatal protocol error%', 'LIKE')
->execute();
// End of ugly hack.
return $response;
}
function uc_google_checkout_pane_email_allowed($op, $order) {
switch ($op) {
case 'customer':
case 'view':
if (isset($order->data['email_allowed']) && $order->data['email_allowed']) {
$build = array('#markup' => t('Customer will accept marketing emails.'));
}
else {
$build = array('#markup' => t('Customer does not want marketing emails.'));
}
return $build;
}
}
/**
* Adds setting callbacks to the payment settings section
* The fulfillment sections need coded still. JS.
*/
function uc_payment_method_google_checkout($op, &$order) {
switch ($op) {
case 'order-view':
$build['#markup'] = l(t('Google Checkout terminal'), 'admin/store/orders/' . $order->order_id . '/google_checkout');
return $build;
case 'settings':
$form = array();
$form['link'] = array(
'#markup' => l(t('Click here to go to Google Checkout settings.'), 'admin/store/settings/google_checkout'),
);
return $form;
}
}
function uc_google_checkout_new_order($new_order) {
$order_id = $new_order->{'shopping-cart'}->{'merchant-private-data'}->{'order-id'};
$cart_id = (string) $new_order->{'shopping-cart'}->{'merchant-private-data'}->{'cart-id'};
$order = uc_order_load($order_id);
if ($order) {
$shipping_address = $new_order->{'buyer-shipping-address'};
$order->delivery_company = $shipping_address->{'company-name'};
$order->delivery_first_name = $shipping_address->{'structured-name'}->{'first-name'};
$order->delivery_last_name = $shipping_address->{'structured-name'}->{'last-name'};
$order->delivery_phone = $shipping_address->phone;
$order->delivery_street1 = $shipping_address->address1;
$order->delivery_street2 = $shipping_address->address2;
$order->delivery_city = $shipping_address->city;
$zone_id = db_query("SELECT zone_id FROM {uc_zones} WHERE zone_code = :code", array(':code' => $shipping_address->region))->fetchField();
$order->delivery_zone = $zone_id;
$countries = uc_get_country_data(array('country_iso_code_2' => $shipping_address->{'country-code'}));
$order->delivery_country = $countries[0]['country_id'];
$order->delivery_postal_code = $shipping_address->{'postal-code'};
$billing_address = $new_order->{'buyer-billing-address'};
$order->billing_company = $billing_address->{'company-name'};
$order->billing_first_name = $billing_address->{'structured-name'}->{'first-name'};
$order->billing_last_name = $billing_address->{'structured-name'}->{'last-name'};
$order->billing_phone = $billing_address->phone;
$order->billing_street1 = $billing_address->address1;
$order->billing_street2 = $billing_address->address2;
$order->billing_city = $billing_address->city;
if ($billing_address['region'] != $shipping_address->region) {
$zone_id = db_query("SELECT zone_id FROM {uc_zones} WHERE zone_code = :code", array(':code' => $billing_address->region))->fetchField();
}
$order->billing_zone = $zone_id;
if ($billing_address->{'country-code'} != $shipping_address->{'country-code'}) {
$countries = uc_get_country_data(array('country_iso_code_2' => $billing_address->{'country-code'}));
}
$order->billing_country = $countries[0]['country_id'];
$order->billing_postal_code = $billing_address->{'postal-code'};
if (!$order->primary_email) {
$order->primary_email = $billing_address->email;
}
if ($new_order->{'buyer-marketing-preferences'}->{'email-allowed'} == 'true') {
$order->data['email_allowed'] = TRUE;
if (module_exists('simplenews')) {
simplenews_subscribe_user($order->primary_email, variable_get('uc_google_checkout_simplenews_tid', 0), TRUE);
}
}
else {
$order->data['email_allowed'] = FALSE;
if (module_exists('simplenews')) {
simplenews_unsubscribe_user($order->primary_email, variable_get('uc_google_checkout_simplenews_tid', 0), FALSE);
}
}
$order->payment_method = 'google_checkout';
$comments = array();
uc_order_line_item_add($order_id, 'tax', t('Total tax'), $new_order->{'order-adjustment'}->{'total-tax'});
if (isset($new_order->{'order-adjustment'}->shipping)) {
$shipping_line = $new_order->{'order-adjustment'}->shipping[0];
uc_order_line_item_add($order_id, 'shipping', check_plain($shipping_line->{'shipping-name'}), $shipping_line->{'shipping-cost'});
}
if (isset($new_order->{'order-adjustment'}->{'merchant-codes'})) {
foreach ($new_order->{'order-adjustment'}->{'merchant-codes'}->children() as $adjustment) {
$type = $adjustment->getName();
if ($type == 'coupon-adjustment') {
uc_order_line_item_add($order_id, 'gc_coupon', check_plain($adjustment->code), -$adjustment->{'applied-amount'});
$comments[] = check_plain($adjustment->message);
}
elseif ($type == 'gift-certificate-adjustment') {
uc_order_line_item_add($order_id, 'gc_gift_certificate', check_plain($adjustment->code), -($adjustment->{'applied-amount'}));
$comments[] = check_plain($adjustment->message);
}
}
}
uc_order_save($order);
uc_cart_complete_sale($order);
// uc_cart_complete_sale() empties the current cart (Google Checkout
// API's cart) so we must empty the customer's manually.
uc_cart_empty($cart_id);
// Add a comment to let sales team know this came in through the site.
uc_order_comment_save($order->order_id, 0, t('Order created through Google Checkout (#@gco_order).', array('@gco_order' => $new_order->{'google-order-number'})), 'admin');
// uc_cart_complete_sale() also unsets some $_SESSION variables. These
// are tied to the user-id, so we record that for when they log in later.
$users = variable_get('uc_google_checkout_order_users', array());
$users[$order->uid] = $order->uid;
variable_set('uc_google_checkout_order_users', $users);
// Add messages from order adjustments (coupons, gift certificates, etc.).
foreach ($comments as $comment) {
$comment = trim($comment);
if ($comment) {
uc_order_comment_save($order->order_id, 0, $comment, 'order', $order->order_status, 0);
}
}
db_insert('uc_gc_orders')
->fields(array(
'order_id' => $order_id,
'gc_order_number' => $new_order->{'google-order-number'},
'gc_total' => $new_order->{'order-total'},
))
->execute();
uc_google_checkout_notification_acknowledgement($new_order['serial-number']);
}
else {
uc_google_checkout_notification_error();
}
}
function uc_google_checkout_accept_risk($risk) {
$order_id = uc_google_checkout_get_order($risk->{'google-order-number'});
if ($order_id) {
$risk_info = $risk->{'risk-information'};
$assessment = t('Risk information notification:') . '
';
$avs_response = $risk_info->{'avs-response'};
switch ($avs_response) {
case 'Y':
$assessment .= t('- Full AVS match (address and postal code)');
break;
case 'P':
$assessment .= t('- Partial AVS match (postal code only)');
break;
case 'A':
$assessment .= t('- Partial AVS match (address only)');
break;
case 'N':
$assessment .= t('- No AVS match');
break;
case 'U':
$assessment .= t('- AVS not supported by issuer');
break;
default:
$assessment .= t('Error: No AVS response.');
break;
}
$assessment .= '
';
$cvn_response = $risk_info->{'cvn-response'};
switch ($cvn_response) {
case 'M':
$assessment .= t('- CVN match');
break;
case 'N':
$assessment .= t('- No CVN match');
break;
case 'U':
$assessment .= t('- CVN not available');
break;
case 'E':
$assessment .= t('- CVN error');
break;
default:
$assessment .= t('Error: No CVN response.');
break;
}
$assessment .= '
';
$assessment .= t('Partial CC number: %s', array('%s' => $risk_info->{'partial-cc-number'}));
$assessment .= '
';
$assessment .= format_plural($risk_info->{'buyer-account-age'}, 'Google Checkout member for 1 month.', 'Google Checkout member for @count months.');
$assessment .= '
';
$assessment .= t('Eligible for protection: @bool', array('@bool' => drupal_strtoupper($risk_info->{'eligible-for-protection'})));
uc_order_comment_save($order_id, 0, $assessment, 'admin', 'chargeable');
uc_google_checkout_notification_acknowledgement($risk['serial-number']);
}
}
function uc_google_checkout_order_state_change($change) {
$order_id = uc_google_checkout_get_order($change->{'google-order-number'});
if ($order_id) {
$new_financial = (string) $change->{'new-financial-order-state'};
$new_fulfillment = (string) $change->{'new-fulfillment-order-state'};
$prev_financial = (string) $change->{'previous-financial-order-state'};
$prev_fulfillment = (string) $change->{'previous-fulfillment-order-state'};
db_update('uc_gc_orders')
->fields(array(
'financial_state' => $new_financial,
'fulfillment_state' => $new_fulfillment,
))
->condition('order_id', $order_id)
->condition('financial_state', $prev_financial)
->condition('fulfillment_state', $prev_fulfillment)
->execute();
if ($new_financial != $prev_financial) {
$_SESSION['google_updates'] = TRUE;
switch ($new_financial) {
case 'CHARGEABLE':
uc_order_update_status($order_id, 'chargeable');
break;
case 'CHARGING':
watchdog('google', 'Charging @order_id', array('@order_id' => $order_id));
break;
case 'CHARGED':
watchdog('google', 'Charged @order_id', array('@order_id' => $order_id));
break;
case 'PAYMENT_DECLINED':
watchdog('google', 'Payment declined @order_id', array('@order_id' => $order_id));
break;
case 'CANCELLED_BY_GOOGLE':
$message = t('Order %order canceled by Google: %reason', array('%order' => $order_id, '%reason' => $change->reason));
uc_order_comment_save($order_id, 0, $message, 'admin', 'canceled');
case 'CANCELLED':
uc_order_comment_save($order_id, 0, t('Order canceled.'), 'order', 'canceled');
uc_order_update_status($order_id, 'canceled');
break;
default:
break;
}
unset($_SESSION['google_updates']);
}
elseif ($new_fulfillment != $prev_fulfillment) {
$_SESSION['google_updates'] = TRUE;
switch ($new_fulfillment) {
case 'PROCESSING':
watchdog('google', 'Processing @order_id', array('@order_id' => $order_id));
break;
case 'DELIVERED':
uc_order_update_status($order_id, 'completed');
watchdog('google', 'Delivered @order_id', array('@order_id' => $order_id));
break;
case 'WILL_NOT_DELIVER':
watchdog('google', 'Will not deliver @order_id', array('@order_id' => $order_id));
break;
}
unset($_SESSION['google_updates']);
}
uc_google_checkout_notification_acknowledgement($change['serial-number']);
}
else {
uc_google_checkout_notification_error();
}
}
function uc_google_checkout_charge($order_id, $amount) {
$google_order_number = uc_google_checkout_get_google_number($order_id);
$output = '';
$output .= '';
$output .= "\n";
$output .= '';
$output .= '' . $amount . '';
$output .= '';
if ($response = uc_google_checkout_send_request('request', $output)) {
drupal_set_message(t('Charge request sent to Google Checkout. The charge confirmation should appear on this page momentarily.'));
}
return 'admin/store/orders/' . $order_id;
}
function uc_google_checkout_charge_order($charge) {
$order_id = uc_google_checkout_get_order($charge->{'google-order-number'});
if ($order_id) {
$amount = (string) $charge->{'latest-charge-amount'};
uc_payment_enter($order_id, 'google_checkout', $amount, 0,
'', t('Payment received by Google Checkout'));
uc_order_comment_save($order_id, 0, t('Payment of %amount received by Google Checkout.', array('%amount' => uc_currency_format($amount))), 'admin', 'chargeable');
uc_google_checkout_notification_acknowledgement($charge['serial-number']);
}
else {
uc_google_checkout_notification_error();
}
}
function uc_google_checkout_refund($order_id, $amount, $reason, $comment = '') {
$google_order_number = uc_google_checkout_get_google_number($order_id);
$output = '';
$output .= '';
$output .= "\n";
$output .= '';
$output .= '' . $amount . '';
$output .= '' . check_plain($comment) . '';
$output .= '' . check_plain($reason) . '';
$output .= '';
if ($response = uc_google_checkout_send_request('request', $output)) {
drupal_set_message(t('Refund request sent to Google Checkout. The refund confirmation should appear on this page momentarily.'));
}
return 'admin/store/orders/' . $order_id;
}
function uc_google_checkout_refund_order($refund) {
$order_id = uc_google_checkout_get_order($refund->{'google-order-number'});
if ($order_id) {
uc_payment_enter($order_id, 'google_checkout', -$refund->{'latest-refund-amount'},
0, '', t('Refund received by Google Checkout'));
uc_order_comment_save($order_id, 0, t('Refund of %amount received by Google Checkout.', array('%amount' => uc_currency_format($refund->{'latest-refund-amount'}))),
'admin', 'processing');
uc_google_checkout_notification_acknowledgement($refund['serial-number']);
}
else {
uc_google_checkout_notification_error();
}
}
function uc_google_checkout_notify_update($form, &$form_state) {
$order = uc_order_load($form_state['values']['order_id']);
if ($order !== FALSE && isset($order->google_order_number) && isset($form_state['values']['order_comment']) && drupal_strlen($form_state['values']['order_comment'])) {
$request = uc_google_checkout_buyer_message_request($order->google_order_number, $form_state['values']['order_comment']);
$response = uc_google_checkout_send_request('request', $request);
}
}
function uc_google_checkout_buyer_message_request($google_order_number, $message) {
$output = '';
$output .= "\n";
$output .= '';
$output .= '' . check_plain($message) . '';
$output .= 'true';
$output .= '';
return $output;
}
function uc_google_checkout_cancel_order($order) {
$request = '';
$request .= "\n";
$request .= '';
$request .= '' . token_replace(variable_get('uc_google_checkout_order_cancel_reason', t('Order canceled. See order comments at [uc_order:url] for more information.')), array('uc_order' => $order)) . '';
$request .= '';
if ($response = uc_google_checkout_send_request('request', $request)) {
return TRUE;
}
else {
return FALSE;
}
}
function uc_google_checkout_notification_acknowledgement($serial_number) {
drupal_set_header('200 OK');
print '';
print "\n";
print '';
exit();
}
function uc_google_checkout_notification_error($message = NULL) {
if (is_null($message)) {
$message = t('Unknown order id or malformed XML.');
}
drupal_set_header('400 Bad Request');
watchdog('google', '!message', array('!message' => $message), WATCHDOG_ERROR);
exit();
}
function uc_google_checkout_get_order($google_order_number) {
return db_query("SELECT order_id FROM {uc_gc_orders} WHERE gc_order_number = :number", array(':number' => $google_order_number))->fetchField();
}
function uc_google_checkout_get_google_number($order_id) {
return db_query("SELECT gc_order_number FROM {uc_gc_orders} WHERE order_id = :id", array(':id' => $order_id))->fetchField();
}
function uc_google_checkout_shipping_services() {
return array_merge(uc_google_checkout_fedex_services(), uc_google_checkout_ups_services(), uc_google_checkout_usps_services());
}
function uc_google_checkout_fedex_services() {
return array(
'fedex_ground' => 'Ground',
'fedex_home' => 'Home Delivery',
'fedex_express' => 'Express Saver',
'fedex_first' => 'First Overnight',
'fedex_priority' => 'Priority Overnight',
'fedex_standard' => 'Standard Overnight',
'fedex_2day' => '2Day',
);
}
function uc_google_checkout_ups_services() {
return array(
'ups_next_day' => 'Next Day Air',
'ups_next_day_am' => 'Next Day Air Early AM',
'ups_next_day_saver' => 'Next Day Air Saver',
'ups_2nd_day' => '2nd Day Air',
'ups_2nd_day_am' => '2nd Day Air AM',
'ups_3_day' => '3 Day Select',
'ups_ground' => 'Ground',
);
}
function uc_google_checkout_usps_services() {
return array(
'usps_express' => 'Express Mail',
'usps_priority' => 'Priority Mail',
'usps_parcel' => 'Parcel Post',
'usps_media' => 'Media Mail',
);
}
function uc_google_checkout_shipping_companies() {
return array(
'fedex' => 'FedEx',
'ups' => 'UPS',
'usps' => 'USPS',
);
}
/**
* Returns an array of options for the currency selection widget.
*/
function _uc_google_checkout_currency_codes() {
return drupal_map_assoc(array('AUD', 'CAD', 'EUR', 'GBP', 'HKD', 'JPY', 'USD'));
}