{"id":44388114,"url":"https://github.com/jeffhuen/tiger_stripe","last_synced_at":"2026-02-17T06:01:07.884Z","repository":{"id":337571116,"uuid":"1154226111","full_name":"jeffhuen/tiger_stripe","owner":"jeffhuen","description":"A Stripe library for Elixir — typed SDK, client, and webhooks generated from the official OpenAPI spec.","archived":false,"fork":false,"pushed_at":"2026-02-12T22:22:13.000Z","size":1561,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-15T09:21:04.608Z","etag":null,"topics":["elixir","hex-package","openapi","payments","phoenix","sdk","stripe","stripe-api","stripe-connect","webhooks"],"latest_commit_sha":null,"homepage":"https://hexdocs.pm/tiger_stripe/","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/jeffhuen.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-10T06:29:56.000Z","updated_at":"2026-02-15T05:16:16.000Z","dependencies_parsed_at":"2026-02-15T04:00:48.222Z","dependency_job_id":null,"html_url":"https://github.com/jeffhuen/tiger_stripe","commit_stats":null,"previous_names":["jeffhuen/stripe_elixir"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jeffhuen/tiger_stripe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffhuen%2Ftiger_stripe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffhuen%2Ftiger_stripe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffhuen%2Ftiger_stripe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffhuen%2Ftiger_stripe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jeffhuen","download_url":"https://codeload.github.com/jeffhuen/tiger_stripe/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffhuen%2Ftiger_stripe/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29500821,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-16T03:57:51.541Z","status":"ssl_error","status_checked_at":"2026-02-16T03:55:59.854Z","response_time":115,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["elixir","hex-package","openapi","payments","phoenix","sdk","stripe","stripe-api","stripe-connect","webhooks"],"created_at":"2026-02-12T01:45:51.289Z","updated_at":"2026-02-16T05:01:25.751Z","avatar_url":"https://github.com/jeffhuen.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TigerStripe\n\nComprehensive Elixir SDK for the [Stripe API](https://stripe.com/docs/api),\nwith verified 1:1 feature parity to the official [Ruby SDK](https://github.com/stripe/stripe-ruby).\n\n\u003e **Note:** This is not an official Stripe SDK. Stripe does not publish a\n\u003e first-party Elixir library. This project is generated from the same\n\u003e [OpenAPI spec](https://github.com/stripe/openapi) that Stripe uses to\n\u003e build their official SDKs, follows the same service architecture, and is\n\u003e tested for 1:1 parity against the official\n\u003e [Ruby SDK](https://github.com/stripe/stripe-ruby). The goal is an\n\u003e idiomatic Elixir experience with the same API coverage.\n\n### What's Included\n\nThe **SDK layer** provides typed resource structs, typed request params, per-event\nmodules, and auto-paging pagination — all generated from the spec with full\ndocumentation. The **client layer** handles HTTP execution via Finch with\nconnection pooling, automatic retries, request encoding, response\ndeserialization, and telemetry.\n\nTogether, the full V1 + V2 API surface is covered: 190 service modules,\n307 typed resource structs, 523 typed params modules, webhook signature\nverification, OAuth, file uploads, streaming responses, and per-event typed\nmodules.\n\n## Coming from the Ruby SDK\n\nTigerStripe has the same API coverage as the official Ruby SDK but follows\nElixir conventions. Three things work differently:\n\n**Service modules instead of resource methods.** Ruby calls methods on\nresource classes (`Stripe::Charge.create`). Elixir uses dedicated service\nmodules — the same internal architecture the Ruby SDK uses, surfaced\nexplicitly:\n\n```ruby\n# Ruby\ncharge = Stripe::Charge.create({amount: 2000, currency: \"usd\"})\n```\n\n```elixir\n# Elixir\n{:ok, charge} = Stripe.Services.ChargeService.create(client, %{amount: 2000, currency: \"usd\"})\n```\n\n**Explicit client argument.** Ruby uses a global `Stripe.api_key`. Elixir\npasses a client struct to every call — no global mutable state, safe for\nconcurrent use with multiple API keys or connected accounts:\n\n```ruby\n# Ruby\nStripe.api_key = \"sk_test_...\"\ncharge = Stripe::Charge.retrieve(\"ch_123\")\n```\n\n```elixir\n# Elixir\nclient = Stripe.client()\n{:ok, charge} = Stripe.Services.ChargeService.retrieve(client, \"ch_123\")\n```\n\n**Tuples instead of exceptions.** Ruby raises `Stripe::StripeError` on\nfailure. Elixir returns `{:ok, result}` / `{:error, %Stripe.Error{}}` tuples\nfor pattern matching:\n\n```ruby\n# Ruby\nbegin\n  charge = Stripe::Charge.create(params)\nrescue Stripe::CardError =\u003e e\n  puts e.message\nend\n```\n\n```elixir\n# Elixir\ncase Stripe.Services.ChargeService.create(client, params) do\n  {:ok, charge} -\u003e charge\n  {:error, %Stripe.Error{type: :card_error} = err} -\u003e Logger.warning(err.message)\nend\n```\n\nEverything else — endpoint paths, parameter names, resource fields, webhook\npayloads, pagination, file uploads, OAuth — is 1:1 with the Ruby SDK.\n\n## Installation\n\n### With Igniter (recommended for Phoenix)\n\n\u003e **Beta:** The Igniter installer is new and under active testing.\n\u003e [Report issues here.](https://github.com/jeffhuen/tiger_stripe/issues)\n\nIf your project uses [Igniter](https://hex.pm/packages/igniter), one command\nsets up everything — config, webhook plug, controller, and route:\n\n```bash\nmix igniter.install tiger_stripe\n```\n\nSee the [Igniter Installer](guides/igniter-installer.md) guide for a detailed\nwalkthrough of what the installer does.\n\n### Manual\n\nAdd `tiger_stripe` to your dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:tiger_stripe, \"~\u003e 0.1.7\"}\n  ]\nend\n```\n\nRequires Elixir 1.19+ and OTP 27+.\n\n## Configuration\n\n```elixir\n# config/dev.exs — sandbox credentials\nconfig :tiger_stripe,\n  api_key: \"sk_test_...\",\n  webhook_secret: \"whsec_test_...\"\n\n# config/runtime.exs — production credentials\nif config_env() == :prod do\n  config :tiger_stripe,\n    api_key: System.fetch_env!(\"STRIPE_SECRET_KEY\"),\n    webhook_secret: System.fetch_env!(\"STRIPE_WEBHOOK_SECRET\")\nend\n```\n\nOptional global defaults (all have sensible defaults if omitted):\n\n```elixir\nconfig :tiger_stripe,\n  api_key: \"sk_test_...\",\n  webhook_secret: \"whsec_...\",\n  api_version: \"2026-01-28.clover\",  # pin API version\n  client_id: \"ca_...\",               # OAuth client ID (Connect platforms)\n  max_retries: 3,                    # default: 2\n  open_timeout: 30_000,              # connection timeout in ms\n  read_timeout: 80_000               # read timeout in ms\n```\n\nSee the [Getting Started](guides/getting-started.md) guide for all config\noptions and precedence rules.\n\n## Quick Start\n\n```elixir\nclient = Stripe.client()\n\n# Create a customer\n{:ok, customer} = Stripe.Services.CustomerService.create(client, %{\n  email: \"jane@example.com\"\n})\n\n# Retrieve a payment intent\n{:ok, intent} = Stripe.Services.PaymentIntentService.retrieve(client, \"pi_123\")\n\n# List charges (returns a typed ListObject)\n{:ok, charges} = Stripe.Services.ChargeService.list(client, %{\"limit\" =\u003e 10})\n```\n\nResponses are automatically deserialized into typed structs:\n\n```elixir\ncustomer.id        #=\u003e \"cus_abc123\"\ncustomer.email     #=\u003e \"jane@example.com\"\ncustomer.__struct__ #=\u003e Stripe.Resources.Customer\n```\n\nOverride config per-client for Connect or multi-key scenarios:\n\n```elixir\nclient = Stripe.client(stripe_account: \"acct_connected\")\nclient = Stripe.client(\"sk_test_other_key\", max_retries: 5)\n```\n\n## Features\n\n### SDK\n\n- **Full API coverage** — every V1 and V2 endpoint from the OpenAPI spec, with\n  dedicated service modules matching the Ruby SDK layout\n- **Typed resources** — API responses are deserialized into typed Elixir structs\n  with `@type t` definitions, expandable field support, and inner types\n- **Typed params** — request parameters have dedicated struct modules with\n  `@typedoc` annotations sourced from the OpenAPI spec\n- **Per-event typed modules** — V2 and thin V1 events get dedicated modules\n  with typed data structs and `fetch_related_object/2`\n- **Auto-paging pagination** — lazy `Stream`-based iteration for V1 lists,\n  search results, and V2 lists\n- **Webhook verification** — HMAC-SHA256 signature verification with\n  constant-time comparison and timestamp tolerance\n- **OAuth** — `authorize_url`, `token`, and `deauthorize` for Stripe Connect\n- **Documentation** — `@moduledoc`, `@doc`, `@typedoc`, `@spec`, and\n  `@deprecated` on all generated modules, sourced from the OpenAPI spec\n\n### Client\n\n- **Finch HTTP client** — modern HTTP/2-capable client with connection pooling\n  via NimblePool (replaces legacy Hackney)\n- **Automatic retries** — exponential backoff with jitter, respects\n  `stripe-should-retry` header, auto-generated idempotency keys for V2\n- **Request encoding** — V1 form-encoded, V2 JSON, automatic multipart for\n  file uploads\n- **Response deserialization** — JSON to typed structs via object type registry\n- **Streaming** — chunked response streaming for large payloads and SSE\n- **Telemetry** — `:telemetry` events for request lifecycle observability\n- **Per-client configuration** — explicit struct with no global state, safe for\n  concurrent use with multiple API keys or connected accounts\n- **Test stubs** — process-scoped HTTP stubs via NimbleOwnership for\n  `async: true` tests\n\n## Guides\n\n- [Getting Started](guides/getting-started.md) — installation, configuration, first API call, pagination, error handling\n- [Igniter Installer](guides/igniter-installer.md) — one-command Phoenix setup (beta)\n- [Webhooks](guides/webhooks.md) — signature verification, WebhookPlug setup, typed event modules\n- [Connect \u0026 OAuth](guides/connect-and-oauth.md) — connected accounts, OAuth flow, multi-tenant patterns\n- [Testing](guides/testing.md) — process-scoped HTTP stubs with `async: true` support\n- [Telemetry](guides/telemetry.md) — request lifecycle events, logging, metrics\n\n## Development\n\n```bash\n# Sync the OpenAPI spec\nbash scripts/sync_openapi.sh\n\n# Generate the SDK\nmix stripe.generate --clean --stats\n\n# Verify\nmix compile --warnings-as-errors\nmix test\nmix docs --warnings-as-errors\nbash scripts/diff_ruby.sh\n```\n\n### Code Generation\n\nThe SDK is auto-generated from Stripe's unified OpenAPI spec (`spec3.sdk.json`)\nvia `mix stripe.generate`. The generator produces 1,044 files:\n\n- **190 service modules** (189 generated + 1 hand-written `OAuthService`)\n- **307 resource structs** with `@type t`, expandable fields, and inner types\n- **523 params modules** with `@typedoc` field annotations\n- **2 registries** (object types and event types)\n- **22 event modules** (20 per-event typed + 1 constants + 1 unknown fallback)\n\nA small set of [overrides](lib/stripe/generator/overrides.ex) handle\ncases where the spec's metadata doesn't match the Ruby SDK's service layout.\nEach override is documented with a reason and a reference to the corresponding\nRuby service file, enforced by tests.\n\n### Parity Testing\n\nRuby SDK parity is a hard invariant. CI runs `scripts/diff_ruby.sh` to verify\n1:1 service file and endpoint coverage. The test suite includes dedicated\nparity assertions comparing the generated endpoint set against both the OpenAPI\nspec and the Ruby SDK fixture tree.\n\n## License\n\nMIT License. See `LICENSE` for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffhuen%2Ftiger_stripe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeffhuen%2Ftiger_stripe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffhuen%2Ftiger_stripe/lists"}