# 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);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.payram.com/payram-sdk/typescript-javascript-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
