Help! PHP Developers need a "simple" 2 page checkout dwolla example

(Car Social) #1

Many PHP developers are confused about the API for a simple Form Post to Off-Site Gateway.

We know how to create a product order form to post to the gateway; that is well documented. Were the confusion comes in how can we simply get URL parameters BACK from the gateway to get checkout details

As PHP developers, some of us don’t know what curl is or json or node or ect… We simply need a very small simple sample of two pages:

  • a very simply sample product/order form where form=action post to the gateway.
  • a php page that gets the URL parameters of the checkout transaction response from the gateway after Checkout is complete.

no curl, no json, nothing else, just simple URL parameters


Signature verification(or generation) not working
Is the old API broken? I get "[Error] => Invalid application credentials."
(Gordon Zheng) #2

Here’s an example of a page to submit the form to Dwolla’s Gateway (via the Submit Directly flow), and another page, return.php, where the user is redirected to after they have checked out, or failed to, at the Gateway. Comments in line!


$key 		= "vzh0C2TKeWWCXWKnLhdTi4UloeH8VSAiEW+Q2mHvn4bPuhYraB";
$secret 	= "eH8VSAiEW+Q2mHvn4bPuhYraBvzh0C2TKeWWCXWKnLhdTi4Ulo";
$timestamp 	= time();
$order_id 	= "order";

$signature 	= hash_hmac('sha1', "{$key}&{$timestamp}&{$order_id}", $secret);

<form accept-charset="UTF-8" action="" method="post">

<input id="key" name="key" type="hidden" value="<?= $key ?>" /> 
<input id="signature" name="signature" type="hidden" value="<?= $signature ?>" />
<input id="timestamp" name="timestamp" type="hidden" value="<?= $timestamp ?>" />
<input id="callback" name="callback" type="hidden" value="insert callback URL here" /> <!-- optional parameter -->
<input id="redirect" name="redirect" type="hidden" value="insert URL TO return.php here" /> <!-- optional parameter -->
<input id="assumeCosts" name="assumeCosts" type="hidden" value="false" /> <!-- optional parameter -->
<input id="allowFundingSources" name="allowFundingSources" type="hidden" value="true" /> <!-- optional parameter -->
<input id="checkoutWithApi" name="checkoutWithApi" type="hidden" value="false" /> <!-- optional parameter -->
<input id="orderid" name="orderid" type="hidden" value="<?= $order_id ?>" />
<input id="test" name="test" type="hidden" value="false" /> <!-- optional parameter -->
<input id="name" name="name" type="hidden" value="Purchase" />
<input id="description" name="description" type="hidden" value="Description something" />
<input id="destinationId" name="destinationId" type="hidden" value="812-713-9234" />
<input id="amount" name="amount" type="hidden" value="0.2" />
<input id="shipping" name="shipping" type="hidden" value="0.1" /> <!-- optional parameter -->
<input id="tax" name="tax" type="hidden" value="0.1" /> <!-- optional parameter -->
<input id="notes" name="notes" type="hidden" value="These are notes" /> <!-- optional parameter -->
<button type="submit">Submit Order</button>

And here’s return.php:


$key 		= "vzh0C2TKeWWCXWKnLhdTi4UloeH8VSAiEW+Q2mHvn4bPuhYraB";
$secret 	= "eH8VSAiEW+Q2mHvn4bPuhYraBvzh0C2TKeWWCXWKnLhdTi4Ulo";

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

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

// example successful request:
// example failure:

// first, check for any errors
if (array_key_exists("error", $_GET)) {
	// find out what happened:
	$error_description = $_GET['error_description']; // "User Cancelled"

// second, extract the checkoutId, amount, and signature of the checkout:

$checkoutId = $_GET['checkoutId'];
$amount = $_GET['amount'];
$signature = $_GET['signature'];

// third, validate the signature before you do anything with the data.

$signatureValid = verifyGatewaySignature($signature, $checkoutId, $amount);

if (!$signatureValid) {
	exit("Bad signature!");

$status = $_GET['status'];

if ($status == "Completed") {
	// do something useful with the checkout results:
	echo $status;


The key and secret used in these examples are invalid. Create an API application to generate your own credentials.

The comments should explain most of the code, but let me know if I can clarify any of it!

Beginner question:
Hello, Can I get a quote to build a shopping cart with one item with Dwolla?
Add a simple pay button
Using the off-site payment gateway directly
(Ben Milne) #3

Just gave it a shot @gordon. Worked pretty easily :smile:

Thanks for posting.

(Loganathan Natarajan) #4

The sample provided helped me to resolve my problem. Ton Thanks to gordon

(Loganathan Natarajan) #5

one more issue just caught,

it says “Bad signature!”


(Spencer Hunter) #6

Hi @logudotcom! As discussed in this post: Signature verification(or generation) not working. The $secret needs to be defined as a global within the verifyGatewaySignature function. I have updated the example above to reflect this.

Please let us know if you are still having issues! :slight_smile:

(Loganathan Natarajan) #7

Hi @spencer Thanks for the reply. I was removed earlier due to Bad Signature exit? Now I have fixed as per the link you had given. Hats off … Thanks again for your follow up.

(Ben Milne) #8

Also worth mentioning to get Direct to work you need to add the following:

<input id="AllowGuestCheckout" name="AllowGuestCheckout" type="hidden" value="true" />
<input id="AllowFundingSources" name="AllowFundingSources" type="hidden" value="true" />

(Cory Anderson) #9

(Cory Anderson) #10

(Cory Anderson) #11

(Spencer Hunter) #12