Introducing Braintree.js

When you're processing credit card payments, PCI compliance can be a drag. Even if you're not storing credit card data in your system (which you shouldn't be), you'll still be subject to a large amount of PCI scope if raw credit card data passes through your system at all. This can mean audits, fees and other undesirable things.

In the past, Braintree provided Transparent Redirect (TR) to our merchants as a tool to greatly reduce PCI scope. With TR, credit card data is passed directly to Braintree's servers, meaning no credit card data passes through merchants' servers at all. When we launched it, TR was a massive improvement on the status quo and has worked wonderfully for thousands of merchants. However, TR isn't all sunshine and rainbows. Because the form posts directly to Braintree's servers, it can be difficult to perform complicated validations on the data without lots of client side javascript or splitting your payment flow into two steps. Also, because it requires posting a form to an external service, it can be difficult to write automated tests for TR flows.

Today, we're announcing Braintree.js. It allows merchants to reduce their PCI scope in a flexible and testable manner.


How it Works

Braintree.js uses asymmetric encryption to prevent raw credit card data from passing through merchants' servers. It intercepts a form submit in the browser that contains sensitive data, encrypts that data with a public key provided to merchants by Braintree and then submits the form with the encrypted data to the server. Braintree retains the private key of the key pair so that merchants are unable to decrypt the encrypted fields server-side. Any string field in Braintree's API can be encrypted and encrypted values can be transparently dropped into any API call (we'll see how this helps testing later).

Braintree.js differs from other libraries that provide tokenization in the browser because it does not add dependencies to external services in client side code. It allows a merchant to simply encrypt the data in the browser, then pass it to their server and call existing Braintree client library functions.

Below is a simple example of using Braintree.js to encrypt sensitive values in a form.

  <head><title>Braintree Payment Form</title>  </head>
    <h1>Braintree Payment Form</h1>
      <form action="/create_transaction" method="POST" id="braintree-payment-form">
        <p><label>Card Number</label>
          <input type="text" size="20" autocomplete="off" data-encrypted-name="number" />
          <input type="text" size="4" autocomplete="off" data-encrypted-name="cvv" />
        <p><label>Expiration (MM/YYYY)</label> 
          <input type="text" size="2" data-encrypted-name="month" /> / 
          <input type="text" size="4" data-encrypted-name="year" />
        <input type="submit" id="submit" />
<script type="text/javascript" src=""> </script> <script type="text/javascript"> var braintree = Braintree.create("YourClientSideEncryptionKey") braintree.onSubmitEncryptForm('braintree-payment-form'); </script> </body> </html>

You simply annotate the inputs you want to encrypt with the "data-encrypted-name" attribute and then call "onSubmitEncryptForm" with the form's id. That's all there is to it.


Remember, you should always serve your payments form and submit information to your server via HTTPS. HTTPS protects sensitive data in transit from bad actors while Braintree.js protects you from expanding PCI scope. Also, be mindful about third-party javascript you include in your application as it has access to all information in the DOM.


Because there is no dependency on external systems in the client's browser, merchants have the flexibility to include Braintree.js into almost any existing workflow. The example above shows a drop-in solution for encrypting and submitting a form, but if your process is more complex Braintree.js provides access to lower-level encryption APIs and can easily be used in an AJAX payment flow.

Ease of Testing

Testing actions that accept input from a Braintree.js powered form is simple because of an important design decision: any string value in the Braintree API can be transparently replaced with encrypted data. For example, the following ruby code would work when provided with a plain text testing credit card number or an encrypted credit card number.
  :amount => "100.00",
  :creditcard => {
    :number => params[:number],
    :expirationdate => params[:expiration_date]

This means you can write automated tests that exercise this action without the browser being involved. When encrypted form posts from the browser hit the same action, no code changes are necessary. Just make sure that in your view you don't add a "name" attribute to any form fields that have a "data-encrypted-name" attribute because we don't want these fields submitted with the form.

Try It

If you like what you see, sign up for a free Braintree sandbox account and check out the developer documentation. We think you'll enjoy it!

Drew Olson Drew is a Principal Engineer at Braintree. More posts by this author

You Might Also Like