Skip to content

Instantly share code, notes, and snippets.

@allella
Created January 29, 2016 21:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save allella/94c555b330859a62a710 to your computer and use it in GitHub Desktop.
Save allella/94c555b330859a62a710 to your computer and use it in GitHub Desktop.
A Simple Braintree PHP Hosted Fields Example using an onPaymentMethodReceived To Override the Submit Button
<?php
Braintree_Configuration::environment('sandbox');
Braintree_Configuration::merchantId('YOURMERCHANTIDHERE');
Braintree_Configuration::publicKey('YOURPUBLICKEYHERE');
Braintree_Configuration::privateKey('YOURPRIVATEKEYHERE');
$result = Braintree_Transaction::sale([
'amount' => '150.00',
'paymentMethodNonce' => $_POST['nonce']
]);
if ($result->success && isset($_POST['nonce']) )
{
print_r("Success ID: " . $result->transaction->id);
print_r($_POST);
print_r($result);
}
else
{
print_r("Error Message: " . $result->message);
}
?>
<html>
<head>
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<style>
#card-number, #cvv, #expiration-date { height: 40px;
border: 1px solid #333;
}
</style>
</head>
<body>
<form action="/braintest.php" id="credit-card-info" name="credit-card-info" method="POST">
<label for="card-number">Card Number</label>
<div id="card-number"></div>
<label for="cvv">CVV</label>
<div id="cvv"></div>
<label for="expiration-date">Expiration Date</label>
<div id="expiration-date"></div>
<input type="hidden" id="nonce" name="nonce" value="" />
<input type="submit" value="Pay" />
</form>
<script src="https://js.braintreegateway.com/v2/braintree.js"></script>
<script>
braintree.setup("<?php echo($clientToken = Braintree_ClientToken::generate());?>", "custom", {
id: "credit-card-info",
hostedFields: {
number: {
selector: "#card-number"
},
cvv: {
selector: "#cvv"
},
expirationDate: {
selector: "#expiration-date"
},
styles: {
"input": {
"color": "#3A3A3A"
},
":focus": { color: "#333333" },
".invalid": { color: "#FF0000" },
}
},
onPaymentMethodReceived: function (details) {
$("#nonce").val(details.nonce);
var form = document.getElementById('credit-card-info');
HTMLFormElement.prototype.submit.call(form);
}
});
</script>
</body>
</html>
@allella
Copy link
Author

allella commented Jan 29, 2016

This was written when the Braintree Javascript API was version 2 and when the PHP SDK was version 3.8.0. jQuery is also included and used in the code above.

This is using the sandbox environment. In sandbox mode you can use fake/test credit card #'s to trigger different success or failures. Also, note that the $ amount can trigger certain gateway responses, so you have to pay attention to the fake credit card number and amount.

You'll need to install the PHP SDK using Composer for the Braintree_Configuration and Braintree_ClientToken libraries to load/work
https://developers.braintreepayments.com/start/hello-server/php. If you don't use Composer then you'll have to include those classes manually.

When you click the submit button the onPaymentMethodReceived callback will attach a "nonce" value to the hidden input HTML field that has id="nonce" and then immediately submits the form. This allows you to see all your other form elements in the PHP POST array, including the nonce value from Braintree's server.

@allella
Copy link
Author

allella commented Jan 29, 2016

If you see an error in the browser console that says

Uncaught TypeError: FormNapper requires an HTMLFormElement element or the id string of one.

then the reason is you need an id value on the HTML form tag.

In the code above our form has an
id="credit-card-info"
which the
var form = document.getElementById('credit-card-info');
uses to locate the form, so FormNapper can hijack the submit button and attach the onPaymentMethodReceived callback.

Copy link

ghost commented Aug 6, 2016

@allella I'm currently trying to do this in a GWT application:

    private native void setupCreditCardForm(String domId, String serverToken) /*-{

        var form = $doc.getElementById(domId);

        braintree.setup(
            serverToken,
            "custom",
            {
                id: domId,
                hostedFields: {
                    number: {
                        selector: "#number"
                    },
                    cvv: {
                        selector: "#cvv"
                    },
                    expirationDate: {
                        selector: "#expiration_date"
                    }
                }
            });
    }-*/;

The var form is correctly fetched but for some reason I'm getting:

braintree-2.27.0.min.js:5 Uncaught TypeError: FormNapper requires an HTMLFormElement element or the id string of one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment