stripe_client 0.1.1
stripe_client: ^0.1.1 copied to clipboard
Pure Dart client for the Stripe API: typed resources, webhook signature verification, automatic retries and idempotency keys. Runs on Dart servers, CLIs and Cloud Functions.
stripe_client #
A pure Dart client for the Stripe API. Runs on Dart servers, CLIs and Cloud Functions — there is no Flutter dependency, and no build step for you.
Used in production at Fullphysio, where it runs inside our Dart Cloud Functions. Bug reports are welcome — see CONTRIBUTING.md.
Warning
This client uses your secret API key. Run it on a server, a Cloud Function or a CLI — never ship it inside a Flutter app, where the key can be extracted. For in-app payment UI use flutter_stripe.
final stripe = StripeClient(apiKey: Platform.environment['STRIPE_API_KEY']!);
final session = await stripe.checkout.sessions.create(
CheckoutSessionCreateParams(
mode: CheckoutSessionMode.subscription,
lineItems: [CheckoutSessionLineItemParams(price: priceId, quantity: 1)],
successUrl: 'https://example.com/done',
cancelUrl: 'https://example.com/cancel',
),
);
Why this exists #
No maintained Dart Stripe client covers the server API. The two community
packages predate the promotionCodes and invoices resources, and the one
that is complete was produced by a closed generator, so it cannot be
regenerated and is pinned to a 2023 API version.
This package takes the opposite approach: the runtime is a hand port of
stripe-node, and the models are written against Stripe's own OpenAPI
specification, vendored in this repository and pinned by digest. Bumping the
API version is a diff against that spec, not a fork of a closed generator.
Webhooks #
Signature verification is static — it needs no client and no API key:
final event = StripeWebhooks.constructEvent(
payload: request.rawBody,
header: request.headers['stripe-signature']!,
secret: endpointSecret,
);
Pass the raw request bytes, never a re-encoded or already-parsed body. Verification uses a constant-time comparison, accepts any one of the signatures present in the header (so secret rotation works), and rejects timestamps outside a 300-second tolerance.
Fidelity to stripe-node #
This client reproduces stripe-node 19.3.1's observable behaviour, including
details that are easy to get subtly wrong:
- Retries on 409, on 5xx, and on a connection reset, with jittered exponential
backoff capped at five seconds, honouring
Retry-Afterup to 60 seconds, and respecting the server'sstripe-should-retryheader over all of it. - An idempotency key is generated for every POST, so those retries are safe.
- Request bodies follow Stripe's bracket-notation form encoding exactly, including the way empty collections disappear from the wire entirely.
Conformance is enforced by golden tests whose fixtures were captured from the
real stripe-node, not written by hand.
Scope #
This is an early release, and the operations below are the whole of it:
| Namespace | Operations |
|---|---|
checkout.sessions |
create |
billingPortal.sessions |
create |
customers |
retrieve, update, createBalanceTransaction |
subscriptions |
retrieve, list |
promotionCodes |
create, retrieve, list |
invoices |
retrieve |
prices |
retrieve |
products |
retrieve |
Plus webhook signature verification, and decoding for the objects those
operations and webhook payloads return — including Coupon, Discount,
Event, Plan, InvoiceLineItem and SubscriptionItem.
Not here yet. Pagination past one page: list takes a limit but no
starting_after cursor, so it cannot walk beyond 100 objects. Writes other
than the ones above (no subscriptions.update, no invoices.list). Payment
Intents, Charges, Refunds, Setup Intents and Payment Methods as resources —
they appear only in StripeCardError's fields today.
Out of scope. The v2 API, Connect, Issuing, Terminal, Tax registrations, file uploads, and Stripe's realtime/SSE surfaces.
Adding a missing operation is a small, mechanical change against the vendored spec — open an issue if you need one.
Relationship to stripe-node and to Stripe #
This is an independent port, not an official Stripe product and not endorsed by
Stripe. See THIRD_PARTY_NOTICES for the licences of stripe-node, qs and
Stripe's OpenAPI specification, whose terms this package's derivation respects.