Back to 0fee
0fee

Building 8 SDKs With Zero Human Engineers

How we built 8 SDKs in 7 languages plus 3 platform plugins for 0fee.dev with zero human engineers. By Juste A. Gnimavo and Claude.

Thales & Claude | March 25, 2026 8 min 0fee
sdkdeveloper-experiencetypescriptpythongorustflutter

Most payment platforms take months to build their SDK ecosystem. Stripe's first SDK (Ruby) was maintained by a team. PayPal's SDKs are maintained by dozens of engineers. We built 8 SDKs in 7 programming languages plus 3 platform plugins, all generated by Claude, all following an identical resource pattern, with zero runtime dependencies in most cases.

The SDK timeline spans the entire 0fee.dev build history -- from Session 002 to Session 080 -- because SDKs are never "done." They evolve with the API.

The SDK Timeline

SessionDateSDKsVersionCoverage
002Dec 11, 2025TypeScript, Pythonv1.0~21%
003Dec 11, 2025Go, Ruby, PHP, Java, C#v1.0~21%
065Dec 25, 2025TypeScript, Python (rewrite)v2.0~45%
079Feb 14, 2026PHP, Gov3.0~65%
080Feb 15, 2026Rust, Java, Flutter, React Nativev3.0~79%

API coverage went from 21% (basic CRUD for payments) to 79% (payments, transactions, apps, providers, webhooks, invoices, feature requests, analytics). The remaining 21% covers admin-only endpoints that SDKs do not need to expose.

The Identical Resource Pattern

Every SDK follows the same architectural pattern regardless of language. This makes the SDKs predictable: if you know how to use one, you know how to use all of them.

Client
  |
  +-- payments      (create, get, list, cancel)
  +-- transactions   (get, list, export)
  +-- apps           (create, get, list, update, delete)
  +-- providers      (list, get)
  +-- webhooks       (create, get, list, delete, verify)
  +-- invoices       (get, list, download)
  +-- paymentLinks   (create, get, list, delete)
  +-- paymentMethods (list)

Each resource is a namespace on the client object. Each namespace exposes the same CRUD methods (where applicable). Here is how the same operation looks across all 8 SDKs:

Create a Payment

TypeScript: ``typescript const zerofee = new ZeroFee({ apiKey: 'sk_live_...' }); const payment = await zerofee.payments.create({ amount: 10.00, currency: 'USD', reference: 'order-123', }); ``

Python: ``python client = ZeroFee(api_key="sk_live_...") payment = client.payments.create( amount=10.00, currency="USD", reference="order-123", ) ``

Go: ``go client := zerofee.New("sk_live_...") payment, err := client.Payments.Create(&zerofee.PaymentParams{ Amount: 10.00, Currency: "USD", Reference: "order-123", }) ``

Rust: ``rust let client = ZeroFee::new("sk_live_..."); let payment = client.payments().create(PaymentParams { amount: 10.00, currency: "USD".to_string(), reference: "order-123".to_string(), ..Default::default() }).await?; ``

PHP: ``php $client = new ZeroFee('sk_live_...'); $payment = $client->payments->create([ 'amount' => 10.00, 'currency' => 'USD', 'reference' => 'order-123', ]); ``

Java: ``java ZeroFee client = new ZeroFee("sk_live_..."); Payment payment = client.payments().create( PaymentParams.builder() .amount(10.00) .currency("USD") .reference("order-123") .build() ); ``

Flutter (Dart): ``dart final client = ZeroFee(apiKey: 'sk_live_...'); final payment = await client.payments.create( amount: 10.00, currency: 'USD', reference: 'order-123', ); ``

React Native: ``typescript // Uses the TypeScript SDK import { ZeroFee } from '@0fee/react-native'; BLANK const zerofee = new ZeroFee({ apiKey: 'sk_live_...' }); const payment = await zerofee.payments.create({ amount: 10.00, currency: 'USD', reference: 'order-123', }); ``

The Zero Runtime Dependencies Philosophy

Most SDKs are dependency-free or near-dependency-free:

SDKLanguageRuntime Dependencies
TypeScriptNode.js0 (uses native fetch)
PythonPython 3.8+httpx only
GoGo 1.21+0 (uses net/http)
RustRustreqwest, serde
PHPPHP 8.1+0 (uses curl extension)
JavaJava 11+0 (uses java.net.http.HttpClient)
FlutterDarthttp package
React NativeJS/TS0 (wraps TypeScript SDK)

Zero dependencies means: - No version conflicts with the developer's existing packages - No supply chain attack surface from transitive dependencies - Faster installation (npm install does not download a tree of packages) - Smaller bundle size for frontend SDKs

The TypeScript SDK in particular benefits from zero dependencies. Many developers are frustrated by SDKs that pull in axios, node-fetch, or other HTTP libraries when the platform already provides fetch natively.

SDK v1 to v2: The Rewrite (Session 065)

The v1 SDKs from Sessions 002-003 were generated quickly and had limitations:

Issuev1v2
HTTP clientaxios / requestsNative fetch / httpx
Type safetyPartial typesFull request/response types
Error handlingGeneric exceptionsTyped error classes
RetriesNoneExponential backoff
Webhook verificationMissingBuilt-in
PaginationManualIterator helpers

The v2 rewrite focused on TypeScript and Python (the two most popular SDKs by download count). The pattern established in v2 became the template for all v3 SDKs.

Typed Error Handling

typescript// v1: Generic error
try {
    await zerofee.payments.create({...});
} catch (e) {
    console.error(e.message); // "Request failed"
}

// v2: Typed errors
try {
    await zerofee.payments.create({...});
} catch (e) {
    if (e instanceof ZeroFeeValidationError) {
        console.error('Validation:', e.errors);
    } else if (e instanceof ZeroFeeAuthError) {
        console.error('Invalid API key');
    } else if (e instanceof ZeroFeeRateLimitError) {
        console.error(`Retry after ${e.retryAfter} seconds`);
    }
}

Automatic Retry

typescript// Built into the HTTP client
class ZeroFeeHttpClient {
    private maxRetries = 3;
    private retryDelay = 1000; // ms

    async request(method: string, path: string, data?: any): Promise<any> {
        let lastError: Error | null = null;

        for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
            try {
                const response = await fetch(`${this.baseUrl}${path}`, {
                    method,
                    headers: this.headers,
                    body: data ? JSON.stringify(data) : undefined,
                });

                if (response.status === 429) {
                    // Rate limited: respect Retry-After header
                    const retryAfter = parseInt(response.headers.get('Retry-After') || '1');
                    await this.sleep(retryAfter * 1000);
                    continue;
                }

                if (response.status >= 500 && attempt < this.maxRetries) {
                    // Server error: retry with exponential backoff
                    await this.sleep(this.retryDelay * Math.pow(2, attempt));
                    continue;
                }

                return await this.handleResponse(response);
            } catch (error) {
                lastError = error as Error;
                if (attempt < this.maxRetries) {
                    await this.sleep(this.retryDelay * Math.pow(2, attempt));
                }
            }
        }

        throw lastError;
    }
}

SDK v3: The Expansion (Sessions 079-080)

v3 added four new SDKs and upgraded PHP and Go:

Rust SDK: Async by default using tokio and reqwest. Full type system with Rust enums for payment statuses and methods.

Java SDK: Uses java.net.http.HttpClient (Java 11+). Builder pattern for all request objects. CompletableFuture for async operations.

Flutter SDK: Dart-native with http package. Designed for mobile payment flows -- includes a pre-built checkout widget component.

React Native SDK: Wraps the TypeScript SDK with React Native-specific components. Includes a PaymentSheet component that renders the checkout flow in a modal.

The 3 Platform Plugins

Beyond SDKs, Session 084 produced three platform plugins:

WHMCS Plugin

php// modules/gateways/zerofee.php
function zerofee_capture($params) {
    $client = new ZeroFee($params['apiKey']);

    $payment = $client->payments->create([
        'amount' => $params['amount'],
        'currency' => $params['currency'],
        'reference' => 'whmcs-' . $params['invoiceid'],
        'customer_email' => $params['clientdetails']['email'],
    ]);

    if ($payment->status === 'completed') {
        return ['status' => 'success', 'transid' => $payment->id];
    }

    return ['status' => 'declined', 'rawdata' => $payment->toArray()];
}

WordPress Plugin

A WordPress payment gateway plugin that adds 0fee.dev as a payment option on any WordPress site using WooCommerce or a custom form.

WooCommerce Plugin

Extends the WordPress plugin specifically for WooCommerce:

phpclass WC_Gateway_ZeroFee extends WC_Payment_Gateway {
    public function process_payment($order_id) {
        $order = wc_get_order($order_id);
        $client = new ZeroFee($this->api_key);

        $payment = $client->payments->create([
            'amount' => $order->get_total(),
            'currency' => $order->get_currency(),
            'reference' => 'woo-' . $order_id,
        ]);

        return [
            'result' => 'success',
            'redirect' => $payment->checkout_url,
        ];
    }
}

API Coverage Evolution

Session 002:  ████░░░░░░░░░░░░░░░░  21%  (payments CRUD)
Session 003:  ████░░░░░░░░░░░░░░░░  21%  (same coverage, more languages)
Session 065:  █████████░░░░░░░░░░░  45%  (+transactions, apps, webhooks)
Session 079:  █████████████░░░░░░░  65%  (+invoices, payment links, providers)
Session 080:  ████████████████░░░░  79%  (+feature requests, analytics, methods)

The remaining 21% covers admin endpoints (user management, platform stats, audit logs) that are not exposed through SDKs.

What We Learned

Generate all SDKs from the same template. The identical resource pattern across all 8 SDKs was only possible because we used the API specification as the source of truth. Each SDK is a language-specific implementation of the same abstract interface.

Zero dependencies is a competitive advantage. Developers notice and appreciate SDKs that do not pull in transitive dependencies. It eliminates version conflicts and reduces security audit surface.

Platform plugins reach developers where they are. Not every developer builds from scratch. WooCommerce alone powers 29% of e-commerce sites. The WHMCS plugin reaches hosting companies. Platform plugins are high-leverage for adoption.

SDK maintenance is ongoing. The timeline from v1 to v3 over 78 sessions shows that SDKs are never "done." Every API change, every new feature, every bug fix propagates to 8 SDK packages and 3 plugins. This is the hidden cost of a broad SDK ecosystem.

AI-generated SDKs are consistent. Claude generates each SDK with the same patterns, same error handling, same retry logic. There is no "this SDK was written by a Go expert and that one was written by a Java intern" quality variation. Consistency across languages is a direct benefit of AI generation.


This article is part of the "How We Built 0fee.dev" series. 0fee.dev is a payment orchestrator covering 53+ providers across 200+ countries, built by Juste A. GNIMAVO and Claude from Abidjan with zero human engineers. Follow the series for the complete build story.

Share this article:

Responses

Write a response
0/2000
Loading responses...

Related Articles