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

Source Code for Package simplify

   1   
   2  # 
   3  # Copyright (c) 2013, 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. 872 - C{card => addressCountry}: Country code (ISO-3166-1-alpha-2 code) of residence of the cardholder. 873 - C{card => addressLine1}: Address of the cardholder. 874 - C{card => addressLine2}: Address of the cardholder if needed. 875 - C{card => addressState}: State code (USPS code) of residence of the cardholder. 876 - C{card => addressZip}: Postal code of the cardholder. 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 B{required } 879 - C{card => expYear}: Expiration year of the card. Format is YY. Example: 2013 = 13 B{required } 880 - C{card => name}: Name as appears on the card. 881 - C{card => number}: Card number as it appears on the card. 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. B{default:20} 914 - C{offset} Used in paging of the list. This is the start offset of the page. B{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 946 - C{couponCode}: Code that identifies the coupon to be used. 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. 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. 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. 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. B{default:20} 975 - C{offset} Used in paging of the list. This is the start offset of the page. B{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. 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. 1022 - C{card => addressCountry}: Country code (ISO-3166-1-alpha-2 code) of residence of the cardholder. 1023 - C{card => addressLine1}: Address of the cardholder 1024 - C{card => addressLine2}: Address of the cardholder if needed. 1025 - C{card => addressState}: State code (USPS code) of residence of the cardholder. 1026 - C{card => addressZip}: Postal code of the cardholder. 1027 - C{card => cvc}: CVC security code of the card. This is the code on the back of the card. Example: 123 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 => name}: Name as appears on the card. 1031 - C{card => number}: Card number as it appears on the card. B{required } 1032 - C{email}: Email address of the customer B{required } 1033 - C{name}: Customer name B{required } 1034 - C{reference}: Reference field for external applications use. 1035 - C{subscriptions => amount}: Amount of payment in minor units. Example: 1000 = 10.00 1036 - C{subscriptions => coupon}: Coupon associated with the subscription for the customer. 1037 - C{subscriptions => currency}: Currency code (ISO-4217). Must match the currency associated with your account. B{default:USD} 1038 - C{subscriptions => customer}: The customer ID to create the subscription for. Do not supply this when creating a customer. 1039 - C{subscriptions => frequency}: Frequency of payment for the plan. Example: Monthly 1040 - C{subscriptions => name}: Name describing subscription 1041 - C{subscriptions => plan}: The plan ID that the subscription should be created from. 1042 - C{subscriptions => quantity}: Quantity of the plan for the subscription. 1043 - C{token}: If specified, card associated with card token will be used 1044 @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. 1045 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1046 @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. 1047 @return: a Customer object 1048 """ 1049 return PaymentsApi.create("customer", auth_args, params)
1050
1051 - def delete(self, *auth_args):
1052 """ 1053 Delete this object 1054 @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. 1055 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1056 """ 1057 return PaymentsApi.delete("customer", auth_args, self.object_id)
1058 1059 @staticmethod
1060 - def list(criteria = None, *auth_args):
1061 """ 1062 Retrieve Customer objects. 1063 @param criteria: a dict of parameters; valid keys are: 1064 - C{filter} Filters to apply to the list. 1065 - C{max} Allows up to a max of 50 list items to return. B{default:20} 1066 - C{offset} Used in paging of the list. This is the start offset of the page. B{default:0} 1067 - 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}. 1068 @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. 1069 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1070 @return: an object which contains the list of Customer objects in the <code>list</code> property and the total number 1071 of objects available for the given criteria in the <code>total</code> property. 1072 """ 1073 return PaymentsApi.list("customer", auth_args, criteria)
1074 1075 @staticmethod
1076 - def find(object_id, *auth_args):
1077 """ 1078 Retrieve a Customer object from the API 1079 @param object_id: ID of object to retrieve 1080 @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. 1081 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1082 @return: a Customer object 1083 """ 1084 return PaymentsApi.find("customer", auth_args, object_id)
1085
1086 - def update(self, *auth_args):
1087 """ 1088 Updates this object 1089 1090 The properties that can be updated: 1091 - C{card => addressCity} City of the cardholder. 1092 1093 - C{card => addressCountry} Country code (ISO-3166-1-alpha-2 code) of residence of the cardholder. 1094 1095 - C{card => addressLine1} Address of the cardholder. 1096 1097 - C{card => addressLine2} Address of the cardholder if needed. 1098 1099 - C{card => addressState} State code (USPS code) of residence of the cardholder. 1100 1101 - C{card => addressZip} Postal code of the cardholder. 1102 1103 - C{card => cvc} CVC security code of the card. This is the code on the back of the card. Example: 123 1104 1105 - C{card => expMonth} Expiration month of the card. Format is MM. Example: January = 01 B{(required)} 1106 1107 - C{card => expYear} Expiration year of the card. Format is YY. Example: 2013 = 13 B{(required)} 1108 1109 - C{card => name} Name as appears on the card. 1110 1111 - C{card => number} Card number as it appears on the card. B{(required)} 1112 1113 - C{email} Email address of the customer B{(required)} 1114 1115 - C{name} Customer name B{(required)} 1116 1117 - C{reference} Reference field for external applications use. 1118 1119 @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. 1120 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1121 @return: a Customer object. 1122 """ 1123 return PaymentsApi.update("customer", auth_args, self.object_id, self.to_dict())
1124
1125 -class Deposit(Domain):
1126 """ 1127 A Deposit object. 1128 """ 1129 1130 1131 @staticmethod
1132 - def list(criteria = None, *auth_args):
1133 """ 1134 Retrieve Deposit objects. 1135 @param criteria: a dict of parameters; valid keys are: 1136 - C{filter} Filters to apply to the list. 1137 - C{max} Allows up to a max of 50 list items to return. B{default:20} 1138 - C{offset} Used in paging of the list. This is the start offset of the page. B{default:0} 1139 - 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}. 1140 @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. 1141 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1142 @return: an object which contains the list of Deposit objects in the <code>list</code> property and the total number 1143 of objects available for the given criteria in the <code>total</code> property. 1144 """ 1145 return PaymentsApi.list("deposit", auth_args, criteria)
1146 1147 @staticmethod
1148 - def find(object_id, *auth_args):
1149 """ 1150 Retrieve a Deposit object from the API 1151 @param object_id: ID of object to retrieve 1152 @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. 1153 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1154 @return: a Deposit object 1155 """ 1156 return PaymentsApi.find("deposit", auth_args, object_id)
1157
1158 -class Invoice(Domain):
1159 """ 1160 A Invoice object. 1161 """ 1162 1163 1164 @staticmethod
1165 - def list(criteria = None, *auth_args):
1166 """ 1167 Retrieve Invoice objects. 1168 @param criteria: a dict of parameters; valid keys are: 1169 - C{filter} Filters to apply to the list. 1170 - C{max} Allows up to a max of 50 list items to return. B{default:20} 1171 - C{offset} Used in paging of the list. This is the start offset of the page. B{default:0} 1172 - 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}. 1173 @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. 1174 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1175 @return: an object which contains the list of Invoice objects in the <code>list</code> property and the total number 1176 of objects available for the given criteria in the <code>total</code> property. 1177 """ 1178 return PaymentsApi.list("invoice", auth_args, criteria)
1179 1180 @staticmethod
1181 - def find(object_id, *auth_args):
1182 """ 1183 Retrieve a Invoice object from the API 1184 @param object_id: ID of object to retrieve 1185 @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. 1186 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1187 @return: a Invoice object 1188 """ 1189 return PaymentsApi.find("invoice", auth_args, object_id)
1190
1191 - def update(self, *auth_args):
1192 """ 1193 Updates this object 1194 1195 The properties that can be updated: 1196 - C{status} Status of the invoice. Examples: OPEN = Invoice has not been processed and can have invoice items added to it. PAID = Invoice has been paid. UNPAID = Invoice was not paid when the card was processed. System will try up to 5 times to process the card. B{(required)} 1197 1198 @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. 1199 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1200 @return: a Invoice object. 1201 """ 1202 return PaymentsApi.update("invoice", auth_args, self.object_id, self.to_dict())
1203
1204 -class InvoiceItem(Domain):
1205 """ 1206 A InvoiceItem object. 1207 """ 1208 1209 1210 @staticmethod
1211 - def create(params, *auth_args):
1212 """ 1213 Creates an InvoiceItem object 1214 @param params: a dict of parameters; valid keys are: 1215 - C{amount}: Amount of the invoice item (minor units). Example: 1000 = 10.00 B{required } 1216 - C{currency}: Currency code (ISO-4217) for the invoice item. Must match the currency associated with your account. B{required }B{default:USD} 1217 - C{description}: Individual items of an invoice 1218 - C{invoice}: Description of the invoice item B{required } 1219 @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. 1220 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1221 @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. 1222 @return: a InvoiceItem object 1223 """ 1224 return PaymentsApi.create("invoiceItem", auth_args, params)
1225
1226 - def delete(self, *auth_args):
1227 """ 1228 Delete this object 1229 @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. 1230 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1231 """ 1232 return PaymentsApi.delete("invoiceItem", auth_args, self.object_id)
1233 1234 @staticmethod
1235 - def list(criteria = None, *auth_args):
1236 """ 1237 Retrieve InvoiceItem objects. 1238 @param criteria: a dict of parameters; valid keys are: 1239 - C{filter} Filters to apply to the list. 1240 - C{max} Allows up to a max of 50 list items to return. B{default:20} 1241 - C{offset} Used in paging of the list. This is the start offset of the page. B{default:0} 1242 - 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}. 1243 @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. 1244 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1245 @return: an object which contains the list of InvoiceItem objects in the <code>list</code> property and the total number 1246 of objects available for the given criteria in the <code>total</code> property. 1247 """ 1248 return PaymentsApi.list("invoiceItem", auth_args, criteria)
1249 1250 @staticmethod
1251 - def find(object_id, *auth_args):
1252 """ 1253 Retrieve a InvoiceItem object from the API 1254 @param object_id: ID of object to retrieve 1255 @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. 1256 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1257 @return: a InvoiceItem object 1258 """ 1259 return PaymentsApi.find("invoiceItem", auth_args, object_id)
1260
1261 - def update(self, *auth_args):
1262 """ 1263 Updates this object 1264 1265 The properties that can be updated: 1266 - C{amount} Amount of the invoice item (minor units). Example: 1000 = 10.00 1267 1268 - C{currency} Currency code (ISO-4217) for the invoice item. Must match the currency associated with your account. 1269 1270 - C{description} Individual items of an invoice 1271 1272 @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. 1273 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1274 @return: a InvoiceItem object. 1275 """ 1276 return PaymentsApi.update("invoiceItem", auth_args, self.object_id, self.to_dict())
1277
1278 -class Payment(Domain):
1279 """ 1280 A Payment object. 1281 """ 1282 1283 1284 @staticmethod
1285 - def create(params, *auth_args):
1286 """ 1287 Creates an Payment object 1288 @param params: a dict of parameters; valid keys are: 1289 - C{amount}: Amount of the payment (minor units). Example: 1000 = 10.00 B{required } 1290 - C{card => addressCity}: City of the cardholder. 1291 - C{card => addressCountry}: Country code (ISO-3166-1-alpha-2 code) of residence of the cardholder. 1292 - C{card => addressLine1}: Address of the cardholder. 1293 - C{card => addressLine2}: Address of the cardholder if needed. 1294 - C{card => addressState}: State code (USPS code) of residence of the cardholder. 1295 - C{card => addressZip}: Postal code of the cardholder. 1296 - C{card => cvc}: CVC security code of the card. This is the code on the back of the card. Example: 123 1297 - C{card => expMonth}: Expiration month of the card. Format is MM. Example: January = 01 B{required } 1298 - C{card => expYear}: Expiration year of the card. Format is YY. Example: 2013 = 13 B{required } 1299 - C{card => name}: Name as it appears on the card. 1300 - C{card => number}: Card number as it appears on the card. B{required } 1301 - C{currency}: Currency code (ISO-4217) for the transaction. Must match the currency associated with your account. B{required }B{default:USD} 1302 - C{customer}: ID of customer. If specified, card on file of customer will be used. 1303 - C{description}: Custom naming of payment for external systems to use. 1304 - C{reference}: Custom reference field to be used with outside systems. 1305 - C{token}: If specified, card associated with card token will be used. 1306 @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. 1307 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1308 @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. 1309 @return: a Payment object 1310 """ 1311 return PaymentsApi.create("payment", auth_args, params)
1312 1313 @staticmethod
1314 - def list(criteria = None, *auth_args):
1315 """ 1316 Retrieve Payment objects. 1317 @param criteria: a dict of parameters; valid keys are: 1318 - C{filter} Filters to apply to the list. 1319 - C{max} Allows up to a max of 50 list items to return. B{default:20} 1320 - C{offset} Used in paging of the list. This is the start offset of the page. B{default:0} 1321 - 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}. 1322 @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. 1323 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1324 @return: an object which contains the list of Payment objects in the <code>list</code> property and the total number 1325 of objects available for the given criteria in the <code>total</code> property. 1326 """ 1327 return PaymentsApi.list("payment", auth_args, criteria)
1328 1329 @staticmethod
1330 - def find(object_id, *auth_args):
1331 """ 1332 Retrieve a Payment object from the API 1333 @param object_id: ID of object to retrieve 1334 @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. 1335 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1336 @return: a Payment object 1337 """ 1338 return PaymentsApi.find("payment", auth_args, object_id)
1339
1340 -class Plan(Domain):
1341 """ 1342 A Plan object. 1343 """ 1344 1345 1346 @staticmethod
1347 - def create(params, *auth_args):
1348 """ 1349 Creates an Plan object 1350 @param params: a dict of parameters; valid keys are: 1351 - C{amount}: Amount of payment for the plan in minor units. Example: 1000 = 10.00 B{required } 1352 - C{currency}: Currency code (ISO-4217) for the plan. Must match the currency associated with your account. B{required }B{default:USD} 1353 - C{frequency}: Frequency of payment for the plan. Example: Monthly B{required } 1354 - C{name}: Name of the plan B{required } 1355 @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. 1356 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1357 @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. 1358 @return: a Plan object 1359 """ 1360 return PaymentsApi.create("plan", auth_args, params)
1361
1362 - def delete(self, *auth_args):
1363 """ 1364 Delete this object 1365 @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. 1366 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1367 """ 1368 return PaymentsApi.delete("plan", auth_args, self.object_id)
1369 1370 @staticmethod
1371 - def list(criteria = None, *auth_args):
1372 """ 1373 Retrieve Plan objects. 1374 @param criteria: a dict of parameters; valid keys are: 1375 - C{filter} Filters to apply to the list. 1376 - C{max} Allows up to a max of 50 list items to return. B{default:20} 1377 - C{offset} Used in paging of the list. This is the start offset of the page. B{default:0} 1378 - 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}. 1379 @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. 1380 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1381 @return: an object which contains the list of Plan objects in the <code>list</code> property and the total number 1382 of objects available for the given criteria in the <code>total</code> property. 1383 """ 1384 return PaymentsApi.list("plan", auth_args, criteria)
1385 1386 @staticmethod
1387 - def find(object_id, *auth_args):
1388 """ 1389 Retrieve a Plan object from the API 1390 @param object_id: ID of object to retrieve 1391 @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. 1392 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1393 @return: a Plan object 1394 """ 1395 return PaymentsApi.find("plan", auth_args, object_id)
1396
1397 - def update(self, *auth_args):
1398 """ 1399 Updates this object 1400 1401 The properties that can be updated: 1402 - C{name} Name of the plan. B{(required)} 1403 1404 @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. 1405 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1406 @return: a Plan object. 1407 """ 1408 return PaymentsApi.update("plan", auth_args, self.object_id, self.to_dict())
1409
1410 -class Refund(Domain):
1411 """ 1412 A Refund object. 1413 """ 1414 1415 1416 @staticmethod
1417 - def create(params, *auth_args):
1418 """ 1419 Creates an Refund object 1420 @param params: a dict of parameters; valid keys are: 1421 - C{amount}: Amount of the refund in minor units. Example: 1000 = 10.00 B{required } 1422 - C{payment}: ID of the payment for the refund B{required } 1423 - C{reason}: Reason for the refund 1424 - C{reference}: Custom reference field to be used with outside systems. 1425 @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. 1426 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1427 @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. 1428 @return: a Refund object 1429 """ 1430 return PaymentsApi.create("refund", auth_args, params)
1431 1432 @staticmethod
1433 - def list(criteria = None, *auth_args):
1434 """ 1435 Retrieve Refund objects. 1436 @param criteria: a dict of parameters; valid keys are: 1437 - C{filter} Filters to apply to the list. 1438 - C{max} Allows up to a max of 50 list items to return. B{default:20} 1439 - C{offset} Used in paging of the list. This is the start offset of the page. B{default:0} 1440 - 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}. 1441 @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. 1442 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1443 @return: an object which contains the list of Refund objects in the <code>list</code> property and the total number 1444 of objects available for the given criteria in the <code>total</code> property. 1445 """ 1446 return PaymentsApi.list("refund", auth_args, criteria)
1447 1448 @staticmethod
1449 - def find(object_id, *auth_args):
1450 """ 1451 Retrieve a Refund object from the API 1452 @param object_id: ID of object to retrieve 1453 @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. 1454 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1455 @return: a Refund object 1456 """ 1457 return PaymentsApi.find("refund", auth_args, object_id)
1458
1459 -class Subscription(Domain):
1460 """ 1461 A Subscription object. 1462 """ 1463 1464 1465 @staticmethod
1466 - def create(params, *auth_args):
1467 """ 1468 Creates an Subscription object 1469 @param params: a dict of parameters; valid keys are: 1470 - C{amount}: Amount of the payment (minor units). Example: 1000 = 10.00 1471 - C{coupon}: Coupon ID associated with the subscription 1472 - C{currency}: Currency code (ISO-4217). Must match the currency associated with your account. B{default:USD} 1473 - C{customer}: Customer that is enrolling in the subscription. 1474 - C{frequency}: Frequency of payment for the plan. Example: Monthly 1475 - C{name}: Name describing subscription 1476 - C{plan}: The ID of the plan that should be used for the subscription. 1477 - C{quantity}: Quantity of the plan for the subscription. 1478 @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. 1479 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1480 @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. 1481 @return: a Subscription object 1482 """ 1483 return PaymentsApi.create("subscription", auth_args, params)
1484
1485 - def delete(self, *auth_args):
1486 """ 1487 Delete this object 1488 @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. 1489 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1490 """ 1491 return PaymentsApi.delete("subscription", auth_args, self.object_id)
1492 1493 @staticmethod
1494 - def list(criteria = None, *auth_args):
1495 """ 1496 Retrieve Subscription objects. 1497 @param criteria: a dict of parameters; valid keys are: 1498 - C{filter} Filters to apply to the list. 1499 - C{max} Allows up to a max of 50 list items to return. B{default:20} 1500 - C{offset} Used in paging of the list. This is the start offset of the page. B{default:0} 1501 - 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}. 1502 @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. 1503 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1504 @return: an object which contains the list of Subscription objects in the <code>list</code> property and the total number 1505 of objects available for the given criteria in the <code>total</code> property. 1506 """ 1507 return PaymentsApi.list("subscription", auth_args, criteria)
1508 1509 @staticmethod
1510 - def find(object_id, *auth_args):
1511 """ 1512 Retrieve a Subscription object from the API 1513 @param object_id: ID of object to retrieve 1514 @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. 1515 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1516 @return: a Subscription object 1517 """ 1518 return PaymentsApi.find("subscription", auth_args, object_id)
1519
1520 - def update(self, *auth_args):
1521 """ 1522 Updates this object 1523 1524 The properties that can be updated: 1525 - C{amount} Amount of the payment (minor units). Example: 1000 = 10.00 1526 1527 - C{coupon} Coupon being assigned to this subscription 1528 1529 - C{currency} Currency code (ISO-4217). Must match the currency associated with your account. 1530 1531 - C{frequency} Frequency of payment for the plan. Example: Monthly 1532 1533 - C{name} Name describing subscription 1534 1535 - C{plan} Plan that should be used for the subscription. 1536 1537 - C{prorate} Whether to prorate existing subscription. B{(required)} 1538 1539 - C{quantity} Quantity of the plan for the subscription. 1540 1541 @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. 1542 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1543 @return: a Subscription object. 1544 """ 1545 return PaymentsApi.update("subscription", auth_args, self.object_id, self.to_dict())
1546
1547 -class Webhook(Domain):
1548 """ 1549 A Webhook object. 1550 """ 1551 1552 1553 @staticmethod
1554 - def create(params, *auth_args):
1555 """ 1556 Creates an Webhook object 1557 @param params: a dict of parameters; valid keys are: 1558 - C{url}: Endpoint URL B{required } 1559 @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. 1560 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1561 @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. 1562 @return: a Webhook object 1563 """ 1564 return PaymentsApi.create("webhook", auth_args, params)
1565
1566 - def delete(self, *auth_args):
1567 """ 1568 Delete this object 1569 @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. 1570 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1571 """ 1572 return PaymentsApi.delete("webhook", auth_args, self.object_id)
1573 1574 @staticmethod
1575 - def list(criteria = None, *auth_args):
1576 """ 1577 Retrieve Webhook objects. 1578 @param criteria: a dict of parameters; valid keys are: 1579 - C{filter} Filters to apply to the list. 1580 - C{max} Allows up to a max of 50 list items to return. B{default:20} 1581 - C{offset} Used in paging of the list. This is the start offset of the page. B{default:0} 1582 - 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}. 1583 @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. 1584 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1585 @return: an object which contains the list of Webhook objects in the <code>list</code> property and the total number 1586 of objects available for the given criteria in the <code>total</code> property. 1587 """ 1588 return PaymentsApi.list("webhook", auth_args, criteria)
1589 1590 @staticmethod
1591 - def find(object_id, *auth_args):
1592 """ 1593 Retrieve a Webhook object from the API 1594 @param object_id: ID of object to retrieve 1595 @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. 1596 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1597 @return: a Webhook object 1598 """ 1599 return PaymentsApi.find("webhook", auth_args, object_id)
1600
1601 - def update(self, *auth_args):
1602 """ 1603 Updates this object 1604 1605 The properties that can be updated: 1606 - C{url} Endpoint URL B{(required)} 1607 1608 @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. 1609 For backwards compatibility the public and private keys may be passed instead of an Authentication object. 1610 @return: a Webhook object. 1611 """ 1612 return PaymentsApi.update("webhook", auth_args, self.object_id, self.to_dict())
1613