示例#1
0
    def update_subscription(self,
                            subscription_id,
                            amount=None,
                            start=None,
                            occurrences=None,
                            trial_amount=None,
                            trial_occurrences=None):
        """
        Updates an existing recurring subscription payment. All fields to
        update are optional, and only the provided fields will be udpated.
        Many of the fields have particular restrictions that must be followed,
        as noted below.
        
        ``subscription_id``
            The subscription ID returned from the original create_subscription
            call for the subscription you want to update.
        
        ``amount``
            The updated amount to charge every occurrence, either as an int,
            float, or Decimal.
        
        ``start``
            The updated date to start the subscription, as a date object. This
            may only be udpated if no successful payments have been completed.
        
        ``occurrences``
            This updates the number of times to charge the credit card before
            ending.
        
        ``trial_amount``
            Updates the amount charged during the trial period. This may only
            be updated if you have not begun charging at the regular price.
        
        ``trial_occurrences``
            Updates the number of occurrences for the trial period. This may
            only be updated if you have not begun charging at the regular
            price.
        """
        subscription = self.client.factory.create('ARBSubscriptionType')

        # Add the basic subscription updates
        if amount:
            amount = Decimal(str(amount)).quantize(Decimal('0.01'))
            subscription.amount = str(amount)
        if start and start < date.today():
            raise AuthorizeInvalidError('The start date for the subscription '
                                        'may not be in the past.')
        if start:
            subscription.paymentSchedule.startDate = start.strftime('%Y-%m-%d')
        if occurrences:
            subscription.paymentSchedule.totalOccurrences = occurrences
        if trial_amount:
            trial_amount = Decimal(str(trial_amount))
            trial_amount = trial_amount.quantize(Decimal('0.01'))
            subscription.trialAmount = str(trial_amount)
        if trial_occurrences:
            subscription.paymentSchedule.trialOccurrences = trial_occurrences

        # Make the API call to update the subscription
        self._make_call('ARBUpdateSubscription', subscription_id, subscription)
示例#2
0
    def capture(self,
                profile_id,
                payment_id,
                amount,
                cvv=None,
                invoice_number=None,
                description=None,
                purchase_order_number=None):
        if cvv is not None:
            try:
                int(cvv)
            except ValueError:
                raise AuthorizeInvalidError("CVV Must be a number.")

        transaction = self.client.factory.create('ProfileTransactionType')
        capture = self.client.factory.create('ProfileTransAuthCaptureType')
        amount = Decimal(str(amount)).quantize(Decimal('0.01'))
        capture.amount = str(amount)
        capture.customerProfileId = profile_id
        capture.customerPaymentProfileId = payment_id
        if invoice_number:
            order_type = self.client.factory.create('OrderExType')
            order_type.invoiceNumber = str(invoice_number)
            order_type.description = description if description else ""
            order_type.purchaseOrderNumber = \
                purchase_order_number if purchase_order_number else ""
            capture.order = order_type
        capture.cardCode = cvv
        transaction.profileTransAuthCapture = capture
        response = self._make_call('CreateCustomerProfileTransaction',
                                   transaction, self.transaction_options)
        return parse_response(response.directResponse)
示例#3
0
    def capture(self,
                profile_id,
                payment_id,
                amount,
                cvv=None,
                invoice_num=''):
        """
        Capture with invoice number
        """
        if cvv is not None:
            try:
                int(cvv)
            except ValueError:
                raise AuthorizeInvalidError("CVV Must be a number.")
        transaction = self.client.factory.create('ProfileTransactionType')
        capture = self.client.factory.create('ProfileTransAuthCaptureType')

        if invoice_num:
            order = self.client.factory.create('OrderExType')
            order.invoiceNumber = str(invoice_num).strip()
        else:
            order = None
        amount = Decimal(str(amount)).quantize(Decimal('0.01'))
        capture.amount = str(amount)
        capture.customerProfileId = profile_id
        capture.customerPaymentProfileId = payment_id
        capture.cardCode = cvv
        if order:
            capture.order = order
        transaction.profileTransAuthCapture = capture
        response = self._make_call('CreateCustomerProfileTransaction',
                                   transaction, self.transaction_options)
        return parse_response(response.directResponse)
示例#4
0
 def validate(self):
     """
     Validates the credit card data and raises an
     :class:`AuthorizeInvalidError <authorize.exceptions.AuthorizeInvalidError>`
     if anything doesn't check out. You shouldn't have to call this
     yourself.
     """
     try:
         num = list(map(int, self.card_number))
     except ValueError:
         raise AuthorizeInvalidError('Credit card number is not valid.')
     if sum(num[::-2] + [sum(divmod(d * 2, 10)) for d in num[-2::-2]]) % 10:
         raise AuthorizeInvalidError('Credit card number is not valid.')
     if datetime.now() > self.expiration:
         raise AuthorizeInvalidError('Credit card is expired.')
     if not re.match(r'^[\d+]{3,4}$', self.cvv):
         raise AuthorizeInvalidError('Credit card CVV is invalid format.')
     if not self.card_type:
         raise AuthorizeInvalidError('Credit card number is not valid.')
示例#5
0
 def capture(self, profile_id, payment_id, amount, cvv=None):
     if cvv is not None:
         try:
             int(cvv)
         except ValueError:
             raise AuthorizeInvalidError("CVV Must be a number.")
     transaction = self.client.factory.create('ProfileTransactionType')
     capture = self.client.factory.create('ProfileTransAuthCaptureType')
     amount = Decimal(str(amount)).quantize(Decimal('0.01'))
     capture.amount = str(amount)
     capture.customerProfileId = profile_id
     capture.customerPaymentProfileId = payment_id
     capture.cardCode = cvv
     transaction.profileTransAuthCapture = capture
     response = self._make_call('CreateCustomerProfileTransaction',
                                transaction, self.transaction_options)
     return parse_response(response.directResponse)
示例#6
0
    def update_saved_payment(self, profile_id, payment_id, **kwargs):
        payment_profile = self.client.factory.create(
            'CustomerPaymentProfileExType')
        customer_type_enum = self.client.factory.create('CustomerTypeEnum')
        payment_profile.customerType = customer_type_enum.individual
        payment_simple_type = self.client.factory.create('PaymentType')
        card_simple_type = self.client.factory.create('CreditCardSimpleType')
        number = kwargs['number']
        # Authorize.net uses this constant to indicate that we want to keep
        # the existing expiration date.
        date = 'XXXX'
        card_simple_type.cardNumber = number
        if kwargs['exp_month'] and kwargs['exp_year']:
            exp = CreditCard.exp_time(kwargs['exp_month'], kwargs['exp_year'])
            if exp <= datetime.now():
                raise AuthorizeInvalidError('This credit card has expired.')
            card_simple_type.expirationDate =\
                '{0}-{1:0>2}'.format(kwargs['exp_year'], kwargs['exp_month'])
        else:
            card_simple_type.expirationDate = date
        payment_simple_type.creditCard = card_simple_type
        payment_profile.payment = payment_simple_type
        payment_profile.payment.creditCard = card_simple_type
        payment_profile.customerPaymentProfileId = payment_id

        if kwargs['first_name']:
            payment_profile.billTo.firstName = kwargs['first_name']
        if kwargs['last_name']:
            payment_profile.billTo.lastName = kwargs['last_name']
        payment_profile = self._address_to_profile(
            kwargs['address'], payment_profile)

        self._make_call(
            'UpdateCustomerPaymentProfile', profile_id,
            payment_profile, 'none')

        if not kwargs['email']:
            return
        profile = self.client.factory.create('CustomerProfileExType')
        profile.email = kwargs['email']
        profile.customerProfileId = profile_id
        self._make_call('UpdateCustomerProfile', profile)
示例#7
0
 def _deserialize(self, schema, params={}):
     try:
         deserialized = schema.deserialize(params)
     except colander.Invalid as e:
         raise AuthorizeInvalidError(e)
     return deserialized
    def create_subscription(self, credit_card, amount, start,
            days=None, months=None, occurrences=None, trial_amount=None,
            trial_occurrences=None, invoice_number=None,
            description=None):
        """
        Creates a recurring subscription payment on the CreditCard provided.
        
        ``credit_card``
            The CreditCard instance to create the subscription for.
            Subscriptions require that you provide a first and last name with
            the credit card.
        
        ``amount``
            The amount to charge every occurrence, either as an int, float,
            or Decimal.
        
        ``start``
            The date to start the subscription, as a date object.
        
        ``days``
            Provide either the days or the months argument to indicate the
            interval at which the subscription should recur.

        ``months``
            Provide either the days or the months argument to indicate the
            interval at which the subscription should recur.
        
        ``occurrences``
            If provided, this is the number of times to charge the credit card
            before ending. If not provided, will last until canceled.
        
        ``trial_amount``
            If you want to have a trial period at a lower amount for this
            subscription, provide the amount. (Either both trial arguments
            should be provided, or neither.)
        
        ``trial_occurrences``
            If you want to have a trial period at a lower amount for this
            subscription, provide the number of occurences the trial period
            should last for. (Either both trial arguments should be provided,
            or neither.)
        """
        subscription = self.client.factory.create('ARBSubscriptionType')

        # Add the basic amount and payment fields
        amount = Decimal(str(amount)).quantize(Decimal('0.01'))
        subscription.amount = str(amount)
        payment_type = self.client.factory.create('PaymentType')
        credit_card_type = self.client.factory.create('CreditCardType')
        if invoice_number:
            order_type = self.client.factory.create('OrderType')
            order_type.invoiceNumber = str(invoice_number)
            order_type.description = description if description else ""
            subscription.order = order_type
        credit_card_type.cardNumber = credit_card.card_number
        credit_card_type.expirationDate = '{0}-{1:0>2}'.format(
            credit_card.exp_year, credit_card.exp_month)
        credit_card_type.cardCode = credit_card.cvv
        payment_type.creditCard = credit_card_type
        subscription.payment = payment_type
        if not (credit_card.first_name and credit_card.last_name):
            raise AuthorizeInvalidError('Subscriptions require first name '
                'and last name to be provided with the credit card.')
        subscription.billTo.firstName = credit_card.first_name
        subscription.billTo.lastName = credit_card.last_name

        # Add the fields for the payment schedule
        if (days and months) or not (days or months):
            raise AuthorizeInvalidError('Please provide either the months or '
                'days argument to define the subscription interval.')
        if days:
            try:
                days = int(days)
                assert days >= 7 and days <= 365
            except (AssertionError, ValueError):
                raise AuthorizeInvalidError('The interval days must be an '
                    'integer value between 7 and 365.')
            subscription.paymentSchedule.interval.unit = \
                self.client.factory.create('ARBSubscriptionUnitEnum').days
            subscription.paymentSchedule.interval.length = days
        elif months:
            try:
                months = int(months)
                assert months >= 1 and months <= 12
            except (AssertionError, ValueError):
                raise AuthorizeInvalidError('The interval months must be an '
                    'integer value between 1 and 12.')
            subscription.paymentSchedule.interval.unit = \
                self.client.factory.create('ARBSubscriptionUnitEnum').months
            subscription.paymentSchedule.interval.length = months
        if start < date.today():
            raise AuthorizeInvalidError('The start date for the subscription '
                'may not be in the past.')
        subscription.paymentSchedule.startDate = start.strftime('%Y-%m-%d')
        if occurrences is None:
            occurrences = 9999 # That's what they say to do in the docs
        subscription.paymentSchedule.totalOccurrences = occurrences

        # If a trial period has been specified, add those fields
        if trial_amount and trial_occurrences:
            subscription.paymentSchedule.trialOccurrences = trial_occurrences
            trial_amount = Decimal(str(trial_amount))
            trial_amount = trial_amount.quantize(Decimal('0.01'))
            subscription.trialAmount = str(trial_amount)
        elif trial_amount or trial_occurrences:
            raise AuthorizeInvalidError('To indicate a trial period, you '
                'must provide both a trial amount and occurrences.')

        # Make the API call to create the subscription
        response = self._make_call('ARBCreateSubscription', subscription)
        return response.subscriptionId