# Typescript/Javascript SDK

## Introduction

The PayRam TypeScript SDK helps your backend communicate smoothly with your self-hosted PayRam server. It provides a clean, type-safe interface so you don’t have to manually handle raw API calls, making integration simpler and more reliable. The SDK also includes built-in support for safe request retries and offers framework-friendly helpers for handling webhooks with minimal setup.

### Prerequisites

Before you begin, make sure you have:

* Your PayRam API Key, which is required for authenticating all requests sent through the SDK.
* The Base URL of your PayRam server, which tells the SDK where your self-hosted PayRam instance is running.

## Installation

Install the SDK using your package manager of choice

{% tabs %}
{% tab title="npm" %}

```typescript
npm install payram
```

{% endtab %}

{% tab title="yarn" %}

```javascript
yarn add payram
```

{% endtab %}

{% tab title="pnpm" %}

```javascript
pnpm add payram
```

{% endtab %}
{% endtabs %}

## QuickStart

* Create a new PayRam client instance by passing your API key and server URL.
* You can also provide optional configuration values such as timeouts and retry settings.

```typescript
import { Payram } from 'payram';

const payram = new Payram({
  apiKey: process.env.PAYRAM_API_KEY!,      //required
  baseUrl: process.env.PAYRAM_BASE_URL!,    //required
  config: {
    timeoutMs: 10_000,                      // Optional
    maxRetries: 2,                          // Optional
    retryPolicy: 'safe',                    // Optional
    // allowInsecureHttp: true,             // Optional
  },
});
```

<table><thead><tr><th width="173.91796875">Option</th><th width="211.83984375">Type</th><th>Description</th></tr></thead><tbody><tr><td>apiKey</td><td>string</td><td>Your PayRam API key used to authenticate all SDK requests.</td></tr><tr><td>baseUrl</td><td>string</td><td>The base URL of your self-hosted PayRam server.</td></tr><tr><td>timeoutMs</td><td>number</td><td>Request timeout in milliseconds.</td></tr><tr><td>maxRetries</td><td>number</td><td>Maximum number of retry attempts for a request.</td></tr><tr><td>retryPolicy</td><td>'none' | 'safe' | 'aggressive'</td><td>Controls retry behavior — none disables retries, safe retries idempotent calls, and aggressive retries all requests.</td></tr><tr><td>allowInsecureHttp</td><td>boolean</td><td>Set to false only if your PayRam server is running on an http:// URL (without SSL). Keep it true for https:// </td></tr></tbody></table>

## Payments

In this section you'll get all the methods which are related to the payments

### Create Payments

* Creates a new payment session by sending customer details and the amount to PayRam, and returns both a unique reference\_id for tracking and a redirect URL that your customer can visit to complete the payment.
* These are the required fields you must include when creating a payment request using the PayRam SDK.

<table><thead><tr><th width="169.19921875">Field</th><th width="447.9765625">Description</th><th>Required</th></tr></thead><tbody><tr><td>customerEmail</td><td>Customer’s email address where the payment link will be sent/associated.</td><td>✅ Yes</td></tr><tr><td>customerId</td><td>Unique identifier for the customer.</td><td>✅ Yes</td></tr><tr><td>amountInUSD</td><td>The payment amount in USD.</td><td>✅ Yes</td></tr></tbody></table>

```javascript
// Start a new payment
const checkout = await payram.payments.initiatePayment({
  customerEmail: 'customer@example.com',
  customerId: 'cust_123',
  amountInUSD: 49.99,
});

console.log(checkout.reference_id);  // unique payment ID
console.log(checkout.url);  // redirect your customer here
```

{% hint style="info" %}
**Note : The url field provides a ready-to-use PayRam payment page. You can share this link directly with your customers, or build a custom UI using other API endpoints.**
{% endhint %}

### Payment Status

* Fetches the latest payment details using the reference\_id and returns the current paymentState so you can track whether the payment is pending, completed, or failed.

```javascript
const payment = await payram.payments.getPaymentRequest(checkout.reference_id);
console.log(payment.paymentState);
```

* Shows all payment states and what each one means.

<table><thead><tr><th width="258.23046875">Status</th><th>Description</th></tr></thead><tbody><tr><td>OPEN</td><td>The payment has not been processed yet.</td></tr><tr><td>CANCELLED</td><td>The payment link has expired or was cancelled.</td></tr><tr><td>FILLED</td><td>The user has paid the full requested amount.</td></tr><tr><td>PARTIALLY_FILLED</td><td>The user has paid less than the requested amount.</td></tr><tr><td>OVER_FILLED</td><td>The user has paid more than the requested amount.</td></tr></tbody></table>

## Payout

In this section you'll get all the methods which are related to the payments

### Create Payout

* Creates a new payout request by sending the merchant details, token information, amount, and destination wallet address to the PayRam server.
* These are the required fields you must send when creating a payout through the PayRam SDK.

<table><thead><tr><th width="197.42578125">Field</th><th width="424.18359375">Description</th><th>Required</th></tr></thead><tbody><tr><td>email</td><td>Recipient’s email address.</td><td>✅ Yes</td></tr><tr><td>blockchainCode</td><td>Blockchain network used for the payout (e.g., ETH, TRX, BASE).</td><td>✅ Yes</td></tr><tr><td>currencyCode</td><td>Token symbol used for the payout (e.g., USDC, USDT).</td><td>✅ Yes</td></tr><tr><td>amount</td><td>Amount to transfer.</td><td>✅ Yes</td></tr><tr><td>toAddress</td><td>Recipient’s wallet address on the selected blockchain.</td><td>✅ Yes</td></tr><tr><td>customerID</td><td>Unique identifier for the customer.</td><td>✅ Yes</td></tr></tbody></table>

{% hint style="info" %}
**Note: PayRam currently supports payouts in USDT (ETH, TRX) and USDC (ETH, BASE). Make sure the selected currency matches a supported network when creating a payout.**
{% endhint %}

```typescript
await payram.payouts.createPayout({
  email: 'merchant@example.com',
  blockchainCode: 'ETH',
  currencyCode: 'USDT',
  amount: '125.50',
  toAddress: '0xfeedfacecafebeefdeadbeefdeadbeefdeadbeef',
  customerID: 414817384
});
```

### Payout Status

* Retrieves the latest payout details using its ID so you can check whether the payout is still pending, awaiting approval, processing on-chain, completed, or failed.

```typescript
const payout = await payram.payouts.getPayoutById(42);

console.log(payout.status);
```

* Shows all payment states and what each one means.

| Status                   | Description                                                                   |
| ------------------------ | ----------------------------------------------------------------------------- |
| pending-otp-verification | Waiting for OTP verification before processing.                               |
| pending-approval         | Awaiting admin or system approval.                                            |
| pending                  | Approved and ready for blockchain processing.                                 |
| initiated                | The payout has been broadcast to the blockchain and is awaiting confirmation. |
| sent                     | The payout has been successfully sent to the recipient.                       |
| failed                   | The transaction failed due to a processing error.                             |
| rejected                 | The payout request was declined by the admin or system.                       |
| processed                | The payout is confirmed on-chain and recorded in the accounting.              |
| cancelled                | The transaction was stopped before being sent or processed.                   |

## Webhook

PayRam sends webhook events to your server whenever something important happens, such as a payment updates.

The SDK provides ready-to-use handlers for Express, Fastify, and Next.js (both App Router and Pages Router). These handlers help you process webhooks safely and correctly. They do the following:

* Check the API-Key header to confirm the request really came from your PayRam server
* Read and validate the webhook payload
* Send back the correct response so PayRam knows your server received the event

{% tabs %}
{% tab title="Express Example" %}

```typescript
import express from 'express';
import { Payram } from 'payram';

const app = express();
const payram = new Payram({
  apiKey: process.env.PAYRAM_API_KEY!,
  baseUrl: process.env.PAYRAM_BASE_URL!,
});

app.post(
  '/payram/webhook',
  payram.webhooks.expressWebhook(async (payload, req) => {
    console.log('Received Payram event:', payload.event, payload.reference_id);
    // handle payment / referral events here
  }),
);

app.listen(3000);
```

{% endtab %}

{% tab title="Fastify Example" %}

```typescript
import Fastify from 'fastify';
import { Payram } from 'payram';

const fastify = Fastify();
const payram = new Payram({
  apiKey: process.env.PAYRAM_API_KEY!,
  baseUrl: process.env.PAYRAM_BASE_URL!,
});

fastify.post(
  '/payram/webhook',
  payram.webhooks.fastifyWebhook(async (payload, request) => {
    console.log('Payram webhook event:', payload.event, payload.reference_id);
    // handle payment / referral events here
  }),
);

await fastify.listen({ port: 3000 });
```

{% endtab %}

{% tab title="Next.js Example (App Router)" %}

```typescript
// app/api/payram/webhook/route.ts
import { NextRequest } from 'next/server';
import { Payram } from 'payram';

const payram = new Payram({
  apiKey: process.env.PAYRAM_API_KEY!,
  baseUrl: process.env.PAYRAM_BASE_URL!,
});

export const POST = payram.webhooks.nextAppRouterWebhook(
  async (payload, req: NextRequest) => {
    console.log('Payram webhook event:', payload.event, payload.reference_id);
    // handle payment / referral events here
  },
);
```

{% hint style="info" %}
**Note: The adapter handles verification and sends the reply automatically. No manual res.status(200) is required.**
{% endhint %}
{% endtab %}
{% endtabs %}

## Validate Api Key

The verifyApiKey function lets you manually check the API key inside your request handler. Use it when you are handling webhooks with a custom framework and need to confirm the request is really from your PayRam server.

```typescript
import { verifyApiKey } from 'payram';

if (!verifyApiKey(req.headers, process.env.PAYRAM_API_KEY!)) {
  return res.status(401).json({ error: 'invalid-key' });
}

const payload = req.body;
handleEvent(payload);
```
