示例#1
0
        def __init__(self, transaction=None):
            self.transaction = transaction
            amount = transaction.amount
            # make sure transaction hasn't already been executed
            if transaction.status == TRANSACTION_STATUS_COMPLETE:
                return

            used = transaction.user.credit.use_pledge(amount)
            if used:
                user_to_pay = transaction.campaign.user_to_pay
                credited = user_to_pay.credit.add_to_balance(amount,
                                                             notify=False)
                transaction.status = TRANSACTION_STATUS_COMPLETE
                transaction.date_payment = datetime.now()
                transaction.save()

                # fire signal for sucessful transaction
                transaction_charged.send(sender=self, transaction=transaction)
示例#2
0
        def __init__(self, transaction=None):
            
            self.transaction = transaction
            
            # make sure transaction hasn't already been executed
            if transaction.status == TRANSACTION_STATUS_COMPLETE:
                return
            # make sure we are dealing with a stripe transaction
            if transaction.host <> PAYMENT_HOST_STRIPE:
                raise StripelibError("transaction.host {0} is not the expected {1}".format(transaction.host, PAYMENT_HOST_STRIPE))
            
            sc = StripeClient()
            
            # look first for transaction.user.profile.account.account_id
            try:
                customer_id = transaction.user.profile.account.account_id
            except:
                customer_id = transaction.preapproval_key
            
            if customer_id is not None:    
                try:
                    # useful things to put in description: transaction.id, transaction.user.id,  customer_id, transaction.amount
                    charge = sc.create_charge(transaction.amount, customer=customer_id,
                                              description=json.dumps({"t.id":transaction.id,
                                                                      "email":transaction.user.email if transaction.user else transaction.receipt,
                                                                      "cus.id":customer_id,
                                                                      "tc.id": transaction.campaign.id if transaction.campaign else '0',
                                                                      "amount": float(transaction.amount)}))
                except stripe.StripeError as e:
                    # what to record in terms of errors?  (error log?)
                    # use PaymentResponse to store error

                    r = PaymentResponse.objects.create(api="stripelib.Execute", correlation_id=None,
                                                       timestamp=now(), info=e.message,
                                                       status=TRANSACTION_STATUS_ERROR, transaction=transaction)
                    
                    transaction.status = TRANSACTION_STATUS_ERROR	  	
                    self.errorMessage = e.message # manager puts this on transaction
                    transaction.save()

                    # fire off the fact that transaction failed -- should actually do so only if not a transient error
                    # if card_declined or expired card, ask user to update account
                    if isinstance(e, stripe.CardError) and e.code in ('card_declined', 'expired_card', 'incorrect_number', 'processing_error'):
                        transaction_failed.send(sender=self, transaction=transaction)
                    # otherwise, report exception to us
                    else:
                        logger.exception("transaction id {0}, exception: {1}".format(transaction.id,  e.message))
                    
                    # raise StripelibError(e.message, e)
                    
                else:
                    self.charge = charge
                    
                    transaction.status = TRANSACTION_STATUS_COMPLETE
                    transaction.pay_key = charge.id
                    transaction.date_payment = now()
                    transaction.save()
                    
                    # fire signal for sucessful transaction
                    transaction_charged.send(sender=self, transaction=transaction)

                    
            else:
                # nothing to charge
                raise StripelibError("No customer id available to charge for transaction {0}".format(transaction.id), None)
示例#3
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])