def post(self, request, *args, **kwargs):
        if request.META['CONTENT_TYPE'] != "application/json":
            raise Http404("Incorrect content type")

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

        if data.get('Type') != 'Transaction' or data.get('Subtype') != 'Status':
            raise Http404("Unhandled webhook type: {} / {}".format(data.get('Type'), data.get('Subtype')))

        try:
            txn = Transaction.objects.get(remote_id=data['Transaction']['Id'])
        except Transaction.DoesNotExist:
            raise Http404("Transaction doesn't exist")
        except KeyError:
            raise Http404("Data doesn't contain transaction id")

        dwolla_prep(txn.api_type)
        if not webhooks.verify(request.META.get('HTTP_X_DWOLLA_SIGNATURE'), request.body):
            raise SuspiciousOperation("Transaction signature doesn't verify properly")

        txn.is_confirmed = True if data['Transaction']['Status'] == 'processed' else False
        txn.save()
        return HttpResponse('')
    def test_dwolla_charge__user(self):
        event = EventFactory(api_type=Event.TEST,
                             application_fee_percent=Decimal('2.5'))
        self.assertTrue(event.dwolla_connected())
        dwolla_prep(Event.TEST)

        person = PersonFactory()
        order = OrderFactory(person=person, event=event)
        charge = dwolla_charge(
            sender=person,
            amount=42.15,
            order=order,
            event=event,
            pin=settings.DWOLLA_TEST_USER_PIN,
            source='Balance',
        )

        self.assertIsInstance(charge, dict)
        self.assertEqual(charge["Type"], "money_received")
        self.assertEqual(len(charge['Fees']), 2)
        self.assertEqual(charge["Notes"], "Order {} for {}".format(order.code, event.name))

        txn = Transaction.from_dwolla_charge(charge, event=event)
        # 42.15 * 0.025 = 1.05
        self.assertEqual(Decimal(txn.application_fee), Decimal('1.05'))
        # 0.25
        self.assertEqual(Decimal(txn.processing_fee), Decimal('0.25'))

        refund = dwolla_refund(
            order=order,
            event=event,
            payment_id=txn.remote_id,
            amount=txn.amount,
            pin=settings.DWOLLA_TEST_ORGANIZATION_PIN
        )

        self.assertIsInstance(refund, dict)
        self.assertEqual(refund["Amount"], txn.amount)

        refund_info = transactions.info(
            tid=str(refund['TransactionId']),
            alternate_token=dwolla_get_token(event.organization, event.api_type)
        )
        self.assertEqual(refund_info["Notes"], "Order {} for {}".format(order.code, event.name))

        refund_txn = Transaction.from_dwolla_refund(refund, txn, event=event)
        self.assertEqual(refund_txn.amount, -1 * txn.amount)
        self.assertEqual(refund_txn.application_fee, 0)
        self.assertEqual(refund_txn.processing_fee, 0)
    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        redirect_url = self.object.get_dwolla_connect_url()
        api_type = request.GET['api']
        if 'code' in request.GET:
            qs = request.GET.copy()
            del qs['code']
            if qs:
                redirect_url += "?" + "&".join([k + "=" + v
                                                for k, v in qs.iteritems()])
            dwolla_prep(api_type)
            oauth_tokens = oauth.get(request.GET['code'],
                                     redirect=request.build_absolute_uri(redirect_url))
            if 'access_token' in oauth_tokens:
                token = oauth_tokens['access_token']

                # Now get account info.
                account_info = accounts.full(token)

                if api_type == LIVE:
                    self.object.dwolla_user_id = account_info['Id']
                else:
                    self.object.dwolla_test_user_id = account_info['Id']

                dwolla_set_tokens(self.object, api_type, oauth_tokens)

                self.object.save()
                messages.success(request, "Dwolla account connected!")
            elif 'error_description' in oauth_tokens:
                messages.error(request, oauth_tokens['error_description'])
            else:
                messages.error(request, "Unknown error during dwolla connection.")
        elif 'error_description' in request.GET:
            messages.error(request, request.GET['error_description'])
        else:
            messages.error(request, "Unknown error during dwolla connection.")

        return HttpResponseRedirect(self.get_success_url())