Repository: liberapay/liberapay.com

Issue:
Add details to Stripe payments
Hi, currently all payments done via Stripe are just blank apart from the money amount. Stripe have extra fields you (as the service) can fill out, to note that it's coming from Liberapay. Can you please make the payouts more descriptive. It's becoming a bit of a nuisance manually adding details to each Stripe payment from Liberapay to ensure things are easy to match up between things.


Discussion:
On our side we can set two relevant attributes on charges and transfers: `description` and `metadata`. However I'm not sure what you can see on your side.
When I look on the recipient's side, I see a special `Charge` object with an empty `metadata` dictionary. In other words, the `metadata` set by Liberapay isn't visible to the recipient.

However, the object does contain data on its “source”, so you can identify payments as coming from Liberapay if you use Stripe's API.

```json
{
  …
  "source": {
    "application_icon": "https://s3.amazonaws.com/stripe-uploads/acct_1ChyayFk4eGpfLOCapplication-icon-icon_v2_black.75.png",
    "application_logo": "https://s3.amazonaws.com/stripe-uploads/acct_1ChyayFk4eGpfLOCapplication-logo-icon_v2_yellow_r.100.png",
    "application_name": "Liberapay",
    "application_url": "https://liberapay.com/",
    "id": "acct_1ChyayFk4eGpfLOC",
    "object": "account"
  },
  …
}
```
Here's some examples.

A payment from Liberapay is basically blank: https://imgur.com/4v38AW7

From a different site that does donations: https://imgur.com/i7iFDeO

For any details users allow to show, it should be noted. At the very least it should note it's from Liberapay.
The BuyMeACoffee example is a different payment type that lets you see who the donor is. It's basically the same thing as you processing the payment from the donor directly on your website. Liberapay donations are supposed to be anonymous, so we do things differently.
I'm not asking you to give full donor info, I'm asking you to do more than nothing that's currently shown. At the very least note clearly it's from Liberapay with any other possible info. Right now it's just blank, which is my point.
We're going to try (see #1912), but I can't guarantee that it'll work. The payment object you see on your side isn't the one that Liberapay creates and sees, it's a different one created automatically ~~and opaquely~~ by Stripe.
Great, will update when I see anything and come back another time to report.
The change is now deployed. I'll be able to see if it worked as soon as my own Stripe account receives a new payment through Liberapay.
The descriptions added on Liberapay's side haven't solve the problem, they aren't visible on the recipient's side.

We're going to have to modify the payment on the recipient's side instead. This solution only came to me a few minutes ago, but this time I'm confident that it will solve the problem, because I've tested it manually.

@LiamDawe If you have something to say about what you would like to see in the payment's `description` and `metadata` attributes, now's the time to say it.
Mainly just make it clear the payment is from Liberapay :+1: 

Resolving patch:
diff --git a/liberapay/payin/stripe.py b/liberapay/payin/stripe.py
--- a/liberapay/payin/stripe.py
+++ b/liberapay/payin/stripe.py
@@ -483,7 +483,7 @@ def settle_destination_charge(db, payin, charge, pt, intent_id=None):
 
 
 def update_transfer_metadata(tr, pt):
-    """Set the Transfer's `description` and `metadata` if they're missing.
+    """Set `description` and `metadata` if they're missing.
 
     Args:
         tr (Transfer): the `stripe.Transfer` object to update
@@ -496,7 +496,33 @@ def update_transfer_metadata(tr, pt):
     if not getattr(tr, 'metadata', None):
         attrs['metadata'] = {'payin_transfer_id': pt.id}
     if attrs:
-        tr.modify(tr.id, **attrs)
+        try:
+            tr = tr.modify(tr.id, **attrs)
+        except Exception as e:
+            website.tell_sentry(e, {})
+            return tr
+    if getattr(tr, 'destination_payment', None):
+        py = tr.destination_payment
+        if isinstance(py, str):
+            try:
+                py = stripe.Charge.retrieve(py, stripe_account=tr.destination)
+            except Exception as e:
+                website.tell_sentry(e, {})
+                return tr
+        attrs = {}
+        if not getattr(py, 'description', None):
+            attrs['description'] = tr.description
+        metadata = getattr(py, 'metadata', None) or {}
+        if 'liberapay_transfer_id' not in metadata:
+            metadata['liberapay_transfer_id'] = pt.id
+            attrs['metadata'] = metadata
+        if attrs:
+            attrs['stripe_account'] = tr.destination
+            try:
+                py.modify(py.id, **attrs)
+            except Exception as e:
+                website.tell_sentry(e, {})
+    return tr
 
 
 def generate_charge_description(payin):


Test patch: