Source code for pyticketswitch.payment_methods

import six
from abc import ABCMeta
from pyticketswitch.exceptions import InvalidParametersError


[docs]@six.add_metaclass(ABCMeta) class PaymentMethod(object): """Abstract base class for payment methods"""
[docs] def as_api_parameters(self): """Generate keyword arguments suitable for consumption by the ticketswitch API Returns: dict: dictionary of keyword parameters to pass to the API call. """ raise NotImplementedError( 'as_api_parameters not implemented on ' + self.__class__)
[docs]class CardDetails(object): """Credit card details This should never be returned by the API and is only used for supplying card details to the purchase call. Implements :class:`PaymentMethod <pyticketswitch.payment_methods.PaymentMethod>`. Attributes: card_number (str): the long credit card number. expiry_month (int): the month the card expires in. Defaults to :obj:`None`. expiry_year (int): the year the card expires in. defaults to :obj:`None`. start_month (int): the month the card expires in. Defaults to :obj:`None`. start_year (int): the year the card expires in. :obj:`None`. ccv2 (str): credit card security code. Defaults to :obj:`None`. issue_number (str): issue number of the card. Defaults to :obj:`None`. billing_address (:class:`Address <pyticketswitch.address.Address>`): used when the customer wishes to use an alternate billing address. when not specified the customer address will be used. return_url (str): some card debitors may decide that they need to redirect the user to a third party for verification (for example 3d secure). These parties need a location to return a customer to. When available, it's recomended to provide it. In the situation where a return url is required but not provided, then the payment will fail. return_token (str): a unique token that can be used by you to identify when a card debitor returns to you. user_agent (str): the customer's browser's User-Agent header. only nessicary when providing a return url. accept (str): the customer's browser's Accept header. remote_site (str): the remote site's domain. must match the domain of the return_url. """ def __init__(self, card_number, expiry_month=None, expiry_year=None, start_month=None, start_year=None, ccv2=None, issue_number=None, billing_address=None, return_url=None, return_token=None, user_agent=None, accept=None, remote_site=None): self.card_number = card_number self.expiry_month = expiry_month self.expiry_year = expiry_year self.start_month = start_month self.start_year = start_year self.ccv2 = ccv2 self.issue_number = issue_number self.billing_address = billing_address self.return_url = return_url self.return_token = return_token self.user_agent = user_agent self.accept = accept self.remote_site = remote_site
[docs] def as_api_parameters(self): """Generates a dictionary of parameters to be passed back to the API. Returns: dict: a set of parameters describing the card details to the API. """ params = { 'card_number': self.card_number, } missing_expiry_year = not self.expiry_year missing_expiry_month = not self.expiry_month if missing_expiry_year or missing_expiry_month: raise InvalidParametersError( 'both expiry_year and expiry_month must be specified') params.update( expiry_date='{:0>2}{:0>2}'.format( self.expiry_month, # handle 4 digit years str(self.expiry_year)[-2:] ) ) missing_start_year = not self.start_year missing_start_month = not self.start_month specifying_start_date = self.start_year or self.start_month if specifying_start_date and (missing_start_year or missing_start_month): raise InvalidParametersError( 'both start_year and start_month must be specified or neither specified') if specifying_start_date: params.update( start_date='{:0>2}{:0>2}'.format( self.start_month, str(self.start_year)[-2:] ) ) if self.ccv2: params.update(cv_two=self.ccv2) if self.issue_number: params.update(issue_number=self.issue_number) if self.billing_address: params.update( **self.billing_address.as_api_billing_address_parameters() ) if self.return_url: params.update(return_url=self.return_url) if self.return_token: params.update(return_token=self.return_token) if self.user_agent: params.update(client_http_user_agent=self.user_agent) if self.accept: params.update(client_http_accept=self.accept) if self.remote_site: params.update(remote_site=self.remote_site) return params
[docs]class RedirectionDetails(object): """Information that specifies where a customer will be returned to after being redirected to an external payment provider. Implements :class:`PaymentMethod <pyticketswitch.payment_methods.PaymentMethod>`. Attributes: token (str): a unique token that can be used by you to identify when this callout returns to your website. url (str): the URL that the payment provider should redirect back to on success/failure of the customers payment. user_agent (str): the customer's browser's User-Agent header. accept (str): the customer's browser's Accept header. remote_site (str): the remote site's domain must match the domain of the return_url. """ def __init__(self, token, url, user_agent, accept, remote_site): self.token = token self.url = url self.user_agent = user_agent self.accept = accept self.remote_site = remote_site
[docs] def as_api_parameters(self): """Generate API keyword args for these details. Returns: dict: the redirection details in a format the API will understand. """ return { 'return_token': self.token, 'return_url': self.url, 'client_http_user_agent': self.user_agent, 'client_http_accept': self.accept, 'remote_site': self.remote_site, }
[docs]class StripeDetails(object): """For use with self generated stripe tokens Can be used to provide stripe tokens directly to the API at purchase time avoiding a callout/callback cycle. Implements :class:`PaymentMethod <pyticketswitch.payment_methods.PaymentMethod>`. Attributes: tokens (dict): dictionary of stripe card tokens indexed on bundle source code. If there are multiple bundles in the trolley, then a unique stripe token must be provided for each of the bundles you wish to purchase with stripe. """ def __init__(self, tokens): self.tokens = tokens
[docs] def as_api_parameters(self): """Generate API keyword args for these details. Returns: dict: the stripe details in a format the API will understand. """ return { '{}_callback/stripeToken'.format(source): token for source, token in self.tokens.items() }
[docs]class CiderDetails(object): """For use with multiple payment tokens and details Can be used to provide payment tokens and details directly to the API at purchase time, avoiding a callout/callback cycle. Implements :class:`PaymentMethod <pyticketswitch.payment_methods.PaymentMethod>`. Attributes: data (dict): dictionary of payment tokens and details system_codes (list): a list of systems for which payment is being made """ def __init__(self, data, system_codes): self.data = data self.system_codes = system_codes
[docs] def as_api_parameters(self): """Generate API keyword args for these details. Returns: dict: the cider debitor details in the format the API can use. """ data = {} for system in self.system_codes: data.update({ "{0}_callback/{1}".format(system, variable): self.data[variable] for variable in self.data.keys() }) return data
PaymentMethod.register(CardDetails) PaymentMethod.register(RedirectionDetails) PaymentMethod.register(StripeDetails) PaymentMethod.register(CiderDetails)