September 20, 2013

Painting Adventures

A couple of friends and I decided around a month ago that we wanted to get better at drawing, so we decided to embark on one of those "draw one thing every day for 365 days" projects. Well, if we're being realistic, for approximately 365 days—we even named ourselves "Approximately 1095" (1095 = 365 x 3).

It's been really fun so far:

(I'll write up a separate post later about how/where I'm posting these!)

One day I woke up to discover that my friend Jack had, that morning (on mostly a whim), gone out and purchased a set of painting supplies and was happily painting away on an easel in front of the bay windows in his room.

I thought that was pretty amazing and was inspired to do the same. As much as I like drawing and sketching, the lack of color is sometimes a bit depressing. I've always wanted to experiment with painting (having done digital/Photoshop painting but never physical painting), and decided to try it out1!

Color mixing

The day my acrylic paints arrived (2-day Amazon Prime, ftw), I sat down and practiced mixing a bunch of colors to get a feel for the ratios and color combinations. And it's a good thing I did, because I instantly made the newbie mistake of squeezing out entirely too much dark paint (a dark pigment like red will overwhelm a lighter one like yellow; 90% yellow + 10% red is basically already dark orange).

I ended up with a bunch of index cards with color gradients, much like a Pantone catalog. Pretty fun. I actually like using physical paints a lot more than using a digital color picker, since the colors blend together pretty interestingly when painted, and aren't just one flat color.

First painting!

The prompt of the day for our drawing project was "mermaid" and I knew I wanted to paint a landscape (so hard to mess up!), so I decided to paint the underwater castle from the Little Mermaid.

The hardest part was probably being too scared to paint over things that I had already painted in the background (no undo or layers?!). It was really fun though.

Highly, highly recommend picking up painting as a hobby. It's relatively cheap (I got everything for around $50-60 on Amazon), and it's super fun and relaxing/therapeutic to be swirling paint around for a couple of hours. Not to mention you get an awesome physical piece of art that you can then decorate with, gift, or hide in your closet.

I decided to start off with acrylic because watercolor is really hard to control or recover from mistakes with, and oil has a messier cleanup, but it's really up to your own preference. Enjoy!

I hope to be posting more about the rest of my painting adventures soon! (:

1: I'm still continuing the drawing project, I'll just substitute paintings in every once in a while.

February 23, 2013

Building Stripe's API

I just got back from New York, where I gave my first conference talk ever at the API Strategy and Practice conference. Pretty exciting!

I thought it would be interesting to talk about Stripe's API, particularly lessons learned and what kind things we did to try to make using the API as easy as possible. I've included the slides below, but most of the content isn't on the slides so I'll try to cover some of the highlights below.

As a disclaimer, we definitely don't know everything. A lot of what you see on Stripe today is the product of thought and discussion, as well as a lot of trial and error. I hope you find something in here applicable toward your own API! (:

Highlights

Make it easy to get started

This sounds like a no-brainer, but the best way to get people to try out your API is to make it really easy to get started.

We do things like including passable code snippets throughout our site and documentation. For example, one of the first things you'll see on our front page is a curl snippet you can paste into a terminal to simulate charging a credit card. Regardless of whether you have a Stripe account or not (if logged in, we embed your test API key, else, it's a sample account's API key), you can see the Stripe API in action.

All of our documentation code snippets are similarly easy to copy and paste—we try to embed as much information as possible (API keys, actual object IDs from your account) so you don't have to.

Language-specific libraries and documentation

Since Stripe is an HTTP API, you could easily integrate it into your application with any HTTP client library. However, this still requires constructing requests and parsing responses on your own.

To make this easier, we support official open-source libraries in the most web today (turns out people are pretty attached to their favorite languages). There was a lot of internal discussion about whether we actually wanted to support our own API or allow the community to organically start and maintain the projects themselves.

Ultimately, I think there's a certain degree of trust that users put in official libraries, which makes it easy for them to get started (as opposed to trying to audit different third-party libraries). It also makes it really easy for us to have language-specific documentation this way.

Have a focused API, but allow flexibility

One thing that we found critically important was to keep the API focused. It's tempting to add new features that are nice, but not necessary.

For example, our users frequently want us to add better analytics, tax calculations, or to send user receipts. While these things are nice, they're not our core competency and may very well clutter our API with too many options1.

Instead, you should give your users the tools to be able to write their own extensions. We allow our users (and third party applications) to hook into Stripe in a couple of ways.

Webhooks

Webhooks are a way of Stripe letting you (our user) know when some interesting event has happened on the Stripe server. Examples include charge.succeeded, charge.refunded, invoice.paid, and so on.

With webhooks, it's easy to build something on top of Stripe events, like sending a customer receipts. This has the added benefit of allowing our users to control the entire user experience.

Stripe Connect

Stripe Connect, an API we released just last year, is another way of building on top of the Stripe platform. Connect is an OAuth2 API that allows a Stripe user to authorize access to their Stripe account to a third-party application. This application might be a marketplace, whose users want to accept payments, or an analytics dashboard, who wants to be able to have full access to Stripe data.

Provide a testing environment

One of the most important things you need with an API is a test environment. This is particularly important for a payments API— obviously your users won't want to make live charges when they're trying to test their application.

In our testing environment, we allow you to send test web hooks of any type and provide handy test card numbers that trigger certain errors (like declines). Doing this allows our users to easily test the behavior of their own application in the face of different scenarios instead of having to manually trigger things that are nondeterministic, like declines, or time-dependent, like expiring subscriptions.

If there's certain behavior that your user's application potentially depends on, make sure they can test it easily.

Help your users debug

We're developers too. We know that a large percentage of our users' time is probably spent debugging. We also (unfortunately) know that sometimes you spend a lot of time debugging something that eventually turns out to be really obvious or stupid.

For common or easy errors, you (the API) likely know exactly what's wrong. So why not try to help?

>> Stripe::Customer.create
Stripe::AuthenticationError: No API key provided.  (HINT: set your API key
using "Stripe.api_key = <API-KEY>".  You can generate API keys from the 
Stripe web interface.  See https://stripe.com/api for details, or email
support@stripe.com if you have any questions.)

Or,:

>> Stripe.api_key = TEST_KEY
=> ...
>> Stripe::Charge.retrieve("ch_17SOe5QQ2exd2S")
Stripe::InvalidRequestError: (Status 404) No such charge: ch_17SOe5QQ2exd2S;
a similar object exists in live mode, but a test mode key was used to make
this request.

If you help your users debug, they'll love you.

Dealing with Change

Lastly, dealing with change is never fun. As much as you hope you'll never have to change the API, sometimes you need to make changes, and sometimes those changes are backwards-incompatible.

There's no easy answer to versioning APIs. We keep a version per-user, which reflects the state of the API the first time they made an API request. This version isn't taken into account when we add a new feature or non-breaking change (i.e. you'll always be able to use new features, regardless of what version you're on).

Whenever we make a backwards-incompatible change2, however, we bump the current version of the API (so that any new users will see the "new" changes) and take the legacy user's version into account in the relevant API code paths.

Users can choose to upgrade their versions in the dashboard (after reviewing the details changelogs, of course), or can send a version override header in any API request to test the behavior of a specific version.

Questions?

If you have any questions, feel free to email or tweet at me. Thanks for reading!

Footnotes

  1. I'm not saying that Stripe is not going to do these particular things in the future, but it's not feasible in general to try to accommodate everyone's use case.
  2. We are usually hesitant to do this.

Credit for various parts of the presentation content go to Greg Brockman, Sidd Chandrasekaran, Evan Broder, and Ross Boucher. And of course, credit to everyone at Stripe for actually doing the things I outlined in the talk.

December 21, 2012

Private methods in Ruby

Consider the following code:

(This blew my mind the other day.)

class Hello
  def public_hello
    self.private_hello
  end

  private
  def private_hello
    puts "Hello!"
  end
end

You would expect that this would work fine: private_hello is a private method, but it's being called from within the class.

Nope.

>> hello = Hello.new
=> #<Hello:0x10d0cc200>
>> hello.public_hello
NoMethodError: private method `private_hello' called for #<Hello:0x10d0cc200>
  from (irb):3:in `public_hello'
  from (irb):13

I spent an embarassingly long time trying to figure out what was wrong ("Do I just not understand how private methods work?!"), and confused one of my coworkers as well in the process of doing so.

However, it turned out to be old news. One post puts the issue pretty succinctly:

private methods can never be called with an explicit receiver, even if the receiver is self

So, the problem with self.private_hello is that the private method is being called on an explicit receiver, even though the receiver is technically the same object—you'd need to call private_hello by itself instead.

Having learned access control modifiers in Java first, I thought this was really bizarre. I guess I need to learn Ruby a little better! (:

October 31, 2012

Discount Code Cards

I love career fairs. In college, I loved going to career fairs to get swag—EECS majors are definitely ridiculously spoiled when it comes to getting free things like shirts and food (I even got a poker set once!).

Anyway, while planning our trip to the UC Berkeley Startup Fair this year, I wanted Stripe to stand out so I thought pretty hard about what my favorite types of things to get were.

Number one was shirts, probably. We already had that covered. But I also remembered happily going to the Dropbox booth every semester to get those nifty free space cards: discount codes that you can apply to your account to get 5-10gbs of space at a time.

What if we made free Stripe processing cards? Since we'd be going to a career fair where all of the students were software engineers, and more specifically, very hacker/startup-minded, it made even more sense as a marketing effort.

Implementation

Most of the discount code implementation was already in place from our invite system, so all I really needed to do was generate an extra couple of hundred codes for use at the career fair. The hard part, however, was trying to figure out how to print them.

Traditional business card printing services won't let you print out cards with unique codes on them unless you go through some kind of custom order. I didn't have too much time to spare, so John told me about this nifty hack he used with Moo.com (I later found the same solution on Quora).

Moo lets you do this cool thing where you can print a variable number of designs per order—for example, if you want to have a different photograph on the back of each business card. We found that if you upload 100 different "designs" for 100 different cards, each card would be unique.

Their Text-o-matic tool lets you create up to 100 "designs" that are text only:

I took one look at the page and realized I could easily use a script to automatically generate all of the cards (sigh of relief when I discovered the page was not written in Flash):

// Create an array of the discount codes you want to use here
var texts = ['CODE1', 'CODE2', 'CODE3'];

// Click buttons on the page for each code to create the design
texts.each(function(text) {
  jQuery('#txtFrontText').val(text);
  jQuery('div#divMakeCard input').click();

  // Set color/size
  jQuery('#a_000000').click();
  jQuery('#aReverseColours').click();
  jQuery('#aZoomOut').click();
  jQuery('#aZoomOut').click();

  jQuery('#btnSaveCard').click();
});

Really, really simple but pretty hacky (just run this in the developer console on the web page). After this, you'll just go into their general template wizard and upload the design for the other side of the card to finish them up.

Improvements

Of course, there are several drawbacks to this approach:

  • You can't really design the "variable" side of the card. You either need to upload the images yourself, or use Text-o-matic, which has a super limited set of options (you can't even add a new line or style separate parts of the text).
  • You can only print 100 cards per order. Since the max number of designs you can upload is 100, if you try to double the card count to 200, you'll end up with every unique card twice.

So what can you do?

Probably the only legitimate way to do this is to generate the to-print PDF yourself, either using some kind of software (like InDesign) or hacking something in PostScript. I'll be sure to write a follow up post if I end up doing either!

September 9, 2012

Goodbye, Wordpress!

As you may or may not have noticed, this blog has recently undergone a pretty drastic change. Aside from pure design upgrades, I've moved off Wordpress (good riddance!) and joined the geek bandwagon by writing my blog with Jekyll. Here's my obligatory "I moved to Jekyll" blog post!

Why Jekyll?

  • Wordpress is bloated. I've never even used a third of the features—I wanted something super simple and lightweight that I could gradually add onto (if I wanted to).
  • Custom styling. Wordpress, I've found, is a nightmare to try to style. There are layers upon layers of templates, and I really hate trying to navigate through PHP code. Jekyll, by contrast, is a lot cleaner and easier to deal with.
  • Markdown/Vim > Wordpress editor. I've gotten to the point where I basically need to use Vim for everything (code, obviously, but also notes, to-do lists, etc). Markdown is great, and I like how all of my blog posts are now under version control.
  • Static pages. Blogs are almost pure static content (with the exception of comments, search, etc), so I figured that it would be simpler (and faster) to just have an entirely static site. This makes deploys super easy as well.

My setup

I'm not going to go through in depth how I got my Jekyll set up, because there are more than enough of those guides out there. Here are some of the main components that I used:

All of the templates and styles are handwritten. Being able to customize all aspects of the blog is definitely one of the major perks of using Jekyll!