Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to obtain access token #86

Open
afriedsam opened this issue Mar 12, 2024 · 29 comments
Open

Unable to obtain access token #86

afriedsam opened this issue Mar 12, 2024 · 29 comments
Labels
bug Something isn't working

Comments

@afriedsam
Copy link

afriedsam commented Mar 12, 2024

Running the following code:
from venmo_api import Client
at = Client.get_access_token(username='*****************', password='***********')

getting the following response:
Error: {'error': {'links': None, 'title': 'Error', 'code': 240, 'message': 'OAuth2 Exception: Unable to complete your request. Please try again later.'}}

My friend @Dean-Katz is having the same issue.

@robhannon
Copy link

Same here

@ahatzz11
Copy link

I tried to get a new auth token and ran into the same thing today with Client.get_access_token. I was able to obtain a valid bearer token from observing network calls from a web session and that worked great, but being able to obtain a new token from the python lib would be great.

@eddiew
Copy link

eddiew commented Mar 21, 2024

same here, experienced this today. Works on my local machine but not on a cloud server. Is Venmo is finally locking down this api?

@ahatzz11
Copy link

Since I ran into this I decided to do some digging to see if I could hack my way through this a bit. I was able to grab a valid api token from the network tab during a payment, but this python API still didn't seem to work due to a 403. It seems like tokens created before whatever change venmo made are still considered valid, but I unfortunately revoked all the tokens on my account recently and it seems like they don't let you generate one of these tokens any more.

With this 'new' token it seems like there is now a change in their payment flow - I see a new call to /api/eligibility before the api/payments call. This API call returns:

{
    "eligible": true,
    "eligibilityToken": "eyJ...",
    "fees": [
        {
            "productUri": "venmo:product:buyer_protection:f4de...",
            "appliedTo": "227...",
            "feePercentage": 0,
            "baseFeeAmount": 0,
            "calculatedFeeAmountInCents": 0,
            "feeToken": "eyJ..."
        }
    ]
}

The api/payments request then uses the eligibilityToken:

{
    "targetUserDetails":
    {
        "userId": "227..."
    },
    "amountInCents": 1,
    "audience": "private",
    "note": "Test Transaction",
    "type": "pay",
    "fundingSourceID": "368...",
    "eligibilityToken": "eyJ..."
}

Based on the current __send_or_request_money() function it doesn't seem like this token is being passed and is now something venmo requires. I've whipped up a quick local script to send in this new token (along with a cookie and Csrf-Token header) and was able to get this to work. I don't have the time to redo this python API to get it working, but figured I'd leave what I've found so far here in case some one else wants to tackle this issue.

@afriedsam
Copy link
Author

afriedsam commented Mar 26, 2024

If you log in while tracking the network requests you can also pull out both the deviceID and auth code from one of the requests and log in like this:

from venmo_api import Client
client = Client.get_access_token(username='*****************', password='***********', device_id="********")

or

from venmo_api import Client
client = Client(access_token="***************************")

To find device_id or access_token:

  1. Log in while tracking the network requests and find the get request to https://account.venmo.com/ (it should be the top one)
  2. Search for graphqlHeaderConfig in the response. Here you will find both the device_id and access_token which should work

I am trying to modify the code to pull this info from the request but running into some 403 errors--going to keep trying when I have some time. I don't think you need the eligibility token @ahatzz11.

EDITED: I see you did this already. Going to keep trying to get the token from within code.

@mmohades mmohades added the bug Something isn't working label Mar 29, 2024
@mmohades
Copy link
Owner

Thanks to everyone for flagging this with detailed info! I'm currently tied up, but I hope to look into this next weekend!

@mmohades
Copy link
Owner

mmohades commented Apr 7, 2024

It seems that Venmo may be actively flagging login attempts. If you use a trusted device-id with get_access_token(username=..., password=..., device_id=TRUSTED_DEVICE_ID), it should work. I tested this and it worked for me.

What's interesting is that I removed my iPhone's device ID from the list of trusted devices on Venmo and logged out of the app. Upon attempting to log in via the API, I got the same 403 on the API. Then I tried to log in on my iPhone again, and I got the same error on my iPhone (see attached screenshot).

@jpjpjp
Copy link

jpjpjp commented Apr 14, 2024

To find device_id or access_token:

  1. Log in while tracking the network requests and find the get request to https://account.venmo.com/ (it should be the top one)
  2. Search for graphqlHeaderConfig in the response. Here you will find both the device_id and access_token which should work

FWIW, I found this differently as I didn't see this particular request or any responses that included anything resembling "device_id".

On the network request to login, I found a 'Set-Cookie' in the response headers that it set a cookie called v_id. I used the value of v_id as the device_id described above in the get_access_token() call, which then gave me an access_token

@habersaat
Copy link

Since I ran into this I decided to do some digging to see if I could hack my way through this a bit. I was able to grab a valid api token from the network tab during a payment, but this python API still didn't seem to work due to a 403. It seems like tokens created before whatever change venmo made are still considered valid, but I unfortunately revoked all the tokens on my account recently and it seems like they don't let you generate one of these tokens any more.

With this 'new' token it seems like there is now a change in their payment flow - I see a new call to /api/eligibility before the api/payments call. This API call returns:

{
    "eligible": true,
    "eligibilityToken": "eyJ...",
    "fees": [
        {
            "productUri": "venmo:product:buyer_protection:f4de...",
            "appliedTo": "227...",
            "feePercentage": 0,
            "baseFeeAmount": 0,
            "calculatedFeeAmountInCents": 0,
            "feeToken": "eyJ..."
        }
    ]
}

The api/payments request then uses the eligibilityToken:

{
    "targetUserDetails":
    {
        "userId": "227..."
    },
    "amountInCents": 1,
    "audience": "private",
    "note": "Test Transaction",
    "type": "pay",
    "fundingSourceID": "368...",
    "eligibilityToken": "eyJ..."
}

Based on the current __send_or_request_money() function it doesn't seem like this token is being passed and is now something venmo requires. I've whipped up a quick local script to send in this new token (along with a cookie and Csrf-Token header) and was able to get this to work. I don't have the time to redo this python API to get it working, but figured I'd leave what I've found so far here in case some one else wants to tackle this issue.

@ahatzz11 I'm trying to recreate the same workaround but am having trouble retrieving the eligibility token (getting a 403 error each time). I'm only passing in the access_token in my post request header which I suspect is wrong... can I ask how you set the cookie and Csrf-Token header you mentioned?

@raycekar
Copy link

raycekar commented May 3, 2024

Was planning to try and maybe get a pull request in for a fix but found that when trying to log into venmo on any browser I am presented with a "Something went wrong. Try again later or contact customer support". Script must have tried too many times and locked me out. Anyone else have this for them and did you have to contact customer support?

Edit: guess I was able to use an already trusted device. But it attempting to do the eligibility request, strangely enough I get the 404 error

@raycekar
Copy link

raycekar commented May 8, 2024

Sadly spend some hours on this and when trying to request through either of the following, I get a 404 error, invalid json and can't seem to figure out why:
https://account.venmo.com/api/eligibility - trying to get eligibility token
https://account.venmo.com/_next/data/PS8KMzrdGzuzFp7z0vH5i/en/pay.json - attempting to get csrf-token to feed into eligibility request

@raycekar
Copy link

raycekar commented May 10, 2024

Further digging, I see the HTTP version is HTTP/2 from the developer tools network tab. From what I can see, the requests package only support HTTP/1.1 while another package, HTTPX, supports the new standard. Could this be a possible reason for the 403/404 errors?

EDIT: after reading up on it, sounds whatever site would have to block http/1.1, which im now doubting they would do that since other folks got it to work and the tool still logs in.

@mattmijo
Copy link

It seems that Venmo may be actively flagging login attempts. If you use a trusted device-id with get_access_token(username=..., password=..., device_id=TRUSTED_DEVICE_ID), it should work. I tested this and it worked for me.

What's interesting is that I removed my iPhone's device ID from the list of trusted devices on Venmo and logged out of the app. Upon attempting to log in via the API, I got the same 403 on the API. Then I tried to log in on my iPhone again, and I got the same error on my iPhone (see attached screenshot).

I followed these steps but still results in a 403 error

import requests
from venmo_api import Client
access_token = Client.get_access_token(username='blah', password='blah', device_id='longer blah')
print("My token:", access_token)
print(response.status_code)
print(response.json)

not sure what is happening here.

@KK2NJ
Copy link

KK2NJ commented Aug 1, 2024

Is there any update on this thread?

@raycekar
Copy link

raycekar commented Aug 9, 2024

Is there any update on this thread?

I tried, i failed... to get it to work.

@KK2NJ
Copy link

KK2NJ commented Aug 15, 2024

Is there any update on this thread?

I tried, i failed... to get it to work.

There's a way to do it I can't remember how I did it but you gotta login into your venmo account + f12 + go to networking settings + enable no throttling + find your device id through the information there and then use the access_token code in the documentation

@KK2NJ
Copy link

KK2NJ commented Aug 15, 2024

Is there any update on this thread?

I tried, i failed... to get it to work.

There's a way to do it I can't remember how I did it but you gotta login into your venmo account + f12 + go to networking settings + enable no throttling + find your device id through the information there and then use the access_token code in the documentation

Yeah I found it like the previous commenter said track your networking requests then search for "auth" and there should be "device_id" and "access_token" there you can take the access_token or just use Client.get_access_token with your login details and your device id in a IDE your choice.

@raycekar
Copy link

Is there any update on this thread?

I tried, i failed... to get it to work.

There's a way to do it I can't remember how I did it but you gotta login into your venmo account + f12 + go to networking settings + enable no throttling + find your device id through the information there and then use the access_token code in the documentation

Yeah, I was able to get device ID and all, but it was the eligibility token portion that I was not able to implement to get it to work. Would you care to share the code you had updated.? Or I guess did you not make any updates to the Venmo code?

@rbrisita
Copy link
Contributor

rbrisita commented Sep 6, 2024

It was mentioned before but these are the steps I took to get a valid access token through this API:

  1. Visit https://venmo.com/account/sign-in
  2. Open DevTools
  3. Manually sign into Venmo
  4. Search for the https://account.venmo.com/api/auth request
  5. Note the deviceId in the Response
  6. Use that deviceId in your code when calling Client.get_access_token
  7. The response will parrot the device-id and give a new access_token

@raycekar
Copy link

raycekar commented Sep 7, 2024

It was mentioned before but this is the steps I took to get a valid access token through this API:

1. Visit `https://venmo.com/account/sign-in`

2. Open DevTools

3. Manually sign into Venmo

4. Search for the `https://account.venmo.com/api/auth` request

5. Note the `deviceId` in the `Response`

6. Use that `deviceId` in your code when calling `Client.get_access_token`

7. The response will parrot the `device-id` and give a new `access_token`

@rbrisita Are you using the Venmo client to make any payments? I agree that it works when you follow the steps to get your device ID but the making a payment is the portion. Personally I have trouble with as I think the eligibility token needs to be implemented yet.

@rbrisita
Copy link
Contributor

@raycekar I have successfully made charge requests through the API.

@raycekar
Copy link

raycekar commented Oct 3, 2024

@rbrisita could you share me your script (username/password/device_id removed of course). With my script, I can alter it to include device id and get all the way to the requesting the payment and getting the following error:

venmo_api.models.exception.HttpCodeError: HTTP Status code is invalid. Could not make the request because -> 403 Forbidden. Error: {'error': {'message': 'There was an issue with your payment. Try again later.', 'code': 1384, 'links': [], 'title': 'Payment Declined'}}

FYI, trying to automate paying with a debit card and it works when manually sending the payment through the app (and I need it to the be the debit card)

@rbrisita
Copy link
Contributor

rbrisita commented Oct 8, 2024

@raycekar From your error, it looks like it's the payment and not the access token. An access token error states:

{
  "error": {
    "message": "You did not pass a valid OAuth access token.",
    "code": 261,
    "links": null,
    "title": "Error"
  }
}

I would look into supplying the funding source id if you haven't already for the send_money call.
Nothing special about the following code:

from venmo_api import Client
from dotenv import dotenv_values

config = dotenv_values(".env")

user_id = config.get("TARGET_USER_ID", getenv("TARGET_USER_ID"))

username = config.get("VENMO_USER", getenv("VENMO_USER"))
password = config.get("VENMO_PASS", getenv("VENMO_PASS"))
device_id = config.get("VENMO_DEVICE_ID", getenv("VENMO_DEVICE_ID")) # device id taken from a desktop browser

access_token = Client.get_access_token(
  username=username,
  password=password,
  device_id=device_id
)

client = Client(access_token=access_token)

try:
  response = client.payment.request_money(0.01, "Some Message", user_id)
except Exception as e:
  print("Error:", e)

print("Response", response)

@raycekar
Copy link

Thank @rbrisita a ton!
I must had something messed up with my convoluted script but messing around with it from your sample script got me going again

@rbrisita
Copy link
Contributor

Awesome! Glad to be of help.

@jackguo709
Copy link

jackguo709 commented Dec 11, 2024

Question. Is the device ID linked to a particular physical device? If I want to run the python script in a cloud service, then I can't get the device ID ahead of the time

@afriedsam
Copy link
Author

@jackguo709 I believe you could use any device to generate and save your access token. Then, you could skip the earlier steps and just use client = Client(access_token=access_token) in your cloud service.

@jackguo709
Copy link

But I find that if I try to send multiple payments in a short amount of time, or Venmo someone two or three times, the payments will get denied.

@rbrisita
Copy link
Contributor

rbrisita commented Dec 12, 2024

The device id is cross device. Venmo has restrictions on requesting and paying. IIRC, only 30 payment requests per 24 hour period. One can pay as low as 1¢.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests