Signature verification(or generation) not working

(Zachary Sprague) #1

The first time I tried to post this, it didn’t show up anywhere. So here we go again.
I basically followed what was here: Help! PHP Developers need a “simple” 2 page checkout dwolla example

The code I have:

The verifyGatewaySignature function always fails.

(JJH) #2


Are you sure it is the function failing (are you positive your servers’ script is being run)? Maybe try an echo var_dump($data); right after $data is declared to check the values you’re getting back.

Also, the pasted code still has callback and redirect URLs - assuming you’ve changed those to reflect their actual values in your app?

(Zachary Sprague) #3

Yes, I’m positive that the function is returning false. I logged all the data of all the variables.
The script runs fine. The variables are there for $checkoutId, $amount, $dwollaSecret, etc. But the result of verifyGatewaySignature is always false.

And yes, it’s my actual site not in there.

(Gordon Zheng) #4

Seems like we have a slight misunderstanding of what was intended in the example code you referred to. In the example, when we do:

$signature = hash_hmac("sha1", "{$checkoutId}&{$amount}", $secret);

The $checkoutId variable is enclosed in curly braces because that causes PHP to automatically substitute the value of $checkoutId in the string. For example, if I did…

$a = "foo";
$b = "bar";
$result = "{$a} and {$b}";

$result would be "foo and bar".

So, it seems what you’re doing in your code is adding curly braces to the string to be hashed, despite the actual string not requiring them:

$signature = hash_hmac('sha1', "{".$checkoutId.'}&{'.number_format($amount, 2)."}", $dwollaSecret);

The proper format is:

<checkoutId>&<amount, formatted to 2 decimal places>

Which means you can simply do, instead:

amount = number_format($amount, 2);
$signature = hash_hmac('sha1', "{$checkoutId}&{$amount}", $dwollaSecret);

(Zachary Sprague) #5


hash_hmac('sha1', $checkoutId.'&'.number_format($amount, 2), $dwollaSecret);

also work? Because I tried that and it failed.
I also tried exactly what you said.

function verifyGatewaySignature($proposedSignature, $checkoutId, $amount) {
        $amount = number_format($amount, 2);
        $signature = hash_hmac('sha1', "{$checkoutId}&{$amount}", $dwollaSecret); 
        return $signature == $proposedSignature;

That’s still returning “false” for me.

Is there something wrong with the signature generation?

<input id="key" name="key" type="hidden" value="'.$dwollaKey.'" />
<input id="orderid" name="orderid" type="hidden" value="'.$orderId.'" />
<input id="timestamp" name="timestamp" type="hidden" value="'.$unixtime.'" />
<input id="signature" name="signature" type="hidden" value="'.hash_hmac('sha1', "{$dwollaKey}&{$unixtime}&{$orderId}", $dwollaSecret).'" />

I should add that I’m logging all the data posted back from Dwolla. What I get is, for example:

{"Amount":1,"OrderId":"1234","Status":"Completed","Error":null,"TransactionId":null,"CheckoutId":"9f2f761e-3d88-44cd-bbcf-798d79cadb96","Signature":"2f420b9e976a23ae6b4ba9fe7ea036fb4383e3ac","TestMode":"true","ClearingDate":"1\/1\/1970 12:00:00 AM"}

So I know it’s not an issue of any of the variables being missing.

(Zachary Sprague) #6

Anyone else have an idea of why it’s not working?

(David Stancu) #7


Can you make your application in the Dwolla Sandbox and give it a whirl there? If it’s still not working, post your sandbox/uat key and secret and I’ll do exactly what you’re doing on my end so that I can get a better idea of what’s going on with the signature verification.

Let me know, I will be more than happy to assist.


(David Stancu) #8


Hey there! I’m just trying to check in with you; have you made any progress thus far?


(Zachary Sprague) #9

Ah sorry, I got busy with other things.

I was testing it out by having it in test mode while a friend tries to send a dollar.

I guess I could try to sandbox. When I first tried, I ran into some problem that I forgot. I think it had to do with same/similar account info to my non-uat account.
I’ll get back to you with that in a bit.

(Zachary Sprague) #10

The issue I was running in with UAT was it saying to register an account, and it saying I can’t under some duplicate credentials. I didn’t realize I could just log in with my normal account.

Anyway I set uat application keys at

But the problem I have is that I don’t have two checking accounts to test with. I get the error “Destination account cannot be the same as the current account.”

When I try to make a new account, I can’t have two accounts with the same checking account information, it seems. When I try my brokerage account, it can’t connect with Dwolla. So I can’t actually test it out.

(David Stancu) #11


You don’t actually have to tie any real accounts to Sandbox. Make some slave accounts with pre-loaded balances with the sandbox admin tool. There’s a guide on doing this located here.

Give it a whirl and let me know! :smiley:



(Zachary Sprague) #12

I tried it on UAT and this is what I got:


“false” is still returned by this function:
    function verifyGatewaySignature($proposedSignature, $checkoutId, $amount) {
        $amount = number_format($amount, 2);
        $signature = hash_hmac(‘sha1’, “{$checkoutId}&{$amount}”, $dwollaSecret);
        return $signature == $proposedSignature;
(code formatting on here seems to work weird)

uat Key


uat Secret


Source code:

I am writing the information sent to the callback url to a file in order to debug. That’s how I’m seeing that it’s not verifying the signature.

Besides that, it’s sending me proper accid(orderId) and amount info. But it’s not verifying that signature it sends.

I appreciate the help. Hopefully we can figure this out.

(Gordon Zheng) #13

Wow. I finally see what’s going on…

The verifyGatewaySignature function doesn’t have access to the $dwollaSecret variable because it’s in the global scope, and the function is restricted to the local scope, unless you define $dwollaSecret as a global within the function, like so…

$dwollaSecret = "sObX/aXpL4LAAeb1MjpEzwX1R3y6nNSNrIZfU1bpwcYfbAPRIJ";

function verifyGatewaySignature($proposedSignature, $checkoutId, $amount) {
    global $dwollaSecret;

    $amount = number_format($amount, 2);
    $signature = hash_hmac('sha1', "{$checkoutId}&{$amount}", $dwollaSecret); 
    return $signature == $proposedSignature;

That took a decent amount of frustration before I realized this about PHP.

Hope that helps!

Help! PHP Developers need a "simple" 2 page checkout dwolla example
(Zachary Sprague) #14

Ah so it was just an odd thing about how PHP works. :confused:

Thanks a bunch. It’s working now.

(Cory Anderson) #15

(Cory Anderson) #16