{"id":17528472,"url":"https://github.com/sorentwo/braintree-elixir","last_synced_at":"2025-05-15T07:06:18.379Z","repository":{"id":3800927,"uuid":"50941308","full_name":"sorentwo/braintree-elixir","owner":"sorentwo","description":":credit_card: Native elixir client for Braintree","archived":false,"fork":false,"pushed_at":"2025-05-13T12:30:58.000Z","size":473,"stargazers_count":102,"open_issues_count":2,"forks_count":63,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-05-15T03:55:29.210Z","etag":null,"topics":["braintree","elixir","payment-processing"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sorentwo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-02-02T18:17:26.000Z","updated_at":"2025-03-27T17:14:08.000Z","dependencies_parsed_at":"2023-01-14T11:15:50.156Z","dependency_job_id":"e9881f3f-9f8b-48c7-a2b5-4678a20e49c1","html_url":"https://github.com/sorentwo/braintree-elixir","commit_stats":{"total_commits":290,"total_committers":43,"mean_commits":6.744186046511628,"dds":0.4724137931034482,"last_synced_commit":"20b4953217e16d4697756ac1bcf9362599b5287a"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sorentwo%2Fbraintree-elixir","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sorentwo%2Fbraintree-elixir/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sorentwo%2Fbraintree-elixir/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sorentwo%2Fbraintree-elixir/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sorentwo","download_url":"https://codeload.github.com/sorentwo/braintree-elixir/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254292042,"owners_count":22046426,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["braintree","elixir","payment-processing"],"created_at":"2024-10-20T15:43:50.278Z","updated_at":"2025-05-15T07:06:13.370Z","avatar_url":"https://github.com/sorentwo.png","language":"Elixir","readme":"# Braintree\n\n[![Build Status](https://travis-ci.org/sorentwo/braintree-elixir.svg?branch=master)](https://travis-ci.org/sorentwo/braintree-elixir)\n[![Hex version](https://img.shields.io/hexpm/v/braintree.svg \"Hex version\")](https://hex.pm/packages/braintree)\n[![Hex downloads](https://img.shields.io/hexpm/dt/braintree.svg \"Hex downloads\")](https://hex.pm/packages/braintree)\n[![Inline docs](https://inch-ci.org/github/sorentwo/braintree-elixir.svg)](https://inch-ci.org/github/sorentwo/braintree-elixir)\n\nA native [Braintree][braintree] client library for Elixir.\n\n[braintree]: https://www.braintreepayments.com\n\n## Installation\n\nAdd braintree to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [{:braintree, \"~\u003e 0.13\"}]\nend\n```\n\nOnce that is configured you are all set. Braintree is a library, not an\napplication, but it does rely on `hackney`, which must be started. For Elixir\nversions \u003c 1.4 you'll need to include it in the list of applications:\n\n```elixir\ndef application do\n  [applications: [:braintree]]\nend\n```\n\nWithin your application you will need to configure the merchant id and\nauthorization keys. You do *not* want to put this information in your\n`config.exs` file! Either put it in a `{prod,dev,test}.secret.exs` file which is\nsourced by `config.exs`, or read the values in from the environment in\n`runtime.exs`:\n\n```elixir\nconfig :braintree,\n  environment: :sandbox,\n  master_merchant_id: System.fetch_env!(\"BRAINTREE_MASTER_MERCHANT_ID\"),\n  merchant_id: System.fetch_env!(\"BRAINTREE_MERCHANT_ID\"),\n  public_key:  System.fetch_env!(\"BRAINTREE_PUBLIC_KEY\"),\n  private_key: System.fetch_env!(\"BRAINTREE_PRIVATE_KEY\")\n```\n\nFurthermore, the environment defaults to `:sandbox`, so you'll want to configure\nit with `:production` in `prod.exs`.\n\nBraintree has certificates that will be used for verification during the HTTP\nrequest. This library includes them and will use them by default, but if you\nneed to override them, you may provide the configuration `:cacertfile` and\n`:sandbox_cacertfile`.\n\nYou may optionally pass directly those configuration keys to all functions\nperforming an API call. In that case, those keys will be used to perform the\ncall.\n\nYou can optionally [configure Hackney options][opts] with:\n\n```elixir\nconfig :braintree,\n  http_options: [\n    timeout: 30_000, # default, in milliseconds\n    recv_timeout: 5000 # default, in milliseconds\n  ]\n```\n\n[opts]: https://hexdocs.pm/hackney/hackney.html#request/5\n\n## Usage\n\nThe online [documentation][doc] for Ruby/Java/Python etc. will give you a\ngeneral idea of the modules and available functionality. Where possible the\nnamespacing has been preserved.\n\nThe CRUD functions for each action module break down like this:\n\n```elixir\nalias Braintree.Customer\nalias Braintree.ErrorResponse, as: Error\n\ncase Customer.create(%{company: \"Whale Corp\"}) do\n  {:ok, %Customer{} = customer} -\u003e do_stuff_with_customer(customer)\n  {:error, %Error{} = error}    -\u003e do_stuff_with_error(error)\nend\n```\n\n### Searching\n\nSearch params are constructed with a fairly complex structure of maps. There\nisn't a DSL provided, so queries must be constructed by hand. For example, to\nsearch for a customer:\n\n```elixir\nsearch_params = %{\n  first_name: %{is: \"Jenna\"},\n  last_name: %{\n    starts_with: \"Smith\",\n    contains: \"ith\",\n    is_not: \"Smithsonian\"\n  },\n  email: %{ends_with: \"gmail.com\"}\n}\n\n{:ok, customers} = Braintree.Customer.search(search_params)\n```\n\nOr, to search for pending credit card verifications within a particular dollar\namount:\n\n```elixir\nsearch_params = %{\n  amount: %{\n    min: \"10.0\",\n    max: \"15.0\"\n  },\n  status: [\"approved\", \"pending\"]\n}\n\n{:ok, verifications} = Braintree.CreditCardVerification.search(search_params)\n```\n\n[doc]: https://developers.braintreepayments.com/\n\n\n### Telemetry\n\nIf the `telemetry` application is running, the library will emit telemetry events.\n\nImmediately before the HTTP request is fired, a start event will be fired with the following shape:\n\n```\n event name:    [:braintree, :request, :start]\n measurements:  %{system_time: System.system_time()}\n meta data:     %{method: method, path: path}\n```\n\nOnce the HTTP call completes, a stop event will be fired with the following shape:\n\n```\n event name:    [:braintree, :request, :stop]\n measurements:  %{duration: duration}\n meta data:     %{method: method, path: path, http_status: status}\n```\n\nIf Hackney returns an error, an error event will be fired with the following shape:\n\n```\n event name:    [:braintree, :request, :error]\n measurements:  %{duration: duration}\n meta data:     %{method: method, path: path, error: error_reason}\n```\n\nIf an exception is raised during the Hackney call, an exception event will be fired with the following shape:\n\n```\n event name:    [:braintree, :request, :exception]\n measurements:  %{duration: duration}\n meta data:     %{method: method, path: path, kind: error_type, reason: error_message, stacktrace: stacktrace}\n```\n\n## Testing\n\nYou'll need a Braintree sandbox account to run the integration tests. Also, be\nsure that your account has [Duplicate Transaction Checking][dtc] disabled.\n\n### Merchant Account Features\n\nIn order to test the merchant account features, your sandbox account needs to\nhave a master merchant account and it needs to be added to your environment\nvariables (only needed in test).\n\nYour environment needs to have the following:\n\n* Add-ons with ids: \"bronze\", \"silver\" and \"gold\"\n* Plans with ids: \"starter\", \"business\"\n* \"business\" plan needs to include the following add-ons: \"bronze\" and \"silver\"\n\n### PayPal Account Testing\n\nPayPal testing uses the mocked API flow, which requires linking a sandbox PayPal\naccount. You can accomplish that by following the directions for [linked paypal\ntesting][plp].\n\n[dtc]: https://articles.braintreepayments.com/control-panel/transactions/duplicate-checking\n[plp]: https://developers.braintreepayments.com/guides/paypal/testing-go-live/php#linked-paypal-testing\n\n### Testing Using Only `localhost`\n\nYou can optionally configure the sandbox endpoint url to point towards a local url and\nport for testing which does not need to call out to the Braintree sandbox API.\nFor example, in your `config.exs`\n\n```elixir\nconfig :braintree, :sandbox_endpoint, \"localhost:4001\"\n```\n\nIn conjuction with a libary such as [`Bypass`](https://github.com/PSPDFKit-labs/bypass)\nyou can use this config to define test-specific returns from `Braintree` calls without\nhitting the Braintree sandbox API.\n\n## License\n\nMIT License, see [LICENSE.txt](LICENSE.txt) for details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsorentwo%2Fbraintree-elixir","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsorentwo%2Fbraintree-elixir","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsorentwo%2Fbraintree-elixir/lists"}