PageRenderTime 25ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/wp-e-commerce/merchants/library/googlecart.php

https://gitlab.com/endomorphosis/reservationtelco
PHP | 1178 lines | 794 code | 81 blank | 303 comment | 140 complexity | ee0044e75ff751833521d71fb8da6b4a MD5 | raw file
  1. <?php
  2. /*
  3. * Copyright (C) 2007 Google Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /**
  18. * Classes used to build a shopping cart and submit it to Google Checkout
  19. * @version $Id: googlecart.php 1234 2007-09-25 14:58:57Z ropu $
  20. */
  21. define('MAX_DIGITAL_DESC', 1024);
  22. /**
  23. * Creates a Google Checkout shopping cart and posts it
  24. * to the google checkout sandbox or production environment
  25. * Refer demo/cartdemo.php for different use case scenarios for this code
  26. */
  27. class GoogleCart {
  28. var $merchant_id;
  29. var $merchant_key;
  30. var $variant = false;
  31. var $currency;
  32. var $server_url;
  33. var $schema_url;
  34. var $base_url;
  35. var $checkout_url;
  36. var $checkout_diagnose_url;
  37. var $request_url;
  38. var $request_diagnose_url;
  39. var $google_platform_id = '569400549573161';
  40. var $cart_expiration = "";
  41. var $merchant_private_data = "";
  42. var $edit_cart_url = "";
  43. var $continue_shopping_url = "";
  44. var $request_buyer_phone = "";
  45. var $merchant_calculated_tax = "";
  46. var $merchant_calculations_url = "";
  47. var $accept_merchant_coupons = "";
  48. var $accept_gift_certificates = "";
  49. var $rounding_mode;
  50. var $rounding_rule;
  51. var $analytics_data;
  52. var $item_arr;
  53. var $shipping_arr;
  54. var $default_tax_rules_arr;
  55. var $alternate_tax_tables_arr;
  56. var $xml_data;
  57. var $googleAnalytics_id = false;
  58. var $thirdPartyTackingUrl = false;
  59. var $thirdPartyTackingParams = array();
  60. // For HTML API Conversion
  61. // This tags are those that can be used more than once as a sub tag
  62. // so a "-#" must be added always
  63. /**
  64. * used when using the html api
  65. * tags that can be used more than once, so they need to be numbered
  66. * ("-#" suffix)
  67. */
  68. var $multiple_tags = array(
  69. 'flat-rate-shipping' => array(),
  70. 'merchant-calculated-shipping' => array(),
  71. 'pickup' => array(),
  72. 'parameterized-url' => array(),
  73. 'url-parameter' => array(),
  74. 'item' => array(),
  75. 'us-state-area' => array('tax-area'),
  76. 'us-zip-area' => array('tax-area'),
  77. 'us-country-area' => array('tax-area'),
  78. 'postal-area' => array('tax-area'),
  79. 'alternate-tax-table' => array(),
  80. 'world-area' => array('tax-area'),
  81. 'default-tax-rule' => array(),
  82. 'alternate-tax-rule' => array(),
  83. 'gift-certificate-adjustment' => array(),
  84. 'coupon-adjustment' => array(),
  85. 'coupon-result' => array(),
  86. 'gift-certificate-result' => array(),
  87. 'method' => array(),
  88. 'anonymous-address' => array(),
  89. 'result' => array(),
  90. 'string' => array(),
  91. );
  92. var $ignore_tags = array(
  93. 'xmlns' => true,
  94. 'checkout-shopping-cart' => true,
  95. // Dont know how to translate these tag yet
  96. 'merchant-private-data' => true,
  97. 'merchant-private-item-data' => true,
  98. );
  99. /**
  100. * Has all the logic to build the cart's xml (or html) request to be
  101. * posted to google's servers.
  102. *
  103. * @param string $id the merchant id
  104. * @param string $key the merchant key
  105. * @param string $server_type the server type of the server to be used, one
  106. * of 'sandbox' or 'production'.
  107. * defaults to 'sandbox'
  108. * @param string $currency the currency of the items to be added to the cart
  109. * , as of now values can be 'USD' or 'GBP'.
  110. * defaults to 'USD'
  111. */
  112. function GoogleCart($id, $key, $server_type="sandbox", $currency="USD") {
  113. $this->merchant_id = $id;
  114. $this->merchant_key = $key;
  115. $this->currency = $currency;
  116. if(strtolower($server_type) == "sandbox") {
  117. $this->server_url = "https://sandbox.google.com/checkout/";
  118. } else {
  119. $this->server_url= "https://checkout.google.com/";
  120. }
  121. $this->schema_url = "http://checkout.google.com/schema/2";
  122. $this->base_url = $this->server_url . "api/checkout/v2/";
  123. $this->checkout_url = $this->base_url . "checkout/Merchant/" . $this->merchant_id;
  124. $this->checkoutForm_url = $this->base_url . "checkoutForm/Merchant/" . $this->merchant_id;
  125. //The item, shipping and tax table arrays are initialized
  126. $this->item_arr = array();
  127. $this->shipping_arr = array();
  128. $this->alternate_tax_tables_arr = array();
  129. }
  130. /**
  131. * Sets the cart's expiration date
  132. *
  133. * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_good-until-date <good-until-date>}
  134. *
  135. * @param string $cart_expire a string representing a date in the
  136. * iso 8601 date and time format: {@link http://www.w3.org/TR/NOTE-datetime}
  137. *
  138. * @return void
  139. */
  140. function SetCartExpiration($cart_expire) {
  141. $this->cart_expiration = $cart_expire;
  142. }
  143. /**
  144. * Sets the merchant's private data.
  145. *
  146. * Google Checkout will return this data in the
  147. * <merchant-calculation-callback> and the
  148. * <new-order-notification> for the order.
  149. *
  150. * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_merchant-private-data <merchant-private-data>}
  151. *
  152. * @param MerchantPrivateData $data an object which contains the data to be
  153. * sent as merchant-private-data
  154. *
  155. * @return void
  156. */
  157. function SetMerchantPrivateData($data) {
  158. $this->merchant_private_data = $data;
  159. }
  160. /**
  161. * Sets the url where the customer can edit his cart.
  162. *
  163. * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_edit-cart-url <edit-cart-url>}
  164. *
  165. * @param string $url the merchant's site edit cart url
  166. * @return void
  167. */
  168. function SetEditCartUrl($url) {
  169. $this->edit_cart_url= $url;
  170. }
  171. /**
  172. * Sets the continue shopping url, which allows the customer to return
  173. * to the merchant's site after confirming an order.
  174. *
  175. * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_continue-shopping-url <continue-shopping-url>}
  176. *
  177. * @param string $url the merchant's site continue shopping url
  178. * @return void
  179. */
  180. function SetContinueShoppingUrl($url) {
  181. $this->continue_shopping_url = $url;
  182. }
  183. /**
  184. * Sets whether the customer must enter a phone number to complete an order.
  185. * If set to true, the customer must enter a number, which Google Checkout
  186. * will return in the new order notification for the order.
  187. *
  188. * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_request-buyer-phone-number <request-buyer-phone-number>}
  189. *
  190. * @param bool $req true if the customer's phone number is *required*
  191. * to complete an order.
  192. * defaults to false.
  193. * @return void
  194. */
  195. function SetRequestBuyerPhone($req) {
  196. $this->request_buyer_phone = $this->_GetBooleanValue($req, "false");
  197. }
  198. /**
  199. * Sets the information about calculations that will be performed by the
  200. * merchant.
  201. *
  202. * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_merchant-calculations <merchant-calculations>}
  203. *
  204. * @param string $url the merchant calculations callback url
  205. * @param bool $tax_option true if the merchant has to do tax calculations.
  206. * defaults to false.
  207. * @param bool $coupons true if the merchant accepts discount coupons.
  208. * defaults to false.
  209. * @param bool $gift_cert true if the merchant accepts gift certificates.
  210. * defaults to false.
  211. * @return void
  212. */
  213. function SetMerchantCalculations($url, $tax_option = "false",
  214. $coupons = "false", $gift_cert = "false") {
  215. $this->merchant_calculations_url = $url;
  216. $this->merchant_calculated_tax = $this->_GetBooleanValue($tax_option, "false");
  217. $this->accept_merchant_coupons = $this->_GetBooleanValue($coupons, "false");
  218. $this->accept_gift_certificates = $this->_GetBooleanValue($gift_cert, "false");
  219. }
  220. /**
  221. * Add an item to the cart.
  222. *
  223. * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_item <item>}
  224. *
  225. * @param GoogleItem $google_item an object that represents an item
  226. * (defined in googleitem.php)
  227. *
  228. * @return void
  229. */
  230. function AddItem($google_item) {
  231. $this->item_arr[] = $google_item;
  232. }
  233. /**
  234. * Add a shipping method to the cart.
  235. *
  236. * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_shipping-methods <shipping-methods>}
  237. *
  238. * @param object $ship an object that represents a shipping method, must be
  239. * one of the methods defined in googleshipping.php
  240. *
  241. * @return void
  242. */
  243. function AddShipping($ship) {
  244. $this->shipping_arr[] = $ship;
  245. }
  246. /**
  247. * Add a default tax rule to the cart.
  248. *
  249. * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_default-tax-rule <default-tax-rule>}
  250. *
  251. * @param GoogleDefaultTaxRule $rules an object that represents a default
  252. * tax rule (defined in googletax.php)
  253. *
  254. * @return void
  255. */
  256. function AddDefaultTaxRules($rules) {
  257. $this->default_tax_table = true;
  258. $this->default_tax_rules_arr[] = $rules;
  259. }
  260. /**
  261. * Add an alternate tax table to the cart.
  262. *
  263. * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_alternate-tax-table <alternate-tax-table>}
  264. *
  265. * @param GoogleAlternateTaxTable $tax an object that represents an
  266. * alternate tax table
  267. * (defined in googletax.php)
  268. *
  269. * @return void
  270. */
  271. function AddAlternateTaxTables($tax) {
  272. $this->alternate_tax_tables_arr[] = $tax;
  273. }
  274. /**
  275. * Set the policy to be used to round monetary values.
  276. * Rounding policy explanation here:
  277. * {@link http://code.google.com/apis/checkout/developer/Google_Checkout_Rounding_Policy.html}
  278. *
  279. * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_rounding-policy <rounding-policy>}
  280. *
  281. * @param string $mode one of "UP", "DOWN", "CEILING", "HALF_DOWN"
  282. * or "HALF_EVEN", described here: {@link http://java.sun.com/j2se/1.5.0/docs/api/java/math/RoundingMode.html}
  283. * @param string $rule one of "PER_LINE", "TOTAL"
  284. *
  285. * @return void
  286. */
  287. function AddRoundingPolicy($mode, $rule) {
  288. switch ($mode) {
  289. case "UP":
  290. case "DOWN":
  291. case "CEILING":
  292. case "HALF_UP":
  293. case "HALF_DOWN":
  294. case "HALF_EVEN":
  295. $this->rounding_mode = $mode;
  296. break;
  297. default:
  298. break;
  299. }
  300. switch ($rule) {
  301. case "PER_LINE":
  302. case "TOTAL":
  303. $this->rounding_rule = $rule;
  304. break;
  305. default:
  306. break;
  307. }
  308. }
  309. /**
  310. * Set the google analytics data.
  311. *
  312. * {@link http://code.google.com/apis/checkout/developer/checkout_analytics_integration.html info on Checkout and Analytics integration}
  313. *
  314. * @param string $data the analytics data
  315. *
  316. * @return void
  317. */
  318. function SetAnalyticsData($data) {
  319. $this->analytics_data = $data;
  320. }
  321. /**
  322. * Add a google analytics tracking id.
  323. *
  324. * {@link http://code.google.com/apis/checkout/developer/checkout_analytics_integration.html info on Checkout and Analytics integration}
  325. *
  326. * @param string $GA_id the google analytics id
  327. *
  328. * @return void
  329. */
  330. function AddGoogleAnalyticsTracking($GA_id) {
  331. $this->googleAnalytics_id = $GA_id;
  332. }
  333. /**
  334. * Add third-party tracking to the cart
  335. *
  336. * Described here:
  337. * {@link http://code.google.com/apis/checkout/developer/checkout_analytics_integration.html#googleCheckoutAnalyticsIntegrationAlternate}
  338. *
  339. * @param $tracking_attr_types attributes to be tracked, one of
  340. * ('buyer-id',
  341. * 'order-id',
  342. * 'order-subtotal',
  343. * 'order-subtotal-plus-tax',
  344. * 'order-subtotal-plus-shipping',
  345. * 'order-total',
  346. * 'tax-amount',
  347. * 'shipping-amount',
  348. * 'coupon-amount',
  349. * 'coupon-amount',
  350. * 'billing-city',
  351. * 'billing-region',
  352. * 'billing-postal-code',
  353. * 'billing-country-code',
  354. * 'shipping-city',
  355. * 'shipping-region',
  356. * 'shipping-postal-code',
  357. * 'shipping-country-code')
  358. * More info http://code.google.com/apis/checkout/developer/checkout_pixel_tracking.html#googleCheckout_tag_url-parameter
  359. */
  360. function AddThirdPartyTracking($url, $tracking_param_types = array()) {
  361. $this->thirdPartyTackingUrl = $url;
  362. $this->thirdPartyTackingParams = $tracking_param_types;
  363. }
  364. /**
  365. * Builds the cart's xml to be sent to Google Checkout.
  366. *
  367. * @return string the cart's xml
  368. */
  369. function GetXML() {
  370. require_once('xml-processing/gc_xmlbuilder.php');
  371. $xml_data = new gc_XmlBuilder();
  372. $xml_data->Push('checkout-shopping-cart',
  373. array('xmlns' => $this->schema_url));
  374. $xml_data->Push('shopping-cart');
  375. //Add cart expiration if set
  376. if($this->cart_expiration != "") {
  377. $xml_data->Push('cart-expiration');
  378. $xml_data->Element('good-until-date', $this->cart_expiration);
  379. $xml_data->Pop('cart-expiration');
  380. }
  381. //Add XML data for each of the items
  382. $xml_data->Push('items');
  383. foreach($this->item_arr as $item) {
  384. $xml_data->Push('item');
  385. $xml_data->Element('item-name', $item->item_name);
  386. $xml_data->Element('item-description', $item->item_description);
  387. $xml_data->Element('unit-price', $item->unit_price,
  388. array('currency' => $this->currency));
  389. $xml_data->Element('quantity', $item->quantity);
  390. if($item->merchant_private_item_data != '') {
  391. // echo get_class($item->merchant_private_item_data);
  392. if(is_a($item->merchant_private_item_data,
  393. 'merchantprivate')) {
  394. $item->merchant_private_item_data->AddMerchantPrivateToXML($xml_data);
  395. }
  396. else {
  397. $xml_data->Element('merchant-private-item-data',
  398. $item->merchant_private_item_data);
  399. }
  400. }
  401. if($item->merchant_item_id != '')
  402. $xml_data->Element('merchant-item-id', $item->merchant_item_id);
  403. if($item->tax_table_selector != '')
  404. $xml_data->Element('tax-table-selector', $item->tax_table_selector);
  405. // Carrier calculation
  406. if($item->item_weight != '' && $item->numeric_weight !== '') {
  407. $xml_data->EmptyElement('item-weight', array( 'unit' => $item->item_weight,
  408. 'value' => $item->numeric_weight
  409. ));
  410. }
  411. // New Digital Delivery Tags
  412. if($item->digital_content) {
  413. $xml_data->push('digital-content');
  414. if(!empty($item->digital_url)) {
  415. $xml_data->element('description', substr($item->digital_description,
  416. 0, MAX_DIGITAL_DESC));
  417. $xml_data->element('url', $item->digital_url);
  418. // To avoid NULL key message in GC confirmation Page
  419. if(!empty($item->digital_key)) {
  420. $xml_data->element('key', $item->digital_key);
  421. }
  422. }
  423. else {
  424. $xml_data->element('email-delivery',
  425. $this->_GetBooleanValue($item->email_delivery, "true"));
  426. }
  427. $xml_data->pop('digital-content');
  428. }
  429. $xml_data->Pop('item');
  430. }
  431. $xml_data->Pop('items');
  432. if($this->merchant_private_data != '') {
  433. if(is_a($this->merchant_private_data, 'merchantprivate')) {
  434. $this->merchant_private_data->AddMerchantPrivateToXML($xml_data);
  435. }
  436. else {
  437. $xml_data->Element('merchant-private-data',
  438. $this->merchant_private_data);
  439. }
  440. }
  441. $xml_data->Pop('shopping-cart');
  442. $xml_data->Push('checkout-flow-support');
  443. $xml_data->Push('merchant-checkout-flow-support');
  444. $xml_data->Element('platform-id', $this->google_platform_id);
  445. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  446. if($this->edit_cart_url != '')
  447. $xml_data->Element('edit-cart-url', $this->edit_cart_url);
  448. if($this->continue_shopping_url != '')
  449. $xml_data->Element('continue-shopping-url',
  450. $this->continue_shopping_url);
  451. if(count($this->shipping_arr) > 0)
  452. $xml_data->Push('shipping-methods');
  453. //Add the shipping methods
  454. foreach($this->shipping_arr as $ship) {
  455. //Pickup shipping handled in else part
  456. if($ship->type == "flat-rate-shipping" ||
  457. $ship->type == "merchant-calculated-shipping"
  458. // If shipping-company calc support addr-filtering and shipping restrictions as a subatag of shipping-company-calculated-shipping
  459. // ||$ship->type == "shipping-company-calculated-shipping"
  460. ) {
  461. $xml_data->Push($ship->type, array('name' => $ship->name));
  462. $xml_data->Element('price', $ship->price,
  463. array('currency' => $this->currency));
  464. $shipping_restrictions = $ship->shipping_restrictions;
  465. if (isset($shipping_restrictions)) {
  466. $xml_data->Push('shipping-restrictions');
  467. if ($shipping_restrictions->allow_us_po_box === true) {
  468. $xml_data->Element('allow-us-po-box', "true");
  469. } else {
  470. $xml_data->Element('allow-us-po-box', "false");
  471. }
  472. //Check if allowed restrictions specified
  473. if($shipping_restrictions->allowed_restrictions) {
  474. $xml_data->Push('allowed-areas');
  475. if($shipping_restrictions->allowed_country_area != "")
  476. $xml_data->EmptyElement('us-country-area',
  477. array('country-area' =>
  478. $shipping_restrictions->allowed_country_area));
  479. foreach($shipping_restrictions->allowed_state_areas_arr as $current) {
  480. $xml_data->Push('us-state-area');
  481. $xml_data->Element('state', $current);
  482. $xml_data->Pop('us-state-area');
  483. }
  484. foreach($shipping_restrictions->allowed_zip_patterns_arr as $current) {
  485. $xml_data->Push('us-zip-area');
  486. $xml_data->Element('zip-pattern', $current);
  487. $xml_data->Pop('us-zip-area');
  488. }
  489. if($shipping_restrictions->allowed_world_area === true) {
  490. $xml_data->EmptyElement('world-area');
  491. }
  492. for($i=0; $i<count($shipping_restrictions->allowed_country_codes_arr); $i++) {
  493. $xml_data->Push('postal-area');
  494. $country_code = $shipping_restrictions->allowed_country_codes_arr[$i];
  495. $postal_pattern = $shipping_restrictions->allowed_postal_patterns_arr[$i];
  496. $xml_data->Element('country-code', $country_code);
  497. if ($postal_pattern != "") {
  498. $xml_data->Element('postal-code-pattern', $postal_pattern);
  499. }
  500. $xml_data->Pop('postal-area');
  501. }
  502. $xml_data->Pop('allowed-areas');
  503. }
  504. if($shipping_restrictions->excluded_restrictions) {
  505. if (!$shipping_restrictions->allowed_restrictions) {
  506. $xml_data->EmptyElement('allowed-areas');
  507. }
  508. $xml_data->Push('excluded-areas');
  509. if($shipping_restrictions->excluded_country_area != "")
  510. $xml_data->EmptyElement('us-country-area',
  511. array('country-area' =>
  512. $shipping_restrictions->excluded_country_area));
  513. foreach($shipping_restrictions->excluded_state_areas_arr as $current) {
  514. $xml_data->Push('us-state-area');
  515. $xml_data->Element('state', $current);
  516. $xml_data->Pop('us-state-area');
  517. }
  518. foreach($shipping_restrictions->excluded_zip_patterns_arr as $current) {
  519. $xml_data->Push('us-zip-area');
  520. $xml_data->Element('zip-pattern', $current);
  521. $xml_data->Pop('us-zip-area');
  522. }
  523. for($i=0; $i<count($shipping_restrictions->excluded_country_codes_arr); $i++) {
  524. $xml_data->Push('postal-area');
  525. $country_code = $shipping_restrictions->excluded_country_codes_arr[$i];
  526. $postal_pattern = $shipping_restrictions->excluded_postal_patterns_arr[$i];
  527. $xml_data->Element('country-code', $country_code);
  528. if ($postal_pattern != "") {
  529. $xml_data->Element('postal-code-pattern', $postal_pattern);
  530. }
  531. $xml_data->Pop('postal-area');
  532. }
  533. $xml_data->Pop('excluded-areas');
  534. }
  535. $xml_data->Pop('shipping-restrictions');
  536. }
  537. if ($ship->type == "merchant-calculated-shipping") {
  538. $address_filters = $ship->address_filters;
  539. if (isset($address_filters)) {
  540. $xml_data->Push('address-filters');
  541. if ($address_filters->allow_us_po_box === true) {
  542. $xml_data->Element('allow-us-po-box', "true");
  543. } else {
  544. $xml_data->Element('allow-us-po-box', "false");
  545. }
  546. //Check if allowed restrictions specified
  547. if($address_filters->allowed_restrictions) {
  548. $xml_data->Push('allowed-areas');
  549. if($address_filters->allowed_country_area != "")
  550. $xml_data->EmptyElement('us-country-area',
  551. array('country-area' =>
  552. $address_filters->allowed_country_area));
  553. foreach($address_filters->allowed_state_areas_arr as $current) {
  554. $xml_data->Push('us-state-area');
  555. $xml_data->Element('state', $current);
  556. $xml_data->Pop('us-state-area');
  557. }
  558. foreach($address_filters->allowed_zip_patterns_arr as $current) {
  559. $xml_data->Push('us-zip-area');
  560. $xml_data->Element('zip-pattern', $current);
  561. $xml_data->Pop('us-zip-area');
  562. }
  563. if($address_filters->allowed_world_area === true) {
  564. $xml_data->EmptyElement('world-area');
  565. }
  566. for($i=0; $i<count($address_filters->allowed_country_codes_arr); $i++) {
  567. $xml_data->Push('postal-area');
  568. $country_code = $address_filters->allowed_country_codes_arr[$i];
  569. $postal_pattern = $address_filters->allowed_postal_patterns_arr[$i];
  570. $xml_data->Element('country-code', $country_code);
  571. if ($postal_pattern != "") {
  572. $xml_data->Element('postal-code-pattern', $postal_pattern);
  573. }
  574. $xml_data->Pop('postal-area');
  575. }
  576. $xml_data->Pop('allowed-areas');
  577. }
  578. if($address_filters->excluded_restrictions) {
  579. if (!$address_filters->allowed_restrictions) {
  580. $xml_data->EmptyElement('allowed-areas');
  581. }
  582. $xml_data->Push('excluded-areas');
  583. if($address_filters->excluded_country_area != "")
  584. $xml_data->EmptyElement('us-country-area',
  585. array('country-area' =>
  586. $address_filters->excluded_country_area));
  587. foreach($address_filters->excluded_state_areas_arr as $current) {
  588. $xml_data->Push('us-state-area');
  589. $xml_data->Element('state', $current);
  590. $xml_data->Pop('us-state-area');
  591. }
  592. foreach($address_filters->excluded_zip_patterns_arr as $current) {
  593. $xml_data->Push('us-zip-area');
  594. $xml_data->Element('zip-pattern', $current);
  595. $xml_data->Pop('us-zip-area');
  596. }
  597. for($i=0; $i<count($address_filters->excluded_country_codes_arr); $i++) {
  598. $xml_data->Push('postal-area');
  599. $country_code = $address_filters->excluded_country_codes_arr[$i];
  600. $postal_pattern = $address_filters->excluded_postal_patterns_arr[$i];
  601. $xml_data->Element('country-code', $country_code);
  602. if ($postal_pattern != "") {
  603. $xml_data->Element('postal-code-pattern', $postal_pattern);
  604. }
  605. $xml_data->Pop('postal-area');
  606. }
  607. $xml_data->Pop('excluded-areas');
  608. }
  609. $xml_data->Pop('address-filters');
  610. }
  611. }
  612. $xml_data->Pop($ship->type);
  613. }
  614. else if ($ship->type == "carrier-calculated-shipping"){
  615. // $xml_data->Push($ship->type, array('name' => $ship->name));
  616. $xml_data->Push($ship->type);
  617. $xml_data->Push('carrier-calculated-shipping-options');
  618. $CCSoptions = $ship->CarrierCalculatedShippingOptions;
  619. foreach($CCSoptions as $CCSoption){
  620. $xml_data->Push('carrier-calculated-shipping-option');
  621. $xml_data->Element('price', $CCSoption->price,
  622. array('currency' => $this->currency));
  623. $xml_data->Element('shipping-company', $CCSoption->shipping_company);
  624. $xml_data->Element('shipping-type', $CCSoption->shipping_type);
  625. $xml_data->Element('carrier-pickup', $CCSoption->carrier_pickup);
  626. if(!empty($CCSoption->additional_fixed_charge)) {
  627. $xml_data->Element('additional-fixed-charge',
  628. $CCSoption->additional_fixed_charge,
  629. array('currency' => $this->currency));
  630. }
  631. if(!empty($CCSoption->additional_variable_charge_percent)) {
  632. $xml_data->Element('additional-variable-charge-percent',
  633. $CCSoption->additional_variable_charge_percent);
  634. }
  635. $xml_data->Pop('carrier-calculated-shipping-option');
  636. }
  637. $xml_data->Pop('carrier-calculated-shipping-options');
  638. // $ShippingPackage = $ship->ShippingPackage;
  639. $xml_data->Push('shipping-packages');
  640. $xml_data->Push('shipping-package');
  641. $xml_data->Push('ship-from', array('id' => $ship->ShippingPackage->ship_from->id));
  642. $xml_data->Element('city', $ship->ShippingPackage->ship_from->city);
  643. $xml_data->Element('region', $ship->ShippingPackage->ship_from->region);
  644. $xml_data->Element('postal-code', $ship->ShippingPackage->ship_from->postal_code);
  645. $xml_data->Element('country-code', $ship->ShippingPackage->ship_from->country_code);
  646. $xml_data->Pop('ship-from');
  647. $xml_data->EmptyElement('width', array('unit' => $ship->ShippingPackage->unit,
  648. 'value' => $ship->ShippingPackage->width
  649. ));
  650. $xml_data->EmptyElement('length', array('unit' => $ship->ShippingPackage->unit,
  651. 'value' => $ship->ShippingPackage->length
  652. ));
  653. $xml_data->EmptyElement('height', array('unit' => $ship->ShippingPackage->unit,
  654. 'value' => $ship->ShippingPackage->height
  655. ));
  656. $xml_data->Element('delivery-address-category',
  657. $ship->ShippingPackage->delivery_address_category);
  658. $xml_data->Pop('shipping-package');
  659. $xml_data->Pop('shipping-packages');
  660. $xml_data->Pop($ship->type);
  661. }
  662. else if ($ship->type == "pickup") {
  663. $xml_data->Push('pickup', array('name' => $ship->name));
  664. $xml_data->Element('price', $ship->price,
  665. array('currency' => $this->currency));
  666. $xml_data->Pop('pickup');
  667. }
  668. }
  669. if(count($this->shipping_arr) > 0)
  670. $xml_data->Pop('shipping-methods');
  671. if($this->request_buyer_phone != "")
  672. $xml_data->Element('request-buyer-phone-number',
  673. $this->request_buyer_phone);
  674. if($this->merchant_calculations_url != "") {
  675. $xml_data->Push('merchant-calculations');
  676. $xml_data->Element('merchant-calculations-url',
  677. $this->merchant_calculations_url);
  678. if($this->accept_merchant_coupons != "") {
  679. $xml_data->Element('accept-merchant-coupons',
  680. // "true");
  681. $this->accept_merchant_coupons);
  682. }
  683. if($this->accept_gift_certificates != "") {
  684. $xml_data->Element('accept-gift-certificates',
  685. $this->accept_gift_certificates);
  686. }
  687. $xml_data->Pop('merchant-calculations');
  688. }
  689. //Set Third party Tracking
  690. if($this->thirdPartyTackingUrl) {
  691. $xml_data->push('parameterized-urls');
  692. $xml_data->push('parameterized-url',
  693. array('url' => $this->thirdPartyTackingUrl));
  694. if(is_array($this->thirdPartyTackingParams)
  695. && count($this->thirdPartyTackingParams)>0) {
  696. $xml_data->push('parameters');
  697. foreach($this->thirdPartyTackingParams as $tracking_param_name =>
  698. $tracking_param_type) {
  699. $xml_data->emptyElement('url-parameter',
  700. array('name' => $tracking_param_name,
  701. 'type' => $tracking_param_type));
  702. }
  703. $xml_data->pop('parameters');
  704. }
  705. $xml_data->pop('parameterized-url');
  706. $xml_data->pop('parameterized-urls');
  707. }
  708. //Set Default and Alternate tax tables
  709. if( (count($this->alternate_tax_tables_arr) != 0)
  710. || (count($this->default_tax_rules_arr) != 0)) {
  711. if($this->merchant_calculated_tax != "") {
  712. $xml_data->Push('tax-tables',
  713. array('merchant-calculated' => $this->merchant_calculated_tax));
  714. }
  715. else {
  716. $xml_data->Push('tax-tables');
  717. }
  718. if(count($this->default_tax_rules_arr) != 0) {
  719. $xml_data->Push('default-tax-table');
  720. $xml_data->Push('tax-rules');
  721. foreach($this->default_tax_rules_arr as $curr_rule) {
  722. if($curr_rule->country_area != "") {
  723. $xml_data->Push('default-tax-rule');
  724. $xml_data->Element('shipping-taxed', $curr_rule->shipping_taxed);
  725. $xml_data->Element('rate', $curr_rule->tax_rate);
  726. $xml_data->Push('tax-area');
  727. $xml_data->EmptyElement('us-country-area',
  728. array('country-area' => $curr_rule->country_area));
  729. $xml_data->Pop('tax-area');
  730. $xml_data->Pop('default-tax-rule');
  731. }
  732. foreach($curr_rule->state_areas_arr as $current) {
  733. $xml_data->Push('default-tax-rule');
  734. $xml_data->Element('shipping-taxed', $curr_rule->shipping_taxed);
  735. $xml_data->Element('rate', $curr_rule->tax_rate);
  736. $xml_data->Push('tax-area');
  737. $xml_data->Push('us-state-area');
  738. $xml_data->Element('state', $current);
  739. $xml_data->Pop('us-state-area');
  740. $xml_data->Pop('tax-area');
  741. $xml_data->Pop('default-tax-rule');
  742. }
  743. foreach($curr_rule->zip_patterns_arr as $current) {
  744. $xml_data->Push('default-tax-rule');
  745. $xml_data->Element('shipping-taxed', $curr_rule->shipping_taxed);
  746. $xml_data->Element('rate', $curr_rule->tax_rate);
  747. $xml_data->Push('tax-area');
  748. $xml_data->Push('us-zip-area');
  749. $xml_data->Element('zip-pattern', $current);
  750. $xml_data->Pop('us-zip-area');
  751. $xml_data->Pop('tax-area');
  752. $xml_data->Pop('default-tax-rule');
  753. }
  754. for($i=0; $i<count($curr_rule->country_codes_arr); $i++) {
  755. $xml_data->Push('default-tax-rule');
  756. $xml_data->Element('shipping-taxed', $curr_rule->shipping_taxed);
  757. $xml_data->Element('rate', $curr_rule->tax_rate);
  758. $xml_data->Push('tax-area');
  759. $xml_data->Push('postal-area');
  760. $country_code = $curr_rule->country_codes_arr[$i];
  761. $postal_pattern = $curr_rule->postal_patterns_arr[$i];
  762. $xml_data->Element('country-code', $country_code);
  763. if ($postal_pattern != "") {
  764. $xml_data->Element('postal-code-pattern', $postal_pattern);
  765. }
  766. $xml_data->Pop('postal-area');
  767. $xml_data->Pop('tax-area');
  768. $xml_data->Pop('default-tax-rule');
  769. }
  770. if ($curr_rule->world_area === true) {
  771. $xml_data->Push('default-tax-rule');
  772. $xml_data->Element('shipping-taxed', $curr_rule->shipping_taxed);
  773. $xml_data->Element('rate', $curr_rule->tax_rate);
  774. $xml_data->Push('tax-area');
  775. $xml_data->EmptyElement('world-area');
  776. $xml_data->Pop('tax-area');
  777. $xml_data->Pop('default-tax-rule');
  778. }
  779. }
  780. $xml_data->Pop('tax-rules');
  781. $xml_data->Pop('default-tax-table');
  782. }
  783. if(count($this->alternate_tax_tables_arr) != 0) {
  784. $xml_data->Push('alternate-tax-tables');
  785. foreach($this->alternate_tax_tables_arr as $curr_table) {
  786. $xml_data->Push('alternate-tax-table',
  787. array('standalone' => $curr_table->standalone,
  788. 'name' => $curr_table->name));
  789. $xml_data->Push('alternate-tax-rules');
  790. foreach($curr_table->tax_rules_arr as $curr_rule) {
  791. if($curr_rule->country_area != "") {
  792. $xml_data->Push('alternate-tax-rule');
  793. $xml_data->Element('rate', $curr_rule->tax_rate);
  794. $xml_data->Push('tax-area');
  795. $xml_data->EmptyElement('us-country-area',
  796. array('country-area' => $curr_rule->country_area));
  797. $xml_data->Pop('tax-area');
  798. $xml_data->Pop('alternate-tax-rule');
  799. }
  800. foreach($curr_rule->state_areas_arr as $current) {
  801. $xml_data->Push('alternate-tax-rule');
  802. $xml_data->Element('rate', $curr_rule->tax_rate);
  803. $xml_data->Push('tax-area');
  804. $xml_data->Push('us-state-area');
  805. $xml_data->Element('state', $current);
  806. $xml_data->Pop('us-state-area');
  807. $xml_data->Pop('tax-area');
  808. $xml_data->Pop('alternate-tax-rule');
  809. }
  810. foreach($curr_rule->zip_patterns_arr as $current) {
  811. $xml_data->Push('alternate-tax-rule');
  812. $xml_data->Element('rate', $curr_rule->tax_rate);
  813. $xml_data->Push('tax-area');
  814. $xml_data->Push('us-zip-area');
  815. $xml_data->Element('zip-pattern', $current);
  816. $xml_data->Pop('us-zip-area');
  817. $xml_data->Pop('tax-area');
  818. $xml_data->Pop('alternate-tax-rule');
  819. }
  820. for($i=0; $i<count($curr_rule->country_codes_arr); $i++) {
  821. $xml_data->Push('alternate-tax-rule');
  822. $xml_data->Element('rate', $curr_rule->tax_rate);
  823. $xml_data->Push('tax-area');
  824. $xml_data->Push('postal-area');
  825. $country_code = $curr_rule->country_codes_arr[$i];
  826. $postal_pattern = $curr_rule->postal_patterns_arr[$i];
  827. $xml_data->Element('country-code', $country_code);
  828. if ($postal_pattern != "") {
  829. $xml_data->Element('postal-code-pattern', $postal_pattern);
  830. }
  831. $xml_data->Pop('postal-area');
  832. $xml_data->Pop('tax-area');
  833. $xml_data->Pop('alternate-tax-rule');
  834. }
  835. if ($curr_rule->world_area === true) {
  836. $xml_data->Push('alternate-tax-rule');
  837. $xml_data->Element('rate', $curr_rule->tax_rate);
  838. $xml_data->Push('tax-area');
  839. $xml_data->EmptyElement('world-area');
  840. $xml_data->Pop('tax-area');
  841. $xml_data->Pop('alternate-tax-rule');
  842. }
  843. }
  844. $xml_data->Pop('alternate-tax-rules');
  845. $xml_data->Pop('alternate-tax-table');
  846. }
  847. $xml_data->Pop('alternate-tax-tables');
  848. }
  849. $xml_data->Pop('tax-tables');
  850. }
  851. if (($this->rounding_mode != "") && ($this->rounding_rule != "")) {
  852. $xml_data->Push('rounding-policy');
  853. $xml_data->Element('mode', $this->rounding_mode);
  854. $xml_data->Element('rule', $this->rounding_rule);
  855. $xml_data->Pop('rounding-policy');
  856. }
  857. if($this->analytics_data != ''){
  858. $xml_data->Element('analytics-data', $this->analytics_data);
  859. }
  860. $xml_data->Pop('merchant-checkout-flow-support');
  861. $xml_data->Pop('checkout-flow-support');
  862. $xml_data->Pop('checkout-shopping-cart');
  863. //mail("hanzhimeng@gmail.com","",print_r($xml_data->GetXML(),1));
  864. return $xml_data->GetXML();
  865. }
  866. /**
  867. * Set the Google Checkout button's variant.
  868. * {@link http://code.google.com/apis/checkout/developer/index.html#google_checkout_buttons}
  869. *
  870. * @param bool $variant true for an enabled button, false for a
  871. * disabled one
  872. *
  873. * @return void
  874. */
  875. function SetButtonVariant($variant) {
  876. switch ($variant) {
  877. case false:
  878. $this->variant = "disabled";
  879. break;
  880. case true:
  881. default:
  882. $this->variant = "text";
  883. break;
  884. }
  885. }
  886. /**
  887. * Submit a server-to-server request.
  888. * Creates a GoogleRequest object (defined in googlerequest.php) and sends
  889. * it to the Google Checkout server.
  890. *
  891. * more info:
  892. * {@link http://code.google.com/apis/checkout/developer/index.html#alternate_technique}
  893. *
  894. * @return array with the returned http status code (200 if OK) in index 0
  895. * and the redirect url returned by the server in index 1
  896. */
  897. function CheckoutServer2Server($proxy=array(), $certPath='') {
  898. ini_set('include_path', ini_get('include_path').PATH_SEPARATOR.'.');
  899. require_once('library/googlerequest.php');
  900. $GRequest = new GoogleRequest($this->merchant_id,
  901. $this->merchant_key,
  902. $this->server_url=="https://checkout.google.com/"?
  903. "Production":"sandbox",
  904. $this->currency);
  905. $GRequest->SetProxy($proxy);
  906. $GRequest->SetCertificatePath($certPath);
  907. return $GRequest->SendServer2ServerCart($this->GetXML());
  908. }
  909. /**
  910. * Get the Google Checkout button's html to be used in a server-to-server
  911. * request.
  912. *
  913. * {@link http://code.google.com/apis/checkout/developer/index.html#google_checkout_buttons}
  914. *
  915. * @param string $url the merchant's site url where the form will be posted
  916. * to
  917. * @param string $size the size of the button, one of 'large', 'medium' or
  918. * 'small'.
  919. * defaults to 'large'
  920. * @param bool $variant true for an enabled button, false for a
  921. * disabled one. defaults to true. will be ignored if
  922. * SetButtonVariant() was used before.
  923. * @param string $loc the locale of the button's text, the only valid value
  924. * is 'en_US' (used as default)
  925. * @param bool $showtext whether to show Google Checkout text or not,
  926. * defaults to true.
  927. * @param string $style the background style of the button, one of 'white'
  928. * or 'trans'. defaults to "trans"
  929. *
  930. * @return string the button's html
  931. */
  932. function CheckoutServer2ServerButton($url, $size="large", $variant=true,
  933. $loc="en_US",$showtext=true, $style="trans") {
  934. switch (strtolower($size)) {
  935. case "medium":
  936. $width = "168";
  937. $height = "44";
  938. break;
  939. case "small":
  940. $width = "160";
  941. $height = "43";
  942. break;
  943. case "large":
  944. default:
  945. $width = "180";
  946. $height = "46";
  947. break;
  948. }
  949. if($this->variant == false) {
  950. switch ($variant) {
  951. case false:
  952. $this->variant = "disabled";
  953. break;
  954. case true:
  955. default:
  956. $this->variant = "text";
  957. break;
  958. }
  959. }
  960. $data = "<div style=\"width: ".$width."px\">";
  961. if ($this->variant == "text") {
  962. $data .= "<div align=center><form method=\"POST\" action=\"".
  963. $url . "\"" . ($this->googleAnalytics_id?
  964. " onsubmit=\"setUrchinInputCode();\"":"") . ">
  965. <input type=\"image\" name=\"Checkout\" alt=\"Checkout\"
  966. src=\"". $this->server_url."buttons/checkout.gif?merchant_id=" .
  967. $this->merchant_id."&w=".$width. "&h=".$height."&style=".
  968. $style."&variant=".$this->variant."&loc=".$loc."\"
  969. height=\"".$height."\" width=\"".$width. "\" />";
  970. if($this->googleAnalytics_id) {
  971. $data .= "<input type=\"hidden\" name=\"analyticsdata\" value=\"\">";
  972. }
  973. $data .= "</form></div>";
  974. if($this->googleAnalytics_id) {
  975. $data .= "<!-- Start Google analytics -->
  976. <script src=\"https://ssl.google-analytics.com/urchin.js\" type=\"".
  977. "text/javascript\">
  978. </script>
  979. <script type=\"text/javascript\">
  980. _uacct = \"" . $this->googleAnalytics_id . "\";
  981. urchinTracker();
  982. </script>
  983. <script src=\"https://checkout.google.com/files/digital/urchin_po" .
  984. "st.js\" type=\"text/javascript\"></script>
  985. <!-- End Google analytics -->";
  986. } } else {
  987. $data .= "<div><img alt=\"Checkout\" src=\"" .
  988. "". $this->server_url."buttons/checkout.gif?merchant_id=" .
  989. "".$this->merchant_id."&w=".$width. "&h=".$height."&style=".$style.
  990. "&variant=".$this->variant."&loc=".$loc."\" height=\"".$height."\"".
  991. " width=\"".$width. "\" /></div>";
  992. }
  993. $data .= "</div>";
  994. return $data;
  995. }
  996. /**
  997. * Get the Google Checkout button's html.
  998. *
  999. * {@link http://code.google.com/apis/checkout/developer/index.html#google_checkout_buttons}
  1000. *
  1001. * @param string $size the size of the button, one of 'large', 'medium' or
  1002. * 'small'.
  1003. * defaults to 'large'
  1004. * @param bool $variant true for an enabled button, false for a
  1005. * disabled one. defaults to true. will be ignored if
  1006. * SetButtonVariant() was used before.
  1007. * @param string $loc the locale of the button's text, the only valid value
  1008. * is 'en_US' (used as default)
  1009. * @param bool $showtext whether to show Google Checkout text or not,
  1010. * defaults to true.
  1011. * @param string $style the background style of the button, one of 'white'
  1012. * or 'trans'. defaults to "trans"
  1013. *
  1014. * @return string the button's html
  1015. */
  1016. function CheckoutButtonCode($size="large", $variant=true, $loc="en_US",
  1017. $showtext=false, $style="trans") {
  1018. switch (strtolower($size)) {
  1019. case "medium":
  1020. $width = "168";
  1021. $height = "44";
  1022. break;
  1023. case "small":
  1024. $width = "160";
  1025. $height = "43";
  1026. break;
  1027. case "large":
  1028. default:
  1029. $width = "180";
  1030. $height = "46";
  1031. break;
  1032. }
  1033. if($this->variant == false) {
  1034. switch ($variant) {
  1035. case false:
  1036. $this->variant = "disabled";
  1037. break;
  1038. case true:
  1039. default:
  1040. $this->variant = "text";
  1041. break;
  1042. }
  1043. }
  1044. $data = "<div style=\"width: ".$width."px\">";
  1045. if ($this->variant == "text") {
  1046. $data .= "<div align=center><form method=\"POST\" action=\"".
  1047. $this->checkout_url . "\"" . ($this->googleAnalytics_id?
  1048. " onsubmit=\"setUrchinInputCode();\"":"") . ">
  1049. <input type=\"hidden\" name=\"cart\" value=\"".
  1050. base64_encode($this->GetXML()) ."\">
  1051. <input type=\"hidden\" name=\"signature\" value=\"".
  1052. base64_encode($this->CalcHmacSha1($this->GetXML())). "\">
  1053. <input type=\"image\" name=\"Checkout\" alt=\"Checkout\"
  1054. src=\"". $this->server_url."buttons/checkout.gif?merchant_id=" .
  1055. $this->merchant_id."&w=".$width. "&h=".$height."&style=".
  1056. $style."&variant=".$this->variant."&loc=".$loc."\"
  1057. height=\"".$height."\" width=\"".$width. "\" />";
  1058. if($this->googleAnalytics_id) {
  1059. $data .= "<input type=\"hidden\" name=\"analyticsdata\" value=\"\">";
  1060. }
  1061. $data .= "</form></div>";
  1062. if($this->googleAnalytics_id) {
  1063. $data .= "<!-- Start Google analytics -->
  1064. <script src=\"https://ssl.google-analytics.com/urchin.js\" type=\"".
  1065. "text/javascript\">
  1066. </script>
  1067. <script type=\"text/javascript\">
  1068. _uacct = \"" . $this->googleAnalytics_id . "\";
  1069. urchinTracker();
  1070. </script>
  1071. <script src=\"https://checkout.google.com/files/digital/urchin_po" .
  1072. "st.js\" type=\"text/javascript\"></script>
  1073. <!-- End Google analytics -->";
  1074. }
  1075. } else {
  1076. $data .= "<div><img alt=\"Checkout\" src=\"" .
  1077. "". $this->server_url."buttons/checkout.gif?merchant_id=" .
  1078. "".$this->merchant_id."&w=".$width. "&h=".$height."&style=".$style.
  1079. "&variant=".$this->variant."&loc=".$loc."\" height=\"".$height."\"".
  1080. " width=\"".$width. "\" /></div>";
  1081. }
  1082. if($showtext) {
  1083. $data .="<div align=\"center\"><a href=\"javascript:void(window.ope".
  1084. "n('http://checkout.google.com/seller/what_is_google_checkout.html'" .
  1085. ",'whatischeckout','scrollbars=0,resizable=1,directories=0,height=2" .
  1086. "50,width=400'));\" onmouseover=\"return window.status = 'What is G" .
  1087. "oogle Checkout?'\" onmouseout=\"return window.status = ''\"><font " .
  1088. "size=\"-2\">What is Google Checkout?</font></a></div>";
  1089. }
  1090. $data .= "</div>";
  1091. return $data;
  1092. }
  1093. //Code for generating Checkout button
  1094. //@param $variant will be ignored if SetButtonVariant() was used before
  1095. function CheckoutButtonNowCode($size="large", $variant=true, $loc="en_US",
  1096. $showtext=true, $style="trans") {
  1097. switch (strt