Ejemplo n.º 1
0
 def get_source_data(self):
     # https://www.pcisecuritystandards.org/pdfs/pci_fs_data_storage.pdf
     if self.platform == 'stripe':
         stripe.api_key = getattr(settings, 'STRIPE_SECRET_KEY', '')
         stripe.api_version = settings.STRIPE_API_VERSION
         stripe_set_app_info(stripe)
         card = None
         if self.customer_profile_id:
             customer = stripe.Customer.retrieve(self.customer_profile_id)
             default_card_id = customer.get('default_card', None)
             if default_card_id:
                 card = customer.sources.retrieve(default_card_id)
             else:
                 default_source = customer.get('default_source', None)
                 if default_source:
                     sources = customer.get('sources', None)
                     if sources:
                         data = sources.get('data', None)
                         for c in data:
                             if c['id'] == default_source:
                                 card = c
                                 break
             if card:
                 return {
                     'last4': card['last4'],
                     'exp_year': card['exp_year'],
                     'exp_month': card['exp_month']
                 }
     return None
    def handle(self, *args, **options):
        from tendenci.apps.payments.stripe.models import StripeAccount, Charge

        stripe.api_key = settings.STRIPE_SECRET_KEY
        stripe_set_app_info(stripe)

        stripe_accounts = StripeAccount.objects.filter(status_detail='active')
        for stripe_account in stripe_accounts:
            #The charges are returned in sorted order, with the most recent charges
            #appearing first
            has_more = True
            starting_after = None
            [stop_point
             ] = Charge.objects.filter(account=stripe_account).values_list(
                 'charge_id', flat=True).order_by('-charge_dt')[:1] or [None]

            while has_more:
                if starting_after:
                    stripe_charges = stripe.Charge.list(
                        stripe_account=stripe_account.stripe_user_id,
                        starting_after=starting_after)
                else:
                    stripe_charges = stripe.Charge.list(
                        stripe_account=stripe_account.stripe_user_id)
                has_more = stripe_charges.has_more
                for i, stripe_charge in enumerate(stripe_charges):
                    if stop_point and stop_point == stripe_charge.id:
                        has_more = False
                        break
                    starting_after = stripe_charge.id
                    if not Charge.objects.filter(
                            charge_id=stripe_charge.id).exists():
                        params = {
                            'account':
                            stripe_account,
                            'charge_id':
                            stripe_charge.id,
                            'amount':
                            stripe_charge.amount / 100.0,
                            'amount_refunded':
                            stripe_charge.amount_refunded / 100.0,
                            'currency':
                            stripe_charge.currency,
                            'captured':
                            stripe_charge.captured,
                            'livemode':
                            stripe_charge.livemode,
                            'charge_dt':
                            datetime.fromtimestamp(stripe_charge.created),
                        }
                        charge = Charge(**params)
                        charge.save()
Ejemplo n.º 3
0
    def make_payment_transaction(self, payment_profile_id, membership=None):
        """
        Make a payment transaction. This includes:
        1) Make an API call createCustomerProfileTransactionRequest
        2) Create a payment transaction entry
        3) Create a payment entry
        4) If the transaction is successful, populate payment entry with the direct response and mark payment as paid
        """
        amount = self.invoice.balance
        # tender the invoice
        self.invoice.tender(self.recurring_payment.user)

        # create a payment record
        payment = Payment()

        payment.payments_pop_by_invoice_user(self.recurring_payment.user,
                                             self.invoice, self.invoice.guid)

        if self.billing_cycle_start_dt and self.billing_cycle_end_dt:
            description = self.recurring_payment.description
            description += '(billing cycle from {0} to {1})'.format(
                self.billing_cycle_start_dt.strftime('%m/%d/%Y'),
                self.billing_cycle_end_dt.strftime('%m/%d/%Y'))
        else:
            description = payment.description

        # charge user
        if self.recurring_payment.platform == "stripe":
            stripe.api_key = getattr(settings, 'STRIPE_SECRET_KEY', '')
            stripe.api_version = settings.STRIPE_API_VERSION
            stripe_set_app_info(stripe)
            params = {
                'amount': math.trunc(amount * 100),  # amount in cents, again
                'currency': get_setting('site', 'global', 'currency'),
                'description': description,
                'customer': self.recurring_payment.customer_profile_id
            }

            success = False
            response_d = {
                'status_detail': 'not approved',
                'response_code': '0',
                'response_reason_code': '0',
                'result_code': 'Error',  # Error, Ok
                'message_code': '',  # I00001, E00027
            }
            try:
                charge_response = stripe.Charge.create(**params)
                success = True
                response_d['status_detail'] = 'approved'
                response_d['response_code'] = '1'
                response_d['response_subcode'] = '1'
                response_d['response_reason_code'] = '1'
                response_d[
                    'response_reason_text'] = 'This transaction has been approved. (Created# %s)' % charge_response.created
                response_d['trans_id'] = charge_response.id
                response_d['result_code'] = 'Ok'
                response_d['message_text'] = 'Successful.'
            except stripe.error.CardError as e:
                # it's a decline
                json_body = e.json_body
                err = json_body and json_body['error']
                code = err and err['code']
                message = err and err['message']
                charge_response = '{message} status={status}, code={code}'.format(
                    message=message, status=e.http_status, code=code)

                response_d['response_reason_text'] = charge_response
                response_d['message_code'] = code
                response_d['message_text'] = charge_response
            except Exception as e:
                charge_response = e.message
                response_d['response_reason_text'] = charge_response
                response_d['message_text'] = charge_response[:200]

            # update payment
            for key in response_d:
                if hasattr(payment, key):
                    setattr(payment, key, response_d[key])

        else:
            # make a transaction using CIM
            d = {
                'amount': amount,
                'order': {
                    'invoice_number': str(payment.invoice_num),
                    'description': description,
                    'recurring_billing': 'true'
                }
            }

            cpt = CIMCustomerProfileTransaction(
                self.recurring_payment.customer_profile_id, payment_profile_id)

            success, response_d = cpt.create(**d)

            # update the payment entry with the direct response returned from payment gateway
            payment = payment_update_from_response(
                payment, response_d['direct_response'])

        if success:
            payment.mark_as_paid()
            payment.save()
            payment.invoice.make_payment(self.recurring_payment.user,
                                         Decimal(payment.amount))
            # approve membership
            if membership:
                membership.approve()
                # send notification to user

            self.payment_received_dt = datetime.now()
        else:
            if payment.status_detail == '':
                payment.status_detail = 'not approved'
            payment.save()
            self.last_payment_failed_dt = datetime.now()

        self.save()

        # create a payment transaction record
        payment_transaction = PaymentTransaction(
            recurring_payment=self.recurring_payment,
            recurring_payment_invoice=self,
            payment_profile_id=payment_profile_id,
            trans_type='auth_capture',
            amount=amount,
            status=success)

        payment_transaction.payment = payment
        payment_transaction.result_code = response_d['result_code']
        payment_transaction.message_code = response_d['message_code']
        payment_transaction.message_text = response_d['message_text']

        payment_transaction.save()

        return payment_transaction