mmohades / Venmo

Venmo API client for Python
GNU General Public License v3.0
145 stars 43 forks source link

get_user_transactions doesn't retrieve all transactions #26

Closed invictus2010 closed 3 years ago

invictus2010 commented 3 years ago

Hi there,

get_user_transactions does not retrieve all transactions. Specifically, the method does not retrieve transactions that are of the disbursement type.

I have noticed this error when I received a disbursement to my account, but it doesn't show up when I pull my transactions through this package. I'll attempt to see if I can figure out why it's skipping disbursements, but wanted to let the group know.

invictus2010 commented 3 years ago

The request URL that displays my transactions is https://account.venmo.com/api/stories?feedType=me&externalId={myID}

The response includes this, which is not returned by get_user_transactions

{
            "amount": "+ $17.25",
            "avatar": "https://d1v6x81qdeozhc.cloudfront.net/static/assets/generic-merchant-icon-28f6f027e35497269ca41be250c84ecf.png",
            "audience": "public",
            "date": "2020-12-01T17:23:12",
            "id": "3154749044299924050",
            "note": {
                "template": "Order number {deleted}"
            },
            "type": "disbursement",
            "attachments": [],
            "title": {
                "template": "<sender>{{sender.displayName}}</sender> paid <receiver>{{receiver.displayName}}</receiver>",
                "receiver": {
                    "id": "1938537289089024907",
                    "displayName": "you",
                    "username": "{deleted}"
                },
                "sender": {
                    "id": "3072575559323091623",
                    "displayName": "{deleted}",
                    "username": ""
                }
            },
mmohades commented 3 years ago

Thanks for providing the JSON response.

That's correct. Right now, only payment transactions are being processed. It's because the transaction body is different with different types, and the wrapper only supports the payment ones since that's the only type of transaction I've seen. I'll need a sample of other transaction types to add support for them. Other transaction types that I don't have a sample for are:

What is a disbursement transaction type and how do you make one? The JSON you provided, that's all the info a disbursement transaction has? If receiver and sender are users, then there has to be more info.

invictus2010 commented 3 years ago

What is a disbursement transaction type and how do you make one?

A disbursement transaction is when a business or vendor makes a payout on Venmo. Some e-commerce sites and marketplaces pay their suppliers through a Venmo disbursement. For instance, if you recharge Lime scooters you can opt to receive payment through Venmo.

I think Venmo's API has changed significantly since this repository was started. I was trying to reverse engineer how you put the library together, and I can't find many of the calls used here. The API here works! But I was seeing authorization as including api_access_key in the cookie header of the below request URL. I was using my browser, and wasn't on the app though. I'm also a newbie at this, so I could be mistaken about what this library is exactly doing ;). Happy to help out anyway I can.

EDIT: Nevermind, I'm looking at the API calls through my Venmo app and think that's how the repo found the API calls

Here's the complete response from request URL https://account.venmo.com/api/stories?feedType=me&externalId={myID}

{
    "nextId": "2960423109036868168",
    "stories": [{
        "amount": "+ $12.00",
        "avatar": "https://pics.venmo.com/75bf5739-537f-4c23-9bcb-80b61ff24f82?width=460&height=460&photoVersion=1",
        "audience": "private",
        "date": "2020-12-05T23:00:15",
        "id": "3157817790623121766",
        "note": {
            "template": "🐺 🍹"
        },
        "type": "payment",
        "attachments": [],
        "title": {
            "template": "<sender>{{sender.displayName}}</sender> paid <receiver>{{receiver.displayName}}</receiver>",
            "receiver": {
                "id": "1938537289089024907",
                "displayName": "you",
                "username": "{deleted}"
            },
            "sender": {
                "id": "1930526688542720966",
                "displayName": "{deleted}",
                "username": "{deleted}"
            }
        },
        "mentions": {
            "count": 0,
            "data": []
        },
        "externWalletStatus": null,
        "paymentId": "3157817789608099986",
        "likes": {
            "count": 0,
            "userCommentedOrLiked": false
        },
        "comments": {
            "count": 0,
            "userCommentedOrLiked": false
        }
    }, {
        "amount": "$325.25",
        "avatar": "",
        "audience": "private",
        "date": "2020-12-03T20:06:54",
        "id": "3156280990440096466",
        "note": {
            "template": "Estimated arrival: {{date}} <br /> Destination: {{name}} .. {{lastFour}}",
            "date": "12/4/2020",
            "name": "{deleted}",
            "lastFour": "{deleted}"
        },
        "type": "transfer",
        "attachments": [],
        "title": {
            "template": "<sender>Bank Transfer Initiated</sender>"
        },
        "mentions": {
            "count": 0,
            "data": []
        },
        "externWalletStatus": null,
        "subType": "standard"
    }, {
        "amount": "+ $308.00",
        "avatar": "https://pics.venmo.com/af33265d-fe9b-4b22-8a17-c198d32494d2?width=460&height=460&photoVersion=1",
        "audience": "private",
        "date": "2020-12-03T19:33:22",
        "id": "3156264110857913226",
        "note": {
            "template": "The most expensive gift I've ever purchased for a friend. Lol Thanks again, Cuz! 🤗"
        },
        "type": "payment",
        "attachments": [],
        "title": {
            "template": "<sender>{{sender.displayName}}</sender> paid <receiver>{{receiver.displayName}}</receiver>",
            "receiver": {
                "id": "1938537289089024907",
                "displayName": "you",
                "username": "{deleted}"
            },
            "sender": {
                "id": "2233591459217408834",
                "displayName": "{deleted}",
                "username": "{deleted}"
            }
        },
        "mentions": {
            "count": 0,
            "data": []
        },
        "externWalletStatus": null,
        "paymentId": "3156264110270710243",
        "likes": {
            "count": 0,
            "userCommentedOrLiked": false
        },
        "comments": {
            "count": 0,
            "userCommentedOrLiked": false
        }
    }, {
        "amount": "+ $17.25",
        "avatar": "https://d1v6x81qdeozhc.cloudfront.net/static/assets/generic-merchant-icon-28f6f027e35497269ca41be250c84ecf.png",
        "audience": "public",
        "date": "2020-12-01T17:23:12",
        "id": "3154749044299924050",
        "note": {
            "template": "Order number 16740435"
        },
        "type": "disbursement",
        "attachments": [],
        "title": {
            "template": "<sender>{{sender.displayName}}</sender> paid <receiver>{{receiver.displayName}}</receiver>",
            "receiver": {
                "id": "1938537289089024907",
                "displayName": "you",
                "username": "{deleted}"
            },
            "sender": {
                "id": "3072575559323091623",
                "displayName": "{deleted}",
                "username": ""
            }
        },
        "mentions": {
            "count": 0,
            "data": []
        },
        "externWalletStatus": null,
        "likes": {
            "count": 1,
            "userCommentedOrLiked": false
        },
        "comments": {
            "count": 0,
            "userCommentedOrLiked": false
        }
    }, {
        "amount": "- $70.00",
        "avatar": "https://pics.venmo.com/dfcc88c6-7323-4405-8c47-ebcab977026b?width=50&height=50&photoVersion=2&facebook=true",
        "audience": "private",
        "date": "2020-10-29T23:46:57",
        "id": "3131024593381228998",
        "note": {
            "template": "BBQ"
        },
        "type": "payment",
        "attachments": [{
            "url": "https://cdn.emogi.com/cxp/FAN/FANJR-full.gif?de=Y83JMOY43KWHZ1DFTZE0453CWBAENZPW&ma=8T48NX3VJNDMCAYJ&co=FANJR&env&end",
            "type": "holler"
        }],
        "title": {
            "template": "<sender>{{sender.displayName}}</sender> paid <receiver>{{receiver.displayName}}</receiver>",
            "receiver": {
                "id": "1377912305483776073",
                "displayName": "{deleted}",
                "username": "{deleted}"
            },
            "sender": {
                "id": "1938537289089024907",
                "displayName": "{deleted}",
                "username": "{deleted}"
            }
        },
        "mentions": {
            "count": 0,
            "data": []
        },
        "externWalletStatus": null,
        "paymentId": "3131024592584311572",
        "likes": {
            "count": 0,
            "userCommentedOrLiked": false
        },
        "comments": {
            "count": 0,
            "userCommentedOrLiked": false
        }
    }, {
        "amount": "$280.27",
        "avatar": "",
        "audience": "private",
        "date": "2020-10-14T19:26:54",
        "id": "3120022072747622940",
        "note": {
            "template": "Estimated arrival: {{date}} <br /> Destination: {{name}} .. {{lastFour}}",
            "date": "10/15/2020",
            "name": "{deleted}",
            "lastFour": "{deleted}"
        },
        "type": "transfer",
        "attachments": [],
        "title": {
            "template": "<sender>Bank Transfer Initiated</sender>"
        },
        "mentions": {
            "count": 0,
            "data": []
        },
        "externWalletStatus": null,
        "subType": "standard"
    }, {
        "amount": "+ $244.00",
        "avatar": "https://pics.venmo.com/af33265d-fe9b-4b22-8a17-c198d32494d2?width=460&height=460&photoVersion=1",
        "audience": "private",
        "date": "2020-10-14T19:12:09",
        "id": "3120014643980927048",
        "note": {
            "template": "👞🦆💚"
        },
        "type": "payment",
        "attachments": [],
        "title": {
            "template": "<sender>{{sender.displayName}}</sender> paid <receiver>{{receiver.displayName}}</receiver>",
            "receiver": {
                "id": "1938537289089024907",
                "displayName": "{deleted}",
                "username": "{deleted}"
            },
            "sender": {
                "id": "2233591459217408834",
                "displayName": "{deleted}",
                "username": "{deleted}"
            }
        },
        "mentions": {
            "count": 0,
            "data": []
        },
        "externWalletStatus": null,
        "paymentId": "3120014643368559239",
        "likes": {
            "count": 1,
            "userCommentedOrLiked": true
        },
        "comments": {
            "count": 0,
            "userCommentedOrLiked": false
        }
    }, {
        "amount": "- $50.00",
        "avatar": "https://pics.venmo.com/dfcc88c6-7323-4405-8c47-ebcab977026b?width=50&height=50&photoVersion=2&facebook=true",
        "audience": "private",
        "date": "2020-09-26T23:21:39",
        "id": "3107094266434814120",
        "note": {
            "template": "😷😋"
        },
        "type": "payment",
        "attachments": [],
        "title": {
            "template": "<sender>{{sender.displayName}}</sender> paid <receiver>{{receiver.displayName}}</receiver>",
            "receiver": {
                "id": "1377912305483776073",
                "displayName": "{deleted}",
                "username": "{deleted}"
            },
            "sender": {
                "id": "1938537289089024907",
                "displayName": "{deleted}",
                "username": "{deleted}"
            }
        },
        "mentions": {
            "count": 0,
            "data": []
        },
        "externWalletStatus": null,
        "paymentId": "3107094265721782354",
        "likes": {
            "count": 0,
            "userCommentedOrLiked": false
        },
        "comments": {
            "count": 0,
            "userCommentedOrLiked": false
        }
    }, {
        "amount": "+ $60.00",
        "avatar": "https://pics.venmo.com/c0a98363-fcba-4e8a-b1fa-5de7efcaba42?width=460&height=460&photoVersion=7",
        "audience": "friends",
        "date": "2020-07-20T18:20:33",
        "id": "3057657962483942153",
        "note": {
            "template": "printer! thanks so much!"
        },
        "type": "payment",
        "attachments": [],
        "title": {
            "template": "<sender>{{sender.displayName}}</sender> paid <receiver>{{receiver.displayName}}</receiver>",
            "receiver": {
                "id": "1938537289089024907",
                "displayName": "you",
                "username": "{deleted}"
            },
            "sender": {
                "id": "1993191108640768986",
                "displayName": "{deleted}",
                "username": "{deleted}"
            }
        },
        "mentions": {
            "count": 0,
            "data": []
        },
        "externWalletStatus": null,
        "paymentId": "3057657961812853171",
        "likes": {
            "count": 0,
            "userCommentedOrLiked": false
        },
        "comments": {
            "count": 0,
            "userCommentedOrLiked": false
        }
    }, {
        "amount": "- $10.00",
        "avatar": "https://pics.venmo.com/dfcc88c6-7323-4405-8c47-ebcab977026b?width=50&height=50&photoVersion=2&facebook=true",
        "audience": "private",
        "date": "2020-03-08T14:32:15",
        "id": "2960423109036868168",
        "note": {
            "template": "🙏🙏🙏"
        },
        "type": "payment",
        "attachments": [],
        "title": {
            "template": "<sender>{{sender.displayName}}</sender> paid <receiver>{{receiver.displayName}}</receiver>",
            "receiver": {
                "id": "2045083339718656998",
                "displayName": "{deleted}",
                "username": "{deleted}"
            },
            "sender": {
                "id": "1938537289089024907",
                "displayName": "{deleted}",
                "username": "{deleted}"
            }
        },
        "mentions": {
            "count": 0,
            "data": []
        },
        "externWalletStatus": null,
        "paymentId": "2960423108567106150",
        "likes": {
            "count": 0,
            "userCommentedOrLiked": false
        },
        "comments": {
            "count": 0,
            "userCommentedOrLiked": false
        }
    }]
}
invictus2010 commented 3 years ago

I'd expect or recommend that get_user_transactions make a request to this endpoint: https://api.venmo.com/v1/stories/target-or-actor/{userID}

I've found that this endpoint will return all transactions regardless of transaction type.

If you agree, I'd love to make the pull request, but again I'm kind of a newbie...I'm just running the requests using the request library in my iPython notebook.

mmohades commented 3 years ago

That's right, this API wrapper is built based on their phone app's API. The website works a little differently and there are often more limitations on their API when it comes to rate-limit and information. That's the endpoint used for getting the transactions. As I mentioned before, since I haven't seen all the transaction types, I'm only processing payment transactions since they have different structures. You can see here that any other transaction type is skipped.

Thanks for providing the JSON! That will help me with both transfer and disbursement types. I'll look into it better to add support for them as well.

mmohades commented 3 years ago

btw, you can use the API client instead of the request library if you want. I think the following should work:

from venmo_api import ApiClient
user_id = '12345...'
api_client = ApiClient(access_token=access_token)

resource_path = f'/stories/target-or-actor/{user_id}'
response = api_client.call_api(resource_path=resource_path, method='GET')
alexsands commented 3 years ago

Thanks for providing the JSON! That will help me with both transfer and disbursement types. I'll look into it better to add support for them as well.

I was also curious why the length of my resulting transactions didn't === count for get_user_transactions, but noticed it only supports payment types right now. I had a few transfer types in my transactions. If you'd like an example of a transfer type object, here's one from my ApiClient call:

{'app': None,
    'audience': 'private',
    'authorization': None,
    'comments': {'count': 0, 'data': []},
    'date_created': '2021-01-01T07:36:39',
    'date_updated': '2021-01-01T07:36:39',
    'id': '3177656623658164291',
    'likes': {'count': 0, 'data': []},
    'mentions': {'count': 0, 'data': []},
    'note': None,
    'payment': None,
    'transfer': {'amount': 100.0,
                 'amount_cents': 10000,
                 'amount_fee_cents': 0,
                 'amount_requested_cents': 10000,
                 'date_requested': '2021-01-01T07:36:39',
                 'destination': {'account_status': 'verified',
                                 'asset_name': 'wells',
                                 'assets': {'detail': 'https://d1v6x81qdeozhc.cloudfront.net/static/images/payment-methods/banks/wells/detail-a1bfdf35000cb6d3e3e4bec7c8f108eb.jpg',
                                            'thumbnail': 'https://d1v6x81qdeozhc.cloudfront.net/static/images/payment-methods/banks/wells/thumbnail-cd34fad9a14cd21c3d683616a007979e.jpg'},
                                 'bank_account': None,
                                 'card': None,
                                 'id': '2468350160565552617',
                                 'image_url': {'detail': 'https://d1v6x81qdeozhc.cloudfront.net/static/images/payment-methods/banks/wells/detail-a1bfdf35000cb6d3e3e4bec7c8f108eb.jpg',
                                               'thumbnail': 'https://d1v6x81qdeozhc.cloudfront.net/static/images/payment-methods/banks/wells/thumbnail-cd34fad9a14cd21c3d683616a007979e.jpg'},
                                 'is_default': True,
                                 'last_four': '1234',
                                 'name': 'Wells Fargo Bank',
                                 'transfer_to_estimate': '2021-01-05T13:00:00',
                                 'type': 'bank'},
                 'status': 'issued',
                 'type': 'standard'},
    'type': 'transfer'}

Thanks for this library, it's very helpful!

mmohades commented 3 years ago

Thanks for this library, it's very helpful!

Thanks for providing the sample. Adding support for these two types of transactions is the next thing that will be added to the API wrapper.

alexsands commented 3 years ago

I'll need a sample of other transaction types to add support for them. Other transaction types that I don't have a sample for are:

  • refund

Here's one for refund too!

{
  'app': None,
  'audience': 'private',
  'authorization': None,
  'comments': {'count': 0, 'data': []},
  'date_created': '2021-01-01T01:31:51',
  'date_updated': '2021-01-01T01:31:51',
  'id': '3178512388641610159',
  'likes': {'count': 0, 'data': []},
  'mentions': {'count': 0, 'data': []},
  'note': None,
  'payment': None,
  'refund': {'amount': 12.34,
             'amount_cents': 1234,
             'date_created': '2021-01-01T01:31:51',
             'destination': {'assets': None,
                             'bank_account': None,
                             'card': None,
                             'default_transfer_destination': 'none',
                             'fee': None,
                             'id': '1306094511401544109',
                             'image_url': None,
                             'last_four': None,
                             'merchant_payment_role': 'default',
                             'name': 'Venmo balance',
                             'peer_payment_role': 'default',
                             'top_up_role': 'none',
                             'type': 'balance'},
             'estimated_arrival': '2021-01-01T01:31:51',
             'payment': {'action': 'pay',
                         'actor': {'about': ' ',
                                   'date_joined': '2013-12-09T01:38:38',
                                   'display_name': 'Joe '
                                                   'Smith',
                                   'email': None,
                                   'first_name': 'Joe',
                                   'friend_status': None,
                                   'friends_count': 123,
                                   'id': '1305995571405544863',
                                   'identity': None,
                                   'identity_type': 'personal',
                                   'is_active': True,
                                   'is_blocked': False,
                                   'is_group': False,
                                   'is_payable': True,
                                   'last_name': 'Smith',
                                   'phone': None,
                                   'profile_picture_url': 'https://pics.venmo.com/595f169b-cdf5-42e1-a3e0-21a1f31d12bd?width=460&height=460&photoVersion=3',
                                   'trust_request': None,
                                   'username': 'joesmith'},
                         'amount': 12.34,
                         'audience': 'private',
                         'date_authorized': None,
                         'date_completed': None,
                         'date_created': '2021-01-01T01:25:30',
                         'date_reminded': None,
                         'external_wallet_payment_info': None,
                         'id': '3177908395033547684',
                         'note': 'This is an example',
                         'status': 'cancelled',
                         'target': {'email': 'janedoe@gmail.com',
                                    'merchant': None,
                                    'phone': None,
                                    'redeemable_target': None,
                                    'type': 'email',
                                    'user': None}},
             'type': 'canceled'},
  'transfer': None,
  'type': 'refund'
},
mmohades commented 3 years ago

I haven't gotten the chance to make this changes yet. I'm gonna close this issue for now, but I'll add the support for other types of payment methods as soon as I get the chance.