in Business, Hiring

The Account Executive Interview Process

One of the most important things as we look to scale from processing $1 billion payments a year to $10 billion is growing our sales team. Our vision is to create a global payments network, making payments simpler on the internet no matter what country you're from. We’ve previously written about how we train our salespeople. This blog post is aimed at guiding you through the account executive interview process. We want you to succeed, so we’re going to outline what we look for and how the process works.

The process is split into three sections:

  1. Phone screen
  2. First round interview (1.5 hours)
  3. Final round interview (2.5 hours)

We have identified the following characteristics as being most important for successful salespeople here:

  • Smart. Our product is technical. To succeed here you need to be able to learn technical detail so you communicate potentially confusing things in a simple way.
  • Driven to learn and improve. We believe how good you’ll be a year from now is more dependant on attitude than current ability. How driven you are and how motivated you are to improve are the two most important drivers of success.
  • Coachability. Giving and taking feedback is one of the most important aspects of our company culture. The quicker you are able to act on feedback, the faster you learn.
  • Likeable. People don’t like to buy from people they don’t like. It is essential that anyone we employ is friendly.
  • Communication skills. The ability to explain complex ideas simply is absolutely crucial for our salespeople.

The interview process is designed to test these skills.

1. Phone screen

This interview lasts 10-15 minutes and you will speak to our hiring co-ordinator. We are assessing a few basic things here:

  • Have you done your research on the company?
  • Are you passionate about startups?
  • Do you want to work in sales?

To do well in this interview:

  • Be in a quiet place. Good signal helps too!
  • Be prepared. Make sure you’ve done research on the company. You should have more specific reasons on why you want to join than just ‘interested in startups or fintech.’
  • Be enthusiastic. We want to know you’re excited about joining us.
  • Be positive and engaging. We want to hire people who will make a contribution to our culture, who are respectful, polite, collaborative and energetic.

2. First round interview

This consists of two parts:

  • The background interview. Here we’ll be trying to assess the skills we value in salespeople as well as find out a bit more about your motivations for joining us and why you want to work in sales.
  • The roleplay. For this you will be doing a sales meeting with a mock client. You don’t know anything about them in advance.

In order to succeed in culture fit:

  • Think of examples of where you have demonstrated the skills we care about.
  • Be structured. Good communication is really important in sales. Read about the pyramid principle and apply it in your answers.
  • Be honest. People join a startup for a variety of reasons; tell us what you’re really looking for and what you want to do in your career. It doesn't matter if you’ve not got a history in sales (I didn’t do sales before GC!), but you need to have a good reason to work in sales with us.
  • Do your research. Why is it you want to work for us? Try and be specific as possible. How did you find out about us? What about us excites you?

In order to succeed in the role play:

  • Read SPIN Selling. This forms a great foundation on how we do sales here. If you don’t have time for the whole book, at a minimum read a summary. Prepare some questions for the role play using what you learn.
  • Know our product and industry. Sign up for a GoCardless account and learn how to use it. At a minimum you should read our Recurring Payments Guide and our Direct Debit Guide.
  • Listen attentively. Good questioning and good listening are two of the most important skills in sales. Listen carefully to what we say and use it to ask intelligent questions.
  • Don’t pitch. You should think of this as a conversation not a ‘pitch.’ The key is to really understand the client’s needs. Only then can you align our solution to what the client wants.

3. Final round interview

This consists of three parts:

  • The roleplay. The is the same format as the previous round. After the first role play we will give you feedback. The second round is the same scenario: we want to see if you’ve responded to the feedback.
  • The exec interview. In the final round you get the opportunity to meet our CEO and another member of our management team. The same advice as the background interview applies here.
  • Working with sales. This is a quick challenge. There is no need to prepare anything for this. We’ll give you something you might be faced with on a typical day here.

Good luck and we look forward to meeting you! If you’re unsure about applying, please just do. We'd love to hear from you!

Want to help us hit $10bn? We're hiring!
See job listing
in Engineering

Friday's outage post mortem

The below is a post-mortem on downtime experienced on Friday 3rd July. It was sent around the GoCardless team and is published here for the benefit of our integrators.

Any amount of downtime is completely unacceptable to us. We're sorry to have let you, our customers, down.


On Friday 3rd July 2015, we experienced three separate outages over a period of 1 hour and 35 minutes. It affected our API and our Pro API, as well as the dashboards powered by these APIs.

The first incident was reported at 16:37 BST and all our service were fully up and stable at 18:12 BST.

We apologise for the inconvenience caused. More importantly, we are doing everything we can to make sure this can't happen again.


On Friday 3rd July 2015, at 16:35 BST, we started experiencing network failures on our primary database cluster in SoftLayer’s Amsterdam datacentre. After several minutes of diagnosis it became evident that SoftLayer were having problems within their internal network. We were experiencing very high latency when troubleshooting and seeing high packet loss between servers in our infrastructure. We immediately got in touch with SoftLayer’s technical support team and they confirmed they were having issues with one of their backend routers, which was causing connectivy issues in the whole datacentre.

At 16:37 BST, all the interfaces on SoftLayer’s backend router went down. This caused our PostgreSQL cluster to be partitioned since all nodes lost connectivity to one another. As a result, our API and Pro API became unavailable, as well as the dashboards using these APIs. At 16:39 BST the network came back online and we started repairing our database cluster.

By 16:44 BST, we brought our PostgreSQL cluster up and normal service resumed.

At 17:07 BST, the interfaces on SoftLayer's router flapped again, causing our service to be unavailable. This time one of the standby nodes in our cluster became corrupted. While some of our team worked on repairing the cluster, the remainder started preparing to fail over our database cluster to another datacentre.

By 17:37 BST, all of SoftLayer’s internal network was working properly again. We received confirmation from SoftLayer that the situation was entirely mitigated. We came to the conclusion that at this point, transitioning our database cluster to a different datacentre would cause unnecessary further disruption.

At 18:03 BST, we saw a third occurrence of the internal network flapping, which caused our service to be unavailable again for a short period of time.

By 18:12 BST, our API, Pro API and dashboards were fully operational.

Post mortem

We don't yet have any further details from SoftLayer on the cause of the router issues, but we are awaiting a root cause analysis.

Currently, our PostgreSQL cluster automatically fails over to a new server within the same datacentre in case of any single-node failure. Following these events we have brought forward work to completely automate this failover across datacentres so that we can recover faster from datacentre-wide issues.

Hitting $1bn

We're excited to announce that GoCardless is now processing over $1bn each year. It's a great milestone in our journey to create a new payment network for the Internet.

Over the last year we’ve seen a 250% increase in volume as our customers increasingly recognise the potential of Direct Debit. We've welcomed large new customers, including The Financial Times,, and Habitat, at the same time as continuing to serve thousands of small business. In fact, over half of our volume comes from businesses that have never had access to Direct Debit before.

What's next?

With over 2,000 businesses signing up to collect payment via GoCardless every month it still feels like we are at the beginning of our journey.

European expansion is well under way - we just launched in France, are in open beta in Germany and Ireland, and will be launching across the rest of Europe as soon as we have the team to build and support our business internationally.

We're not planning on stopping at SEPA & UK Direct Debit, either. Our vision is to create an international Direct Debit network to power simple payments for the Internet. Expect more announcements soon!

Want to help us hit $10bn? We're hiring!
See job listings

New API Version - 2015-07-06

Version 2015-07-06 is released today, with the following changes:

  • Removes /helpers endpoint from the API
  • Renames subscription start_at and end_at to start_date and end_date
  • Enforces date format when passing a payment charge_date

For the majority of integrations, the upgrade will be extremely simple, but we will continue our support for v2015-04-29 until the 6th of January, 2016.


Upgrading to the new API version should be extremely simple:

  1. Update your version header:

    GoCardless-Version: 2015-07-06
  2. If you use the subscriptions endpoint, update your integration to use start_date and end_date keys instead of start_at and end_at.

  3. If you generate PDF mandates, update your integration to use the new mandate_pdfs endpoint.

  4. If you use the old /helpers/modulus_check endpoint, update your code to use the new bank_details_lookups endpoint.

Why are GoCardless making these changes?

The above changes achieve two improvements to the GoCardless API:

  1. Dates now all have an _date key, whilst timestamps all have an _at key.

  2. All endpoints act as first class resources. Previously the /helpers endpoints were inconsistent with the rest of the API, making them harder to use.

Off the back of these changes we will release version 1.0 of our Java and Ruby client libraries this week. Python and PHP will follow shortly afterwards.

Need help upgrading or have any questions?
Get in touch
in Engineering

Coach: An alternative to Rails controllers

Today we're open sourcing Coach, a library that removes the complexity from Rails controllers. Bundle your shared behaviour into highly robust, heavily tested middlewares and rely on Coach to join them together, providing static analysis over the entire chain. Coach ensures you only require a glance to see what's being run on each controller endpoint.

At GoCardless we've replaced all our controller code with Coach middlewares.

Why controller code is tricky

Controller code often suffers from hidden behaviour and tangled data dependencies, making it hard to read and difficult to test.

To keep your endpoints performant, you never want to be running a cacheable operation more than once. This leads to memoizing your database queries but the question is then where to store this data? If you want the rest of your controller code to be able to access it, then storing the data on the controller instance is the easiest way to make that happen.

In an attempt to reuse code, controller methods are then split out into controller concerns (mixins), which are included as needed. This leads to controllers that look skinny but have a large amount of included behaviour, all defined far from their call site.

Some of these implicitly defined methods are called in before_actions, making it even more unclear what code is being run when you hit your controllers. Inherited before_actions can lead to a controller that runs several methods before every action without it being clear which these are.

One of the first things we do when a request hits GoCardless is parse authentication details and pull a reference to that access token out of the database. As the request progresses, we make use of that token to scope our database queries, tag our logs and verify permissions. This sharing and reuse of data is what makes writing controller code complex.

So how does Coach help?

Coach rethinks this approach by building your controller code around the data needed for your request. All your controller code is built from Coach::Middlewares, which take a request context and decide on a response. Each middleware can opt to respond itself, or call the next middleware in the chain.

Each middleware can specify the data it requires from those that have ran before it, and can declare what data it will pass to those that come after. This makes the flow of data explicit, and Coach will verify that the requirements have been met before you ever mount an endpoint.

Coach by example

The best way to see the benefits of Coach is with a demonstration...

Mounting an endpoint

class HelloWorld < Coach::Middleware
  def call
    # Middleware return a Rack response
    [ 200, {}, ['hello world'] ]

So we've created ourselves a piece of middleware, HelloWorld. As you'd expect, HelloWorld simply outputs the string 'hello world'.

In an example Rails app, called Example, we can mount this route like so...

Example::Application.routes.draw do
  match "/hello_world",
        via: :get

Once you've booted Rails locally, the following should return 'hello world':

$ curl -XGET http://localhost:3000/hello_world

Building chains

Suppose we didn't want just anybody to see our HelloWorld endpoint. In fact, we'd like to lock it down behind some authentication.

Our request will now have two stages, one where we check authentication details and another where we respond with our secret greeting to the world. Let's split into two pieces, one for each of the two subtasks, allowing us to reuse this authentication flow in other middlewares.

class Authentication < Coach::Middleware
  def call
    unless User.exists?(login: params[:login])
      return [ 401, {}, ['Access denied'] ]

class HelloWorld < Coach::Middleware
  uses Authentication

  def call
    [ 200, {}, ['hello world'] ]

Here we detach the authentication logic into its own middleware. HelloWorld now uses Authentication, and will only run if it has been called via from authentication.

Notice we also use params just like you would in a normal Rails controller. Every middleware class will have access to a request object, which is an instance of ActionDispatch::Request.

Passing data through middleware

So far we've demonstrated how Coach can help you break your controller code into modular pieces. The big innovation with Coach, however, is the ability to explicitly pass your data through the middleware chain.

An example usage here is to create a HelloUser endpoint. We want to protect the route by authentication, as we did before, but this time greet the user that is logged in. Making a small modification to the Authentication middleware we showed above...

class Authentication < Coach::Middleware
  provides :user  # declare that Authentication provides :user

  def call
    return [ 401, {}, ['Access denied'] ] unless user.present?

    provide(user: user)

  def user
    @user ||= User.find_by(login: params[:login])

class HelloUser < Coach::Middleware
  uses Authentication
  requires :user  # state that HelloUser requires this data

  def call
    # Can now access `user`, as it's been provided by Authentication
    [ 200, {}, [ "hello #{}" ] ]

# Inside config/routes.rb
Example::Application.routes.draw do
  match "/hello_user",
        via: :get

Coach analyses your middleware chains whenever a new Handler is created. If any middleware requires :x when its chain does not provide :x, we'll error out before the app even starts.


Our problems with controller code were implicit behaviours, hidden data dependencies and as a consequence of both, difficult testing. Coach has tackled each of these, providing the framework to restructure own controllers into code that is easily understood, and easily maintained.

Coach also hooks into ActiveSupport::Notifications, making monitoring performance of our API really easy. We've written a little adapter that sends detailed performance metrics up to Skylight, where we can keep an eye out for sluggish endpoints.

Coach is on GitHub. As always, we love suggestions, feedback, and pull requests!

We're hiring developers
See job listing