> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fingopay.io/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript SDK

> Developer-friendly & type-safe TypeScript SDK for the Fingo Pay REST API

This library provides convenient access to the Fingo Pay REST API from server-side TypeScript or JavaScript. It is generated with [Stainless](https://www.stainlessapi.com/).

## Installation

Install the Fingo Pay TypeScript SDK using your preferred package manager:

<Tabs>
  <Tab title="npm">
    ```bash theme={"dark"}
    npm install @fingoafrica/fingo-pay
    ```
  </Tab>

  <Tab title="pnpm">
    ```bash theme={"dark"}
    pnpm add @fingoafrica/fingo-pay
    ```
  </Tab>

  <Tab title="yarn">
    ```bash theme={"dark"}
    yarn add @fingoafrica/fingo-pay
    ```
  </Tab>

  <Tab title="bun">
    ```bash theme={"dark"}
    bun add @fingoafrica/fingo-pay
    ```
  </Tab>
</Tabs>

## Quick start

Initialize the SDK with your API key and make your first request:

```typescript theme={"dark"}
import FingoPay from '@fingoafrica/fingo-pay';

const client = new FingoPay({
  apiKey: process.env['FINGO_PAY_API_KEY'], // This is the default and can be omitted
});

const acceptedResponse = await client.mpesa.createCharge({
  amount: 150000,
  merchantTransactionId: 'invoice_48291',
  phoneNumber: '+254712345678',
});

console.log(acceptedResponse.data);
```

<Warning>
  Never expose your secret API key in client-side code or version control. Use environment variables.
</Warning>

## Request & response types

This library includes TypeScript definitions for all request params and response fields. Import and use them for full type safety:

```typescript theme={"dark"}
import FingoPay from '@fingoafrica/fingo-pay';

const client = new FingoPay({
  apiKey: process.env['FINGO_PAY_API_KEY'],
});

const params: FingoPay.MpesaCreateChargeParams = {
  amount: 150000,
  merchantTransactionId: 'invoice_48291',
  phoneNumber: '+254712345678',
};

const acceptedResponse: FingoPay.AcceptedResponse = await client.mpesa.createCharge(params);
```

<Tip>
  Documentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors.
</Tip>

## Handling errors

When the library is unable to connect to the API, or if the API returns a non-success status code (i.e., 4xx or 5xx response), a subclass of `APIError` will be thrown:

```typescript theme={"dark"}
const acceptedResponse = await client.mpesa
  .createCharge({
    amount: 150000,
    merchantTransactionId: 'invoice_48291',
    phoneNumber: '+254712345678',
  })
  .catch(async (err) => {
    if (err instanceof FingoPay.APIError) {
      console.log(err.status); // 400
      console.log(err.name); // BadRequestError
      console.log(err.headers); // {server: 'nginx', ...}
    } else {
      throw err;
    }
  });
```

### Error codes

| Status Code | Error Type                 |
| ----------- | -------------------------- |
| 400         | `BadRequestError`          |
| 401         | `AuthenticationError`      |
| 403         | `PermissionDeniedError`    |
| 404         | `NotFoundError`            |
| 422         | `UnprocessableEntityError` |
| 429         | `RateLimitError`           |
| >=500       | `InternalServerError`      |
| N/A         | `APIConnectionError`       |

## Retries

Certain errors are automatically retried **2 times** by default, with a short exponential backoff. The following errors are retried:

* Connection errors (e.g., network connectivity problems)
* 408 Request Timeout
* 409 Conflict
* 429 Rate Limit
* > \=500 Internal errors

Configure or disable retries using the `maxRetries` option:

```typescript theme={"dark"}
// Configure the default for all requests:
const client = new FingoPay({
  maxRetries: 0, // default is 2
});

// Or, configure per-request:
await client.mpesa.createCharge(
  {
    amount: 150000,
    merchantTransactionId: 'invoice_48291',
    phoneNumber: '+254712345678',
  },
  {
    maxRetries: 5,
  }
);
```

## Timeouts

Requests time out after **1 minute** by default. Configure this with the `timeout` option:

```typescript theme={"dark"}
// Configure the default for all requests:
const client = new FingoPay({
  timeout: 20 * 1000, // 20 seconds (default is 1 minute)
});

// Override per-request:
await client.mpesa.createCharge(
  {
    amount: 150000,
    merchantTransactionId: 'invoice_48291',
    phoneNumber: '+254712345678',
  },
  {
    timeout: 5 * 1000,
  }
);
```

<Note>
  On timeout, an `APIConnectionTimeoutError` is thrown. Requests that time out will be retried twice by default.
</Note>

## Advanced usage

### Accessing raw response data

The "raw" `Response` returned by `fetch()` can be accessed through the `.asResponse()` method on the `APIPromise` type. This method returns as soon as the headers for a successful response are received and does not consume the response body, allowing custom parsing or streaming logic.

Use `.withResponse()` to get the raw `Response` along with the parsed data:

```typescript theme={"dark"}
const client = new FingoPay();

// Access raw response without consuming body
const response = await client.mpesa
  .createCharge({
    amount: 150000,
    merchantTransactionId: 'invoice_48291',
    phoneNumber: '+254712345678',
  })
  .asResponse();

console.log(response.headers.get('X-My-Header'));
console.log(response.statusText);

// Get both parsed data and raw response
const { data: acceptedResponse, response: raw } = await client.mpesa
  .createCharge({
    amount: 150000,
    merchantTransactionId: 'invoice_48291',
    phoneNumber: '+254712345678',
  })
  .withResponse();

console.log(raw.headers.get('X-My-Header'));
console.log(acceptedResponse.data);
```

### Logging

<Info>
  All log messages are intended for debugging only. The format and content of log messages may change between releases.
</Info>

#### Log levels

Configure the log level in two ways:

1. Via the `FINGO_PAY_LOG` environment variable
2. Using the `logLevel` client option (overrides the environment variable)

```typescript theme={"dark"}
import FingoPay from '@fingoafrica/fingo-pay';

const client = new FingoPay({
  logLevel: 'debug', // Show all log messages
});
```

Available log levels, from most to least verbose:

| Level   | Description                                     |
| ------- | ----------------------------------------------- |
| `debug` | Show debug messages, info, warnings, and errors |
| `info`  | Show info messages, warnings, and errors        |
| `warn`  | Show warnings and errors (default)              |
| `error` | Show only errors                                |
| `off`   | Disable all logging                             |

<Warning>
  At the `debug` level, all HTTP requests and responses are logged, including headers and bodies. Some authentication-related headers are redacted, but sensitive data in request and response bodies may still be visible.
</Warning>

#### Custom logger

Provide a custom logger instead of the default `globalThis.console`. Most logging libraries are supported, including pino, winston, bunyan, consola, signale, and @std/log.

```typescript theme={"dark"}
import FingoPay from '@fingoafrica/fingo-pay';
import pino from 'pino';

const logger = pino();

const client = new FingoPay({
  logger: logger.child({ name: 'FingoPay' }),
  logLevel: 'debug',
});
```

### Making custom/undocumented requests

#### Undocumented endpoints

Make requests to undocumented endpoints using `client.get`, `client.post`, and other HTTP verbs:

```typescript theme={"dark"}
await client.post('/some/path', {
  body: { some_prop: 'foo' },
  query: { some_query_arg: 'bar' },
});
```

#### Undocumented request params

Use `// @ts-expect-error` for undocumented parameters:

```typescript theme={"dark"}
client.mpesa.createCharge({
  amount: 150000,
  merchantTransactionId: 'invoice_48291',
  phoneNumber: '+254712345678',
  // @ts-expect-error baz is not yet public
  baz: 'undocumented option',
});
```

### Customizing the fetch client

By default, this library expects a global `fetch` function. You can polyfill it globally or pass a custom one:

```typescript theme={"dark"}
import FingoPay from '@fingoafrica/fingo-pay';
import fetch from 'my-fetch';

const client = new FingoPay({ fetch });
```

#### Fetch options

Provide custom fetch options when instantiating the client or making a request:

```typescript theme={"dark"}
import FingoPay from '@fingoafrica/fingo-pay';

const client = new FingoPay({
  fetchOptions: {
    // `RequestInit` options
  },
});
```

### Configuring proxies

Provide custom `fetchOptions` to add runtime-specific proxy options:

<Tabs>
  <Tab title="Node.js">
    ```typescript theme={"dark"}
    import FingoPay from '@fingoafrica/fingo-pay';
    import * as undici from 'undici';

    const proxyAgent = new undici.ProxyAgent('http://localhost:8888');
    const client = new FingoPay({
      fetchOptions: {
        dispatcher: proxyAgent,
      },
    });
    ```
  </Tab>

  <Tab title="Bun">
    ```typescript theme={"dark"}
    import FingoPay from '@fingoafrica/fingo-pay';

    const client = new FingoPay({
      fetchOptions: {
        proxy: 'http://localhost:8888',
      },
    });
    ```
  </Tab>

  <Tab title="Deno">
    ```typescript theme={"dark"}
    import FingoPay from 'npm:@fingoafrica/fingo-pay';

    const httpClient = Deno.createHttpClient({
      proxy: { url: 'http://localhost:8888' },
    });

    const client = new FingoPay({
      fetchOptions: {
        client: httpClient,
      },
    });
    ```
  </Tab>
</Tabs>

## Requirements

<Check>
  TypeScript >= 4.9 is supported.
</Check>

The following runtimes are supported:

| Runtime             | Version                                            |
| ------------------- | -------------------------------------------------- |
| Web browsers        | Up-to-date Chrome, Firefox, Safari, Edge, and more |
| Node.js             | 20 LTS or later (non-EOL) versions                 |
| Deno                | v1.28.0 or higher                                  |
| Bun                 | 1.0 or later                                       |
| Cloudflare Workers  | Latest                                             |
| Vercel Edge Runtime | Latest                                             |
| Jest                | 28 or greater with the "node" environment          |
| Nitro               | v2.6 or greater                                    |

<Warning>
  React Native is not supported at this time. The `jsdom` environment in Jest is also not supported.
</Warning>

## Semantic versioning

This package generally follows SemVer conventions, though certain backwards-incompatible changes may be released as minor versions:

* Changes that only affect static types, without breaking runtime behavior
* Changes to library internals which are technically public but not intended or documented for external use
* Changes that we do not expect to impact the vast majority of users in practice

<CardGroup cols={2}>
  <Card title="SDK Source Code" icon="github" href="https://github.com/fingoafrica/fingo-pay-sdk-ts">
    View the SDK source code and contribute on GitHub
  </Card>

  <Card title="npm Package" icon="npm" href="https://www.npmjs.com/package/@fingoafrica/fingo-pay">
    View the package on npm
  </Card>
</CardGroup>
