Workflow of Payment with Webhooks / Events

I’m trying to understand the full process of a transfer. Let me lay out a scenario (all in the sandbox):

I have a funding source on my main account, ID: 123
I have an unverified customer who adds a funding source they plan to use to send me an ACH payment, ID: 456

If I send a transfer request to Dwolla for a transfer of $1000 from ID 456 to ID 123 then I get the following webhooks:

transfer_created
customer_transfer_created

First question: I don’t really understand the difference between these two events. Why am I getting two events here?

Then when I hit the “Process Bank Transfers” button in the sandbox, I get three more webhook topics:

transfer_completed
customer_transfer_completed
bank_transfer_created

I’m trying to understand what is going on here. It is my understanding (which could be wrong) that there are two ACH transactions happening. The first is from my customer’s bank account into the Dwolla Network, and then the second is from the Dwolla Network into my bank account (funding source).

Are the customer_transfer_completed and the transfer_completed webhooks telling me that the transfer from the customer’s account into the Dwolla network are complete?

Is the bank_transfer_created webhook telling me that Dwolla has initiated a transfer from their network into my bank account, and that transfer is not yet complete?

At this point, my Dwolla dashboard shows that the payment is “Processed” and from what I can tell, I don’t see anything showing a pending transaction to move the money to my account. First, is my understanding correct that the money is in the Dwolla network right now, but not yet sent to my bank account? Second, if that is the case, how can I see the pending transfers into my bank account in the Dwolla Dashboard?

Then if I hit the “Process Bank Transfers” button again, I get one more event:

bank_transfer_completed

I also got an email saying: “Your withdrawal from Dwolla into Superhero Savings Bank has cleared. The funds should now be available in your bank account.”

This seems to further validate my ideas from before. However, I am still a bit confused because there is nothing in the Dashboard at all showing a pending transfer from Dwolla to my account (at least that I can see).

Thank you for reading and helping me understand what’s going on.

Hi @KevinMcKee

First I’d like to share that there are multiple legs to a single transfer, so make sure there are “No pending ACH transfers to process” in order to keep things clean and avoid confusion.

transfer_created Represents funds moving either to or from a Dwolla Master Account’s balance or bank .

customer_transfer_completed Represents funds transferring to an unverified Customer’s bank or to a verified Customer’s balance

bank_transfer_created Represents funds moving either from a Dwolla Master Account’s bank to the Dwolla network or from the Dwolla network to a Dwolla Master Account’s bank.

You can find out more about webhook meanings here

This sounds correct! Let’s try a similar transfer after the message “No pending ACH transfers to process” by pressing the process pending transfers button all the way through.

The meaning of these are shared above, but for a more in depth understanding for the future, the terms “completed” and “processed” represent Dwolla’s part in completing and processing the transfers. This does not mean fund landing in the acount.

For example, a transfer can be completed and then failed if the customer chose to close their bank account before receiving the funds. The “Fail” would trigger when the bank goes to return the funds.

This was defined in the above as well.

“Processed” here means Dwolla successfully processed the transaction.

You should be able to see pending transactions in the Dwolla network before the “process bank transfers” button is clicked.

This are operational notifications that are tied to your account. Completely normal! I hope this helps! Feel free to reach out if there are still any lingering confusions

I am still trying to work through this and I’m still very confused. I know I need to build my system to handle all these webhooks and I can’t correctly respond to them if I don’t know what they represent. Let me see if I can try to be more clear in what I need to know.

Also, just to start, I made sure to process all transfers and start from a clean slate. Then I initiated a transfer and got 2 webhooks after initiating. Then I hit “process” and got 3 more webhooks". Then I hit “process” again and got 1 more webhook. I hit “process” a third time and it said that there was nothing to process.

I initiated a transfer. This was from my unverified customer’s bank account to my verified bank account. I did not have it go to my Dwolla balance.

I got these events: customer_transfer_created and transfer_created. Both events had the same data in them, except the customer_transfer_created had a link to the customer who owns the funding source that was used. I guess my app would just ignore the transfer_created webhook and just rely on the customer_transfer_created webhook since they are exactly the same except the latter has one more piece of information.

Then I hit the process button and I got transfer_completed, customer_transfer_completed, and bank_transfer_created. Again, the transfer_completed and customer_transfer_completed were exactly the same, except the customer id was only on the latter, so again I would assume I can ignore the first and just react to the second.

The issue I have with the third event, the bank_transfer_created event, is that the only information I got from this is a link to a new Transfer record that is different from the Transfer link in the first four webhooks. That means, from what I can tell, is that there is no actual link between this bank_transfer_created event and the customer transfer that initiated it. Is this correct?

I’m hoping I’m missing something because this seems like a big problem. In my system I have a link between this first Transfer (the money moving from the customer account to Dwolla) and the Invoice that they paid. I need to track when the customer initiated the payment (have this with customer_transfer_created), and when the money cleared their account and entered the Dwolla network (have this with the customer_transfer_completed) so I can mark the invoice related to this as “Paid” in our ERP, but that record would show “funds not deposited”. I need a way to link the bank_transfer_created event to the invoice in my system as well, so I know when to go update my ERP and say that the funds have been deposited, but I don’t see any link. Am I missing that?

Finally, I hit process one more time and get the bank_transfer_completed event, which tells me that the money from the original transfer has now hit my account. But again, without a link from the first transfer to the second, I have no way of knowing what invoice this money is related to.

I don’t see anything in the documentation about how to link these items, nor do I see anything about the ability to add metadata to transfers so the link to an Invoice Number could be stored on your end. Am I missing something.

Thanks @kmoreira

Hi @KevinMcKee – Hopefully this helps clarify things!

Determining what webhooks to expect:
This gist should be helpful in determining exactly what webhooks you can expect to receive in the above scenario where a transfer is being made from an Unverified Customer’s bank to your Dwolla Account’s Bank.

Why are there similar webhooks for the same actioin:
For each transfer involving two parties, we send two similar webhooks for each action; one includes the sender’s link and the other includes the receiver’s link. This is so that, if needed, you can handle any business logic separately for the Sender party and the Receiver party.

Linking original transfer with second half of the transfer:
As for linking the original transfer with the second half of the transfer linked in the bank_transfer_created/bank_transfer_completed webhooks, when you make a GET request to the linked transfer, you can find the original transfer as a "funding-transfer" link in the response. Similarly, when you make a GET request to the original transfer, you will find the second half of the transfer as a "funded-transfer" link in the response.

"funding-transfer" → Follow this link to go back and determine how the balance got deposited on the initial bank-to-balance transaction.
"funded-transfer" → Follow this link to go forward and determine the transfer that pushes funds out of a balance and into the bank of a destination Customer.

Linking transfers using "correlationId":
Additionally, you can also use a correlationId to link transfers together. This is a field you can append to a transfer request when creating a transfer like in the following example, and is returned in the response whenever you retrieve the transfer (including the funded and funding transfers).

POST /transfers 

{
   "_links": {
       "source": {},
       "destination": {},
   "amount": {},
   "correlationId": "any-random-string-upto-255-char-no-space"
}

Let us know if you have any questions!

This is great information. Thank you so much! From what I can tell, this solves my questions.

2 Likes

Thanks, @KevinMcKee. Glad it helps!

By the way, we are working on adding this information in our documentation as well, so you will be able to find other transfer scenarios in there soon! Happy New Year!

Hi Shreya - it’s still not clear to me how to link a transfer to the original mass payment item? The correlation id I get on the transfer is the correlation id of the mass payment, not the mass payment item. Is this right, as it doesn’t seem to make much sense? Is there some other way to link the transfer to the item?

Hi @stu_bowes – you’re correct about the correlationId. We don’t have a way to add correlationIDs for masspayment items currently. The correlationID on the masspayment is what’s included in the individual transfers as well.

One way to link the transfer back to its item would be to locate the masspayment, list all items for the masspayment and traverse the list to find the item which has the the transfer in its _links object.