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())