示例#1
0
 def set_credit_approved(self, amount):
     self.amount = amount
     self.host = PAYMENT_HOST_CREDIT
     self.type = PAYMENT_TYPE_AUTHORIZATION
     self.status = TRANSACTION_STATUS_ACTIVE
     self.approved = True
     now_val = now()
     self.date_authorized = now_val
     self.date_expired = now_val + datetime.timedelta(days=settings.PREAPPROVAL_PERIOD)
     self.save()
     pledge_created.send(sender=self, transaction=self)
示例#2
0
    def process_transaction(self,
                            currency,
                            amount,
                            host=PAYMENT_HOST_NONE,
                            campaign=None,
                            user=None,
                            return_url=None,
                            paymentReason="unglue.it Pledge",
                            pledge_extra=None,
                            donation=False,
                            modification=False):
        '''
        process
        
        saves and processes a proposed transaction; decides if the transaction should be processed 
        immediately.
        
        currency: a 3-letter currency code, i.e. USD
        amount: the amount to authorize
        host: the name of the processing module; if none, send user back to decide!
        campaign: required campaign object
        user: optional user object
        return_url: url to redirect supporter to after a successful transaction
        paymentReason:  a memo line that will show up in the Payer's Amazon (and Paypal?) account
        modification: whether this authorize call is part of a modification of an existing pledge
        pledge_extra: extra pledge stuff
        
        return value: a tuple of the new transaction object and a re-direct url.  
                      If the process fails, the redirect url will be None
        donation: transaction is a donation
        '''
        # set the expiry date based on the campaign deadline
        if campaign and campaign.deadline:
            expiry = campaign.deadline + timedelta(
                days=settings.PREAPPROVAL_PERIOD_AFTER_CAMPAIGN)
        else:
            expiry = now() + timedelta(
                days=settings.PREAPPROVAL_PERIOD_AFTER_CAMPAIGN)

        t = Transaction.create(
            amount=0,
            host=host,
            max_amount=amount,
            currency=currency,
            campaign=campaign,
            user=user,
            pledge_extra=pledge_extra,
            donation=donation,
        )
        t.save()
        # does user have enough credit to transact now?
        if user.is_authenticated() and user.credit.available >= amount:
            # YES!
            return_path = "{0}?{1}".format(reverse('pledge_complete'),
                                           urllib.urlencode({'tid': t.id}))
            return_url = urlparse.urljoin(settings.BASE_URL_SECURE,
                                          return_path)
            if campaign.is_pledge():
                success = credit.pledge_transaction(t, user, amount)
                if success:
                    pledge_created.send(sender=self, transaction=t)
            else:
                success = credit.pay_transaction(t, user,
                                                 t.campaign.user_to_pay,
                                                 amount)
                if success:
                    t.amount = amount
                    t.host = PAYMENT_HOST_CREDIT
                    t.execution = EXECUTE_TYPE_INSTANT
                    t.date_executed = now()
                    t.status = TRANSACTION_STATUS_COMPLETE
                    t.save()
                    transaction_charged.send(sender=self, transaction=t)
            if success:
                return t, return_url
            else:
                # shouldn't happen
                logger.error('could not use credit for transaction %s' % t.id)

        # send user to choose payment path
        return t, reverse('fund', args=[t.id])
示例#3
0
    def authorize(self,
                  transaction,
                  expiry=None,
                  return_url=None,
                  paymentReason="unglue.it Pledge",
                  modification=False):
        '''
        authorize
        
        authorizes a set amount of money to be collected at a later date
        
        return_url: url to redirect supporter to after a successful transaction
        paymentReason:  a memo line that will show up in the unglue.it accounting
        modification: whether this authorize call is part of a modification of an existing pledge
        
        return value: a tuple of the new transaction object and a re-direct url.  If the process fails,
                      the redirect url will be None
                      
        '''

        if transaction.host == PAYMENT_HOST_NONE:
            #TODO send user to select a payment processor -- for now, set to a system setting
            transaction.host = settings.PAYMENT_PROCESSOR

        # we might want to not allow for a return_url  to be passed in but calculated
        # here because we have immediate access to the Transaction object.

        if return_url is None:
            return_path = "{0}?{1}".format(
                reverse('pledge_complete'),
                urllib.urlencode({'tid': transaction.id}))
            return_url = urlparse.urljoin(settings.BASE_URL_SECURE,
                                          return_path)

        p = transaction.get_payment_class().Preapproval(
            transaction,
            transaction.max_amount,
            expiry,
            return_url=return_url,
            paymentReason=paymentReason)

        # Create a response for this
        envelope = p.envelope()

        if envelope:
            r = PaymentResponse.objects.create(
                api=p.url,
                correlation_id=p.correlation_id(),
                timestamp=p.timestamp(),
                info=p.raw_response,
                transaction=transaction)

        if p.success() and not p.error():
            transaction.preapproval_key = p.key()
            transaction.save()

            # it make sense for the payment processor library to calculate next_url when
            # user is redirected there.  But if no redirection is required, send user
            # straight on to the return_url
            url = p.next_url()

            if url is None:
                url = return_url

            logger.info("Authorize Success: " + url if url is not None else '')

            # modification and initial pledge use different notification templates --
            # decide which to send
            # we need to fire notifications at the first point at which we are sure
            # that the transaction has successfully completed; triggering notifications
            # when the transaction is initiated risks sending notifications on transactions
            # that for whatever reason fail.  will need other housekeeping to handle those.
            # sadly this point is not yet late enough in the process -- needs to be moved
            # until after we are certain.

            if not modification:
                # BUGBUG:
                # send the notice here for now
                # this is actually premature since we're only about to send the user off to the payment system to
                # authorize a charge
                pledge_created.send(sender=self, transaction=transaction)

            return transaction, url

        else:
            transaction.error = p.error_string()
            transaction.save()
            logger.info("Authorize Error: " + p.error_string())
            return transaction, None