Repository: liberapay/liberapay.com

Issue:
Adding money to Liberapay via direct debit cause 400 bad request
Hi all,

After creating an account I tried to add money to liberapay via direct debit. I entered my IBAN number and selected one of the precomputed amounts. But when pressing the green **Procced** button I was greeted with an error page with the following message.  

400
Bad Request
500 {"Message":"Internal Server Error","Type":"other","Id":"4c25fc92-2b83-4516-9a7c-55ba091e114a#1512924143","Date":1512924145.0,"errors":null}

Whatever I might have done wrong, that is not a message to show users. 

Might be worth to mention that I am accessing the site from Sweden and tried to make the transaction in euro. 


Discussion:
Hi,

This is indeed a serious problem and you're the second person reporting it today.

The error seems to arise during mandate creation, it probably means that either Mangopay or GoCardless are malfunctioning. I haven't received any incident notification from Mangopay and I don't see any in <http://status.mangopay.com/> either. Same for GoCardless, <https://www.gocardless-status.com/>.

More error messages from the other person who reported this issue via email:

500 {"Message":"Internal Server Error","Type":"other","Id":"3d4a1762-10f3-41f2-b5dd-e64126ee3a09#1512912449","Date":1512912450.0,"errors":null}

500 {"Message":"Internal Server Error","Type":"other","Id":"d18f1788-877c-4deb-9e0c-e0dd94e6b42d#1512912774","Date":1512912775.0,"errors":null}

Those were the errors I reported. I actually have 4 deposits "awaiting confirmation" in my wallet from the attempts I made (I made 4 attempts). I was also accessing Librapay from Sweden and tried to make transactions in euro.

Resolving patch:
diff --git a/liberapay/constants.py b/liberapay/constants.py
--- a/liberapay/constants.py
+++ b/liberapay/constants.py
@@ -100,6 +100,9 @@ def with_vat(self):
 
 EPOCH = datetime(1970, 1, 1, 0, 0, 0, 0, utc)
 
+EUROZONE = set("AT BE CY DE EE ES FI FR GR IE IT LT LU LV MT NL PT SI SK".split())
+SEPA = EUROZONE | set("BG CH CZ DK GB GI HR HU IS LI MC NO PL RO SE".split())
+
 EVENTS = [
     Event('income', 1, _("When I receive money")),
     Event('low_balance', 2, _("When there isn't enough money in my wallet to cover my donations")),
@@ -118,10 +121,6 @@ def with_vat(self):
 EVENTS_S = ' '.join(EVENTS.keys())
 
 # https://www.mangopay.com/pricing/
-SEPA = set("""
-    AT BE BG CH CY CZ DE DK EE ES ES FI FR GB GI GR HR HU IE IS IT LI LT LU LV
-    MC MT NL NO PL PT RO SE SI SK
-""".split())
 FEE_PAYIN_BANK_WIRE = Fees(Decimal('0.005'), 0)  # 0.5%
 FEE_PAYIN_CARD = {
     'EUR': Fees(Decimal('0.018'), Money('0.18', 'EUR')),  # 1.8% + €0.18


Test patch:
diff --git a/tests/py/test_public_json.py b/tests/py/test_public_json.py
--- a/tests/py/test_public_json.py
+++ b/tests/py/test_public_json.py
@@ -51,63 +51,6 @@ def test_anonymous_gets_user_goal_if_set(self):
         data = json.loads(self.client.GET('/alice/public.json').text)
         assert data['goal'] == {"amount": "1.00", "currency": "EUR"}
 
-    def test_authenticated_user_gets_their_tip(self):
-        alice = self.make_participant('alice', balance=100)
-        bob = self.make_participant('bob')
-
-        alice.set_tip_to(bob, EUR('1.00'))
-
-        raw = self.client.GET('/bob/public.json', auth_as=alice).text
-
-        data = json.loads(raw)
-
-        assert data['receiving'] == {"amount": "1.00", "currency": "EUR"}
-        assert data['my_tip'] == {"amount": "1.00", "currency": "EUR"}
-
-    def test_authenticated_user_doesnt_get_other_peoples_tips(self):
-        alice = self.make_participant('alice', balance=100)
-        bob = self.make_participant('bob', balance=100)
-        carl = self.make_participant('carl', balance=100)
-        dana = self.make_participant('dana')
-
-        alice.set_tip_to(dana, EUR('1.00'))
-        bob.set_tip_to(dana, EUR('3.00'))
-        carl.set_tip_to(dana, EUR('12.00'))
-
-        raw = self.client.GET('/dana/public.json', auth_as=alice).text
-
-        data = json.loads(raw)
-
-        assert data['receiving'] == {"amount": "16.00", "currency": "EUR"}
-        assert data['my_tip'] == {"amount": "1.00", "currency": "EUR"}
-
-    def test_authenticated_user_gets_zero_if_they_dont_tip(self):
-        alice = self.make_participant('alice', balance=100)
-        bob = self.make_participant('bob', balance=100)
-        carl = self.make_participant('carl')
-
-        bob.set_tip_to(carl, EUR('3.00'))
-
-        raw = self.client.GET('/carl/public.json', auth_as=alice).text
-
-        data = json.loads(raw)
-
-        assert data['receiving'] == {"amount": "3.00", "currency": "EUR"}
-        assert data['my_tip'] == {"amount": "0.00", "currency": "EUR"}
-
-    def test_authenticated_user_gets_self_for_self(self):
-        alice = self.make_participant('alice', balance=100)
-        bob = self.make_participant('bob')
-
-        alice.set_tip_to(bob, EUR('3.00'))
-
-        raw = self.client.GET('/bob/public.json', auth_as=bob).text
-
-        data = json.loads(raw)
-
-        assert data['receiving'] == {"amount": "3.00", "currency": "EUR"}
-        assert data['my_tip'] == 'self'
-
     def test_access_control_allow_origin_header_is_asterisk(self):
         self.make_participant('alice', balance=100)
         response = self.client.GET('/alice/public.json')
@@ -139,7 +82,6 @@ def test_jsonp_works(self):
     "goal": null,
     "id": %(user_id)s,
     "kind": "individual",
-    "my_tip": "self",
     "npatrons": 1,
     "receiving": {
         "amount": "3.00",