Package gchecky :: Module model
[hide private]
[frames] | no frames]

Source Code for Module gchecky.model

  1  """ 
  2  gchecky.model module describes the mapping between Google Checkout API (GC API) 
  3  XML messages (GC API XML Schema) and data classes. 
  4   
  5  This module uses L{gchecky.gxml} to automate much of the work so that 
  6  the actual logic is not cluttered with machinery. 
  7   
  8  The module code is simple and self-documenting. Please read the source code for 
  9  simple description of the data-structures. Note that it tries to follow exactly 
 10  the official GC API XML Schema. 
 11   
 12  All the comments for the GC API are at U{Google Chackout API documentation 
 13  <http://code.google.com/apis/checkout/developer/>}. Please consult it for any 
 14  questions about GC API functioning. 
 15   
 16  @author: etarassov 
 17  @version: $Revision: 91 $ 
 18  @contact: gchecky at gmail 
 19  """ 
 20   
 21  from gchecky import gxml 
 22  from gchecky.data import CountryCode, PresentOrNot 
 23   
24 -def test_document(doc, xml_text=None):
25 """ 26 Method used in doctests: ensures that a document is properly serialized. 27 """ 28 29 def normalize_xml(xml_text): 30 """ 31 Normalize the xml text to canonical form, so that two xml text chunks 32 could be compared directly as strings. 33 """ 34 # If xml misses header, then add it. 35 if len(xml_text) < 2 or xml_text[0:2] != "<?": 36 xml_text = "<?xml version='1.0' encoding='UTF-8'?>\n" + xml_text 37 from xml.dom.minidom import parseString 38 doc = parseString(xml_text) 39 40 text = doc.toprettyxml('') 41 # To avoid formatting problems we just strip all the line returns and 42 # spaces (while it breaks XML into a text string it still makes 43 # this form a 'canonical' one). 44 return text.replace('\n', '').replace(' ', '')
45 46 expected_xml = ((xml_text is not None) and normalize_xml(xml_text)) or None 47 obtained_xml = normalize_xml(doc.toxml(pretty=' ')) 48 49 if expected_xml is not None and expected_xml != obtained_xml: 50 print "Expected:\n\n%s\n\nGot:\n\n%s\n" % (xml_text, doc.toxml(' ')) 51 52 doc2 = gxml.Document.fromxml(doc.toxml()) 53 if not (doc == doc2): 54 print ''' 55 Failed to correctly interpret the generated XML for this document: 56 Original: 57 %s 58 Parsed: 59 %s 60 ''' % (doc.toxml(pretty=True), doc2.toxml()) 61
62 -def test_node(node, xml_text=None):
63 """ 64 Method used in doctests. Ensure that a node is properly serialized. 65 """ 66 class Dummy(gxml.Document): 67 tag_name='dummy' 68 data=gxml.Complex('node', node.__class__, required=True)
69 if xml_text is not None: 70 xml_text = xml_text.replace('<', ' <') 71 # TODO ...just ugly (below) 72 xml_text = "<dummy xmlns='http://checkout.google.com/schema/2'>%s</dummy>" % (xml_text,) 73 test_document(Dummy(data=node), xml_text) 74 75 CURRENCIES = ('USD', 'GBP') 76
77 -class price_t(gxml.Node):
78 value = gxml.Double('', default=0) 79 currency = gxml.String('@currency', values=CURRENCIES)
80 81 DISPLAY_DISPOSITION = ('OPTIMISTIC', 'PESSIMISTIC')
82 -class digital_content_t(gxml.Node):
83 description = gxml.Html('description', max_length=1024, required=False) 84 email_delivery = gxml.Boolean('email-delivery', required=False) 85 key = gxml.String('key', required=False) 86 url = gxml.String('url', required=False) 87 display_disposition = gxml.String('display-disposition', required=False, 88 values=DISPLAY_DISPOSITION)
89
90 -class item_t(gxml.Node):
91 """ 92 >>> test_node(item_t(name='Peter', description='The Great', unit_price=price_t(value=1, currency='GBP'), quantity=1, merchant_item_id='custom_merchant_item_id', 93 ... merchant_private_item_data=['some', {'private':'data', 'to':['test','the'],'thing':None}, '!! Numbers: ', None, False, True, [11, 12., [13.4]]]) 94 ... ) 95 >>> test_node(item_t(name='Peter', description='The Great', unit_price=price_t(value=1, currency='GBP'), quantity=1)) 96 """ 97 name = gxml.String('item-name') 98 description = gxml.String('item-description') 99 unit_price = gxml.Complex('unit-price', price_t) 100 quantity = gxml.Decimal('quantity') 101 merchant_item_id = gxml.String('merchant-item-id', required=False) 102 tax_table_selector = gxml.String('tax-table-selector', required=False) 103 digital_content = gxml.Complex('digital-content', digital_content_t, required=False) 104 merchant_private_item_data = gxml.Any('merchant-private-item-data', 105 save_node_and_xml=True, 106 required=False)
107
108 -class postal_area_t(gxml.Node):
109 """ 110 >>> test_node(postal_area_t(country_code = 'VU'), 111 ... ''' 112 ... <node><country-code>VU</country-code></node> 113 ... ''' 114 ... ) 115 """ 116 country_code = CountryCode('country-code') 117 postal_code_pattern = gxml.String('postal-code-pattern', required=False)
118
119 -class tax_area_t(gxml.Node):
120 world_area = PresentOrNot('world-area', required=False) 121 postal_area = gxml.Complex('postal-area', postal_area_t, required=False) 122 us_state = gxml.String('us-state-area/state', required=False) 123 us_zip_pattern = gxml.String('us-zip-area/zip-pattern', required=False) # regex: [a-zA-Z0-9_]+\*? Note the optional asterisk 124 us_country_area = gxml.String('us-country-area/country-area', values=('CONTINENTAL_48', 'FULL_50_STATES', 'ALL'), required=False) # enum('CONTINENTAL_48', 'FULL_50_STATES', 'ALL')
125
126 -class areas_t(gxml.Node):
127 """ 128 Represents a list of regions. 129 130 >>> test_node( 131 ... areas_t( 132 ... states = ['LA', 'NY'], 133 ... country_areas = ['ALL', 'CONTINENTAL_48'] 134 ... ) 135 ... , 136 ... ''' 137 ... <node> 138 ... <us-state-area> 139 ... <state>LA</state> 140 ... </us-state-area> 141 ... <us-state-area> 142 ... <state>NY</state> 143 ... </us-state-area> 144 ... <us-country-area> 145 ... <country-area>ALL</country-area> 146 ... </us-country-area> 147 ... <us-country-area> 148 ... <country-area>CONTINENTAL_48</country-area> 149 ... </us-country-area> 150 ... </node> 151 ... ''' 152 ... ) 153 """ 154 states = gxml.List('', gxml.String('us-state-area/state'), required=False) 155 zip_patterns = gxml.List('', gxml.String('us-zip-area/zip-pattern'), required=False) # regex: [a-zA-Z0-9_]+\*? Note the optional asterisk 156 country_areas = gxml.List('', gxml.String('us-country-area/country-area'), values=('CONTINENTAL_48', 'FULL_50_STATES', 'ALL'), required=False) # enum('CONTINENTAL_48', 'FULL_50_STATES', 'ALL')
157
158 -class allowed_areas_t(areas_t):
159 postal_areas = gxml.List('', gxml.Complex('postal-area', postal_area_t), required=False) 160 world_area = PresentOrNot('world-area', required=False)
161
162 -class excluded_areas_t(areas_t):
163 postal_areas = gxml.List('', gxml.Complex('postal-area', postal_area_t), required=False)
164
165 -class tax_rule_t(gxml.Node):
166 rate = gxml.Double('rate', default=0.) 167 tax_area = gxml.Complex('tax-area', tax_area_t)
168
169 -class default_tax_rule_t(tax_rule_t):
170 shipping_taxed = gxml.Boolean('shipping-taxed', required=False)
171
172 -class alternate_tax_rule_t(tax_rule_t):
173 pass
174
175 -class default_tax_table_t(gxml.Node):
176 tax_rules = gxml.List('tax-rules', gxml.Complex('default-tax-rule', default_tax_rule_t))
177
178 -class alternate_tax_table_t(gxml.Node):
179 name = gxml.String('@name') 180 standalone = gxml.Boolean('@standalone') 181 alternate_tax_rules = gxml.List('alternate-tax-rules', gxml.Complex('alternate-tax-rule', alternate_tax_rule_t))
182
183 -class tax_tables_t(gxml.Node):
184 merchant_calculated = gxml.Boolean('@merchant-calculated', default=False) 185 default = gxml.Complex('default-tax-table', default_tax_table_t) 186 alternates = gxml.List('alternate-tax-tables', gxml.Complex('alternate-tax-table', alternate_tax_table_t), required=False)
187
188 -class merchant_calculations_t(gxml.Node):
189 merchant_calculations_url = gxml.Url('merchant-calculations-url') 190 accept_merchant_coupons = gxml.Boolean('accept-merchant-coupons', required=False) 191 accept_gift_certificates = gxml.Boolean('accept-gift-certificates', required=False)
192
193 -class shipping_option_t(gxml.Node):
194 """ 195 Represents information about shipping costs. 196 197 >>> test_node( 198 ... shipping_option_t( 199 ... name = 'Testing', 200 ... price = price_t( 201 ... currency = 'GBP', 202 ... value = 9.99, 203 ... ), 204 ... allowed_areas = allowed_areas_t( 205 ... world_area = True, 206 ... ), 207 ... excluded_areas = excluded_areas_t( 208 ... postal_areas = [postal_area_t( 209 ... country_code = 'US', 210 ... )], 211 ... ), 212 ... ) 213 ... , ''' 214 ... <node name='Testing'> 215 ... <price currency='GBP'>9.990</price> 216 ... <shipping-restrictions> 217 ... <allowed-areas> 218 ... <world-area/> 219 ... </allowed-areas> 220 ... <excluded-areas> 221 ... <postal-area> 222 ... <country-code>US</country-code> 223 ... </postal-area> 224 ... </excluded-areas> 225 ... </shipping-restrictions> 226 ... </node> 227 ... ''') 228 """ 229 name = gxml.String('@name') # Attribute, len <= 255, not-empty 230 price = gxml.Complex('price', price_t) 231 allowed_areas = gxml.Complex('shipping-restrictions/allowed-areas', allowed_areas_t, required=False) 232 excluded_areas = gxml.Complex('shipping-restrictions/excluded-areas', excluded_areas_t, required=False)
233
234 -class flat_rate_shipping_t(shipping_option_t):
235 pass
236 -class merchant_calculated_shipping_t(shipping_option_t):
237 pass
238
239 -class pickup_t(gxml.Node):
240 name = gxml.String('@name') 241 price = gxml.Complex('price', price_t)
242
243 -class shipping_methods_t(gxml.Node):
244 flat_rate_shippings = gxml.List('', gxml.Complex('flat-rate-shipping', flat_rate_shipping_t), required=False) # list of flat_rate_shipping_t 245 merchant_calculated_shippings = gxml.List('', gxml.Complex('merchant-calculated-shipping', merchant_calculated_shipping_t), required=False) # list of merchant_calculated_shipping_t 246 pickups = gxml.List('', gxml.Complex('pickup', pickup_t), required=False) # list of pickup_t
247 248 URL_PARAMETER_TYPES=( 249 'buyer-id', # A Google-assigned value that uniquely identifies a customer email address. 250 'order-id', # A Google-assigned value that uniquely identifies an order. This value is displayed in the Merchant Center for each order. If you have implemented the Notification API, you will also see this value in all Google Checkout notifications. 251 'order-subtotal', # The total cost for all of the items in the order including coupons and discounts but excluding taxes and shipping charges. 252 'order-subtotal-plus-tax', # The total cost for all of the items in the order, including taxes, coupons and discounts, but excluding shipping charges. 253 'order-subtotal-plus-shipping', # The total cost for all of the items in the order, including shipping charges, coupons and discounts, but excluding taxes. 254 'order-total', # The total cost for all of the items in the order, including taxes, shipping charges, coupons and discounts. 255 'tax-amount', # The total amount of taxes charged for an order. 256 'shipping-amount', # The shipping cost associated with an order. 257 'coupon-amount', # The total amount of all coupons factored into the order total. 258 'billing-city', # The city associated with the order's billing address. 259 'billing-region', # The U.S. state associated with the order's billing address. 260 'billing-postal-code', # The five-digit U.S. zip code associated with the order's billing address. 261 'billing-country-code', # The two-letter ISO 3166 country code associated with the order's billing address. 262 'shipping-city', # The city associated with the order's shipping address. 263 'shipping-region', # The U.S. state associated with the order's shipping address. 264 'shipping-postal-code', # The five-digit U.S. zip code associated with the order's shipping address. 265 'shipping-country-code', # The two-letter ISO 3166 country code associated with the order's shipping address.', 266 ) 267
268 -class url_parameter_t(gxml.Node):
269 name = gxml.String('@name') 270 type = gxml.String('@type', values=URL_PARAMETER_TYPES)
271
272 -class parameterized_url_t(gxml.Node):
273 url = gxml.Url('@url', required=True) 274 parameters = gxml.List('parameters', gxml.Complex('url-parameter', url_parameter_t), required=True)
275
276 -class checkout_flow_support_t(gxml.Node):
277 """ 278 >>> test_node( 279 ... checkout_flow_support_t( 280 ... parameterized_urls = [ 281 ... parameterized_url_t( 282 ... url='http://google.com/', 283 ... parameters=[url_parameter_t(name='a', type='buyer-id')] 284 ... ), 285 ... parameterized_url_t( 286 ... url='http://yahoo.com/', 287 ... parameters=[url_parameter_t(name='a', type='shipping-city'), 288 ... url_parameter_t(name='b', type='tax-amount')] 289 ... ), 290 ... parameterized_url_t( 291 ... url='http://mozilla.com/', 292 ... parameters=[url_parameter_t(name='a', type='order-total'), 293 ... url_parameter_t(name='b', type='shipping-region'), 294 ... url_parameter_t(name='c', type='shipping-country-code')] 295 ... ) 296 ... ], 297 ... ) 298 ... , 299 ... ''' 300 ... <node> 301 ... <parameterized-urls> 302 ... <parameterized-url url="http://google.com/"> 303 ... <parameters> 304 ... <url-parameter name="a" type="buyer-id"/> 305 ... </parameters> 306 ... </parameterized-url> 307 ... <parameterized-url url="http://yahoo.com/"> 308 ... <parameters> 309 ... <url-parameter name="a" type="shipping-city"/> 310 ... <url-parameter name="b" type="tax-amount"/> 311 ... </parameters> 312 ... </parameterized-url> 313 ... <parameterized-url url="http://mozilla.com/"> 314 ... <parameters> 315 ... <url-parameter name="a" type="order-total"/> 316 ... <url-parameter name="b" type="shipping-region"/> 317 ... <url-parameter name="c" type="shipping-country-code"/> 318 ... </parameters> 319 ... </parameterized-url> 320 ... </parameterized-urls> 321 ... </node> 322 ... ''' 323 ... ) 324 """ 325 edit_cart_url = gxml.Url('edit-cart-url', required=False) # optional, URL 326 continue_shopping_url = gxml.Url('continue-shopping-url', required=False) # optional, URL 327 tax_tables = gxml.Complex('tax-tables', tax_tables_t, required=False) # optional, tax_tables_t 328 shipping_methods = gxml.Complex('shipping-methods', shipping_methods_t, required=False) # optional, shipping_methods_t 329 merchant_calculations = gxml.Complex('merchant-calculations', merchant_calculations_t, required=False) # optional, merchant_calculations_t 330 request_buyer_phone_number = gxml.Boolean('request-buyer-phone-number', required=False) # optional, Boolean 331 platform_id = gxml.Long('platform-id', required=False) 332 analytics_data = gxml.String('analytics-data', required=False) 333 parameterized_urls = gxml.List('parameterized-urls', gxml.Complex('parameterized-url', parameterized_url_t), required=False)
334
335 -class shopping_cart_t(gxml.Node):
336 expiration = gxml.Timestamp('cart-expiration/good-until-date', required=False) 337 items = gxml.List('items', gxml.Complex('item', item_t)) 338 merchant_private_data = gxml.Any('merchant-private-data', 339 save_node_and_xml=True, 340 required=False)
341
342 -class hello_t(gxml.Document):
343 """ 344 Represents a simple test that verifies that your server communicates 345 properly with Google Checkout. The fourth step of 346 the U{Getting Started with Google Checkout<http://code.google.com/apis/checkout/developer/index.html#integration_overview>} 347 section of the Developer's Guide explains how to execute this test. 348 349 >>> test_document(hello_t(), 350 ... "<hello xmlns='http://checkout.google.com/schema/2'/>" 351 ... ) 352 """ 353 tag_name='hello'
354
355 -class bye_t(gxml.Document):
356 """ 357 Represents a response that indicates that Google correctly received 358 a <hello> request. 359 360 >>> test_document( 361 ... bye_t(serial_number="7315dacf-3a2e-80d5-aa36-8345cb54c143") 362 ... , 363 ... ''' 364 ... <bye xmlns="http://checkout.google.com/schema/2" 365 ... serial-number="7315dacf-3a2e-80d5-aa36-8345cb54c143" /> 366 ... ''' 367 ... ) 368 """ 369 tag_name = 'bye' 370 serial_number = gxml.ID('@serial-number')
371
372 -class checkout_shopping_cart_t(gxml.Document):
373 tag_name = 'checkout-shopping-cart' 374 shopping_cart = gxml.Complex('shopping-cart', shopping_cart_t) 375 checkout_flow_support = gxml.Complex('checkout-flow-support/merchant-checkout-flow-support', checkout_flow_support_t) 376 request_initial_auth_details = gxml.Boolean('order-processing-support/request-initial-auth-details', required=False)
377
378 -class coupon_gift_adjustment_t(gxml.Node):
379 code = gxml.String('code') 380 calculated_amount = gxml.Complex('calculated-amount', price_t, required=False) 381 applied_amount = gxml.Complex('applied-amount', price_t) 382 message = gxml.String('message', required=False)
383
384 -class merchant_codes_t(gxml.Node):
385 gift_certificate_adjustment = gxml.List('', gxml.Complex('gift-certificate-adjustment', coupon_gift_adjustment_t)) 386 coupon_adjustment = gxml.List('', gxml.Complex('coupon-adjustment', coupon_gift_adjustment_t))
387
388 -class shipping_adjustment_t(gxml.Node):
389 shipping_name = gxml.String('shipping-name') 390 shipping_cost = gxml.Complex('shipping-cost', price_t)
391 392 # Two classes below represent the single 'shipping' tage, which content 393 # depends on the context the XML Node is present. 394 # http://code.google.com/apis/checkout/developer/index.html#tag_shipping
395 -class shipping_in_order_adjustment_t(gxml.Node):
396 merchant_calculated_shipping_adjustment = gxml.Complex('merchant-calculated-shipping-adjustment', shipping_adjustment_t, required=False) 397 flat_rate_shipping_adjustment = gxml.Complex('flat-rate-shipping-adjustment', shipping_adjustment_t, required=False) 398 pickup_shipping_adjustment = gxml.Complex('pickup-shipping-adjustment', shipping_adjustment_t, required=False)
399
400 -class shipping_in_calculate_t(gxml.Node):
401 methods = gxml.List('', gxml.String('method/@name'))
402
403 -class order_adjustment_t(gxml.Node):
404 adjustment_total = gxml.Complex('adjustment-total', price_t, required=False) 405 merchant_calculation_successful = gxml.Boolean('merchant-calculation-successful', required=False) 406 merchant_codes = gxml.Complex('merchant-codes', merchant_codes_t, required=False) 407 shipping = gxml.Complex('shipping', shipping_in_order_adjustment_t, required=False) 408 total_tax = gxml.Complex('total-tax', price_t, required=False)
409
410 -class address_t(gxml.Node):
411 address1 = gxml.String('address1') 412 address2 = gxml.String('address2', required=False) 413 city = gxml.String('city') 414 company_name = gxml.String('company-name', required=False) 415 contact_name = gxml.String('contact-name', required=False) 416 country_code = gxml.String('country-code') 417 email = gxml.Email('email', required=False) 418 fax = gxml.Phone('fax', required=False, empty=True) 419 phone = gxml.Phone('phone', required=False, empty=True) 420 postal_code = gxml.Zip('postal-code') 421 region = gxml.String('region', empty=True)
422
423 -class buyer_billing_address_t(address_t):
424 pass
425 -class buyer_shipping_address_t(address_t):
426 pass
427 -class billing_address_t(address_t):
428 # google docs do not say address_id is optional, but sandbox omits it.. :S bug? 429 address_id = gxml.ID('@address-id', required=False)
430
431 -class buyer_marketing_preferences_t(gxml.Node):
432 email_allowed = gxml.Boolean('email-allowed')
433 - def read(self, node):
434 return gxml.Node.read(self, node)
435 -class abstract_notification_t(gxml.Document):
436 tag_name = '-notification' 437 serial_number = gxml.ID('@serial-number') 438 google_order_number = gxml.ID('google-order-number') 439 timestamp = gxml.Timestamp('timestamp')
440 441 FINANCIAL_ORDER_STATE=('REVIEWING', 'CHARGEABLE', 'CHARGING', 'CHARGED', 'PAYMENT_DECLINED', 'CANCELLED', 'CANCELLED_BY_GOOGLE') 442 FULFILLMENT_ORDER_STATE=('NEW', 'PROCESSING', 'DELIVERED', 'WILL_NOT_DELIVER') 443
444 -class new_order_notification_t(abstract_notification_t):
445 tag_name = 'new-order-notification' 446 buyer_billing_address = gxml.Complex('buyer-billing-address', buyer_billing_address_t) 447 buyer_id = gxml.Long('buyer-id') 448 buyer_marketing_preferences = gxml.Complex('buyer-marketing-preferences', buyer_marketing_preferences_t) 449 buyer_shipping_address = gxml.Complex('buyer-shipping-address', buyer_shipping_address_t) 450 financial_order_state = gxml.String('financial-order-state', values=FINANCIAL_ORDER_STATE) 451 fulfillment_order_state = gxml.String('fulfillment-order-state', values=FULFILLMENT_ORDER_STATE) 452 order_adjustment = gxml.Complex('order-adjustment', order_adjustment_t) 453 order_total = gxml.Complex('order-total', price_t) 454 shopping_cart = gxml.Complex('shopping-cart', shopping_cart_t)
455
456 -class checkout_redirect_t(gxml.Document):
457 """ 458 Try doctests: 459 >>> a = checkout_redirect_t(serial_number='blabla12345', 460 ... redirect_url='http://www.somewhere.com') 461 >>> b = gxml.Document.fromxml(a.toxml()) 462 >>> a == b 463 True 464 """ 465 tag_name = 'checkout-redirect' 466 serial_number = gxml.ID('@serial-number') 467 redirect_url = gxml.Url('redirect-url')
468
469 -class notification_acknowledgment_t(gxml.Document):
470 tag_name = 'notification-acknowledgment'
471
472 -class order_state_change_notification_t(abstract_notification_t):
473 tag_name = 'order-state-change-notification' 474 new_fulfillment_order_state = gxml.String('new-fulfillment-order-state', values=FINANCIAL_ORDER_STATE) 475 new_financial_order_state = gxml.String('new-financial-order-state', values=FULFILLMENT_ORDER_STATE) 476 previous_financial_order_state = gxml.String('previous-financial-order-state', values=FINANCIAL_ORDER_STATE) 477 previous_fulfillment_order_state = gxml.String('previous-fulfillment-order-state', values=FULFILLMENT_ORDER_STATE) 478 reason = gxml.String('reason', required=False)
479 480 AVS_VALUES=('Y', 'P', 'A', 'N', 'U') 481 CVN_VALUES=('M', 'N', 'U', 'E') 482
483 -class risk_information_t(gxml.Node):
484 avs_response = gxml.String('avs-response', values=AVS_VALUES) 485 billing_address = gxml.Complex('billing-address', billing_address_t) 486 buyer_account_age = gxml.Integer('buyer-account-age') 487 cvn_response = gxml.String('cvn-response', values=CVN_VALUES) 488 eligible_for_protection = gxml.Boolean('eligible-for-protection') 489 ip_address = gxml.IP('ip-address') 490 partial_cc_number = gxml.String('partial-cc-number') # partial CC Number
491
492 -class risk_information_notification_t(abstract_notification_t):
493 tag_name = 'risk-information-notification' 494 risk_information = gxml.Complex('risk-information', risk_information_t)
495
496 -class abstract_order_t(gxml.Document):
497 tag_name='-order' 498 google_order_number = gxml.ID('@google-order-number')
499
500 -class charge_order_t(abstract_order_t):
501 tag_name = 'charge-order' 502 amount = gxml.Complex('amount', price_t, required=False)
503
504 -class refund_order_t(abstract_order_t):
505 tag_name = 'refund-order' 506 amount = gxml.Complex('amount', price_t, required=False) 507 comment = gxml.String('comment', max_length=140, required=False) 508 reason = gxml.String('reason', max_length=140)
509
510 -class cancel_order_t(abstract_order_t):
511 """ 512 Represents an order that should be canceled. A <cancel-order> command 513 sets the financial-order-state and the fulfillment-order-state to canceled. 514 515 >>> test_document( 516 ... cancel_order_t(google_order_number = "841171949013218", 517 ... comment = 'Buyer found a better deal.', 518 ... reason = 'Buyer cancelled the order.' 519 ... ) 520 ... , 521 ... ''' 522 ... <cancel-order xmlns="http://checkout.google.com/schema/2" google-order-number="841171949013218"> 523 ... <comment>Buyer found a better deal.</comment> 524 ... <reason>Buyer cancelled the order.</reason> 525 ... </cancel-order> 526 ... ''' 527 ... ) 528 """ 529 tag_name = 'cancel-order' 530 comment = gxml.String('comment', max_length=140, required=False) 531 reason = gxml.String('reason', max_length=140)
532
533 -class authorize_order_t(abstract_order_t):
534 tag_name = 'authorize-order'
535
536 -class process_order_t(abstract_order_t):
537 tag_name = 'process-order'
538
539 -class add_merchant_order_number_t(abstract_order_t):
540 tag_name = 'add-merchant-order-number' 541 merchant_order_number = gxml.String('merchant-order-number')
542 543 CARRIER_VALUES=('DHL', 'FedEx', 'UPS', 'USPS', 'Other') 544
545 -class tracking_data_t(gxml.Node):
546 carrier = gxml.String('carrier', values=CARRIER_VALUES) 547 tracking_number = gxml.String('tracking-number')
548
549 -class deliver_order_t(abstract_order_t):
550 tag_name='deliver-order' 551 tracking_data = gxml.Complex('tracking-data', tracking_data_t, required=False) 552 send_email = gxml.Boolean('send-email', required=False)
553
554 -class add_tracking_data_t(abstract_order_t):
555 """ 556 Represents a tag containing a request to add a shipper's tracking number 557 to an order. 558 559 >>> test_document( 560 ... add_tracking_data_t( 561 ... google_order_number = '841171949013218', 562 ... tracking_data = tracking_data_t( 563 ... carrier = 'UPS', 564 ... tracking_number = 'Z9842W69871281267' 565 ... ) 566 ... ) 567 ... , 568 ... ''' 569 ... <add-tracking-data xmlns="http://checkout.google.com/schema/2" 570 ... google-order-number="841171949013218"> 571 ... <tracking-data> 572 ... <tracking-number>Z9842W69871281267</tracking-number> 573 ... <carrier>UPS</carrier> 574 ... </tracking-data> 575 ... </add-tracking-data> 576 ... ''' 577 ... ) 578 """ 579 tag_name='add-tracking-data' 580 tracking_data = gxml.Complex('tracking-data', tracking_data_t)
581
582 -class send_buyer_message_t(abstract_order_t):
583 tag_name='send-buyer-message' 584 send_email = gxml.Boolean('send-email', required=False) 585 message = gxml.String('message')
586
587 -class archive_order_t(abstract_order_t):
588 """ 589 Represents a request to archive a particular order. You would archive 590 an order to remove it from your Merchant Center Inbox, indicating that 591 the order has been delivered. 592 593 >>> test_document(archive_order_t(google_order_number = '841171949013218'), 594 ... '''<archive-order xmlns="http://checkout.google.com/schema/2" 595 ... google-order-number="841171949013218" />''' 596 ... ) 597 """ 598 tag_name='archive-order'
599
600 -class unarchive_order_t(abstract_order_t):
601 tag_name='unarchive-order'
602
603 -class charge_amount_notification_t(abstract_notification_t):
604 """ 605 Represents information about a successful charge for an order. 606 607 >>> from datetime import datetime 608 >>> import iso8601 609 >>> test_document( 610 ... charge_amount_notification_t( 611 ... serial_number='95d44287-12b1-4722-bc56-cfaa73f4c0d1', 612 ... google_order_number = '841171949013218', 613 ... timestamp = iso8601.parse_date('2006-03-18T18:25:31.593Z'), 614 ... latest_charge_amount = price_t(currency='USD', value=2226.06), 615 ... total_charge_amount = price_t(currency='USD', value=2226.06) 616 ... ) 617 ... , 618 ... ''' 619 ... <charge-amount-notification xmlns="http://checkout.google.com/schema/2" serial-number="95d44287-12b1-4722-bc56-cfaa73f4c0d1"> 620 ... <latest-charge-amount currency="USD">2226.060</latest-charge-amount> 621 ... <google-order-number>841171949013218</google-order-number> 622 ... <total-charge-amount currency="USD">2226.060</total-charge-amount> 623 ... <timestamp>2006-03-18T18:25:31.593000+00:00</timestamp> 624 ... </charge-amount-notification> 625 ... ''' 626 ... ) 627 """ 628 tag_name='charge-amount-notification' 629 latest_charge_amount = gxml.Complex('latest-charge-amount', price_t) 630 total_charge_amount = gxml.Complex('total-charge-amount', price_t)
631
632 -class refund_amount_notification_t(abstract_notification_t):
633 tag_name='refund-amount-notification' 634 latest_refund_amount = gxml.Complex('latest-refund-amount', price_t) 635 total_refund_amount = gxml.Complex('total-refund-amount', price_t)
636
637 -class chargeback_amount_notification_t(abstract_notification_t):
638 tag_name='chargeback-amount-notification' 639 latest_chargeback_amount = gxml.Complex('latest-chargeback-amount', price_t) 640 total_chargeback_amount = gxml.Complex('total-chargeback-amount', price_t)
641
642 -class authorization_amount_notification_t(abstract_notification_t):
643 tag_name='authorization-amount-notification' 644 authorization_amount = gxml.Complex('authorization-amount', price_t) 645 authorization_expiration_date = gxml.Timestamp('authorization-expiration-date') 646 avs_response = gxml.String('avs-response', values=AVS_VALUES) 647 cvn_response = gxml.String('cvn-response', values=CVN_VALUES)
648
649 -class anonymous_address_t(gxml.Node):
650 id = gxml.String('@id') 651 city = gxml.String('city') 652 region = gxml.String('region', empty=True) 653 postal_code = gxml.Zip('postal-code') 654 country_code = gxml.String('country-code')
655
656 -class merchant_code_string_t(gxml.Node):
657 code = gxml.String('@code')
658
659 -class calculate_t(gxml.Node):
660 addresses = gxml.List('addresses', 661 gxml.Complex('anonymous-address', anonymous_address_t), 662 required=False) 663 merchant_code_strings = gxml.Complex('merchant-code-strings/merchant-code-string', 664 merchant_code_string_t, 665 required=False) 666 shipping = gxml.Complex('shipping', shipping_in_calculate_t, required=False) 667 tax = gxml.Boolean('tax')
668
669 -class merchant_calculation_callback_t(gxml.Document):
670 tag_name = 'merchant-calculation-callback' 671 serial_number = gxml.ID('@serial-number') 672 buyer_id = gxml.Long('buyer-id', required=False) 673 buyer_language = gxml.LanguageCode('buyer-language') 674 calculate = gxml.Complex('calculate', calculate_t) 675 shopping_cart = gxml.Complex('shopping-cart', shopping_cart_t)
676
677 -class discount_result_t(gxml.Node):
678 valid = gxml.Boolean('valid') 679 calculated_amount = gxml.Complex('calculated-amount', price_t) 680 code = gxml.String('code') 681 message = gxml.String('message', max_length=255)
682
683 -class merchant_code_results_t(gxml.Node):
684 coupon_result = gxml.List('', gxml.Complex('coupon-result', discount_result_t)) 685 gift_certificate_result = gxml.List('', gxml.Complex('gift-certificate-result', discount_result_t))
686
687 -class result_t(gxml.Node):
688 shipping_name = gxml.String('@shipping-name') 689 address_id = gxml.String('@address-id') 690 total_tax = gxml.Complex('total-tax', price_t, required=False) 691 shipping_rate = gxml.Complex('shipping-rate', price_t, required=False) 692 shippable = gxml.Boolean('shippable', required=False) 693 merchant_code_results = gxml.Complex('merchant-code-results', 694 merchant_code_results_t, 695 required=False)
696
697 -class merchant_calculation_results_t(gxml.Document):
698 tag_name = 'merchant-calculation-results' 699 results = gxml.List('results', gxml.Complex('result', result_t))
700
701 -class request_received_t(gxml.Document):
702 tag_name = 'request-received' 703 serial_number = gxml.ID('@serial-number')
704 705 # This is custom message type which is only suitable for returning to google 706 # the 'Ok' response.
707 -class ok_t(gxml.Document):
708 tag_name = 'ok'
709
710 -class error_t(gxml.Document):
711 """ 712 Represents a response containing information about an invalid API request. 713 The information is intended to help you debug the problem causing the error. 714 715 >>> test_document( 716 ... error_t(serial_number = '3c394432-8270-411b-9239-98c2c499f87f', 717 ... error_message='Bad username and/or password for API Access.', 718 ... warning_messages = ['IP address is suspicious.', 719 ... 'MAC address is shadowed.'] 720 ... ) 721 ... , 722 ... ''' 723 ... <error xmlns="http://checkout.google.com/schema/2" serial-number="3c394432-8270-411b-9239-98c2c499f87f"> 724 ... <error-message>Bad username and/or password for API Access.</error-message> 725 ... <warning-messages> 726 ... <string>IP address is suspicious.</string> 727 ... <string>MAC address is shadowed.</string> 728 ... </warning-messages> 729 ... </error> 730 ... ''' 731 ... ) 732 """ 733 tag_name = 'error' 734 serial_number = gxml.ID('@serial-number') 735 error_message = gxml.String('error-message') 736 warning_messages = gxml.List('warning-messages', 737 gxml.String('string'), 738 required=False)
739
740 -class diagnosis_t(gxml.Document):
741 """ 742 Represents a diagnostic response to an API request. The diagnostic 743 response contains the parsed XML in your request as well as any warnings 744 generated by your request. 745 Please see the U{Validating XML Messages to Google Checkout 746 <http://code.google.com/apis/checkout/developer/index.html#validating_xml_messages>} 747 section for more information about diagnostic requests and responses. 748 """ 749 tag_name = 'diagnosis' 750 input_xml = gxml.Any('input-xml') 751 warnings = gxml.List('warnings', 752 gxml.String('string'), 753 required=False)
754
755 -class demo_failure_t(gxml.Document):
756 """ 757 >>> test_document( 758 ... demo_failure_t(message='Demo Failure Message') 759 ... , 760 ... '''<demo-failure xmlns="http://checkout.google.com/schema/2" 761 ... message="Demo Failure Message" />''' 762 ... ) 763 """ 764 tag_name = 'demo-failure' 765 message = gxml.String('@message', max_length=25)
766 767 if __name__ == "__main__":
768 - def run_doctests():
769 import doctest 770 doctest.testmod()
771 run_doctests() 772