Type-Safe Payments | Dwolla's New TypeScript SDK

7 min read

Type-Safe Payments: Introducing Dwolla's New TypeScript SDK

Integrating a payment API shouldn't feel like assembling furniture without instructions.

Yet here's what raw API integration often looks like: you misspell amount as ammount in a transfer request, deploy to production, and discover the bug when a payout fails silently. The API just returned a generic 400 error. For payment APIs, where mistakes have real consequences, this friction is a liability.

We've heard from developers who wanted a more robust, type-safe way to integrate. That’s why we've released the Dwolla TypeScript SDK, built with Speakeasy and generated from our OpenAPI spec to bring type-safe API integration to Node.js and TypeScript developers.

Instead of stitching together raw HTTP requests and hoping you got every field and header right, you work with typed methods like dwolla.customers.create() and dwolla.transfers.create(). TypeScript flags mistakes earlier, and the SDK handles OAuth token management so you authenticate once at initialization.

Here’s what’s inside.


Highlights at a Glance


Getting Started

Install the SDK with your preferred package manager:

npm install dwolla
# or: yarn add dwolla | pnpm add dwolla | bun add dwolla

Initialize the client and make your first call:

import { Dwolla } from "dwolla";

const dwolla = new Dwolla({
  server: "sand"
});

// List customers
const customers = await dwolla.customers.list({});
console.log(`Found ${customers._embedded?.customers?.length ?? 0} customers`);

For the complete walkthrough (Sandbox account setup, credentials, environment configuration, and more) see the TypeScript SDK documentation.


What You Get

Type Safety That Catches Mistakes Early

Requests, responses, and errors have comprehensive type definitions. Typos become compile errors instead of production bugs.

What this means for you:

Resource-Based API Design for Faster Development

Methods are organized by resources with full IntelliSense. Type “dwolla.” and explore available operations. No memorizing endpoint paths or tab-switching to docs.

What this means for you:

Automatic OAuth2 Token Management

Provide credentials once at initialization. The SDK acquires and refreshes tokens automatically. No boilerplate token refresh logic cluttering your codebase.

180+ Typed Error Classes for Precise Handling

Catch and handle specific failures instead of parsing error messages with regex.

import * as errors from "dwolla/models/errors";
try {
  await dwolla.transfers.create({ /* ... */ });
} catch (error) {
  if (error instanceof errors.InsufficientFundsError) {
    // Prompt user to add funds
  } else if (error instanceof errors.ValidationError) {
    // Show field-level errors
  } else if (error instanceof errors.DwollaError) {
    console.error(`${error.statusCode}: ${error.message}`);
  }
}

What this means for you:

And More


Why Use the TypeScript SDK?

Here's how it compares to the alternatives.

vs. Direct API Calls

You can always call the Dwolla API directly using fetch or any HTTP client. It works, but you're responsible for:

Aspect Direct API Calls TypeScript SDK
Type Safety None Full compile-time checking
Autocomplete None Full IntelliSense
Token Management Manual Automatic
Error Handling Parse JSON, check status codes Typed error classes
Retries Build it yourself Built-in
Documentation Tab-switch to docs Inline types + JSDoc

Here's the same operation—creating a customer—with raw fetch vs. the SDK:

// Direct API call (fetch)
const token = await getToken(); // You manage this
const res = await fetch("https://api-sandbox.dwolla.com/customers", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/vnd.dwolla.v1.hal+json",
    Accept: "application/vnd.dwolla.v1.hal+json",
  },
  body: JSON.stringify({ firstName: "Jane", lastName: "Doe", email: "jane@example.com" }),
});

// TypeScript SDK
import { Dwolla } from "dwolla";

const dwolla = new Dwolla({
  security: {
    clientID: process.env.DWOLLA_CLIENT_ID!,
    clientSecret: process.env.DWOLLA_CLIENT_SECRET!,
  },
});

await dwolla.customers.create({
  requestBody: { firstName: "Jane", lastName: "Doe", email: "jane@example.com" },
});

When to use direct calls: If you're making a single API call in a script or have very specific HTTP requirements the SDK doesn't support, direct calls might be simpler.

When to use the SDK: For any integration beyond a one-off script, especially in production applications where reliability and maintainability matter.

vs. dwolla-v2-node

The dwolla-v2-node package has been the official Node.js SDK for years. It's stable and works well. If you have an existing integration with it, there's no urgent need to migrate.

That said, the new TypeScript SDK offers significant improvements for TypeScript users.

The difference is visible even in a single call:

// dwolla-v2-node
const res = await client.post("customers", { firstName: "Jane", lastName: "Doe", email: "jane@example.com" });
const location = res.headers.get("location"); // Untyped

// TypeScript SDK
const res = await dwolla.customers.create({
  requestBody: { firstName: "Jane", lastName: "Doe", email: "jane@example.com" },
});
const location = res.location; // Typed string

As your integration grows, the benefits compound:

Aspect dwolla-v2-node TypeScript SDK
API Style Generic HTTP methods (client.post("customers")) Resource methods (dwolla.customers.create())
Type Safety Basic (added via DefinitelyTyped) First-class, generated from OpenAPI
Request Bodies Untyped object Typed interfaces per operation
Responses Generic wrapper Typed models per operation
Errors Generic error object 180+ specific error classes
Bundle Size Full SDK Tree-shakable standalone functions
Maintenance Hand-maintained Auto-generated from OpenAPI spec

Key differences in practice:

  1. Discoverability. With dwolla-v2-node, you need to know the endpoint path ("customers", "transfers", etc.). With the TypeScript SDK, autocomplete shows available methods like dwolla.customers and dwolla.transfers.
  2. Type checking. In dwolla-v2-node, nothing stops you from passing { fristName: "Jane" }. In the TypeScript SDK, that's a compile error.
  3. Error handling. dwolla-v2-node throws a generic error. The TypeScript SDK throws InsufficientFundsError, ValidationError, or one of 180+ specific types you can catch individually.
  4. Staying current. The TypeScript SDK is generated from Dwolla's OpenAPI spec, so new endpoints appear automatically. dwolla-v2-node requires manual updates.

Migration Path

If you're using dwolla-v2-node today:

For new projects, we recommend starting with the TypeScript SDK to take advantage of the improved developer experience.


In Practice

We invited developers to test the TypeScript SDK during beta. Here's what they said:

"The developer experience feels great—the type safety and auto-completion are exactly what we were hoping for. The SDK structure, type definitions, and overall API feel very intuitive. This will be a huge improvement for TypeScript developers working with Dwolla." — Davidson Nascimento, Co-Founder/CTO at Cleo Pay


Get Started Today

The Dwolla TypeScript SDK is designed to make payment integration faster, safer, and less frustrating. With full type safety, automatic token management, and typed error handling, you can focus on building your product instead of wrestling with API mechanics.

Try it in 5 minutes:

Install with npm install dwolla, copy the Getting Started example, and run your first type-safe API call. Then tell us what you think on the developer forum or open an issue on Github if you run into any problems.


Resources

Everything you need to get started and go deeper.

Happy building!