Ruby
Article

Buy Time with the Braintree v.zero SDK

By Glenn Goodrich

This article was sponsored by Braintree. Thank you for supporting the sponsors who make SitePoint possible!

Braintree touts itself as offering “Simple, powerful payments.” We’ve been using Braintree at my company, KYCK, for ages now and I can attest how easy it makes accepting payments. In December of 2013, Braintree was acquired by PayPal. Not much changed due to the acquisition until recently. As the first major change, Braintree has released a new client SDK aimed at making things easier and adding some new features.

The new SDK is called “v.zero,” and it offers:

  • A new Drop-In UI that allows you to start accepting payments with “as little as ten lines of code.”
  • The ability to easily accept PayPal as a payment method. This is the big, new feature of the SDK, and, no doubt, a direct result of the PayPal acquisition.
  • Soon, the ability to accept payments via Bitcoin, through a partnership with Coinbase.
  • Powerful, customizable payment flow to fit your needs when the Drop-In UI doesn’t work.
  • Future changes to the SDK that will be “easy.” In other words, Braintree aims to keep the SDK current with constantly changing technology without forcing developers to overhaul their payment flow.
  • One Touch™ mobile payments with PayPal and Venmo. One Touch makes accepting payments via your mobile app as seamless as possible. This article announcing One Touch has a great video explaining the service. If you are a mobile developer, this is a big deal.

In this post, I’ll walk through some of the features of the v.zero SDK. Most of the focus will be on the Drop-In UI and accepting PayPal, so you can get up and running fast.

The Application

In order to accept payments, there has to be a product. For our app, I want a compelling product. Something that everyone wants or needs, something that they’ll flock to the site to buy. It hit me like a lightning bolt in the middle of the night: Time. Everyone wants more time. So, that’s what we’re going to sell. Our users will be able to buy extra hours to spend as they see fit in their busy lives. We are going to be bazillionaires in no time.

The app is a vanilla Rails app with Devise for authentication. I am not going to walk through setting up the Rails app. Instead, our starting point is a Rails app with a User model that uses Devise’s password authentication. I’ve also added Zurb Foundation for some easy styling. There are roughly 1.2 million tutorials on how to setup Rails and Devise, and I have tagged our starting point (“starting_point”) in the repository.

Our users will have a very simple purchasing flow. Once logged in, the user can choose a payment method (credit card or PayPal) and pay $10 for 1 hour. To start, the application has an OrdersController with a new action and view.

How the SDK Works

The Braintree payment flow consists of four steps:

  • Create a Braintree Account.
  • Add the Braintree Ruby Library to the application.
  • Provide a client token to your client (meaning, the browser, in our case)
  • Receive a payment method nonce from the client (browser) after a payment is authorized (Note: Before this step, if you had asked me what a nonce is, I would’ve said, “an often rabid, small, furry animal that attacks without provocation.” There’s a lot I don’t know.)
  • Create a transaction on Braintree using the payment method nonce.

Create a Braintree Account

In order to use Braintree to accept payments, you have to sign up for a Braintree account. It’s recommended to start in the Braintree “Sandbox,” which allows you to test payments without money actually exchanging hands. The Sandbox is a godsend, allowing developers to perfect the payment flow in an environment that mirrors the real thing.

Head over to the Get Started page and sign up for an account.

Sign Up Form

Braintree will send a confirmation email, so get confirmed and we’re ready to move forward.

The first login drops you on the Sandbox Dashboard, which looks like this:

Sandbox Dashboard

The important bits on this page are: Merchant ID:, Public Key, and Private Key. These values will be used to configure the Braintree SDKs in our Rails app. In fact, if you look on that same page, there is an example Ruby configuration that can be copied and pasted into your app.

Get the Braintree Ruby Library

Example Ruby Configuration

In Rails, this kind of configuration is handled in an initializer. However, we don’t have a Braintree class in our codebase yet. Luckily, Braintree has a Rubygem for us to utilize. Add gem "braintree" to the Gemfile and bundle install.

Create a config/initializers/braintree.rb with the following:

Braintree::Configuration.environment  = ENV['BRAINTREE_ENV']         || :sandbox
Braintree::Configuratio.merchant_id   = ENV['BRAINTREE_MERCHANT_ID'] || 'your merchant id'
Braintree::Configuration.public_key   = ENV['BRAINTREE_PUBLIC_KEY']  || 'your public key'
Braintree::Configuration.private_key  = ENV['BRAINTREE_PRIVATE_KEY'] || 'your private key'

Generate a Client Token

When our users show up to buy more time, Braintree has to know who we are in order to get us our millions. Basically, the users will select a payment method and authorize a payment by submitting a form from our app to Braintree’s servers. The client token will be provided alongside the user’s information, and it tells Braintree who we are by identifying our merchant account on their side. Braintree returns a payment method nonce that represents the authorized payment to our application, which we’ll discuss in a moment.

Drop-In UI

Here is where the new Drop-In UI in the v.zero SDK comes into play. Create a partial called app/views/payment/_form.html.erb:

<form id="checkout" method="post" action="/checkout">
  <div id="dropin"></div>
  <input type="submit" value="Pay $10">
</form>

<script type="text/javascript">
  function setupBT() {
    braintree.setup("<%=@client_token%>", 'dropin', {
      container: 'dropin'
    });
  }
  if (window.addEventListener)
    window.addEventListener("load", setupBT, false);
  else if (window.attachEvent)
    window.attachEvent("onload", setupBT);
  else window.onload = setupBT;
  </script>
</script>

This form is pulled directly from the Braintree docs. The script block is added here to handle the generation of the client token. I wanted to keep it all in one file to make it clearer for this tutorial. The token is created in the OrdersController#new method:

def new
  @client_token = Braintree::ClientToken.generate
end

Those same Braintree docs show the need to add the Braintree javascript file, so let’s do that now. Download the braintree.js file into the vendor/assets/javascripts directory and add it to our app/assets/javascripts/applications.js:

//= require braintree (ADD THIS LINE)
//= require_tree . (This line already exists)

Now, the braintree javascript variable in our setupBT function will exist.

If you run the server (and sign up for an account in the app), the Drop-In UI renders and looks pretty good:

Drop-In UI

It looks like we have the ability to accept PayPal and credit cards out of the box. But that form looks a bit odd without a CVV field. How can we add CVV?

We can add CVV to our form by configuring it in the Braintree Sandbox. Once logged in, Choose “Processing” from the “Settings” menu:

Settings Menu

This page has a metric ton of configuration options, including:

  • Duplicate Transaction Checking, which stops a transaction from being created if it matches one within the last 30 seconds.
  • Accept Venmo.
  • Basic Fraud Protection, including CVV.
  • Custom Fields.
  • Email Receipts.
  • Much, much more.

To get CVV added to the form, we’ll need to configure the rules. Click the “Edit” button under “CVV” and add your rules. Here’s mine:

CVV Rules

With the CVV rules configured, the form now has the CVV field:

CVV Form

That is pretty cool.

Payment Method Nonce

On to the last step in our basic process: getting a payment method nonce from Braintree that we will provide to our Rails server and then back to Braintree to add a payment.

I want this to be as simple as possible for our first payment. As such, we’ll change the action on our form to post to /orders and we’ll render out the @params. Change the form partial:

<%= form_tag orders_path, method: "post" do %>
  <div id="dropin"></div>
  <input type="submit" value="Pay $10">
<% end %>
<%= @params %> <!-- We'll remove this later, just testing now -->

The form is now Rails-ed up a bit, that way there won’t be any authenticity token errors. Also, I added @params so we can get a good look at what is provided to the server by the Braintree form.

POSTing to /orders is going to expect OrdersController#create to exist. Starting simple:

def create
  @params = params
  render action: :new
end

To test the form with a credit card, we need a fake number. You can grab fake credit card numbers from this page on the PayPal site. (They don’t work for real stuff… not that I tried them or anything.)

Fill out the form and see what happens.

Form Filled Out

I immediately noticed the following coolness:

  • It won’t let me type any garbage into the Credit Card or other fields. Some basic, but solid, input validation comes with the form for free. Nice.
  • The text labels are helpful and intuitive. It’s a nice experience, in fact, and better than a form that took KYCK ages to design and implement.

Submitting the form posted to our create method and rendered the params in the view:

{"utf8"=>"✓",
 "authenticity_token"=>"Yxt5NzsrKB4u/rEjmR3A7pIwVbcpGCL/lEBTMx7H8x0=",
 "payment_method_nonce"=>"1e6dfd62-f92e-4703-8807-b3f6b9b28c84",
 "action"=>"create",
 "controller"=>"orders"}

There it is… the payment method nonce. You can read about nonces all you want, but seeing one in the wild is truly a breathtaking experience.

Create a Braintree Transaction

Well, this is pretty exciting. We are already on to the last step in our test run of accepting payments. At this point, it’s simply a matter of creating a transaction on Braintree. This is pretty easy, as it turns out. Change OrdersController#create like so:

def create
  nonce = params[:payment_method_nonce]
  render action: :new and return unless nonce
  result = Braintree::Transaction.sale(
    amount: "10.00",
    payment_method_nonce: nonce
  )

  flash[:notice] = "Sale successful. Head to Sizzler" if result.success?
  flash[:alert] = "Something is amiss. #{result.transaction.processor_response_text}" unless result.success?
  redirect_to action: :new
end

Go back and fill in your form with that fake credit card number and BOOM! We can accept payments.

Sizzler

Enter PayPal

Let’s see if the using PayPal is as easy as using a fake credit card number. Go back to the app and, instead of filling out the form, click that big, blue PayPal button. You should see a popup asking you to sign in:

PayPal Login

Notice it places an overlay on the main form, which is sassy. Once logged in, you’re told exactly what the vendor is asking:

Terms

Click ‘Agree’, and you’re returned to the form. It changes to reflect that you’re using PayPal

Using PayPal

Click “Pay $10” and watch PayPal being accepted. MMMM…that is some good payment.

Counting Our Money

If you head over to the Braintree Sandbox dashboard, you can see that we are movin’ on up!

Money!

Man, today was HUGE for us!

Next Steps

This article scratches the surface of what can be done with the Braintree v.zero SDK. If we wanted to take our time-buying application to the next level, we might:

  • Store Braintree customer IDs on our local Users, allowing these users to reuse payment methods. Braintree offers the Vault that will store tokens for each of the payment methods a user adds. The customer can then choose one of these payment methods when returning to buy more time.
  • Control the transaction life cycle for our application’s transactions. The Braintree transaction processing flow is involved and you need to know it if you’re using Braintree. You can settle, release, refund funds, among other actions. Learn it, live it, love it.
  • Offer subscriptions to our customers. Maybe they can get 10 hours a month for $90 or something. Braintree offers recurring billing that is surprisingly easy to handle. This is where the real cheese lives.

Maybe you have other suggestions for where we can take our time hawking? Let me know what we should do next, and maybe I’ll pen an article for the most requested item.

Remember, the source for this article is in this repository.

In the meantime, watch out for those nonces. They can spring at any time.

Free Guide:

7 Habits of Successful CTOs

"What makes a great CTO?" Engineering skills? Business savvy? An innate tendency to channel a mythical creature (ahem, unicorn)? All of the above? Discover the top traits of the most successful CTOs in this free guide.

  • Cprkash

    Hi Goodrich !

    Thank for all these information, but i’m able to find any option so we can change the description, that would be show on customer credit card payment statement. it show the company name and phone number. but i want show only company name.

  • ggsp

    Hey Cprkash…looks like Dynamic Descriptors are not enabled by default. You need to contact Braintree Support and discuss it with them.

    See this for more details.

  • wac zellmer

    I keep trying to run the server however I’m getting an error saying “/config/initializers/braintree.rb:2:in `’: uninitialized constant Braintree::Configuratio (NameError)”

  • alkesh

    Hey, sorry for the incomplete comment.
    My question is:
    If I use paypal and add my paypal email address. On submit I call the Braintree::Transaction.sle method, then do I need to pass any parameter in this method to tell this is from paypal account?

    Please let me know about this.
    Thanks,

  • ty_qwon_doe

    recurring billing would be a sweet addition, something where you get a subscription for a certain amount of time per month

  • Patrick Bradley

    Thanks for the tutorial.

    You have a typo in your config/intializers/braintree.rb file. You are missing the ‘n’ in ‘::Configuration’.

    This line:

    Braintree::Configuratio.merchant_id = ENV[‘BRAINTREE_MERCHANT_ID’] || ‘your merchant id’

    Should be changed to this:

    Braintree::Configuration.merchant_id = ENV[‘BRAINTREE_MERCHANT_ID’] || ‘your merchant id’

  • matbernard78

    Hello, how can I Download the braintree.js file into the vendor/assets/javascripts directory ?

Recommended
Sponsors
Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in Ruby, once a week, for free.