No such transfer po_*
patroqueeet opened this issue · comments
Describe the bug
Every months first day, on web hook call I receive this exception:
ERROR 2023-11-01 02:21:38,929 log 2107788 140146881369984 Internal Server Error: /_stripe/webhook/***/
Traceback (most recent call last):
File "/home/darg/darg/.ve/lib/python3.8/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/home/darg/darg/.ve/lib/python3.8/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/darg/darg/.ve/lib/python3.8/site-packages/sentry_sdk/integrations/django/views.py", line 85, in sentry_wrapped_callback
return callback(request, *args, **kwargs)
File "/home/darg/darg/.ve/lib/python3.8/site-packages/django/views/generic/base.py", line 104, in view
return self.dispatch(request, *args, **kwargs)
File "/home/darg/darg/.ve/lib/python3.8/site-packages/django/utils/decorators.py", line 46, in _wrapper
return bound_method(*args, **kwargs)
File "/home/darg/darg/.ve/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 56, in wrapper_view
return view_func(*args, **kwargs)
File "/home/darg/darg/.ve/lib/python3.8/site-packages/django/views/generic/base.py", line 143, in dispatch
return handler(request, *args, **kwargs)
File "/home/darg/darg/.ve/lib/python3.8/site-packages/djstripe/views.py", line 47, in post
trigger = WebhookEventTrigger.from_request(
File "/home/darg/darg/.ve/lib/python3.8/site-packages/djstripe/models/webhooks.py", line 268, in from_request
raise e
File "/home/darg/darg/.ve/lib/python3.8/site-packages/djstripe/models/webhooks.py", line 249, in from_request
obj.process(save=False, api_key=api_key)
File "/home/darg/darg/.ve/lib/python3.8/site-packages/djstripe/models/webhooks.py", line 363, in process
self.event = Event.process(self.json_body, api_key=api_key)
File "/home/darg/darg/.ve/lib/python3.8/site-packages/djstripe/models/core.py", line 1654, in process
ret.invoke_webhook_handlers()
File "/home/darg/darg/.ve/lib/python3.8/site-packages/djstripe/models/core.py", line 1666, in invoke_webhook_handlers
webhooks.call_handlers(event=self)
File "/home/darg/darg/.ve/lib/python3.8/site-packages/djstripe/webhooks.py", line 98, in call_handlers
handler_func(event=event)
File "/home/darg/darg/.ve/lib/python3.8/site-packages/djstripe/event_handlers.py", line 353, in other_object_webhook_handler
_handle_crud_like_event(target_cls=target_cls, event=event)
File "/home/darg/darg/.ve/lib/python3.8/site-packages/djstripe/event_handlers.py", line 448, in _handle_crud_like_event
data = target_cls(**kwargs).api_retrieve(
File "/home/darg/darg/.ve/lib/python3.8/site-packages/djstripe/models/base.py", line 202, in api_retrieve
return self.stripe_class.retrieve(
File "/home/darg/darg/.ve/lib/python3.8/site-packages/stripe/api_resources/abstract/api_resource.py", line 12, in retrieve
instance.refresh()
File "/home/darg/darg/.ve/lib/python3.8/site-packages/stripe/api_resources/abstract/api_resource.py", line 16, in refresh
return self._request_and_refresh("get", self.instance_url())
File "/home/darg/darg/.ve/lib/python3.8/site-packages/stripe/api_resources/abstract/api_resource.py", line 90, in _request_and_refresh
obj = StripeObject._request(
File "/home/darg/darg/.ve/lib/python3.8/site-packages/stripe/stripe_object.py", line 282, in _request
response, api_key = requestor.request(method_, url_, params, headers)
File "/home/darg/darg/.ve/lib/python3.8/site-packages/stripe/api_requestor.py", line 122, in request
resp = self.interpret_response(rbody, rcode, rheaders)
File "/home/darg/darg/.ve/lib/python3.8/site-packages/stripe/api_requestor.py", line 399, in interpret_response
self.handle_error_response(rbody, rcode, resp.data, rheaders)
File "/home/darg/darg/.ve/lib/python3.8/site-packages/stripe/api_requestor.py", line 159, in handle_error_response
raise err
stripe.error.InvalidRequestError: Request req_Ah9ioeS1Odqn4Z: No such transfer: 'po_***'
Software versions
- Dj-Stripe version: 2.8.2
- Python version: 3.11
- Django version: 4.2
- Stripe API version: 2017
- Database type and version: psql v11
@patroqueeet Is this a webhook event on your account or on a connected account (yours is a platform account)?
@patroqueeet What is your payout destination? And are you able to retrieve it using the stripe api? If so can you share the json?
@patroqueeet Please go to Django admin and hunt the Event related to this failed event and copy-paste the entire object. You can do so by running the following in django shell as well:
from django.forms import model_to_dict
from djstripe.models import Event
evt = Event.objects.get(id="<ID_OF_FAILED_EVENT>")
print(model_to_dict(evt))
@arnav13081994 that is not working, because the event is not saved to the local db because of the error described.
Please check in the webhook event triggers table for a failed event and then re-run the same command as mentioned below but for the WebhookEventTrigger object
like that:
{
"id": "evt_1O7T7kBBirzkVpobVI9LZcHQ",
"object": "event",
"api_version": "2017-01-27",
"created": 1698801696,
"data": {
"object": {
"id": "po_1O7SohBBirzkVpobNNDVrry3",
"object": "transfer",
"amount": 1,
"amount_reversed": 0,
"application_fee": null,
"arrival_date": 1698796800,
"automatic": true,
"balance_transaction": "txn_1O7SohBBirzkVpobgrc2rTus",
"bank_account": {
"id": "ba_1LX1SjBBirzkVpob7bckjG4y",
"object": "bank_account",
"account_holder_name": null,
"account_holder_type": null,
"account_type": null,
"bank_name": "...",
"country": "DE",
"currency": "eur",
"fingerprint": "2bbLdAFgfBVs1iY3",
"last4": "1234",
"routing_number": "DE...",
"status": "new"
},
"created": 1698800515,
"currency": "eur",
"date": 1698796800,
"description": "STRIPE PAYOUT",
"destination": "ba_1LX1SjBBirzkVpob7bckjG4y",
"failure_balance_transaction": null,
"failure_code": null,
"failure_message": null,
"livemode": true,
"metadata": {
},
"method": "standard",
"original_payout": null,
"recipient": null,
"reconciliation_status": "in_progress",
"reversals": {
"object": "list",
"data": [
],
"has_more": false,
"total_count": 0,
"url": "/v1/transfers/po_1O7SohBBirzkVpobNNDVrry3/reversals"
},
"reversed": false,
"reversed_by": null,
"source_transaction": null,
"source_type": "card",
"statement_descriptor": null,
"status": "in_transit",
"transfer_group": null,
"type": "bank_account"
}
},
"livemode": true,
"pending_webhooks": 2,
"request": null,
"type": "transfer.created"
}
@patroqueeet This is very interesting. I had no idea one could have a payout object id in a transfer
object. Can you please run the following commands in the django shell and let me know if you get an error or a response. In case of a response, please share the JSON
import stripe
stripe.api_key="<YOUR_API_KEY>"
stripe.Payout.retrieve("po_1O7SohBBirzkVpobNNDVrry3")
stripe.Transfer.retrieve("po_1O7SohBBirzkVpobNNDVrry3")
In [212]: stripe.Payout.retrieve("po_1O7SohBBirzkVpobNNDVrry3")
Out[212]:
<Payout transfer id=po_1O7SohBBirzkVpobNNDVrry3 at 0x7fad94c17a40> JSON: {
"amount": 1,
"amount_reversed": 0,
"application_fee": null,
"arrival_date": 1698796800,
"automatic": true,
"balance_transaction": "txn_1O7SohBBirzkVpobgrc2rTus",
"bank_account": {
"account_holder_name": null,
"account_holder_type": null,
"account_type": null,
"bank_name": "...",
"country": "DE",
"currency": "eur",
"fingerprint": "...",
"id": "ba_1LX1SjBBirzkVpob7bckjG4y",
"last4": "...",
"object": "bank_account",
"routing_number": "...",
"status": "new"
},
"created": 1698800515,
"currency": "eur",
"date": 1698796800,
"description": "STRIPE PAYOUT",
"destination": "ba_1LX1SjBBirzkVpob7bckjG4y",
"failure_balance_transaction": null,
"failure_code": null,
"failure_message": null,
"id": "po_1O7SohBBirzkVpobNNDVrry3",
"livemode": true,
"metadata": {},
"method": "standard",
"object": "transfer",
"original_payout": null,
"recipient": null,
"reconciliation_status": "completed",
"reversals": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/transfers/po_1O7SohBBirzkVpobNNDVrry3/reversals"
},
"reversed": false,
"reversed_by": null,
"source_transaction": null,
"source_type": "card",
"statement_descriptor": null,
"status": "paid",
"transfer_group": null,
"type": "bank_account"
}
and
In [213]: stripe.Transfer.retrieve("po_1O7SohBBirzkVpobNNDVrry3")
<Transfer transfer id=po_1O7SohBBirzkVpobNNDVrry3 at 0x7fada425a130> JSON: {
"amount": 1,
"amount_reversed": 0,
"application_fee": null,
"arrival_date": 1698796800,
"automatic": true,
"balance_transaction": "txn_1O7SohBBirzkVpobgrc2rTus",
"bank_account": {
"account_holder_name": null,
"account_holder_type": null,
"account_type": null,
"bank_name": "...",
"country": "DE",
"currency": "eur",
"fingerprint": "...",
"id": "ba_1LX1SjBBirzkVpob7bckjG4y",
"last4": "...",
"object": "bank_account",
"routing_number": "...",
"status": "new"
},
"created": 1698800515,
"currency": "eur",
"date": 1698796800,
"description": "STRIPE PAYOUT",
"destination": "ba_1LX1SjBBirzkVpob7bckjG4y",
"failure_balance_transaction": null,
"failure_code": null,
"failure_message": null,
"id": "po_1O7SohBBirzkVpobNNDVrry3",
"livemode": true,
"metadata": {},
"method": "standard",
"object": "transfer",
"original_payout": null,
"recipient": null,
"reconciliation_status": "completed",
"reversals": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/transfers/po_1O7SohBBirzkVpobNNDVrry3/reversals"
},
"reversed": false,
"reversed_by": null,
"source_transaction": null,
"source_type": "card",
"statement_descriptor": null,
"status": "paid",
"transfer_group": null,
"type": "bank_account"
}
not exactly sure what command I should run. but when checking in stripe I found it is looking for transfers with a
po_***
id, but when I past this ID into stripe search field, I get a payout obj, not a transfer obj. does this help?
@patroqueeet I do not understand how you got a response for stripe.Transfer.retrieve()
when the screenshot shows that the object is not available. Or am I misunderstanding something?
Moreover looking at the JSON the fields are all from the Payout Object even when "object": "transfer"
is mentioned in the JSON.
Indeed I see your point. Still, the symptoms are as they are. Anything I can do to narrow down the source of the symptoms?
I see that you are using sentry. Can you tell me what all params are being passed to the api_retrieve call and what is self.stripe_class
?
Also on this Stripe Account your api version is 2020-XXX
.
Thanks. @patroqueeet Can you run stripe.Transfer.retrieve
with all the params you see above like stripe_account
, expand
, stripe_version
, api_key
and id
as is done here?
learning: fails with version specified. succeeds with no version given. hence checked:
what do you recommend from here? upgrade default to 2020 version?
And further checked. 2020 version is djstripe default (I did not override in settings). so means the webhook is not sending the default djstripe Stripe API version along? Do I read this like: stripe default setting is applied to web hook calls and conflicts with djstripe default setting? Just learned cannot upgrade djstripe default version to 2020. only latest is allowed. what now?
@patroqueeet Please check the api_version
of the webhook endpoint that is receiving this event. It's visible in the admin. You can create a new webhook endpoint with the 2020
version
now I did after finding api version was empty.
In [70]: whep = WebhookEndpoint.objects.get(pk=2)
In [71]: whep.api_version = '2020-08-27'
In [72]: whep.save()
But also found that inside Stripe each WH has an api version assigned. this is set to default 2017* in my case. so now my local model is not aligned with stripe :/ . trying to adjust to 2020* api version in Stripe is not possible, I can only select default or lastest version - will find out what it does now on Dec, 1st...
THX for instantly creating a PR to prevent similar in the future and THX for the great support. was a tricky issue, I assume...