PinStripe.Client (PinStripe v0.3.4)

View Source

A minimal Stripe API client built on Req.

This module provides a simple interface for interacting with the Stripe API, covering the most common operations while maintaining an escape hatch to Req for advanced use cases.

Configuration

Configure your Stripe API key in your application config:

config :pin_stripe,
  stripe_api_key: "sk_test_..."

For testing, configure the client to use Req.Test:

config :pin_stripe,
  req_options: [plug: {Req.Test, PinStripe}]

CRUD Operations

The client supports standard CRUD operations with a consistent API:

Read Operations

Fetch individual resources by ID (string):

Client.read("cus_123")
# => {:ok, %Req.Response{body: %{"id" => "cus_123", ...}}}

List resources by entity type (atom):

Client.read(:customers, limit: 10)
# => {:ok, %Req.Response{body: %{"object" => "list", "data" => [...]}}}

Create Operations

Create resources using entity type atoms:

Client.create(:customers, %{email: "user@example.com"})
# => {:ok, %Req.Response{body: %{"id" => "cus_new", ...}}}

Update Operations

Update resources by ID:

Client.update("cus_123", %{name: "New Name"})
# => {:ok, %Req.Response{body: %{"id" => "cus_123", "name" => "New Name"}}}

Delete Operations

Delete resources by ID:

Client.delete("cus_123")
# => {:ok, %Req.Response{body: %{"id" => "cus_123", "deleted" => true}}}

Supported Entity Types

The following entity types are supported (as atoms):

  • :customers - Customer objects
  • :products - Product objects
  • :prices - Price objects
  • :subscriptions - Subscription objects
  • :invoices - Invoice objects
  • :events - Event objects
  • :checkout_sessions - Checkout Session objects

Error Handling

All operations return {:ok, response} or {:error, reason} tuples:

Client.read(:invalid_entity)
# => {:error, :unrecognized_entity_type}

# HTTP errors return the response with error details
Client.read("cus_nonexistent")
# => {:error, %Req.Response{status: 404, body: %{"error" => ...}}}

Bang Functions

Each CRUD function has a bang version (read!/2, create!/3, update!/3, delete!/2) that raises a RuntimeError instead of returning error tuples:

# Raises on error
response = Client.read!("cus_123")
customer = response.body

# Raises RuntimeError: "Unrecognized entity type: :invalid"
Client.read!(:invalid)

# Raises RuntimeError: "Request failed with status 404: ..."
Client.read!("cus_nonexistent")

ID Prefix Recognition

The client automatically recognizes Stripe ID prefixes:

  • cus_*/customers/{id}
  • product_*/products/{id}
  • price_*/prices/{id}
  • sub_*/subscriptions/{id}
  • inv_*/invoices/{id}
  • evt_*/events/{id}
  • cs_*/checkout/sessions/{id}

Examples

# Fetch a customer
{:ok, response} = Client.read("cus_123")
customer = response.body

# List customers with pagination
{:ok, response} = Client.read(:customers, limit: 10, starting_after: "cus_123")
customers = response.body["data"]

# Create a customer
{:ok, response} = Client.create(:customers, %{
  email: "customer@example.com",
  name: "Jane Doe"
})

# Update a customer
{:ok, response} = Client.update("cus_123", %{
  metadata: %{user_id: "12345"}
})

# Delete a customer
{:ok, response} = Client.delete("cus_123")

Summary

Functions

Creates a new resource.

Creates a new resource, raising on error.

Deletes a resource by ID.

Deletes a resource by ID, raising on error.

Converts an entity atom to its API path.

Parses a Stripe ID or URL path into a full API path.

Reads a resource by ID or lists resources by entity type.

Reads a resource by ID or lists resources by entity type, raising on error.

Updates an existing resource by ID.

Updates an existing resource by ID, raising on error.

Functions

create(entity, params, options \\ [])

Creates a new resource.

Parameters

  • entity - Atom representing the entity type (e.g., :customers, :products)
  • params - Map of parameters for the resource
  • options - Keyword list of additional Req options

Examples

iex> Req.Test.stub(PinStripe, fn conn ->
...>   Req.Test.json(conn, %{id: "cus_new", email: "new@example.com"})
...> end)
iex> {:ok, response} = PinStripe.Client.create(:customers, %{email: "new@example.com"})
iex> response.body["id"]
"cus_new"

# Unrecognized entity type
iex> PinStripe.Client.create(:invalid, %{})
{:error, :unrecognized_entity_type}

create!(entity, params, options \\ [])

Creates a new resource, raising on error.

Similar to create/3 but raises a RuntimeError on error instead of returning an error tuple.

Parameters

  • entity - Atom representing the entity type
  • params - Map of parameters for the resource
  • options - Keyword list of additional Req options

Examples

iex> Req.Test.stub(PinStripe, fn conn ->
...>   Req.Test.json(conn, %{id: "cus_new"})
...> end)
iex> response = PinStripe.Client.create!(:customers, %{email: "test@example.com"})
iex> response.body["id"]
"cus_new"

delete(id, options \\ [])

Deletes a resource by ID.

Parameters

  • id - String ID of the resource (e.g., "cus_123")
  • options - Keyword list of additional Req options

Examples

iex> Req.Test.stub(PinStripe, fn conn ->
...>   Req.Test.json(conn, %{id: "cus_123", deleted: true})
...> end)
iex> {:ok, response} = PinStripe.Client.delete("cus_123")
iex> response.body["deleted"]
true

delete!(id, options \\ [])

Deletes a resource by ID, raising on error.

Similar to delete/2 but raises a RuntimeError on error instead of returning an error tuple.

Parameters

  • id - String ID of the resource
  • options - Keyword list of additional Req options

Examples

iex> Req.Test.stub(PinStripe, fn conn ->
...>   Req.Test.json(conn, %{id: "cus_123", deleted: true})
...> end)
iex> response = PinStripe.Client.delete!("cus_123")
iex> response.body["deleted"]
true

entity_to_path(arg1)

Converts an entity atom to its API path.

Returns {:ok, path} for recognized entities, or {:error, :unrecognized_entity_type} otherwise.

Examples

iex> PinStripe.Client.entity_to_path(:customers)
{:ok, "/customers"}

iex> PinStripe.Client.entity_to_path(:products)
{:ok, "/products"}

iex> PinStripe.Client.entity_to_path(:invalid)
{:error, :unrecognized_entity_type}

new(options \\ [])

parse_url(id)

Parses a Stripe ID or URL path into a full API path.

Recognizes Stripe ID prefixes and converts them to the appropriate API endpoint. Custom paths are returned as-is.

Examples

iex> PinStripe.Client.parse_url("cus_123")
"/customers/cus_123"

iex> PinStripe.Client.parse_url("product_abc")
"/products/product_abc"

iex> PinStripe.Client.parse_url("/custom/path")
"/custom/path"

read(id_or_entity, options \\ [])

Reads a resource by ID or lists resources by entity type.

Parameters

  • id_or_entity - Either a string ID (e.g., "cus_123") or an atom entity type (e.g., :customers)
  • options - Keyword list of options (e.g., query parameters for list operations)

Examples

# Fetch by ID
iex> Req.Test.stub(PinStripe, fn conn ->
...>   Req.Test.json(conn, %{id: "cus_123", email: "test@example.com"})
...> end)
iex> {:ok, response} = PinStripe.Client.read("cus_123")
iex> response.body["id"]
"cus_123"

# List resources
iex> Req.Test.stub(PinStripe, fn conn ->
...>   Req.Test.json(conn, %{object: "list", data: []})
...> end)
iex> {:ok, response} = PinStripe.Client.read(:customers)
iex> response.body["object"]
"list"

# Unrecognized entity type
iex> PinStripe.Client.read(:invalid)
{:error, :unrecognized_entity_type}

read!(id_or_entity, options \\ [])

Reads a resource by ID or lists resources by entity type, raising on error.

Similar to read/2 but raises a RuntimeError on error instead of returning an error tuple.

Parameters

  • id_or_entity - Either a string ID or an atom entity type
  • options - Keyword list of options

Examples

iex> Req.Test.stub(PinStripe, fn conn ->
...>   Req.Test.json(conn, %{id: "cus_123"})
...> end)
iex> response = PinStripe.Client.read!("cus_123")
iex> response.body["id"]
"cus_123"

request(url, options \\ [])

request!(url, options \\ [])

update(id, params, options \\ [])

Updates an existing resource by ID.

Parameters

  • id - String ID of the resource (e.g., "cus_123")
  • params - Map of parameters to update
  • options - Keyword list of additional Req options

Examples

iex> Req.Test.stub(PinStripe, fn conn ->
...>   Req.Test.json(conn, %{id: "cus_123", name: "Updated"})
...> end)
iex> {:ok, response} = PinStripe.Client.update("cus_123", %{name: "Updated"})
iex> response.body["name"]
"Updated"

update!(id, params, options \\ [])

Updates an existing resource by ID, raising on error.

Similar to update/3 but raises a RuntimeError on error instead of returning an error tuple.

Parameters

  • id - String ID of the resource
  • params - Map of parameters to update
  • options - Keyword list of additional Req options

Examples

iex> Req.Test.stub(PinStripe, fn conn ->
...>   Req.Test.json(conn, %{id: "cus_123", name: "Updated"})
...> end)
iex> response = PinStripe.Client.update!("cus_123", %{name: "Updated"})
iex> response.body["name"]
"Updated"