# Braintree

[![Build Status](](
[![Hex version]( "Hex version")](
[![Hex downloads]( "Hex downloads")](
[![Inline docs](](

A native [Braintree][braintree] client library for Elixir.


## Installation

Add braintree to your list of dependencies in `mix.exs`:

def deps do
  [{:braintree, "~> 0.9"}]

Once that is configured you are all set. Braintree is a library, not an
application, but it does rely on `hackney`, which must be started. For Elixir
versions < 1.4 you'll need to include it in the list of applications:

def application do
  [applications: [:braintree]]

Within your application you will need to configure the merchant id and
authorization keys. You do *not* want to put this information in your
`config.exs` file! Either put it in a `{prod,dev,test}.secret.exs` file which is
sourced by `config.exs`, or read the values in from the environment:

config :braintree,
  environment: :sandbox,
  master_merchant_id: {:system, "BRAINTREE_MASTER_MERCHANT_ID"},
  merchant_id: {:system, "BRAINTREE_MERCHANT_ID"},
  public_key:  {:system, "BRAINTREE_PUBLIC_KEY"},
  private_key: {:system, "BRAINTREE_PRIVATE_KEY"}

Furthermore, the environment defaults to `:sandbox`, so you'll want to configure
it with `:production` in `prod.exs`.

You may optionally pass directly those configuration keys to all functions
performing an API call. In that case, those keys will be used to perform the

You can optionally [configure Hackney options][opts] with:

config :braintree,
  http_options: [
    timeout: 30_000, # default, in milliseconds
    recv_timeout: 5000 # default, in milliseconds


## Usage

The online [documentation][doc] for Ruby/Java/Python etc. will give you a
general idea of the modules and available functionality. Where possible the
namespacing has been preserved.

The CRUD functions for each action module break down like this:

alias Braintree.Customer
alias Braintree.ErrorResponse, as: Error

case Customer.create(%{company: "Whale Corp"}) do
  {:ok, %Customer{} = customer} -> do_stuff_with_customer(customer)
  {:error, %Error{} = error}    -> do_stuff_with_error(error)

### Searching

Search params are constructed with a fairly complex structure of maps. There
isn't a DSL provided, so queries must be constructed by hand. For example, to
search for a customer:

search_params = %{
  first_name: %{is: "Jenna"},
  last_name: %{
    starts_with: "Smith",
    contains: "ith",
    is_not: "Smithsonian"
  email: %{ends_with: ""}

{:ok, customers} =

Or, to search for pending credit card verifications within a particular dollar

search_params = %{
  amount: %{
    min: "10.0",
    max: "15.0"
  status: ["approved", "pending"]

{:ok, verifications} =


## Testing

You'll need a Braintree sandbox account to run the integration tests. Also, be
sure that your account has [Duplicate Transaction Checking][dtc] disabled.

### Merchant Account Features

In order to test the merchant account features, your sandbox account needs to
have a master merchant account and it needs to be added to your environment
variables (only needed in test).

Your environment needs to have the following:

* Add-ons with ids: "bronze", "silver" and "gold"
* Plans with ids: "starter", "business"
* "business" plan needs to include the following add-ons: "bronze" and "silver"

### PayPal Account Testing

PayPal testing uses the mocked API flow, which requires linking a sandbox PayPal
account. You can accomplish that by following the directions for [linked paypal


### Testing Using Only `localhost`

You can optionally configure the sandbox endpoint url to point towards a local url and
port for testing which does not need to call out to the Braintree sandbox API.
For example, in your `config.exs`
config :braintree, :sandbox_endpoint, "localhost:4001"
In conjuction with a libary such as [`Bypass`](
you can use this config to define test-specific returns from `Braintree` calls without
hitting the Braintree sandbox API.

## License

MIT License, see [LICENSE.txt](LICENSE.txt) for details.