XUtils

stripity_stripe

An Elixir Library for [Stripe](https://stripe.com/).


Stripe for Elixir

An Elixir library for working with Stripe.

Hex.pm Hex.pm

2.x.x status

Hex Docs Inline docs Coverage Status

Which version should I use?

Below is a list of which Stripe API version recent releases of Stripe Elixir. It only indicates the API version being called, not necessarily its compatibility. See the Stripe API Upgrades page for more details.

Starting with stripity_stripe version 2.5.0, you can specify the Stripe API Version to use for a specific request by including the :api_version option. Note that while this will use a specific Stripe API Version to make the request, the library will still expect a response matching its corresponding default Stripe API Version. See the Shared Options documentation for more details.

:stripity_stripe Stripe API Version
2.0.x 2018-02-28
2.1.0 - 2.2.0 2018-05-21
2.2.2 2018-08-23
2.2.3 - 2.3.0 2018-11-08
2.4.0 - 2.7.0 2019-05-16
master 2019-10-17

Documentation

Configuration

To make API calls, it is necessary to configure your Stripe secret key.

import Config

config :stripity_stripe, api_key: System.get_env("STRIPE_SECRET")
# OR
config :stripity_stripe, api_key: "YOUR SECRET KEY"

It’s possible to use a function or a tuple to resolve the secret:

config :stripity_stripe, api_key: {MyApp.Secrets, :stripe_secret, []}
# OR
config :stripity_stripe, api_key: fn -> System.get_env("STRIPE_SECRET") end

Moreover, if you are using Poison instead of Jason, you can configure the library to use Poison like so:

config :stripity_stripe, json_library: Poison

Timeout

To set timeouts, pass opts for the http client. The default one is Hackney.

config :stripity_stripe, hackney_opts: [{:connect_timeout, 1000}, {:recv_timeout, 5000}]

Request Retries

To set retries, you can pass the number of attempts and range of backoff (time between attempting the request again) in milliseconds.

config :stripity_stripe, :retries, [max_attempts: 3, base_backoff: 500, max_backoff: 2_000]

Intents

Create a new SetupIntent object in Stripe. The created intent ID will be passed to the frontend to use with Stripe elements so the end user can enter their payment details. SetupIntents are ephemeral. It is best to create a new one each time the user reaches your payment page.

{:ok, setup_intent} = Stripe.SetupIntent.create(%{})

# Return the ID to your frontend, and pass it to the confirmCardSetup method from Stripe elements
{:ok, setup_intent.id}

On the frontend, use the setup intent ID you created in conjunction with Stripe elements confirmCardSetup method.

stripe.confirmCardSetup(setupIntentId, {
  payment_method: {
    ...
  }
})
.then(result => {
  const setupIntentId = result.setupIntent.id
  const paymentMethodId = result.setupIntent.payment_method

  // send the paymentMethodId and optionally (if needed) the setupIntentId
})

With the new payment method ID, you can associate the payment method with a Stripe customer.

Get an existing customer.

{:ok, stripe_customer} = Stripe.Customer.retrieve(stripe_customer_id)

Or create a new one.

new_customer = %{
  email: email,
}

{:ok, stripe_customer} = Stripe.Customer.create(new_customer)

Attach the payment method to the customer.

{:ok, _result} = Stripe.PaymentMethod.attach(%{customer: stripe_customer.id, payment_method: payment_method_id})

Now you can charge the customer using a PaymentIntent from Stripe. Since we used a setup intent initially, the payment intent will be authorized to make payments off session, for example to charge for a recurring subscription.

{:ok, charge} = Stripe.PaymentIntent.create(%{
  amount: cents_int,
  currency: "USD",
  customer: stripe_customer.id,
  payment_method: payment_method_id,
  off_session: true,
  confirm: true
})

Testing

Running the tests

By default, mix test will start stripe-mock by finding and invoking the stripe-mock executable. If you would prefer to start it yourself, do so and add an env var SKIP_STRIPE_MOCK_RUN to skip starting stripe-mock. Any value will do. Example:

SKIP_STRIPE_MOCK_RUN=1 mix test

To configure your test environment to use the local stripe-mock server, you may need to set the api_base_url field in your config:

config :stripity_stripe,
  api_key: "sk_test_thisisaboguskey",
  api_base_url: "http://localhost:12111"

Documentation for 1.x.x

Click to expand

## Stripe API Works with API version 2015-10-16 ## Configuration To make API calls, it is necessary to configure your Stripe secret key (and optional platform client id if you are using Stripe Connect): ```elixir import Config config :stripity_stripe, secret_key: "YOUR SECRET KEY" config :stripity_stripe, platform_client_id: "YOUR CONNECT PLATFORM CLIENT ID" ``` ## The API I've tried to make the API somewhat comprehensive and intuitive. If you'd like to see things in detail be sure to have a look at the tests - they show (generally) the way the API goes together. In general, if Stripe requires some information for a given API call, you'll find that as part of the arity of the given function. For instance if you want to delete a Customer, you'll find that you _must_ pass the id along: ```elixir {:ok, result} = Stripe.Customers.delete "some_id" ``` For optional arguments, you can send in a Keyword list that will get translated to parameters. So if you want to update a Subscription, for instance, you must send in the `customer_id` and `subscription_id` with the list of changes: ```elixir # Example of paging through events {:ok, events} = Stripe.Events.list(key, "", 100) # second arg is a marker for paging case events[:has_more] do true -> # retrieve marker last = List.last( events[:data] ) case Stripe.Events.list key, last["id"], 100 do {:ok, events} -> events[:data] # ... end false -> events[:data] end ``` # Connect Stripe Connect allows you to provide your customers with an easy onboarding to their own Stripe account. This is useful when you run an e-commerce as a service platform. Each merchant can transact using their own account using your platform. Then your platform uses Stripe's API with their own API key obtained in the onboarding process. First, you need to register your platform on Stripe Connect to obtain a `client_id`. In your account settings, there's a "Connect" tab, select it. Then fill the information to activate your connect platform settings. The select he `client_id` (notice there's one for dev and one for prod), stash this `client_id` in the config file under ```elixir config :stripity_stripe, platform_client_id: "ac_???" ``` or in an env var named `STRIPE_PLATFORM_CLIENT_ID`. Then you send your users to sign up for the stripe account using a link. Here's an example of a button to start the workflow: Connect with Stripe You can generate this URL using: ```elixir url = Stripe.Connect.generate_button_url csrf_token ``` When the user gets back to your platform, the following url (`redirect_uri` form item on your "Connect" settings) will be used: ``` //yoursvr/your_endpoint?scope=read_write&code=AUTHORIZATION_CODE ``` or ``` //yoursvr/your_endpoint?error=access_denied&error_description=The%20user%20denied%20your%20request ``` Using the code request parameter, you make the following call: ```elixir {:ok, resp} -> Stripe.Connect.oauth_token_callback code resp[:access_token] ``` `resp` will look like this: ```elixir %{ token_type: "bearer", stripe_publishable_key: PUBLISHABLE_KEY, scope: "read_write", livemode: false, stripe_user_id: USER_ID, refresh_token: REFRESH_TOKEN, access_token: ACCESS_TOKEN } ``` You can then pass the `access_token` to the other API modules to act on their behalf. See a [demo](https://github.com/nicrioux/stripity-connect-phoenix) using the Phoenix framework with the bare minimum to get this working. ## Testing Connect The tests are currently manual as they require a unique OAuth authorization code per test. You need to obtain this code manually using the stripe connect workflow (that your user would go through using the above url). First, log in your account. Then go to the following url: https://dashboard.stripe.com/account/applications/settings Create a connect standalone account. Grab your development `client_id`. Put it in your config file. Enter a redirect url to your endpoint. Capture the "code" request parameter. Pass it to `Stripe.Connect.oauth_token_callback` or `Stripe.Connect.get_token`.

History

Statement from original author

Why another Stripe Library? Currently there are a number of them in the Elixir world that are, well just not “done” yet. I started to fork/help but soon it became clear to me that what I wanted was

  • an existing/better test story
  • an API that didn’t just mimic a REST interaction
  • a library that was up to date with Elixir > 1.0 and would, you know, actually compile.
  • function calls that returned a standard {:ok, result} or {:error, message} response

As I began digging things up with these other libraries it became rather apparent that I was not only tweaking the API, but also ripping out a lot of the existing code… and that usually means I should probably do my own thing. So I did.


Articles

  • coming soon...