urls['schema'] = 'http://checkout.google.com/schema/2'; $this->urls['checkout'] = array( 'live' => 'https://%s:%s@checkout.google.com/api/checkout/v2/merchantCheckout/Merchant/%s', 'test' => 'https://%s:%s@sandbox.google.com/checkout/api/checkout/v2/merchantCheckout/Merchant/%s' ); $this->urls['order'] = array( 'live' => 'https://%s:%s@checkout.google.com/api/checkout/v2/request/Merchant/%s', 'test' => 'https://%s:%s@sandbox.google.com/checkout/api/checkout/v2/request/Merchant/%s' ); $this->urls['button'] = array( 'live' => 'http://checkout.google.com/buttons/checkout.gif', 'test' => 'http://sandbox.google.com/checkout/buttons/checkout.gif' ); $this->settings = $Shopp->Settings->get('GoogleCheckout'); $this->settings['merchant_email'] = $Shopp->Settings->get('merchant_email'); $this->settings['location'] = "en_US"; $base = $Shopp->Settings->get('base_operations'); if ($base['country'] == "GB") $this->settings['location'] = "en_UK"; $this->settings['base_operations'] = $Shopp->Settings->get('base_operations'); $this->settings['currency'] = $this->settings['base_operations']['currency']['code']; if (empty($this->settings['currency'])) $this->settings['currency'] = "USD"; $this->settings['taxes'] = $Shopp->Settings->get('taxrates'); add_action('shopp_save_payment_settings',array(&$this,'saveSettings')); return true; } function actions () { } function checkout () { global $Shopp; if ($Shopp->Cart->data->Totals->total == 0) shopp_redirect($Shopp->link('checkout')); $this->transaction = $this->buildCheckoutRequest($Shopp->Cart); $Response = $this->send($this->urls['checkout']); if (!empty($Response)) { if ($Response->getElement('error')) return $this->error(); $redirect = false; $redirect = $Response->getElementContent('redirect-url'); if ($redirect) { // Empty cart on successful sending the order to Google $Shopp->Cart->unload(); session_destroy(); // Start new cart session, just in case they come back for more $Shopp->Cart = new Cart(); session_start(); shopp_redirect($redirect); } } return false; } function process () { if ($this->authentication()) { // Read incoming request data $data = trim(file_get_contents('php://input')); // Handle notifications $XML = new XMLdata($data); $type = key($XML->data); $serial = $XML->getElementAttr($type,'serial-number'); switch($type) { case "new-order-notification": $this->order($XML); break; case "risk-information-notification": $this->risk($XML); break; case "order-state-change-notification": $this->state($XML); break; case "charge-amount-notification": // Not implemented case "refund-amount-notification": // Not implemented case "chargeback-amount-notification": // Not implemented case "authorization-amount-notification": // Not implemented break; } // Send acknowledgement $this->acknowledge($serial); } exit(); } /** * authcode() * Build a hash code for the merchant id and merchant key */ function authcode ($id,$key) { return sha1($id.$key); } /** * authentication() * Authenticate an incoming request */ function authentication () { if (isset($_GET['merc'])) $merc = $_GET['merc']; if (!empty($this->settings['id']) && !empty($this->settings['key']) && $_GET['merc'] == $this->authcode($this->settings['id'],$this->settings['key'])); return true; header('HTTP/1.0 401 Unauthorized'); die("

401 Unauthorized Access

"); exit(); } /** * acknowledge() * Sends an acknowledgement message back to Google to confirm the notification * was received and processed */ function acknowledge ($serial) { header('HTTP/1.0 200 OK'); $_ = array(''."\n"); $_[] .= ''; echo join("\n",$_); } function buildCheckoutRequest ($Cart) { $_ = array(''."\n"); $_[] = ''; // Build the cart $_[] = ''; $_[] = ''; foreach($Cart->contents as $i => $Item) { $_[] = ''; $_[] = ''.htmlspecialchars($Item->name).htmlspecialchars((!empty($Item->optionlabel))?' ('.$Item->optionlabel.')':'').''; $_[] = ''.htmlspecialchars($Item->description).''; $_[] = ''.$Item->unitprice.''; $_[] = ''.$Item->quantity.''; if (!empty($Item->sku)) $_[] = ''.$Item->sku.''; $_[] = ''; $_[] = ''.$Item->product.''; $_[] = ''.$Item->price.''; if (is_array($Item->data) && count($Item->data) > 0) { $_[] = ''; foreach ($Item->data AS $name => $data) { $_[] = ''.attribute_escape($data).''; } $_[] = ''; } $_[] = ''; $_[] = ''; } // Include any discounts if ($Cart->data->Totals->discount > 0) { foreach($Cart->data->PromosApplied as $promo) $discounts[] = $promo->name; $_[] = ''; $_[] = 'Discounts'; $_[] = ''.join(", ",$discounts).''; $_[] = ''.number_format($Cart->data->Totals->discount*-1,2).''; $_[] = '1'; $_[] = ''; } $_[] = ''; // Include notification that the order originated from Shopp $_[] = ''; $_[] = ''.SHOPP_GATEWAY_USERAGENT.''; $_[] = ''.$Cart->ip.''; if (is_array($Cart->data->Order->data) && count($Cart->data->Order->data) > 0) { $_[] = ''; foreach ($Cart->data->Order->data AS $name => $data) { $_[] = ''.attribute_escape($data).''; } $_[] = ''; } $_[] = ''; $_[] = ''; // Build the flow support request $_[] = ''; $_[] = ''; // Shipping Methods if ($Cart->data->Shipping && !empty($Cart->data->ShipCosts)) { $_[] = ''; foreach ($Cart->data->ShipCosts as $i => $shipping) { $label = __('Shipping Option','Shopp').' '.($i+1); if (!empty($shipping['name'])) $label = $shipping['name']; $_[] = ''; $_[] = ''.number_format($shipping['cost'],2).''; $_[] = ''; } $_[] = ''; } if (is_array($this->settings['taxes'])) { $_[] = ''; $_[] = ''; $_[] = ''; foreach ($this->settings['taxes'] as $tax) { $_[] = ''; $_[] = 'false'; $_[] = ''.number_format($tax['rate']/100,4).''; $_[] = ''; if ($tax['country'] == "US" && isset($tax['zone'])) { $_[] = ''; $_[] = ''.$tax['zone'].''; $_[] = ''; } elseif ($tax['country'] == "*") { $_[] = ''; } else { $_[] = ''; $_[] = ''.$tax['country'].''; $_[] = ''; } $_[] = ''; $_[] = ''; } $_[] = ''; $_[] = ''; $_[] = ''; } $_[] = ''; $_[] = ''; $_[] = ''; // echo "
"; print_r($_); echo "
"; return join("\n",$_); } /** * order() * Handles new order notifications from Google */ function order ($XML) { global $Shopp; $db = DB::get(); // Check if this is a Shopp order or not $origin = $XML->getElementContent('shopping-cart-agent'); if (empty($origin) || substr($origin,0,strpos("/",SHOPP_GATEWAY_USERAGENT)) == SHOPP_GATEWAY_USERAGENT) return true; $buyer = $XML->getElement('buyer-billing-address'); $buyer = $buyer['CHILDREN']; $Customer = new Customer(); $name = $XML->getElement('structured-name'); $Customer->firstname = $buyer['structured-name']['CHILDREN']['first-name']['CONTENT']; $Customer->lastname = $buyer['structured-name']['CHILDREN']['last-name']['CONTENT']; if (empty($name)) { $name = $buyer['contact-name']['CONTENT']; $names = explode(" ",$name); $Customer->firstname = $names[0]; $Customer->lastname = $names[count($names)-1]; } $Customer->email = $buyer['email']['CONTENT']; $Customer->phone = $buyer['phone']['CONTENT']; $Customer->save(); $Billing = new Billing(); $Billing->customer = $Customer->id; $Billing->address = $buyer['address1']['CONTENT']; $Billing->xaddress = $buyer['address2']['CONTENT']; $Billing->city = $buyer['city']['CONTENT']; $Billing->state = $buyer['region']['CONTENT']; $Billing->country = $buyer['country-code']['CONTENT']; $Billing->postcode = $buyer['postal-code']['CONTENT']; $Billing->save(); $shipto = $XML->getElement('buyer-shipping-address'); $shipto = $shipto['CHILDREN']; $Shipping = new Shipping(); $Shipping->customer = $Customer->id; $Shipping->address = $shipto['address1']['CONTENT']; $Shipping->xaddress = $shipto['address2']['CONTENT']; $Shipping->city = $shipto['city']['CONTENT']; $Shipping->state = $shipto['region']['CONTENT']; $Shipping->country = $shipto['country-code']['CONTENT']; $Shipping->postcode = $shipto['postal-code']['CONTENT']; $Shipping->save(); $Purchase = new Purchase(); $Purchase->customer = $Customer->id; $Purchase->billing = $Billing->id; $Purchase->shipping = $Shipping->id; $Purchase->copydata($Customer); $Purchase->copydata($Billing); $Purchase->copydata($Shipping,'ship'); $Purchase->freight = $XML->getElementContent('shipping-cost'); $Purchase->tax = $XML->getElementContent('total-tax'); $Purchase->total = $XML->getElementContent('order-total'); $Purchase->subtotal = $Purchase->total-$Purchase->frieght-$Purchase->tax; $Purchase->gateway = "Google Checkout"; $Purchase->transactionid = $XML->getElementContent('google-order-number'); $Purchase->transtatus = $XML->getElementContent('financial-order-state'); $Purchase->ip = $XML->getElementContent('customer-ip'); $orderdata = $XML->getElement('shopp-order-data'); $data = array(); if (is_array($orderdata) && count($orderdata) > 0) foreach ($orderdata as $input) $data[$input['ATTRS']['name']] = $input['CONTENT']; $Purchase->data = $data; $Purchase->save(); $items = $XML->getElement('item'); if (key($items) === "CHILDREN") $items = array($items); foreach ($items as $item) { $xml = $item['CHILDREN']; $itemdata = $xml['merchant-private-item-data']['CHILDREN']; $inputdata = $itemdata['shopp-item-data-list']['CHILDREN']['shopp-item-data']; $data = array(); if (is_array($inputdata) && count($inputdata) > 0) foreach ($inputdata as $input) $data[$input['ATTRS']['name']] = $input['CONTENT']; $Product = new Product($itemdata['shopp-product-id']['CONTENT']); $Item = new Item($Product,$itemdata['shopp-price-id']['CONTENT'],false,$data); $Item->quantity($xml['quantity']['CONTENT']); $Purchased = new Purchased(); $Purchased->copydata($Item); $Purchased->purchase = $Purchase->id; if (!empty($Purchased->download)) $Purchased->keygen(); $Purchased->save(); if ($Item->inventory) $Item->unstock(); } } function risk ($XML) { $id = $XML->getElementContent('google-order-number'); $Purchase = new Purchase($id,'transactionid'); $Purchase->ip = $XML->getElementContent('ip-address'); $Purchase->card = $XML->getElementContent('partial-cc-number'); $Purchase->save(); } function state ($XML) { $id = $XML->getElementContent('google-order-number'); $state = $XML->getElementContent('new-financial-order-state'); $Purchase = new Purchase($id,'transactionid'); $Purchase->transtatus = $state; $Purchase->save(); if (strtoupper($state) == "CHARGEABLE" && $this->settings['autocharge'] == "on") { $_ = array(''."\n"); $_[] = ''; $_[] = ''.$Purchase->total.''; $_[] = ''; $this->transaction = join("\n",$_); $Reponse = $this->send($this->urls['order']); exit(); } } function send ($url) { $connection = curl_init(); $type = "live"; if ($this->settings['testmode'] == "on") $type = "test"; $url = sprintf($url[$type],$this->settings['id'],$this->settings['key'],$this->settings['id']); curl_setopt($connection, CURLOPT_URL,$url); curl_setopt($connection, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($connection, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($connection, CURLOPT_NOPROGRESS, 1); curl_setopt($connection, CURLOPT_VERBOSE, 1); curl_setopt($connection, CURLOPT_FOLLOWLOCATION,0); curl_setopt($connection, CURLOPT_POST, 1); curl_setopt($connection, CURLOPT_POSTFIELDS, $this->transaction); curl_setopt($connection, CURLOPT_TIMEOUT, 60); curl_setopt($connection, CURLOPT_USERAGENT, SHOPP_GATEWAY_USERAGENT); curl_setopt($connection, CURLOPT_REFERER, "https://".$_SERVER['SERVER_NAME']); curl_setopt($connection, CURLOPT_RETURNTRANSFER, 1); $buffer = curl_exec($connection); if ($error = curl_error($connection)) new ShoppError($error,'google_checkout_connection',SHOPP_COMM_ERR); curl_close($connection); $this->Response = new XMLdata($buffer); return $this->Response; } function error () { $message = $this->Response->getElementContent('error-message'); if (!empty($message)) return new ShoppError($message,'google_checkout_error',SHOPP_TRXN_ERR); } function tag ($property,$options=array()) { global $Shopp; switch ($property) { case "button": $type = "live"; if ($this->settings['testmode'] == "on") $type = "test"; $buttonuri = $this->urls['button'][$type]; $buttonuri .= '?merchant_id='.$this->settings['id']; $buttonuri .= '&'.$this->settings['button']; $buttonuri .= '&style='.$this->settings['buttonstyle']; $buttonuri .= '&variant=text'; $buttonuri .= '&loc='.$this->settings['location']; if (SHOPP_PERMALINKS) $url = $Shopp->link('checkout')."?shopp_xco=GoogleCheckout/GoogleCheckout"; else $url = add_query_arg('shopp_xco','GoogleCheckout/GoogleCheckout',$Shopp->link('checkout')); return '

Checkout with Google Checkout

'; } } function settings () { global $Shopp; $buttons = array("w=160&h=43"=>"Small (160x43)","w=168&h=44"=>"Medium (168x44)","w=180&h=46"=>"Large (180x46)"); $styles = array("white"=>"On White Background","trans"=>"With Transparent Background"); ?> settings['enabled'] == "on")?' checked="checked"':''; ?>/>


Enter your Google Checkout merchant ID.


Enter your Google Checkout merchant key.

settings['apiurl'])): ?>


Copy this URL to your Google Checkout integration settings API callback URL.


Select the preferred size and style of the Google Checkout button.

xcosettings('#googlecheckout-enabled','#googlecheckout-settings'); 'GoogleCheckout', 'merc' => $GoogleCheckout->authcode( $_POST['settings']['GoogleCheckout']['id'], $_POST['settings']['GoogleCheckout']['key']) ),$Shopp->link('catalog',true)); $_POST['settings']['GoogleCheckout']['apiurl'] = $url; } } } // end GoogleCheckout class ?>