Hosted Fields Tutorialanchor

Time

25mins

Platforms

Windows & Mac

Difficulty

Easy

Technologies

JavaScript, Node.js, Express

Before you beginanchor

First, make sure you have the latest versions of Node.js and npm installed. You’ll also need a console (e.g. Terminal on Mac, Command Line on Windows) and a text editor of your choice.

To get you up and running quickly, we’ll use Express to generate a Node app with basic routing.

Install the Express app generatoranchor

  1. console
npm install --global express-generator@4

If you’re interested in how the Express generator works or its options, see the Express generator docs.

Get a Braintree sandboxanchor

To successfully run a test transaction, you’ll need a Braintree sandbox account. Log in or sign up for one now.

1. Set up a basic appanchor

Now that you have all the necessary tools installed, we can use the Express app generator to quickly create the basic application structure we’ll use for the tutorial.

Generate the appanchor

In your console, run this command in the directory where you want to store the tutorial code. Use --view=hbs to set the template engine to Handlebars – this is what we will use throughout the tutorial. This command will generate a directory titled braintreeTutorial with your app inside of it.

  1. console
express braintreeTutorial --view=hbs

Open your newly created appanchor

Now let's navigate to the newly created braintreeTutorial directory.

  1. console
cd braintreeTutorial

Install dependenciesanchor

  1. console
npm install

Install Braintree server SDKanchor

The Braintree Node.js library is the server-side Braintree SDK that lets your server make requests to Braintree's API. Let's install this now so that we're ready when we add code to the server side of your integration.

  1. console
npm install braintree --save

2. Add Hosted Fieldsanchor

Our basic app will have one page on the client and one route on the server.

Express already generated an index view that we’ll use for the payment form markup on the client. From here, we'll use Braintree's Hosted Fields to create the form.

To load Hosted Fields on the page, we’ll need to do 3 things:

  1. Include the Braintree client SDK
  2. Get a tokenization key
  3. Add the Hosted Fields UI markup

Include the Braintree client SDKanchor

For this tutorial, we'll use the latest Braintree JavaScript SDK. Add the following code just above the closing </head> tag in views/layout.hbs.

  1. HTML
<!-- includes the Braintree JS client SDK -->
<script src="https://js.braintreegateway.com/web/3.100.0/js/client.min.js"></script>
<script src="https://js.braintreegateway.com/web/3.100.0/js/hosted-fields.min.js"></script>
<!-- includes jQuery --> <script src="http://code.jquery.com/jquery-3.2.1.min.js" crossorigin="anonymous"></script>
note

We only include jQuery here to reduce the complexity of our tutorial code. It’s not a requirement in order to use Braintree.

Get a tokenization keyanchor

There are 2 ways to authorize the client to collect payment information:

  • A client token, which requires a round trip to your server and enables you to use all of Braintree’s client API capabilities
  • A tokenization key, which is a static key with reduced privileges that authorizes a subset of Braintree’s client API capabilities

For this tutorial, we’ll use a tokenization key, which is stored in your Braintree Control Panel. To find it:

  1. In your sandbox Control Panel, go to Account > My User
  2. Under API Keys, Tokenization Keys, Encryption Keys, click View Authorizations
  3. You should see your key under the Tokenization Keys section; if no key appears, click Generate New Tokenization Key
  4. Keep this page open so you can add your key in the code below

For more information or help with this step, see our API Credentials support article.

Add the Hosted Fields UI markupanchor

Hosted Fields requires some HTML markup, which will be initialized using the Braintree JavaScript SDK we included above.

Replace the contents of views/index.hbs with this code:

  1. HTML
<form action="/checkout" id="hosted-fields-form" 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>

  <div id="checkout-message"></div>

  <input id="payment-button" type="submit" value="Pay" disabled />
</form>

<script>
  var form = document.querySelector('#hosted-fields-form');
  var submit = document.querySelector('input[type="submit"]');

  braintree.client.create({
    // Insert your tokenization key here
    authorization: '<use_your_tokenization_key>'
  }, function (clientErr, clientInstance) {
    if (clientErr) {
      console.error(clientErr);
      return;
    }

    // Create a hostedFields component to initialize the form

    braintree.hostedFields.create({
      client: clientInstance,
      // Customize the Hosted Fields.
      // More information can be found at:
      // /braintree/docs/guides/hosted-fields/styling/javascript/v3
      styles: {
        'input': {
          'font-size': '14px'
        },
        'input.invalid': {
          'color': 'red'
        },
        'input.valid': {
          'color': 'green'
        }
      },
      // Configure which fields in your card form will be generated by Hosted Fields instead
      fields: {
        number: {
          container: '#card-number',
          placeholder: '4111 1111 1111 1111'
        },
        cvv: {
          container: '#cvv',
          placeholder: '123'
        },
        expirationDate: {
          container: '#expiration-date',
          placeholder: '10/2022'
        }
      }
    }, function (hostedFieldsErr, instance) {
      if (hostedFieldsErr) {
        console.error(hostedFieldsErr);
        return;
      }

      // Once the fields are initialized enable the submit button
      submit.removeAttribute('disabled');

      // Initialize the form submit event
      form.addEventListener('submit', function (event) {
        event.preventDefault();
        // When the user clicks on the 'Submit payment' button this code will send the
        // encrypted payment information in a variable called a payment method nonce
        instance.tokenize(function (tokenizeErr, payload) {
          if (tokenizeErr) {
            console.error(tokenizeErr);
            return;
          }

          $.ajax({
            type: 'POST',
            url: '/checkout',
            data: {'paymentMethodNonce': payload.nonce}
          }).done(function(result) {
            // Since the following code will overwrite the contents of
            // your page with a success or error message, first teardown
            // the Hosted Fields form to remove any extra event listeners
            // and iframes that the Braintree SDK added to your page
            instance.teardown(function (teardownErr) {
              if (teardownErr) {
                console.error('Could not tear down the Hosted Fields form!');
              } else {
                console.info('Hosted Fields form has been torn down!');
                // Remove the 'Submit payment' button
                form.removeChild(submit);
              }
            });

            if (result.success) {
              $('#checkout-message').html('<h1>Success</h1><p>Your Hosted Fields form is working! Check your <a href="https://sandbox.braintreegateway.com/login">sandbox Control Panel</a> for your test transactions.</p><p>Refresh to try another transaction.</p>');
            } else {
              $('#checkout-message').html('<h1>Error</h1><p>Check your console.</p>');
            }
          });
        });
      }, false);
    });
  });
</script>
note

Be sure to set the authorization parameter to your tokenization key as a string above.

After implementing the code above, your client will have successfully created a paymentMethodNonce string from payload.nonce. A payment method nonce is a one-time-use reference to the payment information that your customer provided in your payment form.

In the next step, we’ll set up your server to receive this paymentMethodNonce string and use it to attempt a transaction.

3. Handle checkoutanchor

Now that the client is set up to securely collect payment information, we’ll create a route on your server that accepts the paymentMethodNonce from the UI and then uses that nonce to create a sale transaction request for $10.

Create a file called routes/checkout.jsanchor

Create this file in your text editor, IDE, or console.

On Macanchor

  1. console
touch routes/checkout.js

On Windowsanchor

  1. console
echo.>routes\checkout.js

Add the payment logicanchor

Get your sandbox API credentialsanchor

Next, get your sandbox API credentials from the sandbox Control Panel. You'll need your:

  • Sandbox merchant ID
  • Public key
  • Private key

You can get all 3 values on the same Authorizations page where you found your tokenization key. For full instructions, follow this quick guide.

important

Never share your public or private key.

Add the route code to routes/checkout.jsanchor

In routes/checkout.js, add the following to create the checkout route.

  1. Node
const express = require("express");
const router = express.Router();
const braintree = require("braintree");

router.post("/", (req, res, next) => {
  const gateway = new braintree.BraintreeGateway({
    environment: braintree.Environment.Sandbox,
    // Use your own credentials from the sandbox Control Panel here
    merchantId: "<use_your_merchant_id>",
    publicKey: "<use_your_public_key>",
    privateKey: "<use_your_private_key>",
  });

  // Use the payment method nonce here
  const nonceFromTheClient = req.body.paymentMethodNonce;
  // Create a new transaction for $10
  const newTransaction = gateway.transaction.sale(
    {
      amount: "10.00",
      paymentMethodNonce: nonceFromTheClient,
      options: {
        // This option requests the funds from the transaction
        // once it has been authorized successfully
        submitForSettlement: true,
      },
    },
    (error, result) => {
      if (result) {
        res.send(result);
      } else {
        res.status(500).send(error);
      }
    }
  );
});

module.exports = router;
⚠️ This code snippet creates a gateway instance using the latest version of the Node SDK. Learn more.
note

Be sure to set the merchantId, publicKey and privateKey parameters above.

To learn more about how the transaction.sale method works and which options you can specify, see the reference.

Connect the route to app.jsanchor

app.js is the file that serves as the main entry point for Node and Express apps. All routes, as well as other critical information that define how your app will work, are stored here. We’ll use the app.js file to link up the route we created in the previous step.

Add a /checkout route to app.jsanchor

After app.use('/users', users); in app.js, add your checkout route:

  1. JavaScript
// The checkout route
const checkout = require("./routes/checkout");
app.use("/checkout", checkout);

4. Create a test transactionanchor

At this point, you should have a properly-initialized payment form when you run your app.

To see your payment UI in action, we’ll run a few test transactions and then view them in the sandbox Control Panel.

Run the appanchor

Run the following command in your console.

  1. console
npm start

Then open http://localhost:3000/ in your browser.

Enter a test card in the payment formanchor

The Braintree sandbox only accepts specific test values. To create a successful transaction in your app, be sure to use the card information below for this test.

  • Card number: 4111 1111 1111 1111
  • Expiry: 09/22
  • CVV: 400
  • Postal Code: 40000

Once you create a successful transaction, feel free to try out other test cards listed on our Testing reference page.

See your transaction in the sandboxanchor

You can view test transactions by logging back into the sandbox Control Panel. At a high level, you'll see your new sale transaction reflected in the graph on your dashboard, but to see its details:

  • Search for 1111 (the last 4 digits of the test card number above) in the search box, or
  • Click Transactions under Advanced Search in the side navigation to search with full control over your parameters

To learn more about searching in the Control Panel, see our Search support article.

Next stepsanchor

Give yourself a high five! Now that you have a basic working integration, choose what you'd like to do next: