Lib_Google_Checkout - Version 1.1.1

Version Notes

1.1.1

Download this release

Release Info

Developer Magento Core Team
Extension Lib_Google_Checkout
Version 1.1.1
Comparing to
See all releases


Version 1.1.1

lib/googlecheckout/googlecart.php ADDED
@@ -0,0 +1,1613 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ /**
19
+ * Classes used to build a shopping cart and submit it to Google Checkout
20
+ * @version $Id: googlecart.php 1234 2007-09-25 14:58:57Z ropu $
21
+ */
22
+
23
+ define('MAX_DIGITAL_DESC', 1024);
24
+
25
+ /**
26
+ * Creates a Google Checkout shopping cart and posts it
27
+ * to the google checkout sandbox or production environment
28
+ * Refer demo/cartdemo.php for different use case scenarios for this code
29
+ */
30
+ class GoogleCart {
31
+ var $merchant_id;
32
+ var $merchant_key;
33
+ var $variant = false;
34
+ var $currency;
35
+ var $server_url;
36
+ var $schema_url;
37
+ var $base_url;
38
+ var $checkout_url;
39
+ var $checkout_diagnose_url;
40
+ var $request_url;
41
+ var $request_diagnose_url;
42
+
43
+ var $cart_expiration = "";
44
+ var $merchant_private_data = "";
45
+ var $edit_cart_url = "";
46
+ var $continue_shopping_url = "";
47
+ var $request_buyer_phone = "";
48
+ var $merchant_calculated_tax = "";
49
+ var $merchant_calculations_url = "";
50
+ var $accept_merchant_coupons = "";
51
+ var $accept_gift_certificates = "";
52
+ var $rounding_mode;
53
+ var $rounding_rule;
54
+ var $analytics_data;
55
+
56
+ var $item_arr;
57
+ var $shipping_arr;
58
+ var $default_tax_rules_arr;
59
+ var $alternate_tax_tables_arr;
60
+ var $xml_data;
61
+
62
+ var $googleAnalytics_id = false;
63
+ var $thirdPartyTackingUrl = false;
64
+ var $thirdPartyTackingParams = array();
65
+
66
+ // For HTML API Conversion
67
+
68
+ // This tags are those that can be used more than once as a sub tag
69
+ // so a "-#" must be added always
70
+ /**
71
+ * used when using the html api
72
+ * tags that can be used more than once, so they need to be numbered
73
+ * ("-#" suffix)
74
+ */
75
+ var $multiple_tags = array(
76
+ 'flat-rate-shipping' => array(),
77
+ 'merchant-calculated-shipping' => array(),
78
+ 'pickup' => array(),
79
+ 'parameterized-url' => array(),
80
+ 'url-parameter' => array(),
81
+ 'item' => array(),
82
+ 'us-state-area' => array('tax-area'),
83
+ 'us-zip-area' => array('tax-area'),
84
+ 'us-country-area' => array('tax-area'),
85
+ 'postal-area' => array('tax-area'),
86
+ 'alternate-tax-table' => array(),
87
+ 'world-area' => array('tax-area'),
88
+ 'default-tax-rule' => array(),
89
+ 'alternate-tax-rule' => array(),
90
+ 'gift-certificate-adjustment' => array(),
91
+ 'coupon-adjustment' => array(),
92
+ 'coupon-result' => array(),
93
+ 'gift-certificate-result' => array(),
94
+ 'method' => array(),
95
+ 'anonymous-address' => array(),
96
+ 'result' => array(),
97
+ 'string' => array(),
98
+ );
99
+
100
+ var $ignore_tags = array(
101
+ 'xmlns' => true,
102
+ 'checkout-shopping-cart' => true,
103
+ // Dont know how to translate these tag yet
104
+ 'merchant-private-data' => true,
105
+ 'merchant-private-item-data' => true,
106
+ );
107
+
108
+
109
+
110
+ /**
111
+ * Has all the logic to build the cart's xml (or html) request to be
112
+ * posted to google's servers.
113
+ *
114
+ * @param string $id the merchant id
115
+ * @param string $key the merchant key
116
+ * @param string $server_type the server type of the server to be used, one
117
+ * of 'sandbox' or 'production'.
118
+ * defaults to 'sandbox'
119
+ * @param string $currency the currency of the items to be added to the cart
120
+ * , as of now values can be 'USD' or 'GBP'.
121
+ * defaults to 'USD'
122
+ */
123
+ function GoogleCart($id, $key, $server_type="sandbox", $currency="USD") {
124
+ $this->merchant_id = $id;
125
+ $this->merchant_key = $key;
126
+ $this->currency = $currency;
127
+
128
+ if(strtolower($server_type) == "sandbox") {
129
+ $this->server_url = "https://sandbox.google.com/checkout/";
130
+ } else {
131
+ $this->server_url= "https://checkout.google.com/";
132
+ }
133
+
134
+
135
+ $this->schema_url = "http://checkout.google.com/schema/2";
136
+ $this->base_url = $this->server_url . "api/checkout/v2/";
137
+ $this->checkout_url = $this->base_url . "checkout/Merchant/" . $this->merchant_id;
138
+ $this->checkoutForm_url = $this->base_url . "checkoutForm/Merchant/" . $this->merchant_id;
139
+
140
+ //The item, shipping and tax table arrays are initialized
141
+ $this->item_arr = array();
142
+ $this->shipping_arr = array();
143
+ $this->alternate_tax_tables_arr = array();
144
+ }
145
+
146
+ /**
147
+ * Sets the cart's expiration date
148
+ *
149
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_good-until-date <good-until-date>}
150
+ *
151
+ * @param string $cart_expire a string representing a date in the
152
+ * iso 8601 date and time format: {@link http://www.w3.org/TR/NOTE-datetime}
153
+ *
154
+ * @return void
155
+ */
156
+ function SetCartExpiration($cart_expire) {
157
+ $this->cart_expiration = $cart_expire;
158
+ }
159
+
160
+ /**
161
+ * Sets the merchant's private data.
162
+ *
163
+ * Google Checkout will return this data in the
164
+ * <merchant-calculation-callback> and the
165
+ * <new-order-notification> for the order.
166
+ *
167
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_merchant-private-data <merchant-private-data>}
168
+ *
169
+ * @param MerchantPrivateData $data an object which contains the data to be
170
+ * sent as merchant-private-data
171
+ *
172
+ * @return void
173
+ */
174
+ function SetMerchantPrivateData($data) {
175
+ $this->merchant_private_data = $data;
176
+ }
177
+
178
+ /**
179
+ * Sets the url where the customer can edit his cart.
180
+ *
181
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_edit-cart-url <edit-cart-url>}
182
+ *
183
+ * @param string $url the merchant's site edit cart url
184
+ * @return void
185
+ */
186
+ function SetEditCartUrl($url) {
187
+ $this->edit_cart_url= $url;
188
+ }
189
+
190
+ /**
191
+ * Sets the continue shopping url, which allows the customer to return
192
+ * to the merchant's site after confirming an order.
193
+ *
194
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_continue-shopping-url <continue-shopping-url>}
195
+ *
196
+ * @param string $url the merchant's site continue shopping url
197
+ * @return void
198
+ */
199
+ function SetContinueShoppingUrl($url) {
200
+ $this->continue_shopping_url = $url;
201
+ }
202
+
203
+ /**
204
+ * Sets whether the customer must enter a phone number to complete an order.
205
+ * If set to true, the customer must enter a number, which Google Checkout
206
+ * will return in the new order notification for the order.
207
+ *
208
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_request-buyer-phone-number <request-buyer-phone-number>}
209
+ *
210
+ * @param bool $req true if the customer's phone number is *required*
211
+ * to complete an order.
212
+ * defaults to false.
213
+ * @return void
214
+ */
215
+ function SetRequestBuyerPhone($req) {
216
+ $this->request_buyer_phone = $this->_GetBooleanValue($req, "false");
217
+ }
218
+
219
+ /**
220
+ * Sets the information about calculations that will be performed by the
221
+ * merchant.
222
+ *
223
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_merchant-calculations <merchant-calculations>}
224
+ *
225
+ * @param string $url the merchant calculations callback url
226
+ * @param bool $tax_option true if the merchant has to do tax calculations.
227
+ * defaults to false.
228
+ * @param bool $coupons true if the merchant accepts discount coupons.
229
+ * defaults to false.
230
+ * @param bool $gift_cert true if the merchant accepts gift certificates.
231
+ * defaults to false.
232
+ * @return void
233
+ */
234
+ function SetMerchantCalculations($url, $tax_option = "false",
235
+ $coupons = "false", $gift_cert = "false") {
236
+ $this->merchant_calculations_url = $url;
237
+ $this->merchant_calculated_tax = $this->_GetBooleanValue($tax_option, "false");
238
+ $this->accept_merchant_coupons = $this->_GetBooleanValue($coupons, "false");
239
+ $this->accept_gift_certificates = $this->_GetBooleanValue($gift_cert, "false");
240
+ }
241
+
242
+ /**
243
+ * Add an item to the cart.
244
+ *
245
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_item <item>}
246
+ *
247
+ * @param GoogleItem $google_item an object that represents an item
248
+ * (defined in googleitem.php)
249
+ *
250
+ * @return void
251
+ */
252
+ function AddItem($google_item) {
253
+ $this->item_arr[] = $google_item;
254
+ }
255
+
256
+ /**
257
+ * Add a shipping method to the cart.
258
+ *
259
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_shipping-methods <shipping-methods>}
260
+ *
261
+ * @param object $ship an object that represents a shipping method, must be
262
+ * one of the methods defined in googleshipping.php
263
+ *
264
+ * @return void
265
+ */
266
+ function AddShipping($ship) {
267
+ $this->shipping_arr[] = $ship;
268
+ }
269
+
270
+ /**
271
+ * Add a default tax rule to the cart.
272
+ *
273
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_default-tax-rule <default-tax-rule>}
274
+ *
275
+ * @param GoogleDefaultTaxRule $rules an object that represents a default
276
+ * tax rule (defined in googletax.php)
277
+ *
278
+ * @return void
279
+ */
280
+ function AddDefaultTaxRules($rules) {
281
+ $this->default_tax_table = true;
282
+ $this->default_tax_rules_arr[] = $rules;
283
+ }
284
+
285
+ /**
286
+ * Add an alternate tax table to the cart.
287
+ *
288
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_alternate-tax-table <alternate-tax-table>}
289
+ *
290
+ * @param GoogleAlternateTaxTable $tax an object that represents an
291
+ * alternate tax table
292
+ * (defined in googletax.php)
293
+ *
294
+ * @return void
295
+ */
296
+ function AddAlternateTaxTables($tax) {
297
+ $this->alternate_tax_tables_arr[] = $tax;
298
+ }
299
+
300
+ /**
301
+ * Set the policy to be used to round monetary values.
302
+ * Rounding policy explanation here:
303
+ * {@link http://code.google.com/apis/checkout/developer/Google_Checkout_Rounding_Policy.html}
304
+ *
305
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_rounding-policy <rounding-policy>}
306
+ *
307
+ * @param string $mode one of "UP", "DOWN", "CEILING", "HALF_DOWN"
308
+ * or "HALF_EVEN", described here: {@link http://java.sun.com/j2se/1.5.0/docs/api/java/math/RoundingMode.html}
309
+ * @param string $rule one of "PER_LINE", "TOTAL"
310
+ *
311
+ * @return void
312
+ */
313
+ function AddRoundingPolicy($mode, $rule) {
314
+ switch ($mode) {
315
+ case "UP":
316
+ case "DOWN":
317
+ case "CEILING":
318
+ case "HALF_UP":
319
+ case "HALF_DOWN":
320
+ case "HALF_EVEN":
321
+ $this->rounding_mode = $mode;
322
+ break;
323
+ default:
324
+ break;
325
+ }
326
+ switch ($rule) {
327
+ case "PER_LINE":
328
+ case "TOTAL":
329
+ $this->rounding_rule = $rule;
330
+ break;
331
+ default:
332
+ break;
333
+ }
334
+ }
335
+
336
+ /**
337
+ * Set the google analytics data.
338
+ *
339
+ * {@link http://code.google.com/apis/checkout/developer/checkout_analytics_integration.html info on Checkout and Analytics integration}
340
+ *
341
+ * @param string $data the analytics data
342
+ *
343
+ * @return void
344
+ */
345
+ function SetAnalyticsData($data) {
346
+ $this->analytics_data = $data;
347
+ }
348
+
349
+ /**
350
+ * Add a google analytics tracking id.
351
+ *
352
+ * {@link http://code.google.com/apis/checkout/developer/checkout_analytics_integration.html info on Checkout and Analytics integration}
353
+ *
354
+ * @param string $GA_id the google analytics id
355
+ *
356
+ * @return void
357
+ */
358
+ function AddGoogleAnalyticsTracking($GA_id) {
359
+ $this->googleAnalytics_id = $GA_id;
360
+ }
361
+
362
+ /**
363
+ * Add third-party tracking to the cart
364
+ *
365
+ * Described here:
366
+ * {@link http://code.google.com/apis/checkout/developer/checkout_analytics_integration.html#googleCheckoutAnalyticsIntegrationAlternate}
367
+ *
368
+ * @param $tracking_attr_types attributes to be tracked, one of
369
+ * ('buyer-id',
370
+ * 'order-id',
371
+ * 'order-subtotal',
372
+ * 'order-subtotal-plus-tax',
373
+ * 'order-subtotal-plus-shipping',
374
+ * 'order-total',
375
+ * 'tax-amount',
376
+ * 'shipping-amount',
377
+ * 'coupon-amount',
378
+ * 'coupon-amount',
379
+ * 'billing-city',
380
+ * 'billing-region',
381
+ * 'billing-postal-code',
382
+ * 'billing-country-code',
383
+ * 'shipping-city',
384
+ * 'shipping-region',
385
+ * 'shipping-postal-code',
386
+ * 'shipping-country-code')
387
+ * More info http://code.google.com/apis/checkout/developer/checkout_pixel_tracking.html#googleCheckout_tag_url-parameter
388
+ */
389
+ function AddThirdPartyTracking($url, $tracking_param_types = array()) {
390
+ $this->thirdPartyTackingUrl = $url;
391
+ $this->thirdPartyTackingParams = $tracking_param_types;
392
+ }
393
+
394
+ /**
395
+ * Builds the cart's xml to be sent to Google Checkout.
396
+ *
397
+ * @return string the cart's xml
398
+ */
399
+ function GetXML() {
400
+ require_once('xml-processing/gc_xmlbuilder.php');
401
+
402
+ $xml_data = new gc_XmlBuilder();
403
+
404
+ $xml_data->Push('checkout-shopping-cart',
405
+ array('xmlns' => $this->schema_url));
406
+ $xml_data->Push('shopping-cart');
407
+
408
+ //Add cart expiration if set
409
+ if($this->cart_expiration != "") {
410
+ $xml_data->Push('cart-expiration');
411
+ $xml_data->Element('good-until-date', $this->cart_expiration);
412
+ $xml_data->Pop('cart-expiration');
413
+ }
414
+
415
+ //Add XML data for each of the items
416
+ $xml_data->Push('items');
417
+ foreach($this->item_arr as $item) {
418
+ $xml_data->Push('item');
419
+ $xml_data->Element('item-name', $item->item_name);
420
+ $xml_data->Element('item-description', $item->item_description);
421
+ $xml_data->Element('unit-price', $item->unit_price,
422
+ array('currency' => $this->currency));
423
+ $xml_data->Element('quantity', $item->quantity);
424
+ if($item->merchant_private_item_data != '') {
425
+ // echo get_class($item->merchant_private_item_data);
426
+ if(is_a($item->merchant_private_item_data,
427
+ 'merchantprivate')) {
428
+ $item->merchant_private_item_data->AddMerchantPrivateToXML($xml_data);
429
+ }
430
+ else {
431
+ $xml_data->Element('merchant-private-item-data',
432
+ $item->merchant_private_item_data);
433
+ }
434
+ }
435
+ if($item->merchant_item_id != '')
436
+ $xml_data->Element('merchant-item-id', $item->merchant_item_id);
437
+ if($item->tax_table_selector != '')
438
+ $xml_data->Element('tax-table-selector', $item->tax_table_selector);
439
+ // Carrier calculation
440
+ if($item->item_weight != '' && $item->numeric_weight !== '') {
441
+ $xml_data->EmptyElement('item-weight', array( 'unit' => $item->item_weight,
442
+ 'value' => $item->numeric_weight
443
+ ));
444
+ }
445
+ // New Digital Delivery Tags
446
+ if($item->digital_content) {
447
+ $xml_data->push('digital-content');
448
+ if(!empty($item->digital_url)) {
449
+ $xml_data->element('description', substr($item->digital_description,
450
+ 0, MAX_DIGITAL_DESC));
451
+ $xml_data->element('url', $item->digital_url);
452
+ // To avoid NULL key message in GC confirmation Page
453
+ if(!empty($item->digital_key)) {
454
+ $xml_data->element('key', $item->digital_key);
455
+ }
456
+ }
457
+ else {
458
+ $xml_data->element('email-delivery',
459
+ $this->_GetBooleanValue($item->email_delivery, "true"));
460
+ }
461
+ $xml_data->pop('digital-content');
462
+ }
463
+ $xml_data->Pop('item');
464
+ }
465
+ $xml_data->Pop('items');
466
+
467
+ if($this->merchant_private_data != '') {
468
+ if(is_a($this->merchant_private_data, 'merchantprivate')) {
469
+ $this->merchant_private_data->AddMerchantPrivateToXML($xml_data);
470
+ }
471
+ else {
472
+ $xml_data->Element('merchant-private-data',
473
+ $this->merchant_private_data);
474
+ }
475
+ }
476
+ $xml_data->Pop('shopping-cart');
477
+
478
+ $xml_data->Push('checkout-flow-support');
479
+ $xml_data->Push('merchant-checkout-flow-support');
480
+ if($this->edit_cart_url != '')
481
+ $xml_data->Element('edit-cart-url', $this->edit_cart_url);
482
+ if($this->continue_shopping_url != '')
483
+ $xml_data->Element('continue-shopping-url',
484
+ $this->continue_shopping_url);
485
+
486
+ if(count($this->shipping_arr) > 0)
487
+ $xml_data->Push('shipping-methods');
488
+
489
+ //Add the shipping methods
490
+ foreach($this->shipping_arr as $ship) {
491
+ //Pickup shipping handled in else part
492
+ if($ship->type == "flat-rate-shipping" ||
493
+ $ship->type == "merchant-calculated-shipping"
494
+ // If shipping-company calc support addr-filtering and shipping restrictions as a subatag of shipping-company-calculated-shipping
495
+ // ||$ship->type == "shipping-company-calculated-shipping"
496
+ ) {
497
+ $xml_data->Push($ship->type, array('name' => $ship->name));
498
+ $xml_data->Element('price', $ship->price,
499
+ array('currency' => $this->currency));
500
+
501
+ $shipping_restrictions = $ship->shipping_restrictions;
502
+ if (isset($shipping_restrictions)) {
503
+ $xml_data->Push('shipping-restrictions');
504
+
505
+ if ($shipping_restrictions->allow_us_po_box === true) {
506
+ $xml_data->Element('allow-us-po-box', "true");
507
+ } else {
508
+ $xml_data->Element('allow-us-po-box', "false");
509
+ }
510
+
511
+ //Check if allowed restrictions specified
512
+ if($shipping_restrictions->allowed_restrictions) {
513
+ $xml_data->Push('allowed-areas');
514
+ if($shipping_restrictions->allowed_country_area != "")
515
+ $xml_data->EmptyElement('us-country-area',
516
+ array('country-area' =>
517
+ $shipping_restrictions->allowed_country_area));
518
+ foreach($shipping_restrictions->allowed_state_areas_arr as $current) {
519
+ $xml_data->Push('us-state-area');
520
+ $xml_data->Element('state', $current);
521
+ $xml_data->Pop('us-state-area');
522
+ }
523
+ foreach($shipping_restrictions->allowed_zip_patterns_arr as $current) {
524
+ $xml_data->Push('us-zip-area');
525
+ $xml_data->Element('zip-pattern', $current);
526
+ $xml_data->Pop('us-zip-area');
527
+ }
528
+ if($shipping_restrictions->allowed_world_area === true) {
529
+ $xml_data->EmptyElement('world-area');
530
+ }
531
+ for($i=0; $i<count($shipping_restrictions->allowed_country_codes_arr); $i++) {
532
+ $xml_data->Push('postal-area');
533
+ $country_code = $shipping_restrictions->allowed_country_codes_arr[$i];
534
+ $postal_pattern = $shipping_restrictions->allowed_postal_patterns_arr[$i];
535
+ $xml_data->Element('country-code', $country_code);
536
+ if ($postal_pattern != "") {
537
+ $xml_data->Element('postal-code-pattern', $postal_pattern);
538
+ }
539
+ $xml_data->Pop('postal-area');
540
+ }
541
+ $xml_data->Pop('allowed-areas');
542
+ }
543
+
544
+ if($shipping_restrictions->excluded_restrictions) {
545
+ if (!$shipping_restrictions->allowed_restrictions) {
546
+ $xml_data->EmptyElement('allowed-areas');
547
+ }
548
+ $xml_data->Push('excluded-areas');
549
+ if($shipping_restrictions->excluded_country_area != "")
550
+ $xml_data->EmptyElement('us-country-area',
551
+ array('country-area' =>
552
+ $shipping_restrictions->excluded_country_area));
553
+ foreach($shipping_restrictions->excluded_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($shipping_restrictions->excluded_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
+ for($i=0; $i<count($shipping_restrictions->excluded_country_codes_arr); $i++) {
564
+ $xml_data->Push('postal-area');
565
+ $country_code = $shipping_restrictions->excluded_country_codes_arr[$i];
566
+ $postal_pattern = $shipping_restrictions->excluded_postal_patterns_arr[$i];
567
+ $xml_data->Element('country-code', $country_code);
568
+ if ($postal_pattern != "") {
569
+ $xml_data->Element('postal-code-pattern', $postal_pattern);
570
+ }
571
+ $xml_data->Pop('postal-area');
572
+ }
573
+ $xml_data->Pop('excluded-areas');
574
+ }
575
+ $xml_data->Pop('shipping-restrictions');
576
+ }
577
+
578
+ if ($ship->type == "merchant-calculated-shipping") {
579
+ $address_filters = $ship->address_filters;
580
+ if (isset($address_filters)) {
581
+ $xml_data->Push('address-filters');
582
+
583
+ if ($address_filters->allow_us_po_box === true) {
584
+ $xml_data->Element('allow-us-po-box', "true");
585
+ } else {
586
+ $xml_data->Element('allow-us-po-box', "false");
587
+ }
588
+
589
+ //Check if allowed restrictions specified
590
+ if($address_filters->allowed_restrictions) {
591
+ $xml_data->Push('allowed-areas');
592
+ if($address_filters->allowed_country_area != "")
593
+ $xml_data->EmptyElement('us-country-area',
594
+ array('country-area' =>
595
+ $address_filters->allowed_country_area));
596
+ foreach($address_filters->allowed_state_areas_arr as $current) {
597
+ $xml_data->Push('us-state-area');
598
+ $xml_data->Element('state', $current);
599
+ $xml_data->Pop('us-state-area');
600
+ }
601
+ foreach($address_filters->allowed_zip_patterns_arr as $current) {
602
+ $xml_data->Push('us-zip-area');
603
+ $xml_data->Element('zip-pattern', $current);
604
+ $xml_data->Pop('us-zip-area');
605
+ }
606
+ if($address_filters->allowed_world_area === true) {
607
+ $xml_data->EmptyElement('world-area');
608
+ }
609
+ for($i=0; $i<count($address_filters->allowed_country_codes_arr); $i++) {
610
+ $xml_data->Push('postal-area');
611
+ $country_code = $address_filters->allowed_country_codes_arr[$i];
612
+ $postal_pattern = $address_filters->allowed_postal_patterns_arr[$i];
613
+ $xml_data->Element('country-code', $country_code);
614
+ if ($postal_pattern != "") {
615
+ $xml_data->Element('postal-code-pattern', $postal_pattern);
616
+ }
617
+ $xml_data->Pop('postal-area');
618
+ }
619
+ $xml_data->Pop('allowed-areas');
620
+ }
621
+
622
+ if($address_filters->excluded_restrictions) {
623
+ if (!$address_filters->allowed_restrictions) {
624
+ $xml_data->EmptyElement('allowed-areas');
625
+ }
626
+ $xml_data->Push('excluded-areas');
627
+ if($address_filters->excluded_country_area != "")
628
+ $xml_data->EmptyElement('us-country-area',
629
+ array('country-area' =>
630
+ $address_filters->excluded_country_area));
631
+ foreach($address_filters->excluded_state_areas_arr as $current) {
632
+ $xml_data->Push('us-state-area');
633
+ $xml_data->Element('state', $current);
634
+ $xml_data->Pop('us-state-area');
635
+ }
636
+ foreach($address_filters->excluded_zip_patterns_arr as $current) {
637
+ $xml_data->Push('us-zip-area');
638
+ $xml_data->Element('zip-pattern', $current);
639
+ $xml_data->Pop('us-zip-area');
640
+ }
641
+ for($i=0; $i<count($address_filters->excluded_country_codes_arr); $i++) {
642
+ $xml_data->Push('postal-area');
643
+ $country_code = $address_filters->excluded_country_codes_arr[$i];
644
+ $postal_pattern = $address_filters->excluded_postal_patterns_arr[$i];
645
+ $xml_data->Element('country-code', $country_code);
646
+ if ($postal_pattern != "") {
647
+ $xml_data->Element('postal-code-pattern', $postal_pattern);
648
+ }
649
+ $xml_data->Pop('postal-area');
650
+ }
651
+ $xml_data->Pop('excluded-areas');
652
+ }
653
+ $xml_data->Pop('address-filters');
654
+ }
655
+ }
656
+ $xml_data->Pop($ship->type);
657
+ }
658
+ else if ($ship->type == "carrier-calculated-shipping"){
659
+ // $xml_data->Push($ship->type, array('name' => $ship->name));
660
+ $xml_data->Push($ship->type);
661
+ $xml_data->Push('carrier-calculated-shipping-options');
662
+ $CCSoptions = $ship->CarrierCalculatedShippingOptions;
663
+ foreach($CCSoptions as $CCSoption){
664
+ $xml_data->Push('carrier-calculated-shipping-option');
665
+ $xml_data->Element('price', $CCSoption->price,
666
+ array('currency' => $this->currency));
667
+ $xml_data->Element('shipping-company', $CCSoption->shipping_company);
668
+ $xml_data->Element('shipping-type', $CCSoption->shipping_type);
669
+ $xml_data->Element('carrier-pickup', $CCSoption->carrier_pickup);
670
+ if(!empty($CCSoption->additional_fixed_charge)) {
671
+ $xml_data->Element('additional-fixed-charge',
672
+ $CCSoption->additional_fixed_charge,
673
+ array('currency' => $this->currency));
674
+ }
675
+ if(!empty($CCSoption->additional_variable_charge_percent)) {
676
+ $xml_data->Element('additional-variable-charge-percent',
677
+ $CCSoption->additional_variable_charge_percent);
678
+ }
679
+ $xml_data->Pop('carrier-calculated-shipping-option');
680
+ }
681
+ $xml_data->Pop('carrier-calculated-shipping-options');
682
+ // $ShippingPackage = $ship->ShippingPackage;
683
+ $xml_data->Push('shipping-packages');
684
+ $xml_data->Push('shipping-package');
685
+ $xml_data->Push('ship-from', array('id' => $ship->ShippingPackage->ship_from->id));
686
+ $xml_data->Element('city', $ship->ShippingPackage->ship_from->city);
687
+ $xml_data->Element('region', $ship->ShippingPackage->ship_from->region);
688
+ $xml_data->Element('postal-code', $ship->ShippingPackage->ship_from->postal_code);
689
+ $xml_data->Element('country-code', $ship->ShippingPackage->ship_from->country_code);
690
+ $xml_data->Pop('ship-from');
691
+
692
+ $xml_data->EmptyElement('width', array('unit' => $ship->ShippingPackage->unit,
693
+ 'value' => $ship->ShippingPackage->width
694
+ ));
695
+ $xml_data->EmptyElement('length', array('unit' => $ship->ShippingPackage->unit,
696
+ 'value' => $ship->ShippingPackage->length
697
+ ));
698
+ $xml_data->EmptyElement('height', array('unit' => $ship->ShippingPackage->unit,
699
+ 'value' => $ship->ShippingPackage->height
700
+ ));
701
+ $xml_data->Element('delivery-address-category',
702
+ $ship->ShippingPackage->delivery_address_category);
703
+ $xml_data->Pop('shipping-package');
704
+ $xml_data->Pop('shipping-packages');
705
+
706
+ $xml_data->Pop($ship->type);
707
+ }
708
+ else if ($ship->type == "pickup") {
709
+ $xml_data->Push('pickup', array('name' => $ship->name));
710
+ $xml_data->Element('price', $ship->price,
711
+ array('currency' => $this->currency));
712
+ $xml_data->Pop('pickup');
713
+ }
714
+ }
715
+ if(count($this->shipping_arr) > 0)
716
+ $xml_data->Pop('shipping-methods');
717
+
718
+ if($this->request_buyer_phone != "")
719
+ $xml_data->Element('request-buyer-phone-number',
720
+ $this->request_buyer_phone);
721
+
722
+ if($this->merchant_calculations_url != "") {
723
+ $xml_data->Push('merchant-calculations');
724
+ $xml_data->Element('merchant-calculations-url',
725
+ $this->merchant_calculations_url);
726
+ if($this->accept_merchant_coupons != "") {
727
+ $xml_data->Element('accept-merchant-coupons',
728
+ $this->accept_merchant_coupons);
729
+ }
730
+ if($this->accept_gift_certificates != "") {
731
+ $xml_data->Element('accept-gift-certificates',
732
+ $this->accept_gift_certificates);
733
+ }
734
+ $xml_data->Pop('merchant-calculations');
735
+ }
736
+ //Set Third party Tracking
737
+ if($this->thirdPartyTackingUrl) {
738
+ $xml_data->push('parameterized-urls');
739
+ $xml_data->push('parameterized-url',
740
+ array('url' => $this->thirdPartyTackingUrl));
741
+ if(is_array($this->thirdPartyTackingParams)
742
+ && count($this->thirdPartyTackingParams)>0) {
743
+ $xml_data->push('parameters');
744
+ foreach($this->thirdPartyTackingParams as $tracking_param_name =>
745
+ $tracking_param_type) {
746
+ $xml_data->emptyElement('url-parameter',
747
+ array('name' => $tracking_param_name,
748
+ 'type' => $tracking_param_type));
749
+ }
750
+ $xml_data->pop('parameters');
751
+ }
752
+ $xml_data->pop('parameterized-url');
753
+ $xml_data->pop('parameterized-urls');
754
+ }
755
+
756
+ //Set Default and Alternate tax tables
757
+ if( (count($this->alternate_tax_tables_arr) != 0)
758
+ || (count($this->default_tax_rules_arr) != 0)) {
759
+ if($this->merchant_calculated_tax != "") {
760
+ $xml_data->Push('tax-tables',
761
+ array('merchant-calculated' => $this->merchant_calculated_tax));
762
+ }
763
+ else {
764
+ $xml_data->Push('tax-tables');
765
+ }
766
+ if(count($this->default_tax_rules_arr) != 0) {
767
+ $xml_data->Push('default-tax-table');
768
+ $xml_data->Push('tax-rules');
769
+ foreach($this->default_tax_rules_arr as $curr_rule) {
770
+
771
+ if($curr_rule->country_area != "") {
772
+ $xml_data->Push('default-tax-rule');
773
+ $xml_data->Element('shipping-taxed', $curr_rule->shipping_taxed);
774
+ $xml_data->Element('rate', $curr_rule->tax_rate);
775
+ $xml_data->Push('tax-area');
776
+ $xml_data->EmptyElement('us-country-area',
777
+ array('country-area' => $curr_rule->country_area));
778
+ $xml_data->Pop('tax-area');
779
+ $xml_data->Pop('default-tax-rule');
780
+ }
781
+
782
+ foreach($curr_rule->state_areas_arr as $current) {
783
+ $xml_data->Push('default-tax-rule');
784
+ $xml_data->Element('shipping-taxed', $curr_rule->shipping_taxed);
785
+ $xml_data->Element('rate', $curr_rule->tax_rate);
786
+ $xml_data->Push('tax-area');
787
+ $xml_data->Push('us-state-area');
788
+ $xml_data->Element('state', $current);
789
+ $xml_data->Pop('us-state-area');
790
+ $xml_data->Pop('tax-area');
791
+ $xml_data->Pop('default-tax-rule');
792
+ }
793
+
794
+ foreach($curr_rule->zip_patterns_arr as $current) {
795
+ $xml_data->Push('default-tax-rule');
796
+ $xml_data->Element('shipping-taxed', $curr_rule->shipping_taxed);
797
+ $xml_data->Element('rate', $curr_rule->tax_rate);
798
+ $xml_data->Push('tax-area');
799
+ $xml_data->Push('us-zip-area');
800
+ $xml_data->Element('zip-pattern', $current);
801
+ $xml_data->Pop('us-zip-area');
802
+ $xml_data->Pop('tax-area');
803
+ $xml_data->Pop('default-tax-rule');
804
+ }
805
+
806
+ for($i=0; $i<count($curr_rule->country_codes_arr); $i++) {
807
+ $xml_data->Push('default-tax-rule');
808
+ $xml_data->Element('shipping-taxed', $curr_rule->shipping_taxed);
809
+ $xml_data->Element('rate', $curr_rule->tax_rate);
810
+ $xml_data->Push('tax-area');
811
+ $xml_data->Push('postal-area');
812
+ $country_code = $curr_rule->country_codes_arr[$i];
813
+ $postal_pattern = $curr_rule->postal_patterns_arr[$i];
814
+ $xml_data->Element('country-code', $country_code);
815
+ if ($postal_pattern != "") {
816
+ $xml_data->Element('postal-code-pattern', $postal_pattern);
817
+ }
818
+ $xml_data->Pop('postal-area');
819
+ $xml_data->Pop('tax-area');
820
+ $xml_data->Pop('default-tax-rule');
821
+ }
822
+
823
+ if ($curr_rule->world_area === true) {
824
+ $xml_data->Push('default-tax-rule');
825
+ $xml_data->Element('shipping-taxed', $curr_rule->shipping_taxed);
826
+ $xml_data->Element('rate', $curr_rule->tax_rate);
827
+ $xml_data->Push('tax-area');
828
+ $xml_data->EmptyElement('world-area');
829
+ $xml_data->Pop('tax-area');
830
+ $xml_data->Pop('default-tax-rule');
831
+ }
832
+ }
833
+ $xml_data->Pop('tax-rules');
834
+ $xml_data->Pop('default-tax-table');
835
+ }
836
+
837
+ if(count($this->alternate_tax_tables_arr) != 0) {
838
+ $xml_data->Push('alternate-tax-tables');
839
+ foreach($this->alternate_tax_tables_arr as $curr_table) {
840
+ $xml_data->Push('alternate-tax-table',
841
+ array('standalone' => $curr_table->standalone,
842
+ 'name' => $curr_table->name));
843
+ $xml_data->Push('alternate-tax-rules');
844
+
845
+ foreach($curr_table->tax_rules_arr as $curr_rule) {
846
+ if($curr_rule->country_area != "") {
847
+ $xml_data->Push('alternate-tax-rule');
848
+ $xml_data->Element('rate', $curr_rule->tax_rate);
849
+ $xml_data->Push('tax-area');
850
+ $xml_data->EmptyElement('us-country-area',
851
+ array('country-area' => $curr_rule->country_area));
852
+ $xml_data->Pop('tax-area');
853
+ $xml_data->Pop('alternate-tax-rule');
854
+ }
855
+
856
+ foreach($curr_rule->state_areas_arr as $current) {
857
+ $xml_data->Push('alternate-tax-rule');
858
+ $xml_data->Element('rate', $curr_rule->tax_rate);
859
+ $xml_data->Push('tax-area');
860
+ $xml_data->Push('us-state-area');
861
+ $xml_data->Element('state', $current);
862
+ $xml_data->Pop('us-state-area');
863
+ $xml_data->Pop('tax-area');
864
+ $xml_data->Pop('alternate-tax-rule');
865
+ }
866
+
867
+ foreach($curr_rule->zip_patterns_arr as $current) {
868
+ $xml_data->Push('alternate-tax-rule');
869
+ $xml_data->Element('rate', $curr_rule->tax_rate);
870
+ $xml_data->Push('tax-area');
871
+ $xml_data->Push('us-zip-area');
872
+ $xml_data->Element('zip-pattern', $current);
873
+ $xml_data->Pop('us-zip-area');
874
+ $xml_data->Pop('tax-area');
875
+ $xml_data->Pop('alternate-tax-rule');
876
+ }
877
+
878
+ for($i=0; $i<count($curr_rule->country_codes_arr); $i++) {
879
+ $xml_data->Push('alternate-tax-rule');
880
+ $xml_data->Element('rate', $curr_rule->tax_rate);
881
+ $xml_data->Push('tax-area');
882
+ $xml_data->Push('postal-area');
883
+ $country_code = $curr_rule->country_codes_arr[$i];
884
+ $postal_pattern = $curr_rule->postal_patterns_arr[$i];
885
+ $xml_data->Element('country-code', $country_code);
886
+ if ($postal_pattern != "") {
887
+ $xml_data->Element('postal-code-pattern', $postal_pattern);
888
+ }
889
+ $xml_data->Pop('postal-area');
890
+ $xml_data->Pop('tax-area');
891
+ $xml_data->Pop('alternate-tax-rule');
892
+ }
893
+
894
+ if ($curr_rule->world_area === true) {
895
+ $xml_data->Push('alternate-tax-rule');
896
+ $xml_data->Element('rate', $curr_rule->tax_rate);
897
+ $xml_data->Push('tax-area');
898
+ $xml_data->EmptyElement('world-area');
899
+ $xml_data->Pop('tax-area');
900
+ $xml_data->Pop('alternate-tax-rule');
901
+ }
902
+ }
903
+ $xml_data->Pop('alternate-tax-rules');
904
+ $xml_data->Pop('alternate-tax-table');
905
+ }
906
+ $xml_data->Pop('alternate-tax-tables');
907
+ }
908
+ $xml_data->Pop('tax-tables');
909
+ }
910
+
911
+ if (($this->rounding_mode != "") && ($this->rounding_rule != "")) {
912
+ $xml_data->Push('rounding-policy');
913
+ $xml_data->Element('mode', $this->rounding_mode);
914
+ $xml_data->Element('rule', $this->rounding_rule);
915
+ $xml_data->Pop('rounding-policy');
916
+ }
917
+ if($this->analytics_data != ''){
918
+ $xml_data->Element('analytics-data', $this->analytics_data);
919
+ }
920
+
921
+ $xml_data->Pop('merchant-checkout-flow-support');
922
+ $xml_data->Pop('checkout-flow-support');
923
+ $xml_data->Pop('checkout-shopping-cart');
924
+
925
+ return $xml_data->GetXML();
926
+ }
927
+
928
+ /**
929
+ * Set the Google Checkout button's variant.
930
+ * {@link http://code.google.com/apis/checkout/developer/index.html#google_checkout_buttons}
931
+ *
932
+ * @param bool $variant true for an enabled button, false for a
933
+ * disabled one
934
+ *
935
+ * @return void
936
+ */
937
+ function SetButtonVariant($variant) {
938
+ switch ($variant) {
939
+ case false:
940
+ $this->variant = "disabled";
941
+ break;
942
+ case true:
943
+ default:
944
+ $this->variant = "text";
945
+ break;
946
+ }
947
+ }
948
+
949
+ /**
950
+ * Submit a server-to-server request.
951
+ * Creates a GoogleRequest object (defined in googlerequest.php) and sends
952
+ * it to the Google Checkout server.
953
+ *
954
+ * more info:
955
+ * {@link http://code.google.com/apis/checkout/developer/index.html#alternate_technique}
956
+ *
957
+ * @return array with the returned http status code (200 if OK) in index 0
958
+ * and the redirect url returned by the server in index 1
959
+ */
960
+ function CheckoutServer2Server($proxy=array(), $certPath='') {
961
+ #ini_set('include_path', ini_get('include_path').PATH_SEPARATOR.'.');
962
+ require_once('googlerequest.php');
963
+ $GRequest = new GoogleRequest($this->merchant_id,
964
+ $this->merchant_key,
965
+ $this->server_url=="https://checkout.google.com/"?
966
+ "Production":"sandbox",
967
+ $this->currency);
968
+ $GRequest->SetProxy($proxy);
969
+ $GRequest->SetCertificatePath($certPath);
970
+
971
+ return $GRequest->SendServer2ServerCart($this->GetXML());
972
+ }
973
+
974
+ /**
975
+ * Get the Google Checkout button's html to be used in a server-to-server
976
+ * request.
977
+ *
978
+ * {@link http://code.google.com/apis/checkout/developer/index.html#google_checkout_buttons}
979
+ *
980
+ * @param string $url the merchant's site url where the form will be posted
981
+ * to
982
+ * @param string $size the size of the button, one of 'large', 'medium' or
983
+ * 'small'.
984
+ * defaults to 'large'
985
+ * @param bool $variant true for an enabled button, false for a
986
+ * disabled one. defaults to true. will be ignored if
987
+ * SetButtonVariant() was used before.
988
+ * @param string $loc the locale of the button's text, the only valid value
989
+ * is 'en_US' (used as default)
990
+ * @param bool $showtext whether to show Google Checkout text or not,
991
+ * defaults to true.
992
+ * @param string $style the background style of the button, one of 'white'
993
+ * or 'trans'. defaults to "trans"
994
+ *
995
+ * @return string the button's html
996
+ */
997
+ function CheckoutServer2ServerButton($url, $size="large", $variant=true,
998
+ $loc="en_US",$showtext=true, $style="trans") {
999
+
1000
+ switch (strtolower($size)) {
1001
+ case "medium":
1002
+ $width = "168";
1003
+ $height = "44";
1004
+ break;
1005
+
1006
+ case "small":
1007
+ $width = "160";
1008
+ $height = "43";
1009
+ break;
1010
+ case "large":
1011
+ default:
1012
+ $width = "180";
1013
+ $height = "46";
1014
+ break;
1015
+ }
1016
+
1017
+ if($this->variant == false) {
1018
+ switch ($variant) {
1019
+ case false:
1020
+ $this->variant = "disabled";
1021
+ break;
1022
+ case true:
1023
+ default:
1024
+ $this->variant = "text";
1025
+ break;
1026
+ }
1027
+ }
1028
+ $data = "<div style=\"width: ".$width."px\">";
1029
+ if ($this->variant == "text") {
1030
+ $data .= "<div align=center><form method=\"POST\" action=\"".
1031
+ $url . "\"" . ($this->googleAnalytics_id?
1032
+ " onsubmit=\"setUrchinInputCode();\"":"") . ">
1033
+ <input type=\"image\" name=\"Checkout\" alt=\"Checkout\"
1034
+ src=\"". $this->server_url."buttons/checkout.gif?merchant_id=" .
1035
+ $this->merchant_id."&w=".$width. "&h=".$height."&style=".
1036
+ $style."&variant=".$this->variant."&loc=".$loc."\"
1037
+ height=\"".$height."\" width=\"".$width. "\" />";
1038
+
1039
+ if($this->googleAnalytics_id) {
1040
+ $data .= "<input type=\"hidden\" name=\"analyticsdata\" value=\"\">";
1041
+ }
1042
+ $data .= "</form></div>";
1043
+ if($this->googleAnalytics_id) {
1044
+ $data .= "<!-- Start Google analytics -->
1045
+ <script src=\"https://ssl.google-analytics.com/urchin.js\" type=\"".
1046
+ "text/javascript\">
1047
+ </script>
1048
+ <script type=\"text/javascript\">
1049
+ _uacct = \"" . $this->googleAnalytics_id . "\";
1050
+ urchinTracker();
1051
+ </script>
1052
+ <script src=\"https://checkout.google.com/files/digital/urchin_po" .
1053
+ "st.js\" type=\"text/javascript\"></script>
1054
+ <!-- End Google analytics -->";
1055
+ } } else {
1056
+ $data .= "<div><img alt=\"Checkout\" src=\"" .
1057
+ "". $this->server_url."buttons/checkout.gif?merchant_id=" .
1058
+ "".$this->merchant_id."&w=".$width. "&h=".$height."&style=".$style.
1059
+ "&variant=".$this->variant."&loc=".$loc."\" height=\"".$height."\"".
1060
+ " width=\"".$width. "\" /></div>";
1061
+
1062
+ }
1063
+ $data .= "</div>";
1064
+ return $data;
1065
+ }
1066
+
1067
+ /**
1068
+ * Get the Google Checkout button's html.
1069
+ *
1070
+ * {@link http://code.google.com/apis/checkout/developer/index.html#google_checkout_buttons}
1071
+ *
1072
+ * @param string $size the size of the button, one of 'large', 'medium' or
1073
+ * 'small'.
1074
+ * defaults to 'large'
1075
+ * @param bool $variant true for an enabled button, false for a
1076
+ * disabled one. defaults to true. will be ignored if
1077
+ * SetButtonVariant() was used before.
1078
+ * @param string $loc the locale of the button's text, the only valid value
1079
+ * is 'en_US' (used as default)
1080
+ * @param bool $showtext whether to show Google Checkout text or not,
1081
+ * defaults to true.
1082
+ * @param string $style the background style of the button, one of 'white'
1083
+ * or 'trans'. defaults to "trans"
1084
+ *
1085
+ * @return string the button's html
1086
+ */
1087
+ function CheckoutButtonCode($size="large", $variant=true, $loc="en_US",
1088
+ $showtext=true, $style="trans") {
1089
+
1090
+ switch (strtolower($size)) {
1091
+ case "medium":
1092
+ $width = "168";
1093
+ $height = "44";
1094
+ break;
1095
+
1096
+ case "small":
1097
+ $width = "160";
1098
+ $height = "43";
1099
+ break;
1100
+ case "large":
1101
+ default:
1102
+ $width = "180";
1103
+ $height = "46";
1104
+ break;
1105
+ }
1106
+
1107
+ if($this->variant == false) {
1108
+ switch ($variant) {
1109
+ case false:
1110
+ $this->variant = "disabled";
1111
+ break;
1112
+ case true:
1113
+ default:
1114
+ $this->variant = "text";
1115
+ break;
1116
+ }
1117
+ }
1118
+
1119
+
1120
+ $data = "<div style=\"width: ".$width."px\">";
1121
+ if ($this->variant == "text") {
1122
+ $data .= "<div align=center><form method=\"POST\" action=\"".
1123
+ $this->checkout_url . "\"" . ($this->googleAnalytics_id?
1124
+ " onsubmit=\"setUrchinInputCode();\"":"") . ">
1125
+ <input type=\"hidden\" name=\"cart\" value=\"".
1126
+ base64_encode($this->GetXML()) ."\">
1127
+ <input type=\"hidden\" name=\"signature\" value=\"".
1128
+ base64_encode($this->CalcHmacSha1($this->GetXML())). "\">
1129
+ <input type=\"image\" name=\"Checkout\" alt=\"Checkout\"
1130
+ src=\"". $this->server_url."buttons/checkout.gif?merchant_id=" .
1131
+ $this->merchant_id."&w=".$width. "&h=".$height."&style=".
1132
+ $style."&variant=".$this->variant."&loc=".$loc."\"
1133
+ height=\"".$height."\" width=\"".$width. "\" />";
1134
+
1135
+ if($this->googleAnalytics_id) {
1136
+ $data .= "<input type=\"hidden\" name=\"analyticsdata\" value=\"\">";
1137
+ }
1138
+ $data .= "</form></div>";
1139
+ if($this->googleAnalytics_id) {
1140
+ $data .= "<!-- Start Google analytics -->
1141
+ <script src=\"https://ssl.google-analytics.com/urchin.js\" type=\"".
1142
+ "text/javascript\">
1143
+ </script>
1144
+ <script type=\"text/javascript\">
1145
+ _uacct = \"" . $this->googleAnalytics_id . "\";
1146
+ urchinTracker();
1147
+ </script>
1148
+ <script src=\"https://checkout.google.com/files/digital/urchin_po" .
1149
+ "st.js\" type=\"text/javascript\"></script>
1150
+ <!-- End Google analytics -->";
1151
+ }
1152
+ } else {
1153
+ $data .= "<div><img alt=\"Checkout\" src=\"" .
1154
+ "". $this->server_url."buttons/checkout.gif?merchant_id=" .
1155
+ "".$this->merchant_id."&w=".$width. "&h=".$height."&style=".$style.
1156
+ "&variant=".$this->variant."&loc=".$loc."\" height=\"".$height."\"".
1157
+ " width=\"".$width. "\" /></div>";
1158
+ }
1159
+ if($showtext) {
1160
+ $data .="<div align=\"center\"><a href=\"javascript:void(window.ope".
1161
+ "n('http://checkout.google.com/seller/what_is_google_checkout.html'" .
1162
+ ",'whatischeckout','scrollbars=0,resizable=1,directories=0,height=2" .
1163
+ "50,width=400'));\" onmouseover=\"return window.status = 'What is G" .
1164
+ "oogle Checkout?'\" onmouseout=\"return window.status = ''\"><font " .
1165
+ "size=\"-2\">What is Google Checkout?</font></a></div>";
1166
+ }
1167
+ $data .= "</div>";
1168
+ return $data;
1169
+ }
1170
+ //Code for generating Checkout button
1171
+ //@param $variant will be ignored if SetButtonVariant() was used before
1172
+ function CheckoutButtonNowCode($size="large", $variant=true, $loc="en_US",
1173
+ $showtext=true, $style="trans") {
1174
+
1175
+ switch (strtolower($size)) {
1176
+ case "small":
1177
+ $width = "121";
1178
+ $height = "44";
1179
+ break;
1180
+ case "large":
1181
+ default:
1182
+ $width = "117";
1183
+ $height = "48";
1184
+ break;
1185
+ }
1186
+
1187
+ if($this->variant == false) {
1188
+ switch ($variant) {
1189
+ case false:
1190
+ $this->variant = "disabled";
1191
+ break;
1192
+ case true:
1193
+ default:
1194
+ $this->variant = "text";
1195
+ break;
1196
+ }
1197
+ }
1198
+
1199
+
1200
+
1201
+ $data = "<div style=\"width: ".$width."px\">";
1202
+ if ($this->variant == "text") {
1203
+ $data .= "<div align=center><form method=\"POST\" action=\"".
1204
+ $this->checkout_url . "\"" . ($this->googleAnalytics_id?
1205
+ " onsubmit=\"setUrchinInputCode();\"":"") . ">
1206
+ <input type=\"hidden\" name=\"buyButtonCart\" value=\"".
1207
+ base64_encode($this->GetXML()) ."//separator//" .
1208
+ base64_encode($this->CalcHmacSha1($this->GetXML())) . "\">
1209
+ <input type=\"image\" name=\"Checkout\" alt=\"BuyNow\"
1210
+ src=\"". $this->server_url."buttons/buy.gif?merchant_id=" .
1211
+ $this->merchant_id."&w=".$width. "&h=".$height."&style=".
1212
+ $style."&variant=".$this->variant."&loc=".$loc."\"
1213
+ height=\"".$height."\" width=\"".$width. "\" />";
1214
+
1215
+ if($this->googleAnalytics_id) {
1216
+ $data .= "<input type=\"hidden\" name=\"analyticsdata\" value=\"\">";
1217
+ }
1218
+ $data .= "</form></div>";
1219
+ if($this->googleAnalytics_id) {
1220
+ $data .= "<!-- Start Google analytics -->
1221
+ <script src=\"https://ssl.google-analytics.com/urchin.js\" type=\"".
1222
+ "text/javascript\">
1223
+ </script>
1224
+ <script type=\"text/javascript\">
1225
+ _uacct = \"" . $this->googleAnalytics_id . "\";
1226
+ urchinTracker();
1227
+ </script>
1228
+ <script src=\"https://checkout.google.com/files/digital/urchin_po" .
1229
+ "st.js\" type=\"text/javascript\"></script>
1230
+ <!-- End Google analytics -->";
1231
+ }
1232
+ // ask for link to BuyNow disable button
1233
+ } else {
1234
+ $data .= "<div><img alt=\"Checkout\" src=\"" .
1235
+ "". $this->server_url."buttons/buy.gif?merchant_id=" .
1236
+ "".$this->merchant_id."&w=".$width. "&h=".$height."&style=".$style.
1237
+ "&variant=".$this->variant."&loc=".$loc."\" height=\"".$height."\"".
1238
+ " width=\"".$width. "\" /></div>";
1239
+ }
1240
+ if($showtext) {
1241
+ $data .="<div align=\"center\"><a href=\"javascript:void(window.ope".
1242
+ "n('http://checkout.google.com/seller/what_is_google_checkout.html'" .
1243
+ ",'whatischeckout','scrollbars=0,resizable=1,directories=0,height=2" .
1244
+ "50,width=400'));\" onmouseover=\"return window.status = 'What is G" .
1245
+ "oogle Checkout?'\" onmouseout=\"return window.status = ''\"><font " .
1246
+ "size=\"-2\">What is Google Checkout?</font></a></div>";
1247
+ }
1248
+ $data .= "</div>";
1249
+ return $data;
1250
+ }
1251
+
1252
+
1253
+ /**
1254
+ * Get the Google Checkout button's html to be used with the html api.
1255
+ *
1256
+ * {@link http://code.google.com/apis/checkout/developer/index.html#google_checkout_buttons}
1257
+ *
1258
+ * @param string $size the size of the button, one of 'large', 'medium' or
1259
+ * 'small'.
1260
+ * defaults to 'large'
1261
+ * @param bool $variant true for an enabled button, false for a
1262
+ * disabled one. defaults to true. will be ignored if
1263
+ * SetButtonVariant() was used before.
1264
+ * @param string $loc the locale of the button's text, the only valid value
1265
+ * is 'en_US' (used as default)
1266
+ * @param bool $showtext whether to show Google Checkout text or not,
1267
+ * defaults to true.
1268
+ * @param string $style the background style of the button, one of 'white'
1269
+ * or 'trans'. defaults to "trans"
1270
+ *
1271
+ * @return string the button's html
1272
+ */
1273
+ function CheckoutHTMLButtonCode($size="large", $variant=true, $loc="en_US",
1274
+ $showtext=true, $style="trans") {
1275
+
1276
+ switch (strtolower($size)) {
1277
+ case "medium":
1278
+ $width = "168";
1279
+ $height = "44";
1280
+ break;
1281
+
1282
+ case "small":
1283
+ $width = "160";
1284
+ $height = "43";
1285
+ break;
1286
+ case "large":
1287
+ default:
1288
+ $width = "180";
1289
+ $height = "46";
1290
+ break;
1291
+ }
1292
+
1293
+ if($this->variant == false) {
1294
+ switch ($variant) {
1295
+ case false:
1296
+ $this->variant = "disabled";
1297
+ break;
1298
+ case true:
1299
+ default:
1300
+ $this->variant = "text";
1301
+ break;
1302
+ }
1303
+ }
1304
+
1305
+
1306
+ $data = "<div style=\"width: ".$width."px\">";
1307
+ if ($this->variant == "text") {
1308
+ $data .= "<div align=\"center\"><form method=\"POST\" action=\"".
1309
+ $this->checkoutForm_url . "\"" . ($this->googleAnalytics_id?
1310
+ " onsubmit=\"setUrchinInputCode();\"":"") . ">";
1311
+
1312
+ $request = $this->GetXML();
1313
+ require_once('xml-processing/gc_xmlparser.php');
1314
+ $xml_parser = new gc_xmlparser($request);
1315
+ $root = $xml_parser->GetRoot();
1316
+ $XMLdata = $xml_parser->GetData();
1317
+ $this->xml2html($XMLdata[$root], '', $data);
1318
+ $data .= "<input type=\"image\" name=\"Checkout\" alt=\"Checkout\" " .
1319
+ "src=\"". $this->server_url."buttons/checkout.gif?merchant_id=".
1320
+ $this->merchant_id."&w=".$width. "&h=".$height."&style=".
1321
+ $style."&variant=".$this->variant."&loc=".$loc."\"
1322
+ height=\"".$height."\" width=\"".$width. "\" />";
1323
+
1324
+ if($this->googleAnalytics_id) {
1325
+ $data .= "<input type=\"hidden\" name=\"analyticsdata\" value=\"\">";
1326
+ }
1327
+ $data .= "</form></div>";
1328
+ if($this->googleAnalytics_id) {
1329
+ $data .= "<!-- Start Google analytics -->
1330
+ <script src=\"https://ssl.google-analytics.com/urchin.js\" type=\"".
1331
+ "text/javascript\">
1332
+ </script>
1333
+ <script type=\"text/javascript\">
1334
+ _uacct = \"" . $this->googleAnalytics_id . "\";
1335
+ urchinTracker();
1336
+ </script>
1337
+ <script src=\"https://checkout.google.com/files/digital/urchin_po" .
1338
+ "st.js\" type=\"text/javascript\"></script>
1339
+ <!-- End Google analytics -->";
1340
+ }
1341
+ } else {
1342
+ $data .= "<div align=\"center\"><img alt=\"Checkout\" src=\"" .
1343
+ "". $this->server_url."buttons/checkout.gif?merchant_id=" .
1344
+ "".$this->merchant_id."&w=".$width. "&h=".$height."&style=".$style.
1345
+ "&variant=".$this->variant."&loc=".$loc."\" height=\"".$height."\"".
1346
+ " width=\"".$width. "\" /></div>";
1347
+ }
1348
+ if($showtext){
1349
+ $data .= "<div align=\"center\"><a href=\"javascript:void(window.ope" .
1350
+ "n('http://checkout.google.com/seller/what_is_google_checkout.html'" .
1351
+ ",'whatischeckout','scrollbars=0,resizable=1,directories=0,height=2" .
1352
+ "50,width=400'));\" onmouseover=\"return window.status = 'What is G" .
1353
+ "oogle Checkout?'\" onmouseout=\"return window.status = ''\"><font " .
1354
+ "size=\"-2\">What is Google Checkout?</font></a></div>";
1355
+ }
1356
+ $data .= "</div>";
1357
+
1358
+
1359
+ return $data;
1360
+
1361
+ }
1362
+
1363
+ /**
1364
+ * @access private
1365
+ */
1366
+ function xml2html($data, $path = '', &$rta){
1367
+ // global $multiple_tags,$ignore_tags;
1368
+ // $arr = gc_get_arr_result($data);
1369
+ foreach($data as $tag_name => $tag) {
1370
+ if(isset($this->ignore_tags[$tag_name])){
1371
+ continue;
1372
+ }
1373
+ if(is_array($tag)){
1374
+ // echo print_r($tag, true) . $tag_name . "<- tag name\n";
1375
+ if(!$this->is_associative_array($data)) {
1376
+ $new_path = $path . '-' . ($tag_name +1);
1377
+ } else {
1378
+ if(isset($this->multiple_tags[$tag_name])
1379
+ && $this->is_associative_array($tag)
1380
+ && !$this->isChildOf($path, $this->multiple_tags[$tag_name])){
1381
+ $tag_name .= '-1';
1382
+ }
1383
+ $new_path = $path . (empty($path)?'':'.') . $tag_name;
1384
+ }
1385
+ $this->xml2html($tag, $new_path, $rta);
1386
+ }
1387
+ else {
1388
+ $new_path = $path;
1389
+ if($tag_name != 'VALUE'){
1390
+ $new_path = $path . "." . $tag_name;
1391
+ }
1392
+ $rta .= '<input type="hidden" name="' .
1393
+ $new_path . '" value="' .$tag . '"/>'."\n";
1394
+ }
1395
+ }
1396
+ }
1397
+
1398
+ // Returns true if a given variable represents an associative array
1399
+ /**
1400
+ * @access private
1401
+ */
1402
+ function is_associative_array($var) {
1403
+ return is_array($var) && !is_numeric(implode('', array_keys($var)));
1404
+ }
1405
+
1406
+ /**
1407
+ * @access private
1408
+ */
1409
+ function isChildOf($path='', $parents=array()){
1410
+ $intersect =array_intersect(explode('.',$path), $parents);
1411
+ return !empty($intersect);
1412
+ }
1413
+
1414
+ /**
1415
+ * Get the Google Checkout acceptance logos html
1416
+ *
1417
+ * {@link http://checkout.google.com/seller/acceptance_logos.html}
1418
+ *
1419
+ * @param integer $type the acceptance logo type, valid values: 1, 2, 3
1420
+ *
1421
+ * @return string the logo's html
1422
+ */
1423
+ function CheckoutAcceptanceLogo($type=1) {
1424
+ switch ($type) {
1425
+ case 2:
1426
+ return '<link rel="stylesheet" href="https://checkout.google.com/' .
1427
+ 'seller/accept/s.css" type="text/css" media="screen" /><scrip' .
1428
+ 't type="text/javascript" src="https://checkout.google.com/se' .
1429
+ 'ller/accept/j.js"></script><script type="text/javascript">sh' .
1430
+ 'owMark(1);</script><noscript><img src="https://checkout.goog' .
1431
+ 'le.com/seller/accept/images/st.gif" width="92" height="88" a' .
1432
+ 'lt="Google Checkout Acceptance Mark" /></noscript>';
1433
+ break;
1434
+ case 3:
1435
+ return '<link rel="stylesheet" href="https://checkout.google.com/' .
1436
+ 'seller/accept/s.css" type="text/css" media="screen" /><scrip' .
1437
+ 't type="text/javascript" src="https://checkout.google.com/se' .
1438
+ 'ller/accept/j.js"></script><script type="text/javascript">sh' .
1439
+ 'owMark(2);</script><noscript><img src="https://checkout.goog' .
1440
+ 'le.com/seller/accept/images/ht.gif" width="182" height="44" ' .
1441
+ 'alt="Google Checkout Acceptance Mark" /></noscript>';
1442
+ break;
1443
+ case 1:
1444
+ default:
1445
+ return '<link rel="stylesheet" href="https://checkout.google.com/' .
1446
+ 'seller/accept/s.css" type="text/css" media="screen" /><scrip' .
1447
+ 't type="text/javascript" src="https://checkout.google.com/se' .
1448
+ 'ller/accept/j.js"></script><script type="text/javascript">sh' .
1449
+ 'owMark(3);</script><noscript><img src="https://checkout.goog' .
1450
+ 'le.com/seller/accept/images/sc.gif" width="72" height="73" a' .
1451
+ 'lt="Google Checkout Acceptance Mark" /></noscript>';
1452
+ break;
1453
+ }
1454
+ }
1455
+
1456
+ /**
1457
+ * Calculates the cart's hmac-sha1 signature, this allows google to verify
1458
+ * that the cart hasn't been tampered by a third-party.
1459
+ *
1460
+ * {@link http://code.google.com/apis/checkout/developer/index.html#create_signature}
1461
+ *
1462
+ * @param string $data the cart's xml
1463
+ * @return string the cart's signature (in binary format)
1464
+ */
1465
+ function CalcHmacSha1($data) {
1466
+ $key = $this->merchant_key;
1467
+ $blocksize = 64;
1468
+ $hashfunc = 'sha1';
1469
+ if (strlen($key) > $blocksize) {
1470
+ $key = pack('H*', $hashfunc($key));
1471
+ }
1472
+ $key = str_pad($key, $blocksize, chr(0x00));
1473
+ $ipad = str_repeat(chr(0x36), $blocksize);
1474
+ $opad = str_repeat(chr(0x5c), $blocksize);
1475
+ $hmac = pack(
1476
+ 'H*', $hashfunc(
1477
+ ($key^$opad).pack(
1478
+ 'H*', $hashfunc(
1479
+ ($key^$ipad).$data
1480
+ )
1481
+ )
1482
+ )
1483
+ );
1484
+ return $hmac;
1485
+ }
1486
+
1487
+ //Method used internally to set true/false cart variables
1488
+ /**
1489
+ * @access private
1490
+ */
1491
+ function _GetBooleanValue($value, $default) {
1492
+ switch(strtolower($value)){
1493
+ case "true":
1494
+ return "true";
1495
+ break;
1496
+ case "false":
1497
+ return"false";
1498
+ break;
1499
+ default:
1500
+ return $default;
1501
+ break;
1502
+ }
1503
+ }
1504
+ //Method used internally to set true/false cart variables
1505
+ // Deprecated, must NOT use eval, bug-prune function
1506
+ /**
1507
+ * @access private
1508
+ */
1509
+ function _SetBooleanValue($string, $value, $default) {
1510
+ $value = strtolower($value);
1511
+ if($value == "true" || $value == "false")
1512
+ eval('$this->'.$string.'="'.$value.'";');
1513
+ else
1514
+ eval('$this->'.$string.'="'.$default.'";');
1515
+ }
1516
+ }
1517
+
1518
+ /**
1519
+ * @abstract
1520
+ * Abstract class that represents the merchant-private-data.
1521
+ *
1522
+ * See {@link MerchantPrivateData} and {@link MerchantPrivateItemData}
1523
+ *
1524
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_merchant-private-data <merchant-private-data>}
1525
+ */
1526
+ class MerchantPrivate {
1527
+ var $data;
1528
+ var $type = "Abstract";
1529
+ function MerchantPrivate() {
1530
+ }
1531
+
1532
+ function AddMerchantPrivateToXML(&$xml_data) {
1533
+ if(is_array($this->data)) {
1534
+ $xml_data->Push($this->type);
1535
+ $this->_recursiveAdd($xml_data, $this->data);
1536
+ $xml_data->Pop($this->type);
1537
+ }
1538
+ else {
1539
+ $xml_data->Element($this->type, (string)$this->data);
1540
+ }
1541
+ }
1542
+
1543
+ /**
1544
+ * @access private
1545
+ */
1546
+ function _recursiveAdd(&$xml_data, $data){
1547
+ foreach($data as $name => $value) {
1548
+ if(is_array($value)) {
1549
+ $xml_data->Push($name);
1550
+ $this->_recursiveAdd($xml_data, $name);
1551
+ $xml_data->Pop($name);
1552
+ }
1553
+ else {
1554
+ $xml_data->Element($name, (string)$value);
1555
+ }
1556
+ }
1557
+ }
1558
+ }
1559
+
1560
+ /**
1561
+ * Class that represents the merchant-private-data.
1562
+ *
1563
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_merchant-private-data <merchant-private-data>}
1564
+ */
1565
+ class MerchantPrivateData extends MerchantPrivate {
1566
+ /**
1567
+ * @param mixed $data a string with the data that will go in the
1568
+ * merchant-private-data tag or an array that will
1569
+ * be mapped to xml, formatted like (e.g.):
1570
+ * array('my-order-id' => 34234,
1571
+ * 'stuff' => array('registered' => 'yes',
1572
+ * 'category' => 'hip stuff'))
1573
+ * this will map to:
1574
+ * <my-order-id>
1575
+ * <stuff>
1576
+ * <registered>yes</registered>
1577
+ * <category>hip stuff</category>
1578
+ * </stuff>
1579
+ * </my-order-id>
1580
+ */
1581
+ function MerchantPrivateData($data = array()) {
1582
+ $this->data = $data;
1583
+ $this->type = 'merchant-private-data';
1584
+ }
1585
+ }
1586
+
1587
+ /**
1588
+ * Class that represents a merchant-private-item-data.
1589
+ *
1590
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_merchant-private-item-data <merchant-private-data>}
1591
+ */
1592
+ class MerchantPrivateItemData extends MerchantPrivate {
1593
+ /**
1594
+ * @param mixed $data a string with the data that will go in the
1595
+ * merchant-private-item-data tag or an array that will
1596
+ * be mapped to xml, formatted like:
1597
+ * array('my-item-id' => 34234,
1598
+ * 'stuff' => array('label' => 'cool',
1599
+ * 'category' => 'hip stuff'))
1600
+ * this will map to:
1601
+ * <my-item-id>
1602
+ * <stuff>
1603
+ * <label>cool</label>
1604
+ * <category>hip stuff</category>
1605
+ * </stuff>
1606
+ * </my-item-id>
1607
+ */
1608
+ function MerchantPrivateItemData($data = array()) {
1609
+ $this->data = $data;
1610
+ $this->type = 'merchant-private-item-data';
1611
+ }
1612
+ }
1613
+ ?>
lib/googlecheckout/googleitem.php ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ /**
19
+ * Classes used to represent an item to be used for Google Checkout
20
+ * @version $Id: googleitem.php 1234 2007-09-25 14:58:57Z ropu $
21
+ */
22
+
23
+ /**
24
+ * Creates an item to be added to the shopping cart.
25
+ * A new instance of the class must be created for each item to be added.
26
+ *
27
+ * Required fields are the item name, description, quantity and price
28
+ * The private-data and tax-selector for each item can be set in the
29
+ * constructor call or using individual Set functions
30
+ */
31
+ class GoogleItem {
32
+
33
+ var $item_name;
34
+ var $item_description;
35
+ var $unit_price;
36
+ var $quantity;
37
+ var $merchant_private_item_data;
38
+ var $merchant_item_id;
39
+ var $tax_table_selector;
40
+ var $email_delivery;
41
+ var $digital_content=false;
42
+ var $digital_description;
43
+ var $digital_key;
44
+ var $digital_url;
45
+
46
+ var $item_weight;
47
+ var $numeric_weight;
48
+
49
+ /**
50
+ * {@link http://code.google.com/apis/checkout/developer/index.html#tag_item <item>}
51
+ *
52
+ * @param string $name the name of the item -- required
53
+ * @param string $desc the description of the item -- required
54
+ * @param integer $qty the number of units of this item the customer has
55
+ * in its shopping cart -- required
56
+ * @param double $price the unit price of the item -- required
57
+ * @param string $item_weight the weight unit used to specify the item's
58
+ * weight,
59
+ * one of 'LB' (pounds) or 'KG' (kilograms)
60
+ * @param double $numeric_weight the weight of the item
61
+ *
62
+ */
63
+ function GoogleItem($name, $desc, $qty, $price, $item_weight='', $numeric_weight='') {
64
+ $this->item_name = $name;
65
+ $this->item_description= $desc;
66
+ $this->unit_price = $price;
67
+ $this->quantity = $qty;
68
+
69
+ if($item_weight != '' && $numeric_weight !== '') {
70
+ switch(strtoupper($item_weight)){
71
+ case 'KG':
72
+ $this->item_weight = strtoupper($item_weight);
73
+ break;
74
+ case 'LB':
75
+ default:
76
+ $this->item_weight = 'LB';
77
+ }
78
+ $this->numeric_weight = (double)$numeric_weight;
79
+ }
80
+ }
81
+
82
+ function SetMerchantPrivateItemData($private_data) {
83
+ $this->merchant_private_item_data = $private_data;
84
+ }
85
+
86
+ /**
87
+ * Set the merchant item id that the merchant uses to uniquely identify an
88
+ * item. Google Checkout will include this value in the
89
+ * merchant calculation callbacks
90
+ *
91
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_merchant-item-id <merchant-item-id>}
92
+ *
93
+ * @param mixed $item_id the value that identifies this item on the
94
+ * merchant's side
95
+ *
96
+ * @return void
97
+ */
98
+ function SetMerchantItemId($item_id) {
99
+ $this->merchant_item_id = $item_id;
100
+ }
101
+
102
+ /**
103
+ * Sets the tax table selector which identifies an alternate tax table that
104
+ * should be used to calculate tax for a particular item.
105
+ *
106
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_tax-table-selector <tax-table-selector>}
107
+ *
108
+ * @param string $tax_selector this value should correspond to the name
109
+ * of an alternate-tax-table.
110
+ *
111
+ * @return void
112
+ */
113
+ function SetTaxTableSelector($tax_selector) {
114
+ $this->tax_table_selector = $tax_selector;
115
+ }
116
+
117
+ /**
118
+ * Used when the item's content is digital, sets whether the merchant will
119
+ * send an email to the buyer explaining how to access the digital content.
120
+ * Email delivery allows the merchant to charge the buyer for an order
121
+ * before allowing the buyer to access the digital content.
122
+ *
123
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_email-delivery <email-delivery>}
124
+ *
125
+ * @param bool $email_delivery true if email_delivery applies, defaults to
126
+ * false
127
+ *
128
+ * @return void
129
+ */
130
+ function SetEmailDigitalDelivery($email_delivery='false') {
131
+ $this->digital_url = '';
132
+ $this->digital_key = '';
133
+ $this->digital_description = '';
134
+ $this->email_delivery = $email_delivery;
135
+ $this->digital_content=true;
136
+ }
137
+
138
+ /**
139
+ * Sets the information related to the digital delivery of the item.
140
+ *
141
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_digital-content <digital-content>}
142
+ *
143
+ * @param string $digital_url the url the customer must go to download the
144
+ * item. --optional
145
+ * @param string $digital_key the key which allows to download or unlock the
146
+ * digital content item -- optional
147
+ * @param string $digital_description instructions for downloading adigital
148
+ * content item, 1024 characters max, can
149
+ * contain xml-escaped HTML -- optional
150
+ *
151
+ * @return void
152
+ */
153
+ function SetURLDigitalContent($digital_url, $digital_key, $digital_description) {
154
+ $this->digital_url = $digital_url;
155
+ $this->digital_key = $digital_key;
156
+ $this->digital_description = $digital_description;
157
+ $this->email_delivery = 'false';
158
+ $this->digital_content = true;
159
+ }
160
+ }
161
+ ?>
lib/googlecheckout/googlelog.php ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ // Log levels
19
+ define("L_OFF", 0); // No log
20
+ define("L_ERR", 1); // Log Errors
21
+ define("L_RQST", 2); // Log Request from GC
22
+ define("L_RESP", 4); // Log Resoponse To Google
23
+ define("L_ERR_RQST", L_ERR | L_RQST);
24
+ define("L_ALL", L_ERR | L_RQST | L_RESP);
25
+
26
+ class GoogleLog {
27
+
28
+ var $errorLogFile;
29
+ var $messageLogFile;
30
+ // L_ALL (err+requests+responses), L_ERR, L_RQST, L_RESP, L_OFF
31
+ var $logLevel = L_ERR_RQST;
32
+
33
+ /**
34
+ * SetLogFiles
35
+ */
36
+ function GoogleLog($errorLogFile, $messageLogFile, $logLevel=L_ERR_RQST, $die=true){
37
+ $this->logLevel = $logLevel;
38
+ if($logLevel == L_OFF) {
39
+ $this->logLevel = L_OFF;
40
+ } else {
41
+ if (!$this->errorLogFile = @fopen($errorLogFile, "a")) {
42
+ header('HTTP/1.0 500 Internal Server Error');
43
+ $log = "Cannot open " . $errorLogFile . " file.\n" .
44
+ "Logs are not writable, set them to 777";
45
+ error_log($log, 0);
46
+ if($die) {
47
+ die($log);
48
+ }else {
49
+ echo $log;
50
+ $this->logLevel = L_OFF;
51
+ }
52
+ }
53
+ if (!$this->messageLogFile = @fopen($messageLogFile, "a")) {
54
+ fclose($this->errorLogFile);
55
+ header('HTTP/1.0 500 Internal Server Error');
56
+ $log = "Cannot open " . $messageLogFile . " file.\n" .
57
+ "Logs are not writable, set them to 777";
58
+ error_log($log, 0);
59
+ if($die) {
60
+ die($log);
61
+ }else {
62
+ echo $log;
63
+ $this->logLevel = L_OFF;
64
+ }
65
+ }
66
+ }
67
+ $this->logLevel = $logLevel;;
68
+ }
69
+
70
+ function LogError($log){
71
+ if($this->logLevel & L_ERR){
72
+ fwrite($this->errorLogFile,
73
+ sprintf("\n%s:- %s\n",date("D M j G:i:s T Y"),$log));
74
+ return true;
75
+ }
76
+ return false;
77
+ }
78
+
79
+ function LogRequest($log){
80
+ if($this->logLevel & L_RQST){
81
+ fwrite($this->messageLogFile,
82
+ sprintf("\n%s:- %s\n",date("D M j G:i:s T Y"),$log));
83
+ return true;
84
+ }
85
+ return false;
86
+ }
87
+
88
+ function LogResponse($log) {
89
+ if($this->logLevel & L_RESP){
90
+ $this->LogRequest($log);
91
+ return true;
92
+ }
93
+ return false;
94
+ }
95
+ }
96
+ ?>
lib/googlecheckout/googlemerchantcalculations.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Copyright (C) 2006 Google Inc.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ /**
20
+ * Used to create the merchant callback results when a
21
+ * merchant-calculated feedback structure is received.
22
+ *
23
+ * Multiple results are generated depending on the possible
24
+ * combinations for shipping options and address ids
25
+ *
26
+ * More info: {@link http://code.google.com/apis/checkout/developer/index.html#understanding_merchant_calculation_results}
27
+ */
28
+ // refer to demo/responsehandler.php for generating these results
29
+ class GoogleMerchantCalculations {
30
+ var $results_arr;
31
+ var $currency;
32
+ var $schema_url = "http://checkout.google.com/schema/2";
33
+
34
+ /**
35
+ * @param string $currency the currency used for the calculations,
36
+ * one of "USD" or "GBP"
37
+ *
38
+ * @return void
39
+ */
40
+ function GoogleMerchantCalculations($currency = "USD") {
41
+ $this->results_arr = array();
42
+ $this->currency = $currency;
43
+ }
44
+
45
+ /**
46
+ * Add a result of a merchant calculation to the response to be sent.
47
+ *
48
+ * @param GoogleResult $results the result of a particular merchant
49
+ * calculation
50
+ * @return void
51
+ */
52
+ function AddResult($results) {
53
+ $this->results_arr[] = $results;
54
+ }
55
+
56
+ /**
57
+ * Builds the merchant calculation response xml to be sent to
58
+ * Google Checkout.
59
+ *
60
+ * @return string the response xml
61
+ */
62
+ function GetXML() {
63
+ require_once('xml-processing/gc_xmlbuilder.php');
64
+
65
+ $xml_data = new gc_XmlBuilder();
66
+ $xml_data->Push('merchant-calculation-results',
67
+ array('xmlns' => $this->schema_url));
68
+ $xml_data->Push('results');
69
+
70
+ foreach($this->results_arr as $result) {
71
+ if($result->shipping_name != "") {
72
+ $xml_data->Push('result', array('shipping-name' =>
73
+ $result->shipping_name, 'address-id' => $result->address_id));
74
+ $xml_data->Element('shipping-rate', $result->ship_price,
75
+ array('currency' => $this->currency));
76
+ $xml_data->Element('shippable', $result->shippable);
77
+ } else
78
+ $xml_data->Push('result', array('address-id' => $result->address_id));
79
+
80
+ if($result->tax_amount != "") {
81
+ $xml_data->Element('total-tax', $result->tax_amount,
82
+ array('currency' => $this->currency));
83
+ } else {
84
+ $xml_data->Element('total-tax', 0,
85
+ array('currency' => $this->currency));
86
+ }
87
+
88
+ if((count($result->coupon_arr) != 0) ||
89
+ (count($result->giftcert_arr) != 0) ) {
90
+ $xml_data->Push('merchant-code-results');
91
+
92
+ foreach($result->coupon_arr as $curr_coupon) {
93
+ $xml_data->Push('coupon-result');
94
+ $xml_data->Element('valid', $curr_coupon->coupon_valid);
95
+ $xml_data->Element('code', $curr_coupon->coupon_code);
96
+ $xml_data->Element('calculated-amount', $curr_coupon->coupon_amount,
97
+ array('currency'=> $this->currency));
98
+ $xml_data->Element('message', $curr_coupon->coupon_message);
99
+ $xml_data->Pop('coupon-result');
100
+ }
101
+ foreach($result->giftcert_arr as $curr_gift) {
102
+ $xml_data->Push('gift-result');
103
+ $xml_data->Element('valid', $curr_gift->gift_valid);
104
+ $xml_data->Element('code', $curr_gift->gift_code);
105
+ $xml_data->Element('calculated-amount', $curr_gift->gift_amount,
106
+ array('currency'=> $this->currency));
107
+ $xml_data->Element('message', $curr_gift->gift_message);
108
+ $xml_data->Pop('gift-result');
109
+ }
110
+ $xml_data->Pop('merchant-code-results');
111
+ }
112
+ $xml_data->Pop('result');
113
+ }
114
+ $xml_data->Pop('results');
115
+ $xml_data->Pop('merchant-calculation-results');
116
+ return $xml_data->GetXML();
117
+ }
118
+ }
119
+ ?>
lib/googlecheckout/googlerequest.php ADDED
@@ -0,0 +1,769 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Copyright (C) 2007 Google Inc.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ *
18
+ *
19
+ */
20
+
21
+ /** This class is instantiated everytime any notification or
22
+ * order processing commands are received.
23
+ *
24
+ * @version $Id: googlerequest.php 1234 2007-09-25 14:58:57Z ropu $
25
+ * It has a SendReq function to post different requests to the Google Server
26
+ * Send functions are provided for most of the commands that are supported
27
+ * by the server for this code
28
+ */
29
+ define('PHP_SAMPLE_CODE_VERSION', 'v1.2.5');
30
+ define('ENTER', "\r\n");
31
+ define('DOUBLE_ENTER', ENTER.ENTER);
32
+ // Max size of the Google Messsage string
33
+ define('GOOGLE_MESSAGE_LENGTH', 254);
34
+ define('GOOGLE_REASON_LENGTH', 140);
35
+
36
+ /**
37
+ * Send requests to the Google Checkout server to perform different actions
38
+ */
39
+ // refer demo/responsehandlerdemo.php for different use case scenarios
40
+ class GoogleRequest {
41
+ var $merchant_id;
42
+ var $merchant_key;
43
+ var $currency;
44
+ var $server_url;
45
+ var $schema_url;
46
+ var $base_url;
47
+ var $checkout_url;
48
+ var $checkout_diagnose_url;
49
+ var $request_url;
50
+ var $request_diagnose_url;
51
+ var $merchant_checkout;
52
+ var $proxy = array();
53
+
54
+ var $certPath='';
55
+ var $log;
56
+
57
+ /**
58
+ * @param string $id the merchant id
59
+ * @param string $key the merchant key
60
+ * @param string $server_type the server type of the server to be used, one
61
+ * of 'sandbox' or 'production'.
62
+ * defaults to 'sandbox'
63
+ * @param string $currency the currency of the items to be added to the cart
64
+ * , as of now values can be 'USD' or 'GBP'.
65
+ * defaults to 'USD'
66
+ */
67
+ function GoogleRequest($id, $key, $server_type="sandbox", $currency="USD") {
68
+ $this->merchant_id = $id;
69
+ $this->merchant_key = $key;
70
+ $this->currency = $currency;
71
+
72
+ if(strtolower($server_type) == "sandbox") {
73
+ $this->server_url = "https://sandbox.google.com/checkout/";
74
+ } else {
75
+ $this->server_url = "https://checkout.google.com/";
76
+ }
77
+
78
+
79
+ $this->schema_url = "http://checkout.google.com/schema/2";
80
+ $this->base_url = $this->server_url . "api/checkout/v2/";
81
+ $this->request_url = $this->base_url . "request/Merchant/" . $this->merchant_id;
82
+ $this->merchant_checkout = $this->base_url . "merchantCheckout/Merchant/" . $this->merchant_id;
83
+
84
+ #ini_set('include_path', ini_get('include_path').PATH_SEPARATOR.'.');
85
+ require_once('googlelog.php');
86
+ $this->log = new GoogleLog('', '', L_OFF);
87
+
88
+ }
89
+
90
+ function SetLogFiles($errorLogFile, $messageLogFile, $logLevel=L_ERR_RQST) {
91
+ $this->log = new GoogleLog($errorLogFile, $messageLogFile, $logLevel);
92
+ }
93
+ /**
94
+ * Submit a SetCertificatePath request.
95
+ *
96
+ * GC Accepted SSL Certs:
97
+ * {@link http://googlecheckoutapi.blogspot.com/2007/07/accepting-50-additional-ssl-root-cas.html}
98
+ *
99
+ * @param string $certPath The name of a file holding one or more certificates
100
+ * to verify the peer with
101
+ */
102
+
103
+ function SetCertificatePath($certPath) {
104
+ $this->certPath = $certPath;
105
+ }
106
+
107
+ /**
108
+ * Submit a server-to-server request.
109
+ *
110
+ * more info:
111
+ * {@link http://code.google.com/apis/checkout/developer/index.html#alternate_technique}
112
+ *
113
+ * @param string $xml_cart the cart's xml
114
+ * @param bool $die whether to die() or not after performing the request,
115
+ * defaults to true
116
+ *
117
+ * @return array with the returned http status code (200 if OK) in index 0
118
+ * and the redirect url returned by the server in index 1
119
+ */
120
+ function SendServer2ServerCart($xml_cart, $die=true) {
121
+ list($status, $body) = $this->SendReq($this->merchant_checkout,
122
+ $this->GetAuthenticationHeaders(), $xml_cart);
123
+ if($status != 200 ){
124
+ return array($status, $body);
125
+ } else {
126
+ #ini_set('include_path', ini_get('include_path').PATH_SEPARATOR.'.');
127
+ require_once('xml-processing/gc_xmlparser.php');
128
+
129
+ $xml_parser = new gc_xmlparser($body);
130
+ $root = $xml_parser->GetRoot();
131
+ $data = $xml_parser->GetData();
132
+
133
+ $this->log->logRequest("Redirecting to: ".
134
+ $data[$root]['redirect-url']['VALUE']);
135
+ header('Location: ' . $data[$root]['redirect-url']['VALUE']);
136
+ if($die) {
137
+ die($data[$root]['redirect-url']['VALUE']);
138
+ }
139
+ else {
140
+ return array(200, $data[$root]['redirect-url']['VALUE']);
141
+ }
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Send a <charge-order> command to the Google Checkout server
147
+ *
148
+ * info: {@link http://code.google.com/apis/checkout/developer/index.html#charge_order_example}
149
+ *
150
+ * @param string $google_order the google id of the order
151
+ * @param double $amount the amount to be charged, if empty the whole
152
+ * amount of the order will be charged
153
+ *
154
+ * @return array the status code and body of the response
155
+ */
156
+ function SendChargeOrder($google_order, $amount='') {
157
+ $postargs = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
158
+ <charge-order xmlns=\"".$this->schema_url.
159
+ "\" google-order-number=\"". $google_order. "\">";
160
+ if ($amount != '') {
161
+ $postargs .= "<amount currency=\"" . $this->currency . "\">" .
162
+ $amount . "</amount>";
163
+ }
164
+ $postargs .= "</charge-order>";
165
+ return $this->SendReq($this->request_url,
166
+ $this->GetAuthenticationHeaders(), $postargs);
167
+ }
168
+
169
+ /**
170
+ * Send a <refund-order> command to the Google Checkout server
171
+ *
172
+ * info: {@link http://code.google.com/apis/checkout/developer/index.html#refund_order_example}
173
+ *
174
+ * @param string $google_order the google id of the order
175
+ * @param double $amount the amount to be refunded, if empty the whole
176
+ * amount of the order will be refunded
177
+ * @param string $reason the reason why the refund is taking place
178
+ * @param string $comment a comment about the refund
179
+ *
180
+ * @return array the status code and body of the response
181
+ */
182
+ function SendRefundOrder($google_order, $amount, $reason,
183
+ $comment='') {
184
+ $postargs = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
185
+ <refund-order xmlns=\"".$this->schema_url.
186
+ "\" google-order-number=\"". $google_order. "\">" .
187
+ "<reason>". $reason . "</reason>";
188
+ if($amount!=0) {
189
+ $postargs .= "<amount currency=\"" . $this->currency . "\">".
190
+ htmlentities($amount)."</amount>";
191
+ }
192
+ $postargs .= "<comment>". htmlentities($comment) . "</comment>
193
+ </refund-order>";
194
+ return $this->SendReq($this->request_url,
195
+ $this->GetAuthenticationHeaders(), $postargs);
196
+ }
197
+
198
+ /**
199
+ * Send a <cancel-order> command to the Google Checkout server
200
+ *
201
+ * info: {@link http://code.google.com/apis/checkout/developer/index.html#refund_order_example}
202
+ *
203
+ * @param string $google_order the google id of the order
204
+ * @param string $reason the reason why the order is being cancelled
205
+ * @param string $comment a comment about the cancellation
206
+ *
207
+ * @return array the status code and body of the response
208
+ */
209
+ function SendCancelOrder($google_order, $reason, $comment) {
210
+ $postargs = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
211
+ <cancel-order xmlns=\"".$this->schema_url.
212
+ "\" google-order-number=\"". $google_order. "\">
213
+ <reason>".
214
+ (substr(htmlentities(strip_tags($reason)),0,GOOGLE_REASON_LENGTH)) .
215
+ "</reason>
216
+ <comment>".
217
+ (substr(htmlentities(strip_tags($comment)),0,GOOGLE_REASON_LENGTH)) .
218
+ "</comment>
219
+ </cancel-order>";
220
+ return $this->SendReq($this->request_url,
221
+ $this->GetAuthenticationHeaders(), $postargs);
222
+ }
223
+
224
+ /**
225
+ * Send an <add-tracking-data> command to the Google Checkout server, which
226
+ * will associate a shipper's tracking number with an order.
227
+ *
228
+ * info: {@link http://code.google.com/apis/checkout/developer/index.html#add_tracking_data_example}
229
+ *
230
+ * @param string $google_order the google id of the order
231
+ * @param string $carrier the carrier, valid values are "DHL", "FedEx",
232
+ * "UPS", "USPS" and "Other"
233
+ * @param string $tracking_no the shipper's tracking number
234
+ *
235
+ * @return array the status code and body of the response
236
+ */
237
+ function SendTrackingData($google_order, $carrier,
238
+ $tracking_no) {
239
+ $postargs = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
240
+ <add-tracking-data xmlns=\"". $this->schema_url .
241
+ "\" google-order-number=\"". $google_order . "\">
242
+ <tracking-data>
243
+ <carrier>". htmlentities($carrier) . "</carrier>
244
+ <tracking-number>". $tracking_no . "</tracking-number>
245
+ </tracking-data>
246
+ </add-tracking-data>";
247
+ return $this->SendReq($this->request_url,
248
+ $this->GetAuthenticationHeaders(), $postargs);
249
+ }
250
+
251
+ /**
252
+ * Send an <add-merchant-order-number> command to the Google Checkout
253
+ * server, which will associate a merchant order number with an order
254
+ *
255
+ * info: {@link http://code.google.com/apis/checkout/developer/index.html#add_merchant_order_number_example}
256
+ *
257
+ * @param string $google_order the google id of the order
258
+ * @param string $merchant_order the merchant id of the order
259
+ *
260
+ * @return array the status code and body of the response
261
+ */
262
+ function SendMerchantOrderNumber($google_order,
263
+ $merchant_order, $timeout=false) {
264
+ $postargs = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
265
+ <add-merchant-order-number xmlns=\"". $this->schema_url .
266
+ "\" google-order-number=\"". $google_order . "\">
267
+ <merchant-order-number>" . $merchant_order .
268
+ "</merchant-order-number>
269
+ </add-merchant-order-number>";
270
+ return $this->SendReq($this->request_url,
271
+ $this->GetAuthenticationHeaders(), $postargs, $timeout);
272
+ }
273
+
274
+ /**
275
+ * Send a <send-buyer-message> command to the Google Checkout
276
+ * server, which will place a message in the customer's Google Checkout
277
+ * account
278
+ *
279
+ * info: {@link http://code.google.com/apis/checkout/developer/index.html#send_buyer_message_example}
280
+ *
281
+ * @param string $google_order the google id of the order
282
+ * @param string $message the message to be sent to the customer
283
+ * @param string $send_email whether Google should send an email to
284
+ * the buyer, use "true" or"false",
285
+ * defaults to "true"
286
+ *
287
+ * @return array the status code and body of the response
288
+ */
289
+ function SendBuyerMessage($google_order, $message,
290
+ $send_mail="true", $timeout=false) {
291
+ $postargs = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
292
+ <send-buyer-message xmlns=\"". $this->schema_url .
293
+ "\" google-order-number=\"". $google_order . "\">
294
+ <message>" .
295
+ (substr(htmlentities(strip_tags($message)),0,GOOGLE_MESSAGE_LENGTH))
296
+ . "</message>
297
+ <send-email>" . strtolower($send_mail) . "</send-email>
298
+ </send-buyer-message>";
299
+ return $this->SendReq($this->request_url,
300
+ $this->GetAuthenticationHeaders(), $postargs, $timeout);
301
+ }
302
+
303
+ /**
304
+ * Send a <process-order> command to the Google Checkout
305
+ * server, which will update an order's fulfillment state from NEW to
306
+ * PROCESSING
307
+ *
308
+ * info: {@link http://code.google.com/apis/checkout/developer/index.html#process_order_example}
309
+ *
310
+ * @param string $google_order the google id of the order
311
+ *
312
+ * @return array the status code and body of the response
313
+ */
314
+ function SendProcessOrder($google_order) {
315
+ $postargs = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
316
+ <process-order xmlns=\"".$this->schema_url .
317
+ "\" google-order-number=\"". $google_order. "\"/> ";
318
+ return $this->SendReq($this->request_url,
319
+ $this->GetAuthenticationHeaders(), $postargs);
320
+ }
321
+
322
+ /**
323
+ * Send a <deliver-order> command to the Google Checkout server, which
324
+ * will update an order's fulfillment state from either NEW or PROCESSING
325
+ * to DELIVERED
326
+ *
327
+ * info: {@link http://code.google.com/apis/checkout/developer/index.html#deliver_order_example}
328
+ *
329
+ * @param string $google_order the google id of the order
330
+ * @param string $carrier the carrier, valid values are "DHL", "FedEx",
331
+ * "UPS", "USPS" and "Other"
332
+ * @param string $tracking_no the shipper's tracking number
333
+ * @param string $send_email whether Google should send an email to
334
+ * the buyer, use "true" or"false",
335
+ * defaults to "true"
336
+ *
337
+ * @return array the status code and body of the response
338
+ */
339
+ function SendDeliverOrder($google_order, $carrier="",
340
+ $tracking_no="", $send_mail = "true") {
341
+ $postargs = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
342
+ <deliver-order xmlns=\"". $this->schema_url .
343
+ "\" google-order-number=\"". $google_order . "\">";
344
+ if($carrier != "" && $tracking_no != "") {
345
+ $postargs .= "<tracking-data>
346
+ <carrier>". htmlentities($carrier) . "</carrier>
347
+ <tracking-number>". htmlentities($tracking_no) . "</tracking-number>
348
+ </tracking-data>";
349
+ }
350
+ $postargs .= "<send-email>". strtolower($send_mail) . "</send-email>
351
+ </deliver-order>";
352
+ return $this->SendReq($this->request_url,
353
+ $this->GetAuthenticationHeaders(), $postargs);
354
+ }
355
+
356
+ /**
357
+ * Send a <archive-order> command to the Google Checkout
358
+ * server, which removes an order from the merchant's Merchant Center Inbox
359
+ *
360
+ * info: {@link http://code.google.com/apis/checkout/developer/index.html#archive_order_example}
361
+ *
362
+ * @param string $google_order the google id of the order
363
+ *
364
+ * @return array the status code and body of the response
365
+ */
366
+ function SendArchiveOrder($google_order) {
367
+ $postargs = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
368
+ <archive-order xmlns=\"".$this->schema_url.
369
+ "\" google-order-number=\"". $google_order. "\"/>";
370
+ return $this->SendReq($this->request_url,
371
+ $this->GetAuthenticationHeaders(), $postargs);
372
+ }
373
+
374
+ /**
375
+ * Send a <archive-order> command to the Google Checkout
376
+ * server, which returns a previously archived order to the merchant's
377
+ * Merchant Center Inbox
378
+ *
379
+ * info: {@link http://code.google.com/apis/checkout/developer/index.html#unarchive_order_example}
380
+ *
381
+ * @param string $google_order the google id of the order
382
+ *
383
+ * @return array the status code and body of the response
384
+ */
385
+ function SendUnarchiveOrder($google_order) {
386
+ $postargs = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
387
+ <unarchive-order xmlns=\"".
388
+ $this->schema_url."\" google-order-number=\"".
389
+ $google_order. "\"/>";
390
+ return $this->SendReq($this->request_url,
391
+ $this->GetAuthenticationHeaders(), $postargs);
392
+ }
393
+
394
+ /**
395
+ * Ship items API Commands
396
+ * info: {@link http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API_Line_Item_Shipping.html}
397
+ *
398
+ *
399
+ */
400
+
401
+ /**
402
+ * Send a <ship-items> command to the Google Checkout
403
+ * server,
404
+ *
405
+ * info: {@link http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API_Line_Item_Shipping.html#tag_ship-items}
406
+ *
407
+ * @param string $google_order the google id of the order
408
+ * @param array $items_list a list of GoogleShipItem classes.
409
+ * @param string $send_email whether Google should send an email to
410
+ * the buyer, use "true" or"false",
411
+ * defaults to "true"
412
+ *
413
+ * @return array the status code and body of the response
414
+ */
415
+
416
+ function SendShipItems($google_order, $items_list=array(), $send_mail="true") {
417
+ $postargs = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
418
+ <ship-items xmlns=\"". $this->schema_url .
419
+ "\" google-order-number=\"". $google_order . "\">" .
420
+ "<item-shipping-information-list>\n";
421
+ foreach($items_list as $item) {
422
+ $postargs .= "<item-shipping-information>
423
+ <item-id>
424
+ <merchant-item-id>" . $item->merchant_item_id . "</merchant-item-id>
425
+ </item-id>\n";
426
+
427
+ if(count($item->tracking_data_list)) {
428
+ $postargs .= "<tracking-data-list>\n";
429
+ foreach($item->tracking_data_list as $tracking_data) {
430
+ $postargs .= "<tracking-data>
431
+ <carrier>". htmlentities($tracking_data['carrier']) . "</carrier>
432
+ <tracking-number>". $tracking_data['tracking-number'] . "</tracking-number>
433
+ </tracking-data>\n";
434
+ }
435
+ $postargs .= "</tracking-data-list>\n";
436
+ }
437
+ $postargs .= "</item-shipping-information>\n";
438
+ }
439
+ $postargs .= "</item-shipping-information-list>\n" .
440
+ "<send-email>". strtolower($send_mail) . "</send-email>
441
+ </ship-items>";
442
+ return $this->SendReq($this->request_url,
443
+ $this->GetAuthenticationHeaders(), $postargs);
444
+
445
+ }
446
+
447
+ /**
448
+ * Send a <backorder-items> command to the Google Checkout
449
+ *
450
+ * info: {@link http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API_Line_Item_Shipping.html#tag_backorder-items}
451
+ *
452
+ * @param string $google_order the google id of the order
453
+ * @param array $items_list a list of GoogleShipItem classes.
454
+ * @param string $send_email whether Google should send an email to
455
+ * the buyer, use "true" or"false",
456
+ * defaults to "true"
457
+ *
458
+ * @return array the status code and body of the response
459
+ */
460
+ function SendBackorderItems($google_order, $items_list=array(), $send_mail="true") {
461
+ $postargs = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
462
+ <backorder-items xmlns=\"".
463
+ $this->schema_url."\" google-order-number=\"".
464
+ $google_order. "\">";
465
+ $postargs .= "<item-ids>";
466
+ foreach($items_list as $item) {
467
+ $postargs .= "<item-id>
468
+ <merchant-item-id>" . $item->merchant_item_id . "</merchant-item-id>
469
+ </item-id>";
470
+ }
471
+ $postargs .= "</item-ids>";
472
+ $postargs .= "<send-email>". strtolower($send_mail) . "</send-email>
473
+ </backorder-items>";
474
+ return $this->SendReq($this->request_url,
475
+ $this->GetAuthenticationHeaders(), $postargs);
476
+ }
477
+
478
+ /**
479
+ * Send a <cancel-items> command to the Google Checkout
480
+ *
481
+ * info: {@link http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API_Line_Item_Shipping.html#tag_cancel-items}
482
+ *
483
+ * @param string $google_order the google id of the order
484
+ * @param array $items_list a list of GoogleShipItem classes.
485
+ * @param string $reason the reason why the refund is taking place
486
+ * @param string $comment a comment about the refund
487
+ * @param string $send_email whether Google should send an email to
488
+ * the buyer, use "true" or"false",
489
+ * defaults to "true"
490
+ *
491
+ * @return array the status code and body of the response
492
+ */
493
+ function SendCancelItems($google_order, $items_list=array(), $reason,
494
+ $comment='', $send_mail="true") {
495
+ $postargs = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
496
+ <cancel-items xmlns=\"".
497
+ $this->schema_url."\" google-order-number=\"".
498
+ $google_order. "\">";
499
+ $postargs .= "<item-ids>";
500
+ foreach($items_list as $item) {
501
+ $postargs .= "<item-id>
502
+ <merchant-item-id>" . $item->merchant_item_id . "</merchant-item-id>
503
+ </item-id>";
504
+ }
505
+ $postargs .= "</item-ids>";
506
+ $postargs .= "<send-email>". strtolower($send_mail) . "</send-email>
507
+ <reason>".
508
+ (substr(htmlentities(strip_tags($reason)),0,GOOGLE_REASON_LENGTH)) .
509
+ "</reason>
510
+ <comment>".
511
+ (substr(htmlentities(strip_tags($comment)),0,GOOGLE_REASON_LENGTH)) .
512
+ "</comment>
513
+ </cancel-items>";
514
+ return $this->SendReq($this->request_url,
515
+ $this->GetAuthenticationHeaders(), $postargs);
516
+ }
517
+
518
+ /**
519
+ * Send a <return-items> command to the Google Checkout
520
+ *
521
+ * info: {@link http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API_Line_Item_Shipping.html#tag_return-items}
522
+ *
523
+ * @param string $google_order the google id of the order
524
+ * @param array $items_list a list of GoogleShipItem classes.
525
+ * @param string $send_email whether Google should send an email to
526
+ * the buyer, use "true" or"false",
527
+ * defaults to "true"
528
+ *
529
+ * @return array the status code and body of the response
530
+ */
531
+ function SendReturnItems($google_order, $items_list=array(), $send_mail="true") {
532
+ $postargs = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
533
+ <return-items xmlns=\"".
534
+ $this->schema_url."\" google-order-number=\"".
535
+ $google_order. "\">";
536
+ $postargs .= "<item-ids>";
537
+ foreach($items_list as $item) {
538
+ $postargs .= "<item-id>
539
+ <merchant-item-id>" . $item->merchant_item_id . "</merchant-item-id>
540
+ </item-id>";
541
+ }
542
+ $postargs .= "</item-ids>";
543
+ $postargs .= "<send-email>". strtolower($send_mail) . "</send-email>
544
+ </return-items>";
545
+ return $this->SendReq($this->request_url,
546
+ $this->GetAuthenticationHeaders(), $postargs);
547
+ }
548
+
549
+ /**
550
+ * Send a <reset-items-shipping-information> command to the Google Checkout
551
+ *
552
+ * info: {@link http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API_Line_Item_Shipping.html#tag_reset-items-shipping-information}
553
+ *
554
+ * @param string $google_order the google id of the order
555
+ * @param array $items_list a list of GoogleShipItem classes.
556
+ * @param string $send_email whether Google should send an email to
557
+ * the buyer, use "true" or"false",
558
+ * defaults to "true"
559
+ *
560
+ * @return array the status code and body of the response
561
+ */
562
+ function SendResetItemsShippingInformation($google_order, $items_list=array(), $send_mail="true") {
563
+ $postargs = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
564
+ <reset-items-shipping-information xmlns=\"".
565
+ $this->schema_url."\" google-order-number=\"".
566
+ $google_order. "\">";
567
+ $postargs .= "<item-ids>";
568
+ foreach($items_list as $item) {
569
+ $postargs .= "<item-id>
570
+ <merchant-item-id>" . $item->merchant_item_id . "</merchant-item-id>
571
+ </item-id>";
572
+ }
573
+ $postargs .= "</item-ids>";
574
+ $postargs .= "<send-email>". strtolower($send_mail) . "</send-email>
575
+ </reset-items-shipping-information>";
576
+ return $this->SendReq($this->request_url,
577
+ $this->GetAuthenticationHeaders(), $postargs);
578
+ }
579
+
580
+ /**
581
+ * @access private
582
+ */
583
+ function GetAuthenticationHeaders() {
584
+ $headers = array();
585
+ $headers[] = "Authorization: Basic ".base64_encode(
586
+ $this->merchant_id.':'.$this->merchant_key);
587
+ $headers[] = "Content-Type: application/xml; charset=UTF-8";
588
+ $headers[] = "Accept: application/xml; charset=UTF-8";
589
+ $headers[] = "User-Agent: GC-PHP-Sample_code (" . PHP_SAMPLE_CODE_VERSION . "/ropu)";
590
+ return $headers;
591
+ }
592
+ /**
593
+ * Set the proxy to be used by the connections to the outside
594
+ *
595
+ * @param array $proxy Array('host' => 'proxy-host', 'port' => 'proxy-port')
596
+ *
597
+ */
598
+ function SetProxy($proxy=array()) {
599
+ if(is_array($proxy) && count($proxy)) {
600
+ $this->proxy['host'] = $proxy['host'];
601
+ $this->proxy['port'] = $proxy['port'];
602
+ }
603
+ }
604
+
605
+ /**
606
+ * @access private
607
+ */
608
+ function SendReq($url, $header_arr, $postargs, $timeout=false) {
609
+ // Get the curl session object
610
+ $session = curl_init($url);
611
+ $this->log->LogRequest($postargs);
612
+
613
+ if (Mage::getStoreConfig('google/checkout/debug')) {
614
+ $debug = Mage::getModel('googlecheckout/api_debug');
615
+ $debug->setDir('out')->setUrl($url)->setRequestBody($postargs)->save();
616
+ }
617
+
618
+ // Set the POST options.
619
+ curl_setopt($session, CURLOPT_POST, true);
620
+ curl_setopt($session, CURLOPT_HTTPHEADER, $header_arr);
621
+ curl_setopt($session, CURLOPT_POSTFIELDS, $postargs);
622
+ curl_setopt($session, CURLOPT_HEADER, true);
623
+ curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
624
+
625
+ if(!empty($this->certPath) && file_exists($this->certPath)) {
626
+ curl_setopt($session, CURLOPT_SSL_VERIFYPEER, true);
627
+ curl_setopt($session, CURLOPT_CAINFO, $this->certPath);
628
+ }
629
+ else {
630
+ curl_setopt($session, CURLOPT_SSL_VERIFYPEER, false);
631
+ }
632
+
633
+ if(is_array($this->proxy) && count($this->proxy)) {
634
+ curl_setopt($session, CURLOPT_PROXY,
635
+ $this->proxy['host'] . ":" . $this->proxy['port']);
636
+ }
637
+ if($timeout != false){
638
+ curl_setopt($session, CURLOPT_TIMEOUT, $timeout);
639
+
640
+ }
641
+ // Do the POST and then close the session
642
+ $response = curl_exec($session);
643
+
644
+ if (!empty($debug)) {
645
+ $debug->setResponseBody($response)->save();
646
+ }
647
+
648
+ if (curl_errno($session)) {
649
+ $this->log->LogError(curl_error($session));
650
+ return array("CURL_ERR", curl_error($session));
651
+ } else {
652
+ curl_close($session);
653
+ }
654
+ $heads = $this->parse_headers($response);
655
+ $body = $this->get_body_x($response);
656
+
657
+ // // Get HTTP Status code from the response
658
+ $status_code = array();
659
+ preg_match('/\d\d\d/', $heads[0], $status_code);
660
+
661
+ // Check for errors
662
+ switch( $status_code[0] ) {
663
+ case 200:
664
+ // Success
665
+ $this->log->LogResponse($response);
666
+ return array(200, $body);
667
+ break;
668
+ case 503:
669
+ $this->log->LogError($response);
670
+ return array(503, htmlentities($body));
671
+ break;
672
+ case 403:
673
+ $this->log->LogError($response);
674
+ return array(403, htmlentities($body));
675
+ break;
676
+ case 400:
677
+ $this->log->LogError($response);
678
+ return array(400, htmlentities($body));
679
+ break;
680
+ default:
681
+ $this->log->LogError($response);
682
+ return array("ERR", htmlentities($body));
683
+ break;
684
+ }
685
+ }
686
+
687
+ // Private functions
688
+ // Function to get HTTP headers,
689
+ // will also work with HTTP 200 status added by some proxy servers
690
+ /**
691
+ * @access private
692
+ */
693
+ function parse_headers($message) {
694
+ $head_end = strpos($message, DOUBLE_ENTER);
695
+ $headers = $this->get_headers_x(substr($message,0,
696
+ $head_end + strlen(DOUBLE_ENTER)));
697
+ if(!is_array($headers) || empty($headers)){
698
+ return null;
699
+ }
700
+ if(!preg_match('%[HTTP/\d\.\d] (\d\d\d)%', $headers[0], $status_code)) {
701
+ return null;
702
+ }
703
+ switch( $status_code[1] ) {
704
+ case '200':
705
+ $parsed = $this->parse_headers(substr($message,
706
+ $head_end + strlen(DOUBLE_ENTER)));
707
+ return is_null($parsed)?$headers:$parsed;
708
+ break;
709
+ default:
710
+ return $headers;
711
+ break;
712
+ }
713
+ }
714
+
715
+ /**
716
+ * @access private
717
+ */
718
+ function get_headers_x($heads, $format=0) {
719
+ $fp = explode(ENTER, $heads);
720
+ foreach($fp as $header){
721
+ if($header == "") {
722
+ $eoheader = true;
723
+ break;
724
+ } else {
725
+ $header = trim($header);
726
+ }
727
+
728
+ if($format == 1) {
729
+ $key = array_shift(explode(':',$header));
730
+ if($key == $header) {
731
+ $headers[] = $header;
732
+ } else {
733
+ $headers[$key]=substr($header,strlen($key)+2);
734
+ }
735
+ unset($key);
736
+ } else {
737
+ $headers[] = $header;
738
+ }
739
+ }
740
+ return $headers;
741
+ }
742
+
743
+ /**
744
+ * @access private
745
+ */
746
+ function get_body_x($heads){
747
+ $fp = explode(DOUBLE_ENTER, $heads, 2);
748
+ return $fp[1];
749
+ }
750
+ }
751
+
752
+ class GoogleShipItem {
753
+ var $merchant_item_id;
754
+ var $tracking_data_list;
755
+ var $tracking_no;
756
+
757
+ function GoogleShipItem($merchant_item_id, $tracking_data_list=array()) {
758
+ $this->merchant_item_id = $merchant_item_id;
759
+ $this->tracking_data_list = $tracking_data_list;
760
+ }
761
+
762
+ function AddTrackingData($carrier, $tracking_no) {
763
+ if($carrier != "" && $tracking_no != "") {
764
+ $this->tracking_data_list[] = array('carrier' => $carrier,
765
+ 'tracking-number' => $tracking_no);
766
+ }
767
+ }
768
+ }
769
+ ?>
lib/googlecheckout/googleresponse.php ADDED
@@ -0,0 +1,240 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Copyright (C) 2007 Google Inc.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ /* This class is instantiated everytime any notification or
20
+ * order processing commands are received.
21
+ *
22
+ * Refer demo/responsehandlerdemo.php for different use case scenarios
23
+ * for this code
24
+ */
25
+
26
+
27
+ /**
28
+ * Handles the response to notifications sent by the Google Checkout server.
29
+ */
30
+ class GoogleResponse {
31
+ var $merchant_id;
32
+ var $merchant_key;
33
+ var $schema_url;
34
+ var $serial_number;
35
+
36
+ var $log;
37
+ var $response;
38
+ var $root='';
39
+ var $data=array();
40
+ var $xml_parser;
41
+
42
+ /**
43
+ * @param string $id the merchant id
44
+ * @param string $key the merchant key
45
+ */
46
+ function GoogleResponse($id=null, $key=null) {
47
+ $this->merchant_id = $id;
48
+ $this->merchant_key = $key;
49
+ $this->schema_url = "http://checkout.google.com/schema/2";
50
+ #ini_set('include_path', ini_get('include_path').PATH_SEPARATOR.'.');
51
+ require_once('googlelog.php');
52
+ $this->log = new GoogleLog('', '', L_OFF);
53
+ }
54
+
55
+ function setSerialNumber($num)
56
+ {
57
+ $this->serial_number = $num;
58
+ }
59
+
60
+ /**
61
+ * @param string $id the merchant id
62
+ * @param string $key the merchant key
63
+ */
64
+ function SetMerchantAuthentication($id, $key){
65
+ $this->merchant_id = $id;
66
+ $this->merchant_key = $key;
67
+ }
68
+
69
+ function SetLogFiles($errorLogFile, $messageLogFile, $logLevel=L_ERR_RQST) {
70
+ $this->log = new GoogleLog($errorLogFile, $messageLogFile, $logLevel);
71
+ }
72
+
73
+ /**
74
+ * Verifies that the authentication sent by Google Checkout matches the
75
+ * merchant id and key
76
+ *
77
+ * @param string $headers the headers from the request
78
+ */
79
+ function HttpAuthentication($headers=null, $die=true) {
80
+ if(!is_null($headers)) {
81
+ $_SERVER = $headers;
82
+ }
83
+ // moshe's fix for CGI
84
+ if (empty($_SERVER['HTTP_AUTHORIZATION'])) {
85
+ foreach ($_SERVER as $k=>$v) {
86
+ if (substr($k, -18)==='HTTP_AUTHORIZATION' && !empty($v)) {
87
+ $_SERVER['HTTP_AUTHORIZATION'] = $v;
88
+ break;
89
+ }
90
+ }
91
+ }
92
+
93
+ if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
94
+ $compare_mer_id = $_SERVER['PHP_AUTH_USER'];
95
+ $compare_mer_key = $_SERVER['PHP_AUTH_PW'];
96
+ }
97
+
98
+ // IIS Note:: For HTTP Authentication to work with IIS,
99
+ // the PHP directive cgi.rfc2616_headers must be set to 0 (the default value).
100
+ else if(isset($_SERVER['HTTP_AUTHORIZATION'])){
101
+ list($compare_mer_id, $compare_mer_key) = explode(':',
102
+ base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'],
103
+ strpos($_SERVER['HTTP_AUTHORIZATION'], " ") + 1)));
104
+ } else if(isset($_SERVER['Authorization'])) {
105
+ list($compare_mer_id, $compare_mer_key) = explode(':',
106
+ base64_decode(substr($_SERVER['Authorization'],
107
+ strpos($_SERVER['Authorization'], " ") + 1)));
108
+ } else {
109
+ $this->SendFailAuthenticationStatus(
110
+ "Failed to Get Basic Authentication Headers",$die);
111
+ return false;
112
+ }
113
+ if($compare_mer_id != $this->merchant_id
114
+ || $compare_mer_key != $this->merchant_key) {
115
+ $this->SendFailAuthenticationStatus("Invalid Merchant Id/Key Pair",$die);
116
+ return false;
117
+ }
118
+ return true;
119
+ }
120
+
121
+ function ProcessMerchantCalculations($merchant_calc) {
122
+ $this->SendOKStatus();
123
+ $result = $merchant_calc->GetXML();
124
+ echo $result;
125
+ }
126
+
127
+ // Notification API
128
+ function ProcessNewOrderNotification() {
129
+ $this->SendAck();
130
+ }
131
+ function ProcessRiskInformationNotification() {
132
+ $this->SendAck();
133
+ }
134
+ function ProcessOrderStateChangeNotification() {
135
+ $this->SendAck();
136
+ }
137
+ // Amount Notifications
138
+ function ProcessChargeAmountNotification() {
139
+ $this->SendAck();
140
+ }
141
+ function ProcessRefundAmountNotification() {
142
+ $this->SendAck();
143
+ }
144
+ function ProcessChargebackAmountNotification() {
145
+ $this->SendAck();
146
+ }
147
+ function ProcessAuthorizationAmountNotification() {
148
+ $this->SendAck();
149
+ }
150
+
151
+ function SendOKStatus() {
152
+ header('HTTP/1.0 200 OK');
153
+ }
154
+
155
+ /**
156
+ * Set the response header indicating an erroneous authentication from
157
+ * Google Checkout
158
+ *
159
+ * @param string $msg the message to log
160
+ */
161
+ function SendFailAuthenticationStatus($msg="401 Unauthorized Access",
162
+ $die=true) {
163
+ $this->log->logError($msg);
164
+ header('WWW-Authenticate: Basic realm="GoogleCheckout API Callback"');
165
+ header('HTTP/1.0 401 Unauthorized');
166
+ if($die) {
167
+ die($msg);
168
+ } else {
169
+ echo $msg;
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Set the response header indicating a malformed request from Google
175
+ * Checkout
176
+ *
177
+ * @param string $msg the message to log
178
+ */
179
+ function SendBadRequestStatus($msg="400 Bad Request", $die=true) {
180
+ $this->log->logError($msg);
181
+ header('HTTP/1.0 400 Bad Request');
182
+ if($die) {
183
+ die($msg);
184
+ } else {
185
+ echo $msg;
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Set the response header indicating that an internal error ocurred and
191
+ * the notification sent by Google Checkout can't be processed right now
192
+ *
193
+ * @param string $msg the message to log
194
+ */
195
+ function SendServerErrorStatus($msg="500 Internal Server Error",
196
+ $die=true) {
197
+ $this->log->logError($msg);
198
+ header('HTTP/1.0 500 Internal Server Error');
199
+ if($die) {
200
+ die($msg);
201
+ } else {
202
+ echo $msg;
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Send an acknowledgement in response to Google Checkout's request
208
+ */
209
+ function SendAck($die=false) {
210
+ $this->SendOKStatus();
211
+ $acknowledgment = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" .
212
+ "<notification-acknowledgment xmlns=\"" .
213
+ $this->schema_url . "\" serial-number=\"" .
214
+ $this->serial_number . "\"/>";
215
+ $this->log->LogResponse($acknowledgment);
216
+ if($die) {
217
+ die($acknowledgment);
218
+ } else {
219
+ echo $acknowledgment;
220
+ }
221
+ }
222
+
223
+ /**
224
+ * @access private
225
+ */
226
+ function GetParsedXML($request=null){
227
+ if(!is_null($request)) {
228
+ $this->log->LogRequest($request);
229
+ $this->response = $request;
230
+ #ini_set('include_path', ini_get('include_path').PATH_SEPARATOR.'.');
231
+ require_once('xml-processing/gc_xmlparser.php');
232
+
233
+ $this->xml_parser = new gc_xmlparser($request);
234
+ $this->root = $this->xml_parser->GetRoot();
235
+ $this->data = $this->xml_parser->GetData();
236
+ }
237
+ return array($this->root, $this->data);
238
+ }
239
+ }
240
+ ?>
lib/googlecheckout/googleresult.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Copyright (C) 2006 Google Inc.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ /**
20
+ * Used to create a Google Checkout result as a response to a
21
+ * merchant-calculations feedback structure, i.e shipping, tax, coupons and
22
+ * gift certificates.
23
+ *
24
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_result <result>}
25
+ */
26
+ // refer to demo/responsehandlerdemo.php for usage of this code
27
+ class GoogleResult {
28
+ var $shipping_name;
29
+ var $address_id;
30
+ var $shippable;
31
+ var $ship_price;
32
+
33
+ var $tax_amount;
34
+
35
+ var $coupon_arr = array();
36
+ var $giftcert_arr = array();
37
+
38
+ /**
39
+ * @param integer $address_id the id of the anonymous address sent by
40
+ * Google Checkout.
41
+ */
42
+ function GoogleResult($address_id) {
43
+ $this->address_id = $address_id;
44
+ }
45
+
46
+ function SetShippingDetails($name, $price, $shippable = "true") {
47
+ $this->shipping_name = $name;
48
+ $this->ship_price = $price;
49
+ $this->shippable = $shippable;
50
+ }
51
+
52
+ function SetTaxDetails($amount) {
53
+ $this->tax_amount = $amount;
54
+ }
55
+
56
+ function AddCoupons($coupon) {
57
+ $this->coupon_arr[] = $coupon;
58
+ }
59
+
60
+ function AddGiftCertificates($gift) {
61
+ $this->giftcert_arr[] = $gift;
62
+ }
63
+ }
64
+
65
+ /**
66
+ * This is a class used to return the results of coupons the buyer supplied in
67
+ * the order page.
68
+ *
69
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_coupon-result <coupon-result>}
70
+ */
71
+ class GoogleCoupons {
72
+ var $coupon_valid;
73
+ var $coupon_code;
74
+ var $coupon_amount;
75
+ var $coupon_message;
76
+
77
+ function googlecoupons($valid, $code, $amount, $message) {
78
+ $this->coupon_valid = $valid;
79
+ $this->coupon_code = $code;
80
+ $this->coupon_amount = $amount;
81
+ $this->coupon_message = $message;
82
+ }
83
+ }
84
+
85
+ /**
86
+ * This is a class used to return the results of gift certificates
87
+ * supplied by the buyer on the place order page
88
+ *
89
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_gift-certificate-result} <gift-certificate-result>
90
+ */
91
+
92
+ class GoogleGiftcerts {
93
+ var $gift_valid;
94
+ var $gift_code;
95
+ var $gift_amount;
96
+ var $gift_message;
97
+
98
+ function googlegiftcerts($valid, $code, $amount, $message) {
99
+ $this->gift_valid = $valid;
100
+ $this->gift_code = $code;
101
+ $this->gift_amount = $amount;
102
+ $this->gift_message = $message;
103
+ }
104
+ }
105
+ ?>
lib/googlecheckout/googleshipping.php ADDED
@@ -0,0 +1,532 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ /**
19
+ * Classes used to represent shipping types
20
+ * @version $Id: googleshipping.php 1234 2007-09-25 14:58:57Z ropu $
21
+ */
22
+
23
+ /**
24
+ * Class that represents flat rate shipping
25
+ *
26
+ * info:
27
+ * {@link http://code.google.com/apis/checkout/developer/index.html#tag_flat-rate-shipping}
28
+ * {@link http://code.google.com/apis/checkout/developer/index.html#shipping_xsd}
29
+ *
30
+ */
31
+ class GoogleFlatRateShipping {
32
+
33
+ var $price;
34
+ var $name;
35
+ var $type = "flat-rate-shipping";
36
+ var $shipping_restrictions;
37
+
38
+ /**
39
+ * @param string $name a name for the shipping
40
+ * @param double $price the price for this shipping
41
+ */
42
+ function GoogleFlatRateShipping($name, $price) {
43
+ $this->name = $name;
44
+ $this->price = $price;
45
+ }
46
+
47
+ /**
48
+ * Adds a restriction to this shipping.
49
+ *
50
+ * @param GoogleShippingFilters $restrictions the shipping restrictions
51
+ */
52
+ function AddShippingRestrictions($restrictions) {
53
+ $this->shipping_restrictions = $restrictions;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Represents a merchant calculated shipping
59
+ *
60
+ * info:
61
+ * {@link http://code.google.com/apis/checkout/developer/index.html#shipping_xsd}
62
+ * {@link http://code.google.com/apis/checkout/developer/index.html#merchant_calculations_specifying}
63
+ */
64
+ class GoogleMerchantCalculatedShipping {
65
+
66
+ var $price;
67
+ var $name;
68
+ var $type = "merchant-calculated-shipping";
69
+ var $shipping_restrictions;
70
+ var $address_filters;
71
+
72
+ /**
73
+ * @param string $name a name for the shipping
74
+ * @param double $price the default price for this shipping, used if the
75
+ * calculation can't be made for some reason.
76
+ */
77
+ function GoogleMerchantCalculatedShipping($name, $price) {
78
+ $this->price = $price;
79
+ $this->name = $name;
80
+ }
81
+
82
+ /**
83
+ * Adds a restriction to this shipping.
84
+ *
85
+ * @param GoogleShippingFilters $restrictions the shipping restrictions
86
+ */
87
+ function AddShippingRestrictions($restrictions) {
88
+ $this->shipping_restrictions = $restrictions;
89
+ }
90
+
91
+ /**
92
+ * Adds an address filter to this shipping.
93
+ *
94
+ * @param GoogleShippingFilters $filters the address filters
95
+ */
96
+ function AddAddressFilters($filters) {
97
+ $this->address_filters = $filters;
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Represents carrier calculated shipping
103
+ */
104
+ class GoogleCarrierCalculatedShipping {
105
+
106
+ var $name;
107
+ var $type = "carrier-calculated-shipping";
108
+
109
+ var $CarrierCalculatedShippingOptions = array();
110
+ // var $ShippingPackages = array();
111
+ var $ShippingPackage;
112
+
113
+ /**
114
+ * @param string $name the name of this shipping
115
+ */
116
+ function GoogleCarrierCalculatedShipping($name) {
117
+ $this->name = $name;
118
+ }
119
+
120
+ /**
121
+ * @param GoogleCarrierCalculatedShippingOption $option the option to be
122
+ * added to the carrier calculated shipping
123
+ */
124
+ function addCarrierCalculatedShippingOptions($option){
125
+ $this->CarrierCalculatedShippingOptions[] = $option;
126
+ }
127
+
128
+ /**
129
+ * @param GoogleShippingPackage $package
130
+ */
131
+ function addShippingPackage($package){
132
+ // $this->ShippingPackages[] = $package;
133
+ $this->ShippingPackage = $package;
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Represents a shipping method for which Google Checkout will obtain
139
+ * shipping costs for the order.
140
+ */
141
+ class GoogleCarrierCalculatedShippingOption {
142
+
143
+ var $price;
144
+ var $shipping_company;
145
+ var $shipping_type;
146
+ var $carrier_pickup;
147
+ var $additional_fixed_charge;
148
+ var $additional_variable_charge_percent;
149
+ // var $shipping_restrictions;
150
+ // var $address_filters;
151
+
152
+ /**
153
+ * @param double $price the default shipping cost to be used if Google is
154
+ * unable to obtain the shipping_company's shipping rate for
155
+ * the option
156
+ * @param string $shipping_company the name of the shipping_company
157
+ * @param string $shipping_type the shipping option, valid values are here:
158
+ * http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API_Carrier_Calculated_Shipping.html#tag_shipping-type
159
+ * @param double $additional_fixed_charge a handling charge that will be
160
+ * added to the total cost of the order if this shipping option is selected.
161
+ * defaults to 0
162
+ * @param double $additional_variable_charge_percent A percentage by which
163
+ * the shipping rate will be adjusted. The value may be positive or
164
+ * negative. defaults to 0.
165
+ * @param string $carrier_pickup Specifies how the package will be
166
+ * transfered from the merchand to the shipper. Valid values are
167
+ * "REGULAR_PICKUP", "SPECIAL_PICKUP", "DROP_OFF". Defaults to "DROP_OFF".
168
+ *
169
+ */
170
+ function GoogleCarrierCalculatedShippingOption($price, $shipping_company,
171
+ $shipping_type, $additional_fixed_charge=0,
172
+ $additional_variable_charge_percent=0, $carrier_pickup='DROP_OFF') {
173
+ $this->price = (double)$price;
174
+ $this->shipping_company = $shipping_company;
175
+ $this->shipping_type = trim($shipping_type);
176
+ switch(strtoupper($carrier_pickup)){
177
+ case 'DROP_OFF':
178
+ case 'REGULAR_PICKUP':
179
+ case 'SPECIAL_PICKUP':
180
+ $this->carrier_pickup = $carrier_pickup;;
181
+ break;
182
+ default:
183
+ $this->carrier_pickup = 'DROP_OFF';
184
+ }
185
+ if($additional_fixed_charge){
186
+ $this->additional_fixed_charge = (double)$additional_fixed_charge;
187
+ }
188
+ if($additional_variable_charge_percent){
189
+ $this->additional_variable_charge_percent = (double)$additional_variable_charge_percent;
190
+ }
191
+ }
192
+
193
+ // function AddShippingRestrictions($restrictions) {
194
+ // $this->shipping_restrictions = $restrictions;
195
+ // }
196
+ //
197
+ // function AddAddressFilters($filters) {
198
+ // $this->address_filters = $filters;
199
+ // }
200
+ }
201
+
202
+ /**
203
+ * Represents an individual package that will be shipped to the buyer.
204
+ */
205
+ class GoogleShippingPackage {
206
+
207
+ var $width;
208
+ var $length;
209
+ var $height;
210
+ var $unit;
211
+ var $ship_from;
212
+ var $delivery_address_category;
213
+
214
+ /**
215
+ * @param GoogleShipFrom $ship_from where the package ships from
216
+ * @param double $width the width of the package
217
+ * @param double $length the length of the package
218
+ * @param double $height the height of the package
219
+ * @param string $unit the unit used to measure the width/length/height
220
+ * of the package, valid values "IN", "CM"
221
+ * @param string $delivery_address_category indicates whether the shipping
222
+ * method should be applied to a residential or commercial address, valid
223
+ * values are "RESIDENTIAL", "COMMERCIAL"
224
+ */
225
+ function GoogleShippingPackage($ship_from, $width, $length, $height, $unit,
226
+ $delivery_address_category='RESIDENTIAL') {
227
+ $this->width = (double)$width;
228
+ $this->length = (double)$length;
229
+ $this->height = (double)$height;
230
+ switch(strtoupper($unit)){
231
+ case 'CM':
232
+ $this->unit = strtoupper($unit);
233
+ break;
234
+ case 'IN':
235
+ default:
236
+ $this->unit = 'IN';
237
+ }
238
+
239
+ $this->ship_from = $ship_from;
240
+ switch(strtoupper($delivery_address_category)){
241
+ case 'COMMERCIAL':
242
+ $this->delivery_address_category = strtoupper($delivery_address_category);
243
+ break;
244
+ case 'RESIDENTIAL':
245
+ default:
246
+ $this->delivery_address_category = 'RESIDENTIAL';
247
+ }
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Represents the location from where packages will be shipped from.
253
+ * Used with {@link GoogleShippingPackage}.
254
+ */
255
+ class GoogleShipFrom {
256
+ var $id;
257
+ var $city;
258
+ var $country_code;
259
+ var $postal_code;
260
+ var $region;
261
+
262
+ /**
263
+ * @param string $id an id for this address
264
+ * @param string $city the city
265
+ * @param string $country_code a 2-letter iso country code
266
+ * @param string $postal_code the zip
267
+ * @param string $region the region
268
+ */
269
+ function GoogleShipFrom($id, $city, $country_code,
270
+ $postal_code, $region) {
271
+ $this->id = $id;
272
+ $this->city = $city;
273
+ $this->country_code = $country_code;
274
+ $this->postal_code = $postal_code;
275
+ $this->region = $region;
276
+ }
277
+ }
278
+
279
+ /**
280
+ *
281
+ * Shipping restrictions contain information about particular areas where
282
+ * items can (or cannot) be shipped.
283
+ *
284
+ * More info:
285
+ * {@link http://code.google.com/apis/checkout/developer/index.html#tag_shipping-restrictions}
286
+ *
287
+ * Address filters identify areas where a particular merchant-calculated
288
+ * shipping method is available or unavailable. Address filters are applied
289
+ * before Google Checkout sends a <merchant-calculation-callback> to the
290
+ * merchant. Google Checkout will not ask you to calculate the cost of a
291
+ * particular shipping method for an address if the address filters in the
292
+ * Checkout API request indicate that the method is not available for the
293
+ * address.
294
+ *
295
+ * More info:
296
+ * {@link http://code.google.com/apis/checkout/developer/index.html#tag_address-filters}
297
+ */
298
+ class GoogleShippingFilters {
299
+
300
+ var $allow_us_po_box = true;
301
+
302
+ var $allowed_restrictions = false;
303
+ var $excluded_restrictions = false;
304
+
305
+ var $allowed_world_area = false;
306
+ var $allowed_country_codes_arr;
307
+ var $allowed_postal_patterns_arr;
308
+ var $allowed_country_area;
309
+ var $allowed_state_areas_arr;
310
+ var $allowed_zip_patterns_arr;
311
+
312
+ var $excluded_country_codes_arr;
313
+ var $excluded_postal_patterns_arr;
314
+ var $excluded_country_area;
315
+ var $excluded_state_areas_arr;
316
+ var $excluded_zip_patterns_arr;
317
+
318
+ function GoogleShippingFilters() {
319
+ $this->allowed_country_codes_arr = array();
320
+ $this->allowed_postal_patterns_arr = array();
321
+ $this->allowed_state_areas_arr = array();
322
+ $this->allowed_zip_patterns_arr = array();
323
+
324
+ $this->excluded_country_codes_arr = array();
325
+ $this->excluded_postal_patterns_arr = array();
326
+ $this->excluded_state_areas_arr = array();
327
+ $this->excluded_zip_patterns_arr = array();
328
+ }
329
+
330
+ /**
331
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_allow-us-po-box <allow-us-po-box>}
332
+ *
333
+ * @param bool $allow_us_po_box whether to allow delivery to PO boxes in US,
334
+ * defaults to true
335
+ */
336
+ function SetAllowUsPoBox($allow_us_po_box = true) {
337
+ $this->allow_us_po_box = $allow_us_po_box;
338
+ }
339
+
340
+ /**
341
+ * Set the world as allowed delivery area.
342
+ *
343
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_world-area <world-area>}
344
+ *
345
+ * @param bool $world_area Set worldwide allowed shipping, defaults to true
346
+ */
347
+ function SetAllowedWorldArea($world_area = true) {
348
+ $this->allowed_restrictions = true;
349
+ $this->allowed_world_area = $world_area;
350
+ }
351
+
352
+ // Allows
353
+ /**
354
+ * Add a postal area to be allowed for delivery.
355
+ *
356
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_postal-area <postal-area>}
357
+ *
358
+ * @param string $country_code 2-letter iso country code
359
+ * @param string $postal_pattern Pattern that matches the postal areas to
360
+ * be allowed, as defined in {@link http://code.google.com/apis/checkout/developer/index.html#tag_postal-code-pattern}
361
+ */
362
+ function AddAllowedPostalArea($country_code, $postal_pattern = "") {
363
+ $this->allowed_restrictions = true;
364
+ $this->allowed_country_codes_arr[] = $country_code;
365
+ $this->allowed_postal_patterns_arr[]= $postal_pattern;
366
+ }
367
+
368
+ /**
369
+ * Add a us country area to be allowed for delivery.
370
+ *
371
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_us-country-area <us-country-area>}
372
+ *
373
+ * @param string $country_area the area to allow, one of "CONTINENTAL",
374
+ * "FULL_50_STATES" or "ALL"
375
+ *
376
+ */
377
+ function SetAllowedCountryArea($country_area) {
378
+ switch ($country_area) {
379
+ case "CONTINENTAL_48":
380
+ case "FULL_50_STATES":
381
+ case "ALL":
382
+ $this->allowed_country_area = $country_area;
383
+ $this->allowed_restrictions = true;
384
+ break;
385
+ default:
386
+ $this->allowed_country_area = "";
387
+ break;
388
+ }
389
+ }
390
+
391
+ /**
392
+ * Allow shipping to areas specified by state.
393
+ *
394
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_us-state-area <us-state-area>}
395
+ *
396
+ * @param array $areas Areas to be allowed
397
+ */
398
+ function SetAllowedStateAreas($areas) {
399
+ $this->allowed_restrictions = true;
400
+ $this->allowed_state_areas_arr = $areas;
401
+ }
402
+
403
+ /**
404
+ * Allow shipping to areas specified by state.
405
+ *
406
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_us-state-area <us-state-area>}
407
+ *
408
+ * @param string $area Area to be allowed
409
+ */
410
+ function AddAllowedStateArea($area) {
411
+ $this->allowed_restrictions = true;
412
+ $this->allowed_state_areas_arr[] = $area;
413
+ }
414
+
415
+ /**
416
+ * Allow shipping to areas specified by zip patterns.
417
+ *
418
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_us-zip-area <us-zip-area>}
419
+ *
420
+ * @param array $zips
421
+ */
422
+ function SetAllowedZipPatterns($zips) {
423
+ $this->allowed_restrictions = true;
424
+ $this->allowed_zip_patterns_arr = $zips;
425
+ }
426
+
427
+ /**
428
+ * Allow shipping to area specified by zip pattern.
429
+ *
430
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_us-zip-area <us-zip-area>}
431
+ *
432
+ * @param string
433
+ */
434
+ function AddAllowedZipPattern($zip) {
435
+ $this->allowed_restrictions = true;
436
+ $this->allowed_zip_patterns_arr[] = $zip;
437
+ }
438
+
439
+ /**
440
+ * Exclude postal areas from shipping.
441
+ *
442
+ * @see AddAllowedPostalArea
443
+ */
444
+ function AddExcludedPostalArea($country_code, $postal_pattern = "") {
445
+ $this->excluded_restrictions = true;
446
+ $this->excluded_country_codes_arr[] = $country_code;
447
+ $this->excluded_postal_patterns_arr[]= $postal_pattern;
448
+ }
449
+
450
+ /**
451
+ * Exclude state areas from shipping.
452
+ *
453
+ * @see SetAllowedStateAreas
454
+ */
455
+ function SetExcludedStateAreas($areas) {
456
+ $this->excluded_restrictions = true;
457
+ $this->excluded_state_areas_arr = $areas;
458
+ }
459
+
460
+ /**
461
+ * Exclude state area from shipping.
462
+ *
463
+ * @see AddAllowedStateArea
464
+ */
465
+ function AddExcludedStateArea($area) {
466
+ $this->excluded_restrictions = true;
467
+ $this->excluded_state_areas_arr[] = $area;
468
+ }
469
+
470
+ /**
471
+ * Exclude shipping to area specified by zip pattern.
472
+ *
473
+ * @see SetAllowedZipPatterns
474
+ */
475
+ function SetExcludedZipPatternsStateAreas($zips) {
476
+ $this->excluded_restrictions = true;
477
+ $this->excluded_zip_patterns_arr = $zips;
478
+ }
479
+
480
+ /**
481
+ * Exclude shipping to area specified by zip pattern.
482
+ *
483
+ * @see AddExcludedZipPattern
484
+ */
485
+ function SetAllowedZipPatternsStateArea($zip) {
486
+ $this->excluded_restrictions = true;
487
+ $this->excluded_zip_patterns_arr[] = $zip;
488
+ }
489
+
490
+ /**
491
+ * Exclude shipping to country area
492
+ *
493
+ * @see SetAllowedCountryArea
494
+ */
495
+ function SetExcludedCountryArea($country_area) {
496
+ switch ($country_area) {
497
+ case "CONTINENTAL_48":
498
+ case "FULL_50_STATES":
499
+ case "ALL":
500
+ $this->excluded_country_area = $country_area;
501
+ $this->excluded_restrictions = true;
502
+ break;
503
+
504
+ default:
505
+ $this->excluded_country_area = "";
506
+ break;
507
+ }
508
+ }
509
+ }
510
+
511
+ /**
512
+ * Used as a shipping option in which neither a carrier nor a ship-to
513
+ * address is specified
514
+ *
515
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_pickup} <pickup>
516
+ */
517
+ class GooglePickUp {
518
+
519
+ var $price;
520
+ var $name;
521
+ var $type = "pickup";
522
+
523
+ /**
524
+ * @param string $name the name of this shipping option
525
+ * @param double $price the handling cost (if there is one)
526
+ */
527
+ function GooglePickUp($name, $price) {
528
+ $this->price = $price;
529
+ $this->name = $name;
530
+ }
531
+ }
532
+ ?>
lib/googlecheckout/googletax.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * Copyright (C) 2006 Google Inc.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ /**
20
+ * Classes used to handle tax rules and tables
21
+ */
22
+
23
+ /**
24
+ * Represents a tax rule
25
+ *
26
+ * @see GoogleDefaultTaxRule
27
+ * @see GoogleAlternateTaxRule
28
+ *
29
+ * @abstract
30
+ */
31
+ class GoogleTaxRule {
32
+
33
+ var $tax_rate;
34
+
35
+ var $world_area = false;
36
+ var $country_codes_arr;
37
+ var $postal_patterns_arr;
38
+ var $state_areas_arr;
39
+ var $zip_patterns_arr;
40
+ var $country_area;
41
+
42
+ function GoogleTaxRule() {
43
+ }
44
+
45
+ function SetWorldArea($world_area = true) {
46
+ $this->world_area = $world_area;
47
+ }
48
+
49
+ function AddPostalArea($country_code, $postal_pattern = "") {
50
+ $this->country_codes_arr[] = $country_code;
51
+ $this->postal_patterns_arr[]= $postal_pattern;
52
+ }
53
+
54
+ function SetStateAreas($areas) {
55
+ if(is_array($areas))
56
+ $this->state_areas_arr = $areas;
57
+ else
58
+ $this->state_areas_arr = array($areas);
59
+ }
60
+
61
+ function SetZipPatterns($zips) {
62
+ if(is_array($zips))
63
+ $this->zip_patterns_arr = $zips;
64
+ else
65
+ $this->zip_patterns_arr = array($zips);
66
+ }
67
+
68
+ function SetCountryArea($country_area) {
69
+ switch ($country_area) {
70
+ case "CONTINENTAL_48":
71
+ case "FULL_50_STATES":
72
+ case "ALL":
73
+ $this->country_area = $country_area;
74
+ break;
75
+ default:
76
+ $this->country_area = "";
77
+ break;
78
+ }
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Represents a default tax rule
84
+ *
85
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_default-tax-rule <default-tax-rule>}
86
+ */
87
+ class GoogleDefaultTaxRule extends GoogleTaxRule {
88
+
89
+ var $shipping_taxed = false;
90
+
91
+ function GoogleDefaultTaxRule($tax_rate, $shipping_taxed = "false") {
92
+ $this->tax_rate = $tax_rate;
93
+ $this->shipping_taxed= $shipping_taxed;
94
+
95
+ $this->country_codes_arr = array();
96
+ $this->postal_patterns_arr = array();
97
+ $this->state_areas_arr = array();
98
+ $this->zip_patterns_arr = array();
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Represents an alternate tax rule
104
+ *
105
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_alternate-tax-rule <alternate-tax-rule>}
106
+ */
107
+ class GoogleAlternateTaxRule extends GoogleTaxRule {
108
+
109
+ function GoogleAlternateTaxRule($tax_rate) {
110
+ $this->tax_rate = $tax_rate;
111
+
112
+ $this->country_codes_arr = array();
113
+ $this->postal_patterns_arr = array();
114
+ $this->state_areas_arr = array();
115
+ $this->zip_patterns_arr = array();
116
+ }
117
+
118
+ }
119
+
120
+
121
+ /**
122
+ * Represents an alternate tax table
123
+ *
124
+ * GC tag: {@link http://code.google.com/apis/checkout/developer/index.html#tag_alternate-tax-table <alternate-tax-table>}
125
+ */
126
+ class GoogleAlternateTaxTable {
127
+
128
+ var $name;
129
+ var $tax_rules_arr;
130
+ var $standalone;
131
+
132
+ function GoogleAlternateTaxTable($name = "", $standalone = "false") {
133
+ if($name != "") {
134
+ $this->name = $name;
135
+ $this->tax_rules_arr = array();
136
+ $this->standalone = $standalone;
137
+ }
138
+ }
139
+
140
+ function AddAlternateTaxRules($rules) {
141
+ $this->tax_rules_arr[] = $rules;
142
+ }
143
+ }
144
+
145
+
146
+ ?>
lib/googlecheckout/xml-processing/gc_xmlbuilder.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Copyright (C) 2006 Google Inc.
4
+
5
+ This program is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU General Public License
7
+ as published by the Free Software Foundation; either version 2
8
+ of the License, or (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
+ */
19
+
20
+ /**
21
+ * Classes used to generate XML data
22
+ * Based on sample code available at http://simon.incutio.com/code/php/XmlWriter.class.php.txt
23
+ */
24
+
25
+ /**
26
+ * Generates xml data
27
+ */
28
+ class gc_XmlBuilder {
29
+ var $xml;
30
+ var $indent;
31
+ var $stack = array();
32
+
33
+ function gc_XmlBuilder($indent = ' ') {
34
+ $this->indent = $indent;
35
+ $this->xml = '<?xml version="1.0" encoding="utf-8"?>'."\n";
36
+ }
37
+
38
+ function _indent() {
39
+ for ($i = 0, $j = count($this->stack); $i < $j; $i++) {
40
+ $this->xml .= $this->indent;
41
+ }
42
+ }
43
+
44
+ //Used when an element has sub-elements
45
+ // This function adds an open tag to the output
46
+ function Push($element, $attributes = array()) {
47
+ $this->_indent();
48
+ $this->xml .= '<'.$element;
49
+ foreach ($attributes as $key => $value) {
50
+ $this->xml .= ' '.$key.'="'.htmlentities($value).'"';
51
+ }
52
+ $this->xml .= ">\n";
53
+ $this->stack[] = $element;
54
+ }
55
+
56
+ //Used when an element has no subelements.
57
+ //Data within the open and close tags are provided with the
58
+ //contents variable
59
+ function Element($element, $content, $attributes = array()) {
60
+ $this->_indent();
61
+ $this->xml .= '<'.$element;
62
+ foreach ($attributes as $key => $value) {
63
+ $this->xml .= ' '.$key.'="'.htmlentities($value).'"';
64
+ }
65
+ $this->xml .= '>'.htmlentities($content).'</'.$element.'>'."\n";
66
+ }
67
+
68
+ function EmptyElement($element, $attributes = array()) {
69
+ $this->_indent();
70
+ $this->xml .= '<'.$element;
71
+ foreach ($attributes as $key => $value) {
72
+ $this->xml .= ' '.$key.'="'.htmlentities($value).'"';
73
+ }
74
+ $this->xml .= " />\n";
75
+ }
76
+
77
+ //Used to close an open tag
78
+ function Pop($pop_element) {
79
+ $element = array_pop($this->stack);
80
+ $this->_indent();
81
+ if($element !== $pop_element)
82
+ die('XML Error: Tag Mismatch when trying to close "'. $pop_element. '"');
83
+ else
84
+ $this->xml .= "</$element>\n";
85
+ }
86
+
87
+ function GetXML() {
88
+ if(count($this->stack) != 0)
89
+ die ('XML Error: No matching closing tag found for " '. array_pop($this->stack). '"');
90
+ else
91
+ return $this->xml;
92
+ }
93
+ }
94
+ ?>
lib/googlecheckout/xml-processing/gc_xmlparser.php ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Classes used to parse xml data
4
+ */
5
+ /*
6
+ Copyright (C) 2007 Google Inc.
7
+
8
+ This program is free software; you can redistribute it and/or
9
+ modify it under the terms of the GNU General Public License
10
+ as published by the Free Software Foundation; either version 2
11
+ of the License, or (at your option) any later version.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with this program; if not, write to the Free Software
20
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21
+
22
+ For more info: http://code.google.com/p/google-checkout-php-sample-code/
23
+
24
+ Upgrades (05/23/2007) ropu:
25
+ Remove UpdateRecursive()
26
+ Support for empty tags (like <world-area/>)
27
+ Accept multiple options in a second parameter
28
+ *
29
+ **/
30
+
31
+ /* This uses SAX parser to convert XML data into PHP associative arrays
32
+ * When invoking the constructor with the input data, strip out the first XML line
33
+ *
34
+ * Member field Description:
35
+ * $params: This stores the XML data. The attributes and contents of XML tags
36
+ * can be accessed as follows
37
+ *
38
+ * <addresses>
39
+ * <anonymous-address id="123"> <test>data 1 </test>
40
+ * </anonymous-address>
41
+ * <anonymous-address id="456"> <test>data 2 </test>
42
+ * </anonymous-address>
43
+ * </addresses>
44
+ *
45
+ * print_r($this->params) will return
46
+ Array
47
+ (
48
+ [addresses] => Array
49
+ (
50
+ [anonymous-address] => Array
51
+ (
52
+ [0] => Array
53
+ (
54
+ [id] => 123
55
+ [test] => Array
56
+ (
57
+ [VALUE] => data 1
58
+ )
59
+
60
+ )
61
+
62
+ [1] => Array
63
+ (
64
+ [id] => 456
65
+ [test] => Array
66
+ (
67
+ [VALUE] => data 2
68
+ )
69
+
70
+ )
71
+
72
+ )
73
+
74
+ )
75
+
76
+ )
77
+ * gc_xmlparser returns an empty params array if it encounters
78
+ * any error during parsing
79
+ */
80
+ // XML to Array
81
+ class gc_xmlparser {
82
+
83
+ var $params = array(); //Stores the object representation of XML data
84
+ var $root = NULL;
85
+ var $global_index = -1;
86
+ var $fold = false;
87
+
88
+ /* Constructor for the class
89
+ * Takes in XML data as input( do not include the <xml> tag
90
+ */
91
+ function gc_xmlparser($input, $xmlParams=array(XML_OPTION_CASE_FOLDING => 0)) {
92
+ $xmlp = xml_parser_create();
93
+ foreach($xmlParams as $opt => $optVal) {
94
+ switch( $opt ) {
95
+ case XML_OPTION_CASE_FOLDING:
96
+ $this->fold = $optVal;
97
+ break;
98
+ default:
99
+ break;
100
+ }
101
+ xml_parser_set_option($xmlp, $opt, $optVal);
102
+ }
103
+
104
+ if(xml_parse_into_struct($xmlp, $input, $vals, $index)) {
105
+ $this->root = $this->_foldCase($vals[0]['tag']);
106
+ $this->params = $this->xml2ary($vals);
107
+ }
108
+ xml_parser_free($xmlp);
109
+ }
110
+
111
+ function _foldCase($arg) {
112
+ return( $this->fold ? strtoupper($arg) : $arg);
113
+ }
114
+
115
+ /*
116
+ * Credits for the structure of this function
117
+ * http://mysrc.blogspot.com/2007/02/php-xml-to-array-and-backwards.html
118
+ *
119
+ * Adapted by Ropu - 05/23/2007
120
+ *
121
+ */
122
+ function xml2ary($vals) {
123
+
124
+ $mnary=array();
125
+ $ary=&$mnary;
126
+ foreach ($vals as $r) {
127
+ $t=$r['tag'];
128
+ if ($r['type']=='open') {
129
+ if (isset($ary[$t]) && !empty($ary[$t])) {
130
+ if (isset($ary[$t][0])){
131
+ $ary[$t][]=array();
132
+ }
133
+ else {
134
+ $ary[$t]=array($ary[$t], array());
135
+ }
136
+ $cv=&$ary[$t][count($ary[$t])-1];
137
+ }
138
+ else {
139
+ $cv=&$ary[$t];
140
+ }
141
+ $cv=array();
142
+ if (isset($r['attributes'])) {
143
+ foreach ($r['attributes'] as $k=>$v) {
144
+ $cv[$k]=$v;
145
+ }
146
+ }
147
+
148
+ $cv['_p']=&$ary;
149
+ $ary=&$cv;
150
+
151
+ } else if ($r['type']=='complete') {
152
+ if (isset($ary[$t]) && !empty($ary[$t])) { // same as open
153
+ if (isset($ary[$t][0])) {
154
+ $ary[$t][]=array();
155
+ }
156
+ else {
157
+ $ary[$t]=array($ary[$t], array());
158
+ }
159
+ $cv=&$ary[$t][count($ary[$t])-1];
160
+ }
161
+ else {
162
+ $cv=&$ary[$t];
163
+ }
164
+ if (isset($r['attributes'])) {
165
+ foreach ($r['attributes'] as $k=>$v) {
166
+ $cv[$k]=$v;
167
+ }
168
+ }
169
+ $cv['VALUE'] = (isset($r['value']) ? $r['value'] : '');
170
+
171
+ } elseif ($r['type']=='close') {
172
+ $ary=&$ary['_p'];
173
+ }
174
+ }
175
+
176
+ $this->_del_p($mnary);
177
+ return $mnary;
178
+ }
179
+
180
+ // _Internal: Remove recursion in result array
181
+ function _del_p(&$ary) {
182
+ foreach ($ary as $k=>$v) {
183
+ if ($k==='_p') {
184
+ unset($ary[$k]);
185
+ }
186
+ else if(is_array($ary[$k])) {
187
+ $this->_del_p($ary[$k]);
188
+ }
189
+ }
190
+ }
191
+
192
+ /* Returns the root of the XML data */
193
+ function GetRoot() {
194
+ return $this->root;
195
+ }
196
+
197
+ /* Returns the array representing the XML data */
198
+ function GetData() {
199
+ return $this->params;
200
+ }
201
+ }
202
+
203
+ /* In case the XML API contains multiple open tags
204
+ with the same value, then invoke this function and
205
+ perform a foreach on the resultant array.
206
+ This takes care of cases when there is only one unique tag
207
+ or multiple tags.
208
+ Examples of this are "anonymous-address", "merchant-code-string"
209
+ from the merchant-calculations-callback API
210
+ */
211
+ function get_arr_result($child_node) {
212
+ $result = array();
213
+ if(isset($child_node)) {
214
+ if(is_associative_array($child_node)) {
215
+ $result[] = $child_node;
216
+ }
217
+ else {
218
+ foreach($child_node as $curr_node){
219
+ $result[] = $curr_node;
220
+ }
221
+ }
222
+ }
223
+ return $result;
224
+ }
225
+
226
+ /* Returns true if a given variable represents an associative array */
227
+ function is_associative_array( $var ) {
228
+ return is_array( $var ) && !is_numeric( implode( '', array_keys( $var ) ) );
229
+ }
230
+ ?>
package.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Lib_Google_Checkout</name>
4
+ <version>1.1.1</version>
5
+ <stability>stable</stability>
6
+ <license>Apache License</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Google Checkout Library</summary>
10
+ <description>Google Checkout Library</description>
11
+ <notes>1.1.1</notes>
12
+ <authors><author><name>Magento Core Team</name><user>auto-converted</user><email>core@magentocommerce.com</email></author></authors>
13
+ <date>2008-07-24</date>
14
+ <time>22:29:31</time>
15
+ <contents><target name="magelib"><dir name="googlecheckout"><dir name="xml-processing"><file name="gc_xmlbuilder.php" hash="8b008a09d4ff42408fb601980f965dac"/><file name="gc_xmlparser.php" hash="9845e8a617eef46f0209140c9f26a90b"/></dir><file name="googlecart.php" hash="5b11319b8489cd2cb50bf2f38797fbb0"/><file name="googleitem.php" hash="2305b454c0b524f835e489a224070c1b"/><file name="googlelog.php" hash="402dfa7bf30450451d6dd76db20e8996"/><file name="googlemerchantcalculations.php" hash="2b8ca5d31c7dfc5f1b305ad0f0f8dc8d"/><file name="googlerequest.php" hash="2d9f2ffdb96c38f57772c151f517fe4c"/><file name="googleresponse.php" hash="4af0da6d2d9f461e9e072a81512a205e"/><file name="googleresult.php" hash="9643ea49bfeb16224f43a8ea79571094"/><file name="googleshipping.php" hash="ba2aa1ce3d1375b48a214fba19f589ff"/><file name="googletax.php" hash="55b8cd73340e491a47f62f8b887404ed"/></dir></target></contents>
16
+ <compatible/>
17
+ <dependencies><required><package><name>Mage_Pear_Helpers</name><channel>community</channel><min>1.0.18800</min><max></max></package></required></dependencies>
18
+ </package>