I think that the Dwolla API sends the wrong transaction ID in notifications. In a normal dwolla money transaction, two transaction IDs are created (this is weird to me, but that's how dwolla does it). Because these two are created at the same time, they are always (in my experience) consecutive numbers. So e.g. if account X sends money to account Y, Y will see transaction id M, and X will see transaction id M+1.
But Dwolla's notification webhook will send Y details of the transaction with id M+1. While ID M+1 is still unique to this transaction, ID M+1 cannot be used by Y via the API - because M+1 is supposed to only be used by X.
Here is a specific example:
Via my webapp, I send money from my personal dwolla account to my organization's via the off-site gateway api.
My webapp is sent the transaction details in both callback and notification form. The transaction id generated by step 1 is 1431566. This is the transaction id sent to both callback and notification. My web app stores this Id for future use.
Via my webapp, I decide to refund my personal dwolla account from my organization's so:
My webapp tries to query dwolla about transaction 1431566, to get the SourceId, but this fails - dwolla reports "Transaction not found for account". My automatic refund cannot continue without an ugly kludge like subtracting one from the Id and trying again.
The manual workaround is to login to my organization's dwolla account via the web interface. Here I can look for the transaction based on datetime and I can see that the transaction ID is actually 1431565 (correctly reported in the web interface). If I go into my organization's database and replace 1431566 with 1431565, I can repeat step 4 and it works this time. After that I can initiate a send() and the refund goes through.
I reported the same problem here before dwolla moved support to stackoverflow: https://getsatisfaction.com/dwolla/topics/callback_and_webhook_notification_sent_wrong_transaction_id_off_by_one
I figure it will be fixed faster if other people have the same problem. Or maybe I'm missing something obvious and someone will point it out.
Thanks to Michael's help, we were able to get around this issue by using the receiver's OAuth token when getting the transaction details instead of the sender's OAuth token.
For example, say I send some money using the API and transactions 1202 for the money sender and 1201 for the money receiver get created. If you make the API call to get details for transaction 1202 but use the receiver's OAuth token, it will give you details for transaction 1201, including fee information.
I'm not sure if the situation is exactly the same since we are acting as the facilitator between two transactions, so no guarantees that this will work in your situation. But it's worth a try.