Package simplify
[hide private]
[frames] | no frames]

Source Code for Package simplify

   1   
   2  # 
   3  # Copyright (c) 2013, 2014 MasterCard International Incorporated 
   4  # All rights reserved. 
   5  #  
   6  # Redistribution and use in source and binary forms, with or without modification, are  
   7  # permitted provided that the following conditions are met: 
   8  #  
   9  # Redistributions of source code must retain the above copyright notice, this list of  
  10  # conditions and the following disclaimer. 
  11  # Redistributions in binary form must reproduce the above copyright notice, this list of  
  12  # conditions and the following disclaimer in the documentation and/or other materials  
  13  # provided with the distribution. 
  14  # Neither the name of the MasterCard International Incorporated nor the names of its  
  15  # contributors may be used to endorse or promote products derived from this software  
  16  # without specific prior written permission. 
  17  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY  
  18  # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  
  19  # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT  
  20  # SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,  
  21  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
  22  # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  
  23  # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER  
  24  # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING  
  25  # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  
  26  # SUCH DAMAGE. 
  27  # 
  28   
  29   
  30  from urllib2 import Request, urlopen, quote, URLError, HTTPError 
  31  import sys 
  32  import base64 
  33  import json 
  34  import hmac 
  35  import hashlib 
  36  import time 
  37  import random 
  38   
  39   
  40  from simplify.constants import Constants 
  41  from simplify.domain import DomainFactory, Domain 
  42   
  43  ################################################################################ 
  44  # Constants 
  45  ################################################################################ 
  46   
  47  HTTP_SUCCESS = 200 
  48  HTTP_REDIRECTED = 302 
  49  HTTP_UNAUTHORIZED = 401 
  50  HTTP_NOT_FOUND = 404 
  51  HTTP_NOT_ALLOWED = 405 
  52  HTTP_BAD_REQUEST = 400 
  53   
  54  HTTP_METHOD_POST = "POST" 
  55  HTTP_METHOD_PUT = "PUT" 
  56  HTTP_METHOD_GET = "GET" 
  57  HTTP_METHOD_DELETE = "DELETE" 
  58   
  59   
  60  ################################################################################ 
  61  # Global variables 
  62  ################################################################################ 
  63   
  64   
  65  public_key = None 
  66  private_key = None 
  67  api_base_sandbox_url = Constants.api_base_sandbox_url 
  68  api_base_live_url = Constants.api_base_live_url 
  69  oauth_base_url = Constants.oauth_base_url 
  70  user_agent = None 
71 72 73 ################################################################################ 74 # Utilities 75 ################################################################################ 76 77 -def build_query_string(criteria):
78 79 if criteria == None: 80 return '' 81 82 query_string = [] 83 if 'max' in criteria: 84 query_string.append("max=" + str(criteria['max'])) 85 86 if 'offset' in criteria: 87 query_string.append("offset=" + str(criteria['offset'])) 88 89 if 'sorting' in criteria: 90 for key, value in criteria['sorting'].iteritems(): 91 query_string.append("sorting[" + key + "]=" + quote(str(value))) 92 93 if 'filter' in criteria: 94 for key, value in criteria['filter'].iteritems(): 95 query_string.append("filter[" + key + "]=" + quote(str(value))) 96 97 return '&'.join(query_string)
98
99 -def handle_http_error(response_body, response_code):
100 101 if response_code == HTTP_REDIRECTED: # this shouldn't happen - if it does it's our problem 102 raise BadRequestError("Unexpected response code returned from the API, have you got the correct URL?", response_code, response_body) 103 elif response_code == HTTP_BAD_REQUEST: 104 raise BadRequestError("Bad request", response_code, response_body) 105 106 elif response_code == HTTP_UNAUTHORIZED: 107 raise AuthenticationError("You are not authorized to make this request. Are you using the correct API keys?", response_code, response_body) 108 109 elif response_code == HTTP_NOT_FOUND: 110 raise ObjectNotFoundError("Object not found", response_code, response_body) 111 112 elif response_code == HTTP_NOT_ALLOWED: 113 raise NotAllowedError("Operation not allowed", response_code, response_body) 114 115 elif response_code < 500: 116 raise BadRequestError("Bad request", response_code, response_body) 117 118 else: 119 raise SysError("An unexpected error has been raised. Looks like there's something wrong at our end." , response_code, response_body)
120
121 122 ################################################################################ 123 # Authentication 124 ################################################################################ 125 126 -class Authentication:
127 128 """ 129 Holds authentication information used when accessing the API. 130 131 @ivar public_key: Public key used to access the API. 132 @ivar private_key: Private key used to access the API. 133 @ivar access_token: OAuth token used to access the API. 134 """ 135
136 - def __init__(self, **kwargs):
137 """ 138 Constructs an Authentication object. 139 140 @param kwargs: contains initial values for the instance variables. Valid keywords 141 are public_key, private_key and access_token. If no value is passed for 142 public_key or its value is None then simplify.public_key is used. If no 143 value is passed for private_key or its value is None then simplify.private_key 144 is used. 145 @return: an Authentication object 146 """ 147 148 self.public_key = kwargs['public_key'] if 'public_key' in kwargs else None 149 if self.public_key == None: 150 global public_key 151 self.public_key = public_key 152 153 self.private_key = kwargs['private_key'] if 'private_key' in kwargs else None 154 if self.private_key == None: 155 global private_key 156 self.private_key = private_key 157 158 self.access_token = kwargs['access_token'] if 'access_token' in kwargs else None
159
160 161 -class AccessToken(Domain):
162 """ 163 OAuth access token. 164 165 @ivar access_token: Access token used when making an API call authenticated using OAuth 166 @ivar refresh_token: Token used when refreshing an access token. 167 @ivar expires_in: Number of seconds from the time the token was created till it expires. 168 """ 169 170 @staticmethod
171 - def create(auth_code, redirect_uri, *auth_args):
172 """ 173 Creates an AccessToken object. 174 175 @param auth_codes: OAuth authentication code. 176 @param redirect_uri: URI to which OAuth requests are redirected. 177 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 178 @return: an AccessToken object object 179 """ 180 181 props = { 182 'grant_type' : 'authorization_code', 183 'code' : auth_code, 184 'redirect_uri' : redirect_uri 185 } 186 187 h = PaymentsApi().send_auth_request(props, 'token', PaymentsApi.create_auth_object(auth_args)) 188 return AccessToken(h)
189 190
191 - def refresh(self, *auth_args):
192 """ 193 Refreshes an AccessToken object. If successful the access_token, refresh_token and expires_in attributes are updated. 194 195 @param auth_args: an Authentication object used for the API call. If no value is passed the global keys simplify.public_key and simplify.private_key are used. 196 """ 197 198 rt = self['refresh_token'] 199 if not rt: 200 raise IllegalArgumentError("Cannot refresh access token; refresh token is invalid.") 201 202 props = { 203 'grant_type' : 'refresh_token', 204 'refresh_token' : rt 205 } 206 207 h = PaymentsApi().send_auth_request(props, 'token', PaymentsApi.create_auth_object(auth_args)) 208 self.__dict__.update(h)
209 210
211 - def revoke(self, *auth_args):
212 """ 213 Revokes an AccessToken object. 214 215 @param auth_args: an Authentication object used for the API call. If no value is passed the global keys simplify.public_key and simplify.private_key are used. 216 """ 217 218 token = self['access_token'] 219 if not token: 220 raise IllegalArgumentError("Cannot revoke access token; access token is invalid.") 221 222 props = { 223 'token' : token, 224 'refresh_token' : token 225 } 226 227 h = PaymentsApi().send_auth_request(props, 'revoke', PaymentsApi.create_auth_object(auth_args)) 228 self.__dict__.clear()
229
230 231 ################################################################################ 232 # Exceptions 233 ################################################################################ 234 235 236 -class ApiError(Exception):
237 """ 238 Base class for all API errors. 239 240 @ivar status: HTTP status code (or None if there is no status). 241 @ivar reference: reference for the error (or None if there is no reference). 242 @ivar error_code: string code for the error (or None if there is no error code). 243 @ivar message: string description of the error (or None if there is no message). 244 @ivar error_data: dictionary containing all the error data (or None if there is no data) 245 """ 246
247 - def __init__(self, message=None, status=500, error_data=None):
248 self.status = status 249 250 self.error_data = json.loads(error_data) if error_data else {} 251 err = self.error_data['error'] if 'error' in self.error_data else {} 252 253 self.reference = self.error_data['reference'] if 'reference' in self.error_data else None 254 self.error_code = err['code'] if 'code' in err else None 255 self.message = err['message'] if 'code' in err else message 256 super(ApiError, self).__init__(self.message)
257 258
259 - def describe(self):
260 """ 261 Returns a string describing the error. 262 @return: a string describing the error. 263 """ 264 return "{0}: \"{1}\" (status: {2}, error code: {3}, reference: {4})".format(self.__class__.__name__, self.message, self.status, self.error_code, self.reference)
265
266 267 -class IllegalArgumentError(ValueError):
268 """ 269 Error raised when passing illegal arguments. 270 """ 271 pass
272
273 -class ApiConnectionError(ApiError):
274 """ 275 Error raised when there are communication errors contacting the API. 276 """ 277 pass
278
279 -class AuthenticationError(ApiError):
280 """ 281 Error raised where there are problems authentication a request. 282 """ 283 pass
284
285 -class BadRequestError(ApiError):
286 287 """ 288 Error raised when the request contains errors. 289 290 @ivar has_field_errors: boolean indicating whether there are field errors. 291 @ivar field_errors: a list containing all field errors. 292 """ 293
294 - class FieldError:
295 """ 296 Represents a single error in a field of data sent in a request to the API. 297 298 @ivar field_name: the name of the field with the error. 299 @ivar error_code: a string code for the error. 300 @ivar message: a string description of the error. 301 """
302 - def __init__(self, error_data):
303 self.field_name = error_data['field'] 304 self.error_code = error_data['code'] 305 self.message = error_data['message']
306
307 - def __str__(self):
308 return "Field error: {0} \"{1}\" ({2})".format(self.field_name, self.message, self.error_code)
309 310
311 - def __init__(self, message, status = 400, error_data = None):
312 super(BadRequestError, self).__init__(message, status, error_data) 313 314 self.field_errors = [] 315 err = self.error_data['error'] if 'error' in self.error_data else {} 316 field_errors = err['fieldErrors'] if 'fieldErrors' in err else [] 317 for field_error in field_errors: 318 self.field_errors.append(BadRequestError.FieldError(field_error)) 319 self.has_field_errors = len(self.field_errors) > 0
320
321 - def describe(self):
322 """ 323 Returns a string describing the error. 324 @return: a string describing the error. 325 """ 326 txt = ApiError.describe(self) 327 for field_error in self.field_errors: 328 txt = txt + "\n" + str(field_error) 329 return txt + "\n"
330
331 -class ObjectNotFoundError(ApiError):
332 """ 333 Error raised when a requested object cannot be found. 334 """ 335 pass
336
337 -class NotAllowedError(ApiError):
338 """ 339 Error raised when a request was not allowed. 340 """ 341 pass
342
343 -class SysError(ApiError):
344 """ 345 Error raised when there was a system error processing a request. 346 """ 347 pass
348
349 350 ################################################################################ 351 # Http - handles the HTTP requests 352 ################################################################################ 353 354 -class Http:
355 - def __init__(self):
356 pass
357
358 - def request(self, auth, url, method, params = None):
359 360 if params is None: 361 params = {} 362 363 jws_signature = Jws.encode(url, auth, params, method == HTTP_METHOD_POST or method == HTTP_METHOD_PUT) 364 365 if method == HTTP_METHOD_POST: 366 request = Request(url, jws_signature) 367 request.add_header("Content-Type", "application/json") 368 369 elif method == HTTP_METHOD_PUT: 370 request = Request(url, jws_signature) 371 request.add_header("Content-Type", "application/json") 372 373 elif method == HTTP_METHOD_DELETE: 374 request = Request(url) 375 request.add_header("Authorization", "JWS " + jws_signature) 376 request.get_method = lambda: HTTP_METHOD_DELETE 377 378 elif method == HTTP_METHOD_GET: 379 request = Request(url) 380 request.add_header("Authorization", "JWS " + jws_signature) 381 382 else: 383 raise ApiConnectionError("HTTP Method {0} not recognised".format(method)) 384 385 request.add_header("Accept", "application/json") 386 global user_agent 387 388 user_agent_hdr = "Python-SDK/" + Constants.version 389 if user_agent != None: 390 user_agent_hdr = user_agent_hdr + " " + user_agent 391 request.add_header("User-Agent", user_agent_hdr) 392 393 try: 394 response = urlopen(request) 395 response_body = response.read() 396 response_code = response.code 397 except HTTPError as err: 398 response_body = err.read() 399 response_code = err.code 400 except URLError as err: 401 msg = "Looks like there's a problem connecting to the API endpoint: {0}\nError: {1}".format(url, str(err)) 402 raise ApiConnectionError(msg) 403 404 return response_body, response_code
405 406
407 - def auth_request(self, auth, url, params):
408 409 jws_signature = Jws.auth_encode(url, auth, params) 410 411 request = Request(url, jws_signature) 412 request.add_header("Content-Type", "application/json") 413 request.add_header("Accept", "application/json") 414 415 global user_agent 416 user_agent_hdr = "Python-SDK/" + Constants.version 417 if user_agent != None: 418 user_agent_hdr = user_agent_hdr + " " + user_agent 419 request.add_header("User-Agent", user_agent_hdr) 420 421 try: 422 response = urlopen(request) 423 response_body = response.read() 424 response_code = response.code 425 except HTTPError as err: 426 response_body = err.read() 427 response_code = err.code 428 except URLError as err: 429 msg = "Looks like there's a problem connecting to the API endpoint: {0}\nError: {1}".format(url, str(err)) 430 raise ApiConnectionError(msg) 431 432 return response_body, response_code
433
434 435 ################################################################################ 436 # JWS WebHook Utils 437 ################################################################################ 438 439 -class Jws:
440 441 NUM_HEADERS = 7 442 ALGORITHM = 'HS256' 443 TYPE = 'JWS' 444 HDR_URI = 'api.simplifycommerce.com/uri' 445 HDR_TIMESTAMP = 'api.simplifycommerce.com/timestamp' 446 HDR_NONCE = 'api.simplifycommerce.com/nonce' 447 HDR_TOKEN = "api.simplifycommerce.com/token"; 448 HDR_UNAME = 'uname' 449 HDR_ALGORITHM = 'alg' 450 HDR_TYPE = 'typ' 451 HDR_KEY_ID = 'kid' 452 TIMESTAMP_MAX_DIFF = 1000 * 60 * 5 # 5 minutes 453
454 - def __init__(self):
455 pass
456 457 @staticmethod
458 - def encode(url, auth, params, has_payload):
459 460 jws_hdr = {'typ': Jws.TYPE, 461 'alg': Jws.ALGORITHM, 462 'kid': auth.public_key, 463 Jws.HDR_URI: url, 464 Jws.HDR_TIMESTAMP: int(round(time.time() * 1000)), 465 Jws.HDR_NONCE: str(random.randint(1, 10*1000))} 466 467 token = auth.access_token 468 if token: 469 jws_hdr[Jws.HDR_TOKEN] = token 470 471 header = base64.urlsafe_b64encode(Jws().encode_json(jws_hdr)).replace('=', '') 472 payload = '' 473 if has_payload: 474 payload = Jws().encode_json(params) 475 payload = base64.urlsafe_b64encode(payload).replace('=', '') 476 477 msg = header + "." + payload 478 signature = Jws().sign(auth.private_key, msg) 479 return msg + "." + signature
480 481 482 @staticmethod
483 - def auth_encode(url, auth, params):
484 485 jws_hdr = {'typ': Jws.TYPE, 486 'alg': Jws.ALGORITHM, 487 'kid': auth.public_key, 488 Jws.HDR_URI: url, 489 Jws.HDR_TIMESTAMP: int(round(time.time() * 1000)), 490 Jws.HDR_NONCE: str(random.randint(1, 10*1000))} 491 492 header = base64.urlsafe_b64encode(Jws().encode_json(jws_hdr)).replace('=', '') 493 494 # Convert map to param string 495 payload = '&'.join([ "%s=%s" % (k,v) for k,v in params.iteritems()]) 496 payload = base64.urlsafe_b64encode(payload).replace('=', '') 497 498 msg = header + "." + payload 499 signature = Jws().sign(auth.private_key, msg) 500 return msg + "." + signature
501 502 503 @staticmethod
504 - def decode(params, auth):
505 506 global public_key 507 public_api_key = auth.public_key if auth.public_key else public_key 508 509 if not public_api_key: 510 raise IllegalArgumentError("Must have a valid public key to connect to the API") 511 512 global private_key 513 private_api_key = auth.private_key if auth.private_key else private_key 514 515 if not private_api_key: 516 raise IllegalArgumentError("Must have a valid private key to connect to the API") 517 518 if not 'payload' in params: 519 raise IllegalArgumentError("Event data is missing payload") 520 521 payload = params['payload'].strip() 522 data = payload.split('.') 523 if len(data) != 3: 524 raise IllegalArgumentError("Incorrectly formatted JWS message") 525 526 msg = "{0}.{1}".format(data[0], data[1]) 527 header = Jws().safe_base64_decode(data[0]) 528 payload = Jws().safe_base64_decode(data[1]) 529 signature = data[2] 530 531 url = None 532 if 'url' in params: 533 url = params['url'] 534 Jws().verify(header, url, public_api_key) 535 536 if signature != Jws().sign(private_api_key, msg): 537 raise AuthenticationError("JWS signature does not match") 538 539 return json.loads(payload)
540
541 - def sign(self, private_api_key, msg):
542 decoded_private_api_key = Jws().safe_base64_decode(private_api_key) 543 signature = hmac.new(decoded_private_api_key, msg, hashlib.sha256).digest() 544 return base64.urlsafe_b64encode(signature).replace('=', '')
545
546 - def verify(self, header, url, public_api_key):
547 548 hdr = json.loads(header) 549 550 if len(hdr) != Jws.NUM_HEADERS: 551 raise AuthenticationError("Incorrect number of JWS header parameters - found {0} but expected {1}".format(len(hdr), Jws.NUM_HEADERS)) 552 553 if not Jws.HDR_ALGORITHM in hdr: 554 raise AuthenticationError("Missing algorithm header") 555 556 if hdr[Jws.HDR_ALGORITHM] != Jws.ALGORITHM: 557 raise AuthenticationError("Incorrect algorithm - found {0} but required {1}".format(hdr[Jws.HDR_ALGORITHM], Jws.ALGORITHM)) 558 559 if not Jws.HDR_TYPE in hdr: 560 raise AuthenticationError("Missing type header") 561 562 if hdr[Jws.HDR_TYPE] != Jws.TYPE: 563 raise AuthenticationError("Incorrect type - found {0} but required {JWS_TYPE}".format(hdr[Jws.HDR_TYPE], Jws.TYPE)) 564 565 if not Jws.HDR_KEY_ID in hdr: 566 raise AuthenticationError("Missing Key ID") 567 568 # keys don't match and it is a live key 569 if hdr[Jws.HDR_KEY_ID] != public_api_key and public_api_key.startswith("lvpb"): 570 raise AuthenticationError("Invalid Key ID") 571 572 if not Jws.HDR_NONCE in hdr: 573 raise AuthenticationError("Missing nonce") 574 575 if not Jws.HDR_URI in hdr: 576 raise AuthenticationError("Missing URI") 577 578 if url != None and hdr[Jws.HDR_URI] != url: 579 raise AuthenticationError("Incorrect URL - found {0} but required {1}".format(hdr[Jws.HDR_URI], url)) 580 581 if not Jws.HDR_TIMESTAMP in hdr: 582 raise AuthenticationError("Missing timestamp") 583 584 if not Jws.HDR_UNAME in hdr: 585 raise AuthenticationError("Missing username") 586 587 # calculate time difference between when the request was created and now 588 time_now = int(round(time.time() * 1000)) 589 timestamp = int(hdr[Jws.HDR_TIMESTAMP]) 590 diff = time_now - timestamp 591 592 if diff > Jws.TIMESTAMP_MAX_DIFF: 593 raise AuthenticationError("Invalid timestamp, the event has expired")
594
595 - def safe_base64_decode(self, url):
596 597 length = len(url) % 4 598 if length == 2: 599 return base64.urlsafe_b64decode(url + "==") 600 if length == 3: 601 return base64.urlsafe_b64decode(url + "=") 602 603 return base64.urlsafe_b64decode(url)
604
605 - def encode_json(self, json_str):
606 607 try: 608 return json.dumps(json_str).encode('utf-8') 609 except Exception: 610 raise ApiError("Invalid format for JSON request")
611
612 613 ################################################################################ 614 # PaymentsApi 615 ################################################################################ 616 617 -class PaymentsApi:
618 619
620 - def __init__(self):
621 pass
622 623 @staticmethod
624 - def create_auth_object(auth_args):
625 626 global public_key 627 global private_key 628 629 if len(auth_args) == 0: 630 auth = Authentication(public_key = public_key, private_key = private_key) 631 632 elif len(auth_args) == 1: 633 auth = auth_args[0] 634 if not isinstance(auth, Authentication): 635 raise IllegalArgumentError("Invalid Authentication object passed") 636 637 elif len(auth_args) == 2: 638 public_api_key = auth_args[0] 639 if public_api_key == None: 640 public_api_key = public_key 641 private_api_key = auth_args[1] 642 if private_api_key == None: 643 private_api_key = private_key 644 auth = Authentication(public_key = public_api_key, private_key = private_api_key) 645 646 else: 647 raise IllegalArgumentError("Invalid authentication arguments passed") 648 649 return auth
650 651 652 @staticmethod
653 - def check_auth(auth):
654 655 if auth == None: 656 raise IllegalArgumentError("Missing authentication object") 657 658 if auth.public_key == None: 659 raise IllegalArgumentError("Must have a valid public key to connect to the API") 660 661 if auth.private_key == None: 662 raise IllegalArgumentError("Must have a valid private key to connect to the API")
663 664 665 666 @staticmethod
667 - def create(object_type, auth_args, params):
668 669 auth = PaymentsApi.create_auth_object(auth_args) 670 url = PaymentsApi.build_request_url(object_type) 671 response = PaymentsApi().execute(object_type, auth, url, HTTP_METHOD_POST, params) 672 673 return response
674 675 @staticmethod
676 - def list(object_type, auth_args, criteria):
677 678 auth = PaymentsApi.create_auth_object(auth_args) 679 url = PaymentsApi.build_request_url(object_type) 680 query_string = build_query_string(criteria) 681 if len(query_string) > 0: 682 url = url + '?' + query_string 683 response = PaymentsApi().execute(object_type, auth, url, HTTP_METHOD_GET) 684 685 return response
686 687 @staticmethod
688 - def find(object_type, auth_args, object_id):
689 690 auth = PaymentsApi.create_auth_object(auth_args) 691 if not object_id: 692 raise IllegalArgumentError("object_object_id is a required field") 693 694 url = PaymentsApi.build_request_url(object_type, object_id) 695 response = PaymentsApi().execute(object_type, auth, url, HTTP_METHOD_GET) 696 697 return response
698 699 @staticmethod
700 - def update(object_type, auth_args, object_id, params):
701 702 auth = PaymentsApi.create_auth_object(auth_args) 703 if not object_id: 704 raise IllegalArgumentError("object_id is a required field") 705 706 url = PaymentsApi.build_request_url(object_type, object_id) 707 response = PaymentsApi().execute(object_type, auth, url, HTTP_METHOD_PUT, params) 708 709 return response
710 711 @staticmethod
712 - def delete(object_type, auth_args, object_id):
713 714 auth = PaymentsApi.create_auth_object(auth_args) 715 if not object_id: 716 raise IllegalArgumentError("object_id is a required field") 717 718 url = PaymentsApi.build_request_url(object_type, object_id) 719 response = PaymentsApi().execute(object_type, auth, url, HTTP_METHOD_DELETE) 720 721 return response
722
723 - def decode(self, auth_args, params):
724 725 auth = PaymentsApi.create_auth_object(auth_args) 726 PaymentsApi.check_auth(auth) 727 728 return Jws.decode(params, auth)
729 730
731 - def execute(self, object_type, auth, url_suffix, method, params = None):
732 733 if params is None: 734 params = {} 735 736 PaymentsApi.check_auth(auth) 737 738 http = Http() 739 740 global api_base_sandbox_url 741 global api_base_live_url 742 743 base_url = api_base_sandbox_url 744 if auth.public_key.startswith('lvpb'): 745 base_url = api_base_live_url 746 url = base_url + "/" + url_suffix 747 748 response_body, response_code = http.request(auth, url, method, params) 749 750 if not response_code == HTTP_SUCCESS: 751 handle_http_error(response_body, response_code) 752 753 try: 754 response = json.loads(response_body) 755 except Exception: 756 raise SysError("Invalid response format returned. Have you got the correct URL {0} \n HTTP Status: {1}".format(url, response_code)) 757 758 if "list" in response: 759 obj = DomainFactory.factory("domain") 760 obj.list = [DomainFactory.factory(object_type, values) for values in response["list"]] 761 obj.total = response["total"] 762 return obj 763 else: 764 return DomainFactory.factory(object_type, response)
765 766
767 - def send_auth_request(self, props, context, auth):
768 769 PaymentsApi.check_auth(auth) 770 771 http = Http() 772 773 global oauth_base_url 774 775 url = oauth_base_url + "/" + context 776 777 response_body, response_code = http.auth_request(auth, url, props) 778 779 780 try: 781 response = json.loads(response_body) 782 except Exception: 783 raise SysError("Invalid response format returned. Have you got the correct URL {0} \n HTTP Status: {1}".format(url, response_code)) 784 785 if response_code == HTTP_SUCCESS: 786 return response 787 elif response_code == HTTP_REDIRECTED: 788 raise BadRequestError("", response_code) 789 elif response_code >= HTTP_BAD_REQUEST: 790 error_code = response['error'] 791 error_desc = response['error_description'] 792 if error_code == 'invalid_request': 793 raise BadRequestError("", response_code, self.get_oauth_error("Error during OAuth request", error_code, error_desc)) 794 elif error_code == 'access_denied': 795 raise AuthenticationError("", response_code, self.get_oauth_error("Access denied for OAuth request", error_code, error_desc)) 796 elif error_code == 'invalid_client': 797 raise AuthenticationError("", response_code, self.get_oauth_error("Invalid client ID in OAuth request", error_code, error_desc)) 798 elif error_code == 'unauthorized_client': 799 raise AuthenticationError("", response_code, self.get_oauth_error("Unauthorized client in OAuth request", error_code, error_desc)) 800 elif error_code == 'unsupported_grant_type': 801 raise BadRequestError("", response_code, self.get_oauth_error("Unsupported grant type in OAuth request", error_code, error_desc)) 802 elif error_code == 'invalid_scope': 803 raise BadRequestError("", response_code, self.get_oauth_error("Invalid scope in OAuth request", error_code, error_desc)) 804 else: 805 raise BadRequestError("", e.response_code, self.get_oauth_error("Unknown OAuth error", error_code, error_desc)) 806 end 807 elif response_code < 500: 808 raise BadRequestError("Bad request", response_code, {}) 809 else: 810 raise SysError("Bad request", response_code, {})
811 812
813 - def get_oauth_error(self, msg, error_code, error_desc):
814 return """{"error" : {"code" : "oauth_error", "message" : "%s, error code '%s', description '%s'" }}""" % (msg, error_code, error_desc)
815 816 817 @classmethod
818 - def build_request_url(cls, object_type, object_id = ''):
819 820 url = object_type 821 if object_id: 822 url = "{0}/{1}".format(url, object_id) 823 824 return url
825
826 827 828 ################################################################################ 829 # Domain classes 830 ################################################################################ 831 832 833 -class Event(Domain):
834 835 """ 836 A Event object. 837 """ 838 839 @staticmethod
840 - def create(params, *auth_args):
841 842 """ 843 Create an Event object. 844 @param params: a dict of parameters; valid keys are: 845 - C{payload}: The raw JWS message payload. B{required} 846 - C{url}: The URL for the webhook. If present it must match the URL registered for the webhook. 847 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 848 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 849 @return: an Event object 850 """ 851 852 obj = PaymentsApi().decode(auth_args, params) 853 854 if not 'event' in obj: 855 raise ApiError("Incorrect data in webhook event") 856 857 return DomainFactory.factory('event', obj['event'])
858
859 -class CardToken(Domain):
860 """ 861 A CardToken object. 862 """ 863 864 865 @staticmethod
866 - def create(params, *auth_args):
867 """ 868 Creates an CardToken object 869 @param params: a dict of parameters; valid keys are: 870 - C{callback}: The URL callback for the cardtoken 871 - C{card => addressCity}: City of the cardholder. [max length: 50, min length: 2] 872 - C{card => addressCountry}: Country code (ISO-3166-1-alpha-2 code) of residence of the cardholder. [max length: 2, min length: 2] 873 - C{card => addressLine1}: Address of the cardholder. [max length: 255] 874 - C{card => addressLine2}: Address of the cardholder if needed. [max length: 255] 875 - C{card => addressState}: State code (USPS code) of residence of the cardholder. [max length: 2, min length: 2] 876 - C{card => addressZip}: Postal code of the cardholder. The postal code size is between 5 and 9 in length and only contain numbers. [max length: 9, min length: 3] 877 - C{card => cvc}: CVC security code of the card. This is the code on the back of the card. Example: 123 878 - C{card => expMonth}: Expiration month of the card. Format is MM. Example: January = 01 [min value: 1, max value: 12] B{required } 879 - C{card => expYear}: Expiration year of the card. Format is YY. Example: 2013 = 13 [max value: 99] B{required } 880 - C{card => name}: Name as appears on the card. [max length: 50, min length: 2] 881 - C{card => number}: Card number as it appears on the card. [max length: 19, min length: 13] B{required } 882 - C{key}: Key used to create the card token. 883 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 884 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 885 @param private_api_key: Private key to use for the API call. If C{None}, the value of C{simplify.private_key} will be used. 886 @return: a CardToken object 887 """ 888 return PaymentsApi.create("cardToken", auth_args, params)
889 890 @staticmethod
891 - def find(object_id, *auth_args):
892 """ 893 Retrieve a CardToken object from the API 894 @param object_id: ID of object to retrieve 895 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 896 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 897 @return: a CardToken object 898 """ 899 return PaymentsApi.find("cardToken", auth_args, object_id)
900
901 -class Chargeback(Domain):
902 """ 903 A Chargeback object. 904 """ 905 906 907 @staticmethod
908 - def list(criteria = None, *auth_args):
909 """ 910 Retrieve Chargeback objects. 911 @param criteria: a dict of parameters; valid keys are: 912 - C{filter} Filters to apply to the list. 913 - C{max} Allows up to a max of 50 list items to return. [max value: 50, default: 20] 914 - C{offset} Used in paging of the list. This is the start offset of the page. [default: 0] 915 - C{sorting} Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either C{asc} for ascending or C{desc} for descending). Sortable properties are: C{id} C{amount} C{description} C{dateCreated}. 916 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 917 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 918 @return: an object which contains the list of Chargeback objects in the <code>list</code> property and the total number 919 of objects available for the given criteria in the <code>total</code> property. 920 """ 921 return PaymentsApi.list("chargeback", auth_args, criteria)
922 923 @staticmethod
924 - def find(object_id, *auth_args):
925 """ 926 Retrieve a Chargeback object from the API 927 @param object_id: ID of object to retrieve 928 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 929 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 930 @return: a Chargeback object 931 """ 932 return PaymentsApi.find("chargeback", auth_args, object_id)
933
934 -class Coupon(Domain):
935 """ 936 A Coupon object. 937 """ 938 939 940 @staticmethod
941 - def create(params, *auth_args):
942 """ 943 Creates an Coupon object 944 @param params: a dict of parameters; valid keys are: 945 - C{amountOff}: Amount off of the price of the product in minor units in the currency of the merchant. While this field is optional, you must provide either amountOff or percentOff for a coupon. Example: 1000 = 10.00 [min value: 1, max value: 99999999] 946 - C{couponCode}: Code that identifies the coupon to be used. [min length: 2] B{required } 947 - C{description}: A brief section that describes the coupon. 948 - C{durationInMonths}: Duration in months that the coupon will be applied after it has first been selected. [min value: 1, max value: 9999] 949 - C{endDate}: Last date of the coupon in UTC millis that the coupon can be applied to a subscription. This ends at 23:59:59 of the merchant timezone. 950 - C{maxRedemptions}: Maximum number of redemptions allowed for the coupon. A redemption is defined as when the coupon is applied to the subscription for the first time. [min value: 1] 951 - C{percentOff}: Percentage off of the price of the product. While this field is optional, you must provide either amountOff or percentOff for a coupon. The percent off is a whole number. [min value: 1, max value: 100] 952 - C{startDate}: First date of the coupon in UTC millis that the coupon can be applied to a subscription. This starts at midnight of the merchant timezone. B{required } 953 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 954 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 955 @param private_api_key: Private key to use for the API call. If C{None}, the value of C{simplify.private_key} will be used. 956 @return: a Coupon object 957 """ 958 return PaymentsApi.create("coupon", auth_args, params)
959
960 - def delete(self, *auth_args):
961 """ 962 Delete this object 963 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 964 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 965 """ 966 return PaymentsApi.delete("coupon", auth_args, self.object_id)
967 968 @staticmethod
969 - def list(criteria = None, *auth_args):
970 """ 971 Retrieve Coupon objects. 972 @param criteria: a dict of parameters; valid keys are: 973 - C{filter} Filters to apply to the list. 974 - C{max} Allows up to a max of 50 list items to return. [max value: 50, default: 20] 975 - C{offset} Used in paging of the list. This is the start offset of the page. [default: 0] 976 - C{sorting} Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either C{asc} for ascending or C{desc} for descending). Sortable properties are: C{dateCreated} C{maxRedemptions} C{timesRedeemed} C{id} C{startDate} C{endDate} C{percentOff} C{couponCode} C{durationInMonths} C{amountOff}. 977 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 978 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 979 @return: an object which contains the list of Coupon objects in the <code>list</code> property and the total number 980 of objects available for the given criteria in the <code>total</code> property. 981 """ 982 return PaymentsApi.list("coupon", auth_args, criteria)
983 984 @staticmethod
985 - def find(object_id, *auth_args):
986 """ 987 Retrieve a Coupon object from the API 988 @param object_id: ID of object to retrieve 989 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 990 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 991 @return: a Coupon object 992 """ 993 return PaymentsApi.find("coupon", auth_args, object_id)
994
995 - def update(self, *auth_args):
996 """ 997 Updates this object 998 999 The properties that can be updated: 1000 - C{endDate} The ending date in UTC millis for the coupon. This must be after the starting date of the coupon. 1001 1002 - C{maxRedemptions} Maximum number of redemptions allowed for the coupon. A redemption is defined as when the coupon is applied to the subscription for the first time. [min value: 1] 1003 1004 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1005 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1006 @return: a Coupon object. 1007 """ 1008 return PaymentsApi.update("coupon", auth_args, self.object_id, self.to_dict())
1009
1010 -class Customer(Domain):
1011 """ 1012 A Customer object. 1013 """ 1014 1015 1016 @staticmethod
1017 - def create(params, *auth_args):
1018 """ 1019 Creates an Customer object 1020 @param params: a dict of parameters; valid keys are: 1021 - C{card => addressCity}: City of the cardholder. B{required } 1022 - C{card => addressCountry}: Country code (ISO-3166-1-alpha-2 code) of residence of the cardholder. B{required } 1023 - C{card => addressLine1}: Address of the cardholder B{required } 1024 - C{card => addressLine2}: Address of the cardholder if needed. B{required } 1025 - C{card => addressState}: State code (USPS code) of residence of the cardholder. B{required } 1026 - C{card => addressZip}: Postal code of the cardholder. The postal code size is between 5 and 9 in length and only contain numbers. B{required } 1027 - C{card => cvc}: CVC security code of the card. This is the code on the back of the card. Example: 123 B{required } 1028 - C{card => expMonth}: Expiration month of the card. Format is MM. Example: January = 01 B{required } 1029 - C{card => expYear}: Expiration year of the card. Format is YY. Example: 2013 = 13 B{required } 1030 - C{card => id}: ID of card. Unused during customer create. 1031 - C{card => name}: Name as appears on the card. B{required } 1032 - C{card => number}: Card number as it appears on the card. [max length: 19, min length: 13] 1033 - C{email}: Email address of the customer B{required } 1034 - C{name}: Customer name [min length: 2] B{required } 1035 - C{reference}: Reference field for external applications use. 1036 - C{subscriptions => amount}: Amount of payment in minor units. Example: 1000 = 10.00 [min value: 50, max value: 99999999] 1037 - C{subscriptions => coupon}: Coupon associated with the subscription for the customer. 1038 - C{subscriptions => currency}: Currency code (ISO-4217). Must match the currency associated with your account. [default: USD] 1039 - C{subscriptions => customer}: The customer ID to create the subscription for. Do not supply this when creating a customer. 1040 - C{subscriptions => frequency}: Frequency of payment for the plan. Example: Monthly 1041 - C{subscriptions => name}: Name describing subscription 1042 - C{subscriptions => plan}: The plan ID that the subscription should be created from. 1043 - C{subscriptions => quantity}: Quantity of the plan for the subscription. [min value: 1] 1044 - C{token}: If specified, card associated with card token will be used 1045 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1046 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1047 @param private_api_key: Private key to use for the API call. If C{None}, the value of C{simplify.private_key} will be used. 1048 @return: a Customer object 1049 """ 1050 return PaymentsApi.create("customer", auth_args, params)
1051
1052 - def delete(self, *auth_args):
1053 """ 1054 Delete this object 1055 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1056 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1057 """ 1058 return PaymentsApi.delete("customer", auth_args, self.object_id)
1059 1060 @staticmethod
1061 - def list(criteria = None, *auth_args):
1062 """ 1063 Retrieve Customer objects. 1064 @param criteria: a dict of parameters; valid keys are: 1065 - C{filter} Filters to apply to the list. 1066 - C{max} Allows up to a max of 50 list items to return. [max value: 50, default: 20] 1067 - C{offset} Used in paging of the list. This is the start offset of the page. [default: 0] 1068 - C{sorting} Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either C{asc} for ascending or C{desc} for descending). Sortable properties are: C{dateCreated} C{id} C{name} C{email} C{reference}. 1069 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1070 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1071 @return: an object which contains the list of Customer objects in the <code>list</code> property and the total number 1072 of objects available for the given criteria in the <code>total</code> property. 1073 """ 1074 return PaymentsApi.list("customer", auth_args, criteria)
1075 1076 @staticmethod
1077 - def find(object_id, *auth_args):
1078 """ 1079 Retrieve a Customer object from the API 1080 @param object_id: ID of object to retrieve 1081 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1082 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1083 @return: a Customer object 1084 """ 1085 return PaymentsApi.find("customer", auth_args, object_id)
1086
1087 - def update(self, *auth_args):
1088 """ 1089 Updates this object 1090 1091 The properties that can be updated: 1092 - C{card => addressCity} City of the cardholder. B{(required)} 1093 1094 - C{card => addressCountry} Country code (ISO-3166-1-alpha-2 code) of residence of the cardholder. B{(required)} 1095 1096 - C{card => addressLine1} Address of the cardholder. B{(required)} 1097 1098 - C{card => addressLine2} Address of the cardholder if needed. B{(required)} 1099 1100 - C{card => addressState} State code (USPS code) of residence of the cardholder. B{(required)} 1101 1102 - C{card => addressZip} Postal code of the cardholder. The postal code size is between 5 and 9 in length and only contain numbers. B{(required)} 1103 1104 - C{card => cvc} CVC security code of the card. This is the code on the back of the card. Example: 123 B{(required)} 1105 1106 - C{card => expMonth} Expiration month of the card. Format is MM. Example: January = 01 B{(required)} 1107 1108 - C{card => expYear} Expiration year of the card. Format is YY. Example: 2013 = 13 B{(required)} 1109 1110 - C{card => id} ID of card. If present, card details for the customer will not be updated. If not present, the customer will be updated with the supplied card details. 1111 1112 - C{card => name} Name as appears on the card. B{(required)} 1113 1114 - C{card => number} Card number as it appears on the card. [max length: 19, min length: 13] 1115 1116 - C{email} Email address of the customer B{(required)} 1117 1118 - C{name} Customer name [min length: 2] B{(required)} 1119 1120 - C{reference} Reference field for external applications use. 1121 1122 - C{token} If specified, card associated with card token will be added to the customer 1123 1124 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1125 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1126 @return: a Customer object. 1127 """ 1128 return PaymentsApi.update("customer", auth_args, self.object_id, self.to_dict())
1129
1130 -class Deposit(Domain):
1131 """ 1132 A Deposit object. 1133 """ 1134 1135 1136 @staticmethod
1137 - def list(criteria = None, *auth_args):
1138 """ 1139 Retrieve Deposit objects. 1140 @param criteria: a dict of parameters; valid keys are: 1141 - C{filter} Filters to apply to the list. 1142 - C{max} Allows up to a max of 50 list items to return. [max value: 50, default: 20] 1143 - C{offset} Used in paging of the list. This is the start offset of the page. [default: 0] 1144 - C{sorting} Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either C{asc} for ascending or C{desc} for descending). Sortable properties are: C{amount} C{dateCreated} C{depositDate}. 1145 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1146 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1147 @return: an object which contains the list of Deposit objects in the <code>list</code> property and the total number 1148 of objects available for the given criteria in the <code>total</code> property. 1149 """ 1150 return PaymentsApi.list("deposit", auth_args, criteria)
1151 1152 @staticmethod
1153 - def find(object_id, *auth_args):
1154 """ 1155 Retrieve a Deposit object from the API 1156 @param object_id: ID of object to retrieve 1157 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1158 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1159 @return: a Deposit object 1160 """ 1161 return PaymentsApi.find("deposit", auth_args, object_id)
1162
1163 -class Invoice(Domain):
1164 """ 1165 A Invoice object. 1166 """ 1167 1168 1169 @staticmethod
1170 - def list(criteria = None, *auth_args):
1171 """ 1172 Retrieve Invoice objects. 1173 @param criteria: a dict of parameters; valid keys are: 1174 - C{filter} Filters to apply to the list. 1175 - C{max} Allows up to a max of 50 list items to return. [max value: 50, default: 20] 1176 - C{offset} Used in paging of the list. This is the start offset of the page. [default: 0] 1177 - C{sorting} Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either C{asc} for ascending or C{desc} for descending). Sortable properties are: C{id} C{invoiceDate} C{customer} C{amount} C{processedDate}. 1178 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1179 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1180 @return: an object which contains the list of Invoice objects in the <code>list</code> property and the total number 1181 of objects available for the given criteria in the <code>total</code> property. 1182 """ 1183 return PaymentsApi.list("invoice", auth_args, criteria)
1184 1185 @staticmethod
1186 - def find(object_id, *auth_args):
1187 """ 1188 Retrieve a Invoice object from the API 1189 @param object_id: ID of object to retrieve 1190 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1191 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1192 @return: a Invoice object 1193 """ 1194 return PaymentsApi.find("invoice", auth_args, object_id)
1195
1196 - def update(self, *auth_args):
1197 """ 1198 Updates this object 1199 1200 The properties that can be updated: 1201 - C{status} New status of the invoice. [valid values: PAID] B{(required)} 1202 1203 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1204 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1205 @return: a Invoice object. 1206 """ 1207 return PaymentsApi.update("invoice", auth_args, self.object_id, self.to_dict())
1208
1209 -class InvoiceItem(Domain):
1210 """ 1211 A InvoiceItem object. 1212 """ 1213 1214 1215 @staticmethod
1216 - def create(params, *auth_args):
1217 """ 1218 Creates an InvoiceItem object 1219 @param params: a dict of parameters; valid keys are: 1220 - C{amount}: Amount of the invoice item (minor units). Example: 1000 = 10.00 [min value: 1, max value: 99999999] B{required } 1221 - C{currency}: Currency code (ISO-4217) for the invoice item. Must match the currency associated with your account. [default: USD] B{required } 1222 - C{description}: Individual items of an invoice 1223 - C{invoice}: Description of the invoice item B{required } 1224 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1225 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1226 @param private_api_key: Private key to use for the API call. If C{None}, the value of C{simplify.private_key} will be used. 1227 @return: a InvoiceItem object 1228 """ 1229 return PaymentsApi.create("invoiceItem", auth_args, params)
1230
1231 - def delete(self, *auth_args):
1232 """ 1233 Delete this object 1234 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1235 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1236 """ 1237 return PaymentsApi.delete("invoiceItem", auth_args, self.object_id)
1238 1239 @staticmethod
1240 - def list(criteria = None, *auth_args):
1241 """ 1242 Retrieve InvoiceItem objects. 1243 @param criteria: a dict of parameters; valid keys are: 1244 - C{filter} Filters to apply to the list. 1245 - C{max} Allows up to a max of 50 list items to return. [max value: 50, default: 20] 1246 - C{offset} Used in paging of the list. This is the start offset of the page. [default: 0] 1247 - C{sorting} Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either C{asc} for ascending or C{desc} for descending). Sortable properties are: C{id} C{amount} C{description} C{invoice}. 1248 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1249 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1250 @return: an object which contains the list of InvoiceItem objects in the <code>list</code> property and the total number 1251 of objects available for the given criteria in the <code>total</code> property. 1252 """ 1253 return PaymentsApi.list("invoiceItem", auth_args, criteria)
1254 1255 @staticmethod
1256 - def find(object_id, *auth_args):
1257 """ 1258 Retrieve a InvoiceItem object from the API 1259 @param object_id: ID of object to retrieve 1260 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1261 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1262 @return: a InvoiceItem object 1263 """ 1264 return PaymentsApi.find("invoiceItem", auth_args, object_id)
1265
1266 - def update(self, *auth_args):
1267 """ 1268 Updates this object 1269 1270 The properties that can be updated: 1271 - C{amount} Amount of the invoice item (minor units). Example: 1000 = 10.00 [min value: 1, max value: 99999999] 1272 1273 - C{currency} Currency code (ISO-4217) for the invoice item. Must match the currency associated with your account. [default: USD] 1274 1275 - C{description} Individual items of an invoice 1276 1277 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1278 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1279 @return: a InvoiceItem object. 1280 """ 1281 return PaymentsApi.update("invoiceItem", auth_args, self.object_id, self.to_dict())
1282
1283 -class Payment(Domain):
1284 """ 1285 A Payment object. 1286 """ 1287 1288 1289 @staticmethod
1290 - def create(params, *auth_args):
1291 """ 1292 Creates an Payment object 1293 @param params: a dict of parameters; valid keys are: 1294 - C{amount}: Amount of the payment (minor units). Example: 1000 = 10.00 [min value: 50, max value: 99999999] B{required } 1295 - C{card => addressCity}: City of the cardholder. [max length: 50, min length: 2] 1296 - C{card => addressCountry}: Country code (ISO-3166-1-alpha-2 code) of residence of the cardholder. [max length: 2, min length: 2] 1297 - C{card => addressLine1}: Address of the cardholder. [max length: 255] 1298 - C{card => addressLine2}: Address of the cardholder if needed. [max length: 255] 1299 - C{card => addressState}: State code (USPS code) of residence of the cardholder. [max length: 2, min length: 2] 1300 - C{card => addressZip}: Postal code of the cardholder. The postal code size is between 5 and 9 in length and only contain numbers. [max length: 9, min length: 3] 1301 - C{card => cvc}: CVC security code of the card. This is the code on the back of the card. Example: 123 1302 - C{card => expMonth}: Expiration month of the card. Format is MM. Example: January = 01 [min value: 1, max value: 12] B{required } 1303 - C{card => expYear}: Expiration year of the card. Format is YY. Example: 2013 = 13 [max value: 99] B{required } 1304 - C{card => name}: Name as it appears on the card. [max length: 50, min length: 2] 1305 - C{card => number}: Card number as it appears on the card. [max length: 19, min length: 13] B{required } 1306 - C{currency}: Currency code (ISO-4217) for the transaction. Must match the currency associated with your account. [default: USD] B{required } 1307 - C{customer}: ID of customer. If specified, card on file of customer will be used. 1308 - C{description}: Custom naming of payment for external systems to use. 1309 - C{reference}: Custom reference field to be used with outside systems. 1310 - C{token}: If specified, card associated with card token will be used. [max length: 255] 1311 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1312 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1313 @param private_api_key: Private key to use for the API call. If C{None}, the value of C{simplify.private_key} will be used. 1314 @return: a Payment object 1315 """ 1316 return PaymentsApi.create("payment", auth_args, params)
1317 1318 @staticmethod
1319 - def list(criteria = None, *auth_args):
1320 """ 1321 Retrieve Payment objects. 1322 @param criteria: a dict of parameters; valid keys are: 1323 - C{filter} Filters to apply to the list. 1324 - C{max} Allows up to a max of 50 list items to return. [max value: 50, default: 20] 1325 - C{offset} Used in paging of the list. This is the start offset of the page. [default: 0] 1326 - C{sorting} Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either C{asc} for ascending or C{desc} for descending). Sortable properties are: C{dateCreated} C{amount} C{id} C{description} C{paymentDate}. 1327 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1328 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1329 @return: an object which contains the list of Payment objects in the <code>list</code> property and the total number 1330 of objects available for the given criteria in the <code>total</code> property. 1331 """ 1332 return PaymentsApi.list("payment", auth_args, criteria)
1333 1334 @staticmethod
1335 - def find(object_id, *auth_args):
1336 """ 1337 Retrieve a Payment object from the API 1338 @param object_id: ID of object to retrieve 1339 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1340 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1341 @return: a Payment object 1342 """ 1343 return PaymentsApi.find("payment", auth_args, object_id)
1344
1345 -class Plan(Domain):
1346 """ 1347 A Plan object. 1348 """ 1349 1350 1351 @staticmethod
1352 - def create(params, *auth_args):
1353 """ 1354 Creates an Plan object 1355 @param params: a dict of parameters; valid keys are: 1356 - C{amount}: Amount of payment for the plan in minor units. Example: 1000 = 10.00 [min value: 50, max value: 99999999] B{required } 1357 - C{currency}: Currency code (ISO-4217) for the plan. Must match the currency associated with your account. [default: USD] B{required } 1358 - C{frequency}: Frequency of payment for the plan. Example: Monthly B{required } 1359 - C{name}: Name of the plan [max length: 50, min length: 2] B{required } 1360 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1361 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1362 @param private_api_key: Private key to use for the API call. If C{None}, the value of C{simplify.private_key} will be used. 1363 @return: a Plan object 1364 """ 1365 return PaymentsApi.create("plan", auth_args, params)
1366
1367 - def delete(self, *auth_args):
1368 """ 1369 Delete this object 1370 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1371 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1372 """ 1373 return PaymentsApi.delete("plan", auth_args, self.object_id)
1374 1375 @staticmethod
1376 - def list(criteria = None, *auth_args):
1377 """ 1378 Retrieve Plan objects. 1379 @param criteria: a dict of parameters; valid keys are: 1380 - C{filter} Filters to apply to the list. 1381 - C{max} Allows up to a max of 50 list items to return. [max value: 50, default: 20] 1382 - C{offset} Used in paging of the list. This is the start offset of the page. [default: 0] 1383 - C{sorting} Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either C{asc} for ascending or C{desc} for descending). Sortable properties are: C{dateCreated} C{amount} C{frequency} C{name} C{id}. 1384 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1385 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1386 @return: an object which contains the list of Plan objects in the <code>list</code> property and the total number 1387 of objects available for the given criteria in the <code>total</code> property. 1388 """ 1389 return PaymentsApi.list("plan", auth_args, criteria)
1390 1391 @staticmethod
1392 - def find(object_id, *auth_args):
1393 """ 1394 Retrieve a Plan object from the API 1395 @param object_id: ID of object to retrieve 1396 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1397 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1398 @return: a Plan object 1399 """ 1400 return PaymentsApi.find("plan", auth_args, object_id)
1401
1402 - def update(self, *auth_args):
1403 """ 1404 Updates this object 1405 1406 The properties that can be updated: 1407 - C{name} Name of the plan. [min length: 2] B{(required)} 1408 1409 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1410 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1411 @return: a Plan object. 1412 """ 1413 return PaymentsApi.update("plan", auth_args, self.object_id, self.to_dict())
1414
1415 -class Refund(Domain):
1416 """ 1417 A Refund object. 1418 """ 1419 1420 1421 @staticmethod
1422 - def create(params, *auth_args):
1423 """ 1424 Creates an Refund object 1425 @param params: a dict of parameters; valid keys are: 1426 - C{amount}: Amount of the refund in minor units. Example: 1000 = 10.00 [min value: 1, max value: 99999999] B{required } 1427 - C{payment}: ID of the payment for the refund B{required } 1428 - C{reason}: Reason for the refund 1429 - C{reference}: Custom reference field to be used with outside systems. 1430 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1431 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1432 @param private_api_key: Private key to use for the API call. If C{None}, the value of C{simplify.private_key} will be used. 1433 @return: a Refund object 1434 """ 1435 return PaymentsApi.create("refund", auth_args, params)
1436 1437 @staticmethod
1438 - def list(criteria = None, *auth_args):
1439 """ 1440 Retrieve Refund objects. 1441 @param criteria: a dict of parameters; valid keys are: 1442 - C{filter} Filters to apply to the list. 1443 - C{max} Allows up to a max of 50 list items to return. [max value: 50, default: 20] 1444 - C{offset} Used in paging of the list. This is the start offset of the page. [default: 0] 1445 - C{sorting} Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either C{asc} for ascending or C{desc} for descending). Sortable properties are: C{id} C{amount} C{description} C{dateCreated} C{paymentDate}. 1446 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1447 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1448 @return: an object which contains the list of Refund objects in the <code>list</code> property and the total number 1449 of objects available for the given criteria in the <code>total</code> property. 1450 """ 1451 return PaymentsApi.list("refund", auth_args, criteria)
1452 1453 @staticmethod
1454 - def find(object_id, *auth_args):
1455 """ 1456 Retrieve a Refund object from the API 1457 @param object_id: ID of object to retrieve 1458 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1459 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1460 @return: a Refund object 1461 """ 1462 return PaymentsApi.find("refund", auth_args, object_id)
1463
1464 -class Subscription(Domain):
1465 """ 1466 A Subscription object. 1467 """ 1468 1469 1470 @staticmethod
1471 - def create(params, *auth_args):
1472 """ 1473 Creates an Subscription object 1474 @param params: a dict of parameters; valid keys are: 1475 - C{amount}: Amount of the payment (minor units). Example: 1000 = 10.00 [min value: 50, max value: 99999999] 1476 - C{coupon}: Coupon ID associated with the subscription 1477 - C{currency}: Currency code (ISO-4217). Must match the currency associated with your account. [default: USD] 1478 - C{customer}: Customer that is enrolling in the subscription. 1479 - C{frequency}: Frequency of payment for the plan. Example: Monthly 1480 - C{name}: Name describing subscription 1481 - C{plan}: The ID of the plan that should be used for the subscription. 1482 - C{quantity}: Quantity of the plan for the subscription. [min value: 1] 1483 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1484 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1485 @param private_api_key: Private key to use for the API call. If C{None}, the value of C{simplify.private_key} will be used. 1486 @return: a Subscription object 1487 """ 1488 return PaymentsApi.create("subscription", auth_args, params)
1489
1490 - def delete(self, *auth_args):
1491 """ 1492 Delete this object 1493 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1494 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1495 """ 1496 return PaymentsApi.delete("subscription", auth_args, self.object_id)
1497 1498 @staticmethod
1499 - def list(criteria = None, *auth_args):
1500 """ 1501 Retrieve Subscription objects. 1502 @param criteria: a dict of parameters; valid keys are: 1503 - C{filter} Filters to apply to the list. 1504 - C{max} Allows up to a max of 50 list items to return. [max value: 50, default: 20] 1505 - C{offset} Used in paging of the list. This is the start offset of the page. [default: 0] 1506 - C{sorting} Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either C{asc} for ascending or C{desc} for descending). Sortable properties are: C{id} C{plan}. 1507 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1508 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1509 @return: an object which contains the list of Subscription objects in the <code>list</code> property and the total number 1510 of objects available for the given criteria in the <code>total</code> property. 1511 """ 1512 return PaymentsApi.list("subscription", auth_args, criteria)
1513 1514 @staticmethod
1515 - def find(object_id, *auth_args):
1516 """ 1517 Retrieve a Subscription object from the API 1518 @param object_id: ID of object to retrieve 1519 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1520 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1521 @return: a Subscription object 1522 """ 1523 return PaymentsApi.find("subscription", auth_args, object_id)
1524
1525 - def update(self, *auth_args):
1526 """ 1527 Updates this object 1528 1529 The properties that can be updated: 1530 - C{amount} Amount of the payment (minor units). Example: 1000 = 10.00 [min value: 50, max value: 99999999] 1531 1532 - C{coupon} Coupon being assigned to this subscription 1533 1534 - C{currency} Currency code (ISO-4217). Must match the currency associated with your account. [default: USD] 1535 1536 - C{frequency} Frequency of payment for the plan. Example: Monthly 1537 1538 - C{name} Name describing subscription 1539 1540 - C{plan} Plan that should be used for the subscription. 1541 1542 - C{prorate} Whether to prorate existing subscription. [default: true] B{(required)} 1543 1544 - C{quantity} Quantity of the plan for the subscription. [min value: 1] 1545 1546 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1547 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1548 @return: a Subscription object. 1549 """ 1550 return PaymentsApi.update("subscription", auth_args, self.object_id, self.to_dict())
1551
1552 -class Webhook(Domain):
1553 """ 1554 A Webhook object. 1555 """ 1556 1557 1558 @staticmethod
1559 - def create(params, *auth_args):
1560 """ 1561 Creates an Webhook object 1562 @param params: a dict of parameters; valid keys are: 1563 - C{url}: Endpoint URL B{required } 1564 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1565 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1566 @param private_api_key: Private key to use for the API call. If C{None}, the value of C{simplify.private_key} will be used. 1567 @return: a Webhook object 1568 """ 1569 return PaymentsApi.create("webhook", auth_args, params)
1570
1571 - def delete(self, *auth_args):
1572 """ 1573 Delete this object 1574 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1575 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1576 """ 1577 return PaymentsApi.delete("webhook", auth_args, self.object_id)
1578 1579 @staticmethod
1580 - def list(criteria = None, *auth_args):
1581 """ 1582 Retrieve Webhook objects. 1583 @param criteria: a dict of parameters; valid keys are: 1584 - C{filter} Filters to apply to the list. 1585 - C{max} Allows up to a max of 50 list items to return. [max value: 50, default: 20] 1586 - C{offset} Used in paging of the list. This is the start offset of the page. [default: 0] 1587 - C{sorting} Allows for ascending or descending sorting of the list. The value maps properties to the sort direction (either C{asc} for ascending or C{desc} for descending). Sortable properties are: C{dateCreated}. 1588 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1589 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1590 @return: an object which contains the list of Webhook objects in the <code>list</code> property and the total number 1591 of objects available for the given criteria in the <code>total</code> property. 1592 """ 1593 return PaymentsApi.list("webhook", auth_args, criteria)
1594 1595 @staticmethod
1596 - def find(object_id, *auth_args):
1597 """ 1598 Retrieve a Webhook object from the API 1599 @param object_id: ID of object to retrieve 1600 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1601 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1602 @return: a Webhook object 1603 """ 1604 return PaymentsApi.find("webhook", auth_args, object_id)
1605
1606 - def update(self, *auth_args):
1607 """ 1608 Updates this object 1609 1610 The properties that can be updated: 1611 - C{url} Endpoint URL B{(required)} 1612 1613 @param auth_args: an Authentication object used for the API call. If no value is passed the gloabl keys simplify.public_key and simplify.private_key are used. 1614 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1615 @return: a Webhook object. 1616 """ 1617 return PaymentsApi.update("webhook", auth_args, self.object_id, self.to_dict())
1618