예제 #1
0
파일: api.py 프로젝트: kahihia/django
def stripe_refund(order, event, payment_id, amount):
    stripe_prep(event.api_type)
    if event.api_type == LIVE:
        access_token = event.organization.stripe_access_token
    else:
        access_token = event.organization.stripe_test_access_token
    # Retrieving the charge and refunding it uses the access token.
    stripe.api_key = access_token
    charge = stripe.Charge.retrieve(payment_id)
    refund = charge.refunds.create(
        amount=int(amount * 100),
        refund_application_fee=True,
        expand=['balance_transaction'],
        metadata={
            'order': order.code,
            'event': event.name,
        },
    )

    stripe_prep(event.api_type)
    try:
        application_fee = stripe.ApplicationFee.all(charge=charge).data[0]
        application_fee_refund = application_fee.refunds.data[0]
    except IndexError:
        raise Exception("No application fee refund found.")
    return {
        'refund': refund,
        'application_fee_refund': application_fee_refund,
    }
예제 #2
0
파일: api.py 프로젝트: kahihia/django
def stripe_charge(source, amount, order, event, customer=None):
    if amount < 0:
        raise InvalidAmountException('Cannot charge an amount less than zero.')
    stripe_prep(event.api_type)
    if event.api_type == LIVE:
        stripe_account = event.organization.stripe_user_id
    else:
        stripe_account = event.organization.stripe_test_user_id

    if customer is not None:
        source = stripe.Token.create(
            customer=customer,
            card=source,
            stripe_account=stripe_account,
        )
    return stripe.Charge.create(
        amount=int(amount * 100),
        currency=event.currency,
        source=source,
        application_fee=int(get_fee(event, amount) * 100),
        expand=['balance_transaction'],
        metadata={
            'order': order.code,
            'event': event.name,
        },
        stripe_account=stripe_account,
    )
예제 #3
0
def stripe_refund(order, event, payment_id, amount):
    stripe_prep(event.api_type)
    if event.api_type == LIVE:
        access_token = event.organization.stripe_access_token
    else:
        access_token = event.organization.stripe_test_access_token
    # Retrieving the charge and refunding it uses the access token.
    stripe.api_key = access_token
    charge = stripe.Charge.retrieve(payment_id)
    refund = charge.refunds.create(
        amount=int(amount * 100),
        refund_application_fee=True,
        expand=['balance_transaction'],
        metadata={
            'order': order.code,
            'event': event.name,
        },
    )

    stripe_prep(event.api_type)
    try:
        application_fee = stripe.ApplicationFee.all(charge=charge).data[0]
        application_fee_refund = application_fee.refunds.data[0]
    except IndexError:
        raise Exception("No application fee refund found.")
    return {
        'refund': refund,
        'application_fee_refund': application_fee_refund,
    }
예제 #4
0
def stripe_charge(source, amount, order, event, customer=None):
    if amount < 0:
        raise InvalidAmountException('Cannot charge an amount less than zero.')
    stripe_prep(event.api_type)
    if event.api_type == LIVE:
        stripe_account = event.organization.stripe_user_id
    else:
        stripe_account = event.organization.stripe_test_user_id

    if customer is not None:
        source = stripe.Token.create(
            customer=customer,
            card=source,
            stripe_account=stripe_account,
        )
    return stripe.Charge.create(
        amount=int(amount * 100),
        currency=event.currency,
        source=source,
        application_fee=int(get_fee(event, amount) * 100),
        expand=['balance_transaction'],
        metadata={
            'order': order.code,
            'event': event.name,
        },
        stripe_account=stripe_account,
    )
예제 #5
0
    def test_charge__no_customer(self):
        event = EventFactory(api_type=TEST,
                             application_fee_percent=Decimal('2.5'))
        order = OrderFactory(event=event)
        self.assertTrue(event.stripe_connected())
        stripe_prep(TEST)
        stripe.api_key = event.organization.stripe_test_access_token

        token = stripe.Token.create(card={
            "number": '4242424242424242',
            "exp_month": 12,
            "exp_year": 2050,
            "cvc": '123'
        }, )
        charge = stripe_charge(
            token,
            amount=42.15,
            order=order,
            event=event,
        )
        self.assertIsInstance(charge.balance_transaction, stripe.StripeObject)
        self.assertEqual(charge.balance_transaction.object,
                         "balance_transaction")
        self.assertEqual(len(charge.balance_transaction.fee_details), 2)
        self.assertEqual(charge.metadata, {
            'order': order.code,
            'event': event.name
        })

        txn = Transaction.from_stripe_charge(charge,
                                             api_type=event.api_type,
                                             event=event)
        # 42.15 * 0.025 = 1.05
        self.assertEqual(txn.application_fee, Decimal('1.05'))
        # (42.15 * 0.029) + 0.30 = 1.52
        self.assertEqual(txn.processing_fee, Decimal('1.52'))

        refund = stripe_refund(order=order,
                               event=event,
                               payment_id=txn.remote_id,
                               amount=txn.amount)
        self.assertEqual(refund['refund'].metadata, {
            'order': order.code,
            'event': event.name
        })

        refund_txn = Transaction.from_stripe_refund(refund,
                                                    api_type=event.api_type,
                                                    related_transaction=txn,
                                                    event=event)
        self.assertEqual(refund_txn.amount, -1 * txn.amount)
        self.assertEqual(refund_txn.application_fee, -1 * txn.application_fee)
        self.assertEqual(refund_txn.processing_fee, -1 * txn.processing_fee)
예제 #6
0
def stripe_organization_oauth_url(organization, api_type, request):
    stripe_prep(api_type)
    if api_type == LIVE:
        client_id = getattr(settings, 'STRIPE_APPLICATION_ID', None)
    else:
        client_id = getattr(settings, 'STRIPE_TEST_APPLICATION_ID', None)
    if not client_id:
        return ''
    redirect_uri = request.build_absolute_uri(reverse('brambling_stripe_connect'))
    base_url = "https://connect.stripe.com/oauth/authorize?client_id={client_id}&response_type=code&scope=read_write&state={state}&redirect_uri={redirect_uri}"
    return base_url.format(client_id=client_id,
                           state="{}|{}".format(organization.slug, api_type),
                           redirect_uri=urllib.quote(redirect_uri))
    def setUp(self):
        stripe_prep(TEST)

        self.event = EventFactory()
        self.order = OrderFactory()

        self.factory = RequestFactory()
        self.view = StripeWebhookView.as_view()
        self.data = json.dumps({'id': 'evt_123_event_id'})

        self.request = self.factory.post(path='/',
                                         content_type='application/json',
                                         data=self.data)
    def setUp(self):
        stripe_prep(TEST)

        self.event = EventFactory()
        self.order = OrderFactory()

        self.factory = RequestFactory()
        self.view = StripeWebhookView.as_view()
        self.data = json.dumps({'id': 'evt_123_event_id'})

        self.request = self.factory.post(path='/',
                                         content_type='application/json',
                                         data=self.data)
예제 #9
0
    def test_charge__customer(self):
        event = EventFactory(api_type=TEST,
                             application_fee_percent=Decimal('2.5'))
        order = OrderFactory(event=event)
        self.assertTrue(event.stripe_connected())
        stripe_prep(TEST)

        token = stripe.Token.create(
            card={
                "number": '4242424242424242',
                "exp_month": 12,
                "exp_year": 2050,
                "cvc": '123'
            },
        )
        customer = stripe.Customer.create(
            source=token,
        )
        source = customer.default_source
        charge = stripe_charge(
            source,
            amount=42.15,
            event=event,
            order=order,
            customer=customer
        )
        self.assertIsInstance(charge.balance_transaction, stripe.StripeObject)
        self.assertEqual(charge.balance_transaction.object, "balance_transaction")
        self.assertEqual(len(charge.balance_transaction.fee_details), 2)
        self.assertEqual(charge.metadata, {'order': order.code, 'event': event.name})

        txn = Transaction.from_stripe_charge(charge, api_type=event.api_type, event=event)
        # 42.15 * 0.025 = 1.05
        self.assertEqual(txn.application_fee, Decimal('1.05'))
        # (42.15 * 0.029) + 0.30 = 1.52
        self.assertEqual(txn.processing_fee, Decimal('1.52'))

        refund = stripe_refund(
            order=order,
            event=event,
            payment_id=txn.remote_id,
            amount=txn.amount
        )
        self.assertEqual(refund['refund'].metadata, {'order': order.code, 'event': event.name})

        refund_txn = Transaction.from_stripe_refund(refund, api_type=event.api_type, related_transaction=txn, event=event)
        self.assertEqual(refund_txn.amount, -1 * txn.amount)
        self.assertEqual(refund_txn.application_fee, -1 * txn.application_fee)
        self.assertEqual(refund_txn.processing_fee, -1 * txn.processing_fee)
예제 #10
0
 def test_add_card(self):
     stripe_prep(TEST)
     token = stripe.Token.create(card={
         "number": '4242424242424242',
         "exp_month": 12,
         "exp_year": 2050,
         "cvc": '123'
     }, )
     customer = stripe.Customer.create()
     self.assertEqual(customer.sources.total_count, 0)
     card = stripe_add_card(customer, token, TEST)
     customer = stripe.Customer.retrieve(customer.id)
     self.assertEqual(customer.sources.total_count, 1)
     stripe_delete_card(customer, card.id)
     customer = stripe.Customer.retrieve(customer.id)
     self.assertEqual(customer.sources.total_count, 0)
예제 #11
0
    def setUp(self):
        stripe_prep(TEST)

        self.event = EventFactory()
        self.order = OrderFactory(event=self.event)

        self.factory = RequestFactory()
        self.view = StripeWebhookView.as_view()
        self.stripe_event = {'id': 'evt_123_event_id'}
        self.data = json.dumps(self.stripe_event)

        self.request = self.factory.post(path='/',
                                         content_type='application/json',
                                         data=self.data)

        item = ItemFactory(event=self.event)
        item_option = ItemOptionFactory(price=60, item=item)
        self.order.add_to_cart(item_option)

        token = stripe.Token.create(
            card={
                'number': '4242424242424242',
                'exp_month': 12,
                'exp_year': 2017,
                'cvc': '123'
            },
        )

        charge = stripe_charge(token, 100, self.order, self.event)

        self.txn = Transaction.from_stripe_charge(
            charge,
            event=self.event,
            order=self.order,
            api_type=self.event.api_type,
        )

        self.refund = stripe_refund(self.order, self.event, charge.id, 100)

        data = mock.Mock(object=mock.Mock(name='charge', id=charge.id))
        self.mock_event = mock.Mock(
            data=data,
            type='charge.refunded',
            livemode=False,
        )
        self.order.mark_cart_paid(self.txn)
예제 #12
0
    def test_charge__negative_amount(self):
        event = EventFactory(api_type=TEST,
                             application_fee_percent=Decimal('2.5'))
        order = OrderFactory(event=event)
        stripe_prep(TEST)
        stripe.api_key = event.organization.stripe_test_access_token
        token = stripe.Token.create(
            card={
                "number": '4242424242424242',
                "exp_month": 12,
                "exp_year": 2050,
                "cvc": '123'
            },
        )

        with self.assertRaises(InvalidAmountException):
            stripe_charge(token, amount=Decimal('-9.01'), order=order,
                          event=event)
예제 #13
0
    def test_charge__negative_amount(self):
        event = EventFactory(api_type=TEST,
                             application_fee_percent=Decimal('2.5'))
        order = OrderFactory(event=event)
        stripe_prep(TEST)
        stripe.api_key = event.organization.stripe_test_access_token
        token = stripe.Token.create(card={
            "number": '4242424242424242',
            "exp_month": 12,
            "exp_year": 2050,
            "cvc": '123'
        }, )

        with self.assertRaises(InvalidAmountException):
            stripe_charge(token,
                          amount=Decimal('-9.01'),
                          order=order,
                          event=event)
예제 #14
0
 def test_add_card(self):
     stripe_prep(TEST)
     token = stripe.Token.create(
         card={
             "number": '4242424242424242',
             "exp_month": 12,
             "exp_year": 2050,
             "cvc": '123'
         },
     )
     customer = stripe.Customer.create()
     self.assertEqual(customer.sources.total_count, 0)
     card = stripe_add_card(customer, token, TEST)
     customer = stripe.Customer.retrieve(customer.id)
     self.assertEqual(customer.sources.total_count, 1)
     stripe_delete_card(customer, card.id)
     customer = stripe.Customer.retrieve(customer.id)
     self.assertEqual(customer.sources.total_count, 0)
    def setUp(self):
        stripe_prep(TEST)

        self.event = EventFactory()
        self.order = OrderFactory(event=self.event)

        self.factory = RequestFactory()
        self.view = StripeWebhookView.as_view()
        self.stripe_event = {'id': 'evt_123_event_id'}
        self.data = json.dumps(self.stripe_event)

        self.request = self.factory.post(path='/',
                                         content_type='application/json',
                                         data=self.data)

        item = ItemFactory(event=self.event)
        item_option = ItemOptionFactory(price=60, item=item)
        self.order.add_to_cart(item_option)

        token = stripe.Token.create(card={
            'number': '4242424242424242',
            'exp_month': 12,
            'exp_year': 2017,
            'cvc': '123'
        }, )

        charge = stripe_charge(token, 100, self.order, self.event)

        self.txn = Transaction.from_stripe_charge(
            charge,
            event=self.event,
            order=self.order,
            api_type=self.event.api_type,
        )

        self.refund = stripe_refund(self.order, self.event, charge.id, 100)

        data = mock.Mock(object=mock.Mock(name='charge', id=charge.id))
        self.mock_event = mock.Mock(
            data=data,
            type='charge.refunded',
            livemode=False,
        )
        self.order.mark_cart_paid(self.txn)
예제 #16
0
파일: api.py 프로젝트: kahihia/django
def stripe_get_customer(user, api_type, create=True):
    stripe_prep(api_type)

    if api_type == LIVE:
        customer_attr = 'stripe_customer_id'
    else:
        customer_attr = 'stripe_test_customer_id'
    customer_id = getattr(user, customer_attr)

    if not customer_id:
        if not create:
            return None
        customer = stripe.Customer.create(
            email=user.email,
            description=user.get_full_name(),
            metadata={'brambling_id': user.id},
        )
        setattr(user, customer_attr, customer.id)
        user.save()
    else:
        customer = stripe.Customer.retrieve(customer_id)
    return customer
예제 #17
0
def stripe_get_customer(user, api_type, create=True):
    stripe_prep(api_type)

    if api_type == LIVE:
        customer_attr = 'stripe_customer_id'
    else:
        customer_attr = 'stripe_test_customer_id'
    customer_id = getattr(user, customer_attr)

    if not customer_id:
        if not create:
            return None
        customer = stripe.Customer.create(
            email=user.email,
            description=user.get_full_name(),
            metadata={
                'brambling_id': user.id
            },
        )
        setattr(user, customer_attr, customer.id)
        user.save()
    else:
        customer = stripe.Customer.retrieve(customer_id)
    return customer
예제 #18
0
    def post(self, request):
        if request.META['CONTENT_TYPE'] != 'application/json':
            raise Http404('Incorrect content type')

        try:
            event_data = json.loads(request.body)
        except ValueError:
            raise Http404('Webhook failed to decode request body')

        stripe_event_id = event_data.get('id')
        if not stripe_event_id:
            raise Http404('Event does not have an id')

        if event_data.get('livemode', False):
            stripe_prep(LIVE)
        else:
            stripe_prep(TEST)

        try:
            event = stripe.Event.retrieve(stripe_event_id)
        except stripe.error.InvalidRequestError:
            raise Http404('Event not found on stripe')

        if event.type != 'charge.refunded':
            return HttpResponse(status=200)

        if event.livemode:
            api_type = ProcessedStripeEvent.LIVE
        else:
            api_type = ProcessedStripeEvent.TEST

        _, new_event = ProcessedStripeEvent.objects.get_or_create(
            api_type=api_type,
            stripe_event_id=stripe_event_id,
        )

        if not new_event:
            return HttpResponse(status=200)

        try:
            charge_id = event.data.object.id
            txn = Transaction.objects.get(
                remote_id=charge_id,
                api_type=api_type,
            )
        except Transaction.DoesNotExist:
            return HttpResponse(status=200)
        except AttributeError:
            raise Http404('Charge id not found')

        event = txn.event
        if event.api_type == LIVE:
            access_token = event.organization.stripe_access_token
        else:
            access_token = event.organization.stripe_test_access_token
        stripe.api_key = access_token

        try:
            charge = stripe.Charge.retrieve(
                charge_id,
                expand=[
                    'balance_transaction',
                    'application_fee',
                    'refunds.balance_transaction',
                ],
            )
        except stripe.error.InvalidRequestError:
            raise Http404('Charge not found on stripe')

        for refund in charge.refunds:
            if Transaction.objects.filter(
                transaction_type=Transaction.REFUND,
                method=Transaction.STRIPE,
                remote_id=refund.id,
                related_transaction=txn,
            ).exists():
                continue
            application_fee_refund = charge.application_fee.refunds.data[0]
            refund_group = {
                'refund': refund,
                'application_fee_refund': application_fee_refund,
            }

            refund_kwargs = {
                'order': txn.order,
                'related_transaction': txn,
                'api_type': txn.api_type,
                'event': txn.event,
            }
            Transaction.from_stripe_refund(refund_group, **refund_kwargs)

        return HttpResponse(status=200)
 def setUp(self):
     stripe_prep(TEST)
     self.factory = RequestFactory()
     self.view = StripeWebhookView.as_view()
예제 #20
0
    def post(self, request):
        if request.META['CONTENT_TYPE'] != 'application/json':
            raise Http404('Incorrect content type')

        try:
            event_data = json.loads(request.body)
        except ValueError:
            raise Http404('Webhook failed to decode request body')

        stripe_event_id = event_data.get('id')
        if not stripe_event_id:
            raise Http404('Event does not have an id')

        if event_data.get('livemode', False):
            stripe_prep(LIVE)
        else:
            stripe_prep(TEST)

        try:
            event = stripe.Event.retrieve(stripe_event_id)
        except stripe.error.InvalidRequestError:
            raise Http404('Event not found on stripe')

        if event.type != 'charge.refunded':
            return HttpResponse(status=200)

        if event.livemode:
            api_type = ProcessedStripeEvent.LIVE
        else:
            api_type = ProcessedStripeEvent.TEST

        _, new_event = ProcessedStripeEvent.objects.get_or_create(
            api_type=api_type,
            stripe_event_id=stripe_event_id,
        )

        if not new_event:
            return HttpResponse(status=200)

        try:
            charge_id = event.data.object.id
            txn = Transaction.objects.get(
                remote_id=charge_id,
                api_type=api_type,
            )
        except Transaction.DoesNotExist:
            return HttpResponse(status=200)
        except AttributeError:
            raise Http404('Charge id not found')

        event = txn.event
        if event.api_type == LIVE:
            access_token = event.organization.stripe_access_token
        else:
            access_token = event.organization.stripe_test_access_token
        stripe.api_key = access_token

        try:
            charge = stripe.Charge.retrieve(
                charge_id,
                expand=[
                    'balance_transaction',
                    'application_fee',
                    'refunds.balance_transaction',
                ],
            )
        except stripe.error.InvalidRequestError:
            raise Http404('Charge not found on stripe')

        for refund in charge.refunds:
            if Transaction.objects.filter(
                    transaction_type=Transaction.REFUND,
                    method=Transaction.STRIPE,
                    remote_id=refund.id,
                    related_transaction=txn,
            ).exists():
                continue
            application_fee_refund = charge.application_fee.refunds.data[0]
            refund_group = {
                'refund': refund,
                'application_fee_refund': application_fee_refund,
            }

            refund_kwargs = {
                'order': txn.order,
                'related_transaction': txn,
                'api_type': txn.api_type,
                'event': txn.event,
            }
            Transaction.from_stripe_refund(refund_group, **refund_kwargs)

        return HttpResponse(status=200)
예제 #21
0
def stripe_add_card(customer, token, api_type):
    stripe_prep(api_type)
    return customer.sources.create(source=token)
예제 #22
0
파일: api.py 프로젝트: kahihia/django
def stripe_add_card(customer, token, api_type):
    stripe_prep(api_type)
    return customer.sources.create(source=token)
예제 #23
0
 def setUp(self):
     stripe_prep(TEST)
     self.factory = RequestFactory()
     self.view = StripeWebhookView.as_view()
예제 #24
0
    def test_partial_refunds(self):
        event = EventFactory(api_type=TEST,
                             application_fee_percent=Decimal('2.5'))
        order = OrderFactory(event=event)
        self.assertTrue(event.stripe_connected())
        stripe_prep(TEST)
        stripe.api_key = event.organization.stripe_test_access_token

        token = stripe.Token.create(
            card={
                "number": '4242424242424242',
                "exp_month": 12,
                "exp_year": 2050,
                "cvc": '123'
            },
        )
        charge = stripe_charge(
            token,
            amount=42.15,
            order=order,
            event=event,
        )
        self.assertIsInstance(charge.balance_transaction, stripe.StripeObject)
        self.assertEqual(charge.balance_transaction.object, "balance_transaction")
        self.assertEqual(len(charge.balance_transaction.fee_details), 2)
        self.assertEqual(charge.metadata, {'order': order.code, 'event': event.name})

        txn = Transaction.from_stripe_charge(charge, api_type=event.api_type, event=event)
        # 42.15 * 0.025 = 1.05
        self.assertEqual(txn.application_fee, Decimal('1.05'))
        # (42.15 * 0.029) + 0.30 = 1.52
        self.assertEqual(txn.processing_fee, Decimal('1.52'))

        refund1_amount = 10
        refund1 = stripe_refund(
            order=order,
            event=event,
            payment_id=txn.remote_id,
            amount=refund1_amount
        )
        self.assertEqual(refund1['refund'].metadata, {'order': order.code, 'event': event.name})

        refund1_txn = Transaction.from_stripe_refund(refund1, api_type=event.api_type, related_transaction=txn, event=event)

        self.assertEqual(refund1_txn.amount, Decimal('-10.00'))
        # 10.00 * 0.025 = 0.25
        self.assertEqual(refund1_txn.application_fee, Decimal('-0.25'))
        # 10.00 * 0.029 = 0.29
        self.assertEqual(refund1_txn.processing_fee, Decimal('-0.29'))

        refund2_amount = 20
        refund2 = stripe_refund(
            order=order,
            event=event,
            payment_id=txn.remote_id,
            amount=refund2_amount
        )
        self.assertEqual(refund2['refund'].metadata, {'order': order.code, 'event': event.name})

        refund2_txn = Transaction.from_stripe_refund(refund2, api_type=event.api_type, related_transaction=txn, event=event)

        self.assertEqual(refund2_txn.amount, Decimal('-20.00'))
        # 20.00 * 0.025 = 0.50
        self.assertEqual(refund2_txn.application_fee, Decimal('-0.50'))
        # 20.00 * 0.029 = 0.58
        self.assertEqual(refund2_txn.processing_fee, Decimal('-0.58'))