Repository: liberapay/liberapay.com

Issue:
/edit/goal
Hello.

When I want to set my role/goal on liberapay.com, I get an error:

```
<input type="radio" name="goal" id="goal-0" value="0.00">

Bad Request
"0.00" is not a properly formatted number. Perhaps you meant 0 oder 0?
```

Just wanted to report it.


Discussion:
What is the language you were using when you got that error? If you were browsing in German or other languages which use commas to separate decimal numbers, that's the correct behaviour.

What we can improve is the error message for 0, both suggestions are the same. 
@haheute Thanks for this report, I can indeed replicate the problem by switching my browser to German.

@jorgesumle It's not the correct behavior, we're using the wrong function to parse the number.

Resolving patch:
diff --git a/liberapay/constants.py b/liberapay/constants.py
--- a/liberapay/constants.py
+++ b/liberapay/constants.py
@@ -271,12 +271,14 @@ def with_vat(self):
         KY KZ LA LC LI LK LS LT LU LV MA MC MD ME MG MH MK ML MN MQ MR MS MT MU
         MV MW MX MY MZ NA NC NE NF NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PL
         PM PN PT PW PY QA RE RO RS RU RW SA SB SC SE SG SH SI SJ SK SL SM SN SO
-        SR ST SV SZ TC TD TG TH TJ TM TN TO TT TT TT TT TV TW TZ UA UG UK US UY
+        SR ST SV SZ TC TD TG TH TJ TM TN TO TT TT TT TT TV TW TZ UA UG GB US UY
         VA VC VE VG VN VU WF WS YE YT ZA ZM ZW
+        PR
     """.split()),  # https://www.paypal.com/us/webapps/mpp/country-worldwide
 
     'stripe': set("""
         AT AU BE CA CH DE DK ES FI FR GB HK IE IT JP LU NL NO NZ PT SE SG US
+        PR
     """.split()),  # https://stripe.com/global
 }
 
diff --git a/liberapay/models/participant.py b/liberapay/models/participant.py
--- a/liberapay/models/participant.py
+++ b/liberapay/models/participant.py
@@ -2184,6 +2184,7 @@ def get_tips_awaiting_renewal(self):
                      t.paid_in_advance < (t.periodic_amount * 0.75) OR
                      t.paid_in_advance < (t.amount * 4)
                    )
+               AND p.status = 'active'
           ORDER BY (t.paid_in_advance).amount / (t.amount).amount NULLS FIRST
                  , t.ctime
         """, (self.id,))]
diff --git a/liberapay/payin/stripe.py b/liberapay/payin/stripe.py
--- a/liberapay/payin/stripe.py
+++ b/liberapay/payin/stripe.py
@@ -38,12 +38,17 @@ def destination_charge(db, payin, payer, statement_descriptor):
     destination = db.one("SELECT id FROM payment_accounts WHERE pk = %s", (pt.destination,))
     amount = payin.amount
     route = ExchangeRoute.from_id(payer, payin.route)
+    if destination == 'acct_1ChyayFk4eGpfLOC':
+        # Stripe rejects the charge if the destination is our own account
+        destination = None
+    else:
+        destination = {'account': destination}
     try:
         charge = stripe.Charge.create(
             amount=amount.int().amount,
             currency=amount.currency.lower(),
             customer=route.remote_user_id,
-            destination={'account': destination},
+            destination=destination,
             metadata={'payin_id': payin.id},
             source=route.address,
             statement_descriptor=statement_descriptor,
@@ -62,13 +67,14 @@ def destination_charge(db, payin, payer, statement_descriptor):
     fee = Money(bt.fee, bt.currency.upper()) / 100
     net_amount = amount_settled - fee
 
-    tr = stripe.Transfer.retrieve(charge.transfer)
-    reversal = tr.reversals.create(
-        amount=bt.fee,
-        description="Stripe fee",
-        metadata={'payin_id': payin.id},
-        idempotency_key='payin_fee_%i' % payin.id,
-    )
+    if destination:
+        tr = stripe.Transfer.retrieve(charge.transfer)
+        reversal = tr.reversals.create(
+            amount=bt.fee,
+            description="Stripe fee",
+            metadata={'payin_id': payin.id},
+            idempotency_key='payin_fee_%i' % payin.id,
+        )
 
     r = db.one("""
         UPDATE payin_transfers
@@ -77,7 +83,7 @@ def destination_charge(db, payin, payer, statement_descriptor):
              , amount = %s
          WHERE payin = %s
      RETURNING id
-    """, (payin.status, charge.transfer, net_amount, payin.id))
+    """, (payin.status, getattr(charge, 'transfer', None), net_amount, payin.id))
     assert r, locals()
 
     return update_payin(


Test patch: