Skip to main content

Overview

The OCPay Node.js SDK provides a modern, type-safe interface for integrating OCPay payments into your Node.js and TypeScript applications. Built with TypeScript and async/await for the best developer experience.

TypeScript Native

Full TypeScript support with complete type definitions

Promise-based

Native Promise support with async/await

Simple API

Clean, intuitive interface

Error Handling

Custom exceptions for different error types

Requirements

  • Node.js 16.0.0 or higher
  • npm, yarn, or pnpm

Installation

Install via npm:
npm install @oneclickdz/ocpay-sdk
Or with yarn:
yarn add @oneclickdz/ocpay-sdk
Or with pnpm:
pnpm add @oneclickdz/ocpay-sdk

Quick Start

1. Initialize SDK

import { OCPay } from '@oneclickdz/ocpay-sdk';

// Initialize with your API access token
const ocpay = new OCPay('your-api-access-token');
Store your API key in environment variables, never in code
# .env file
ONECLICK_API_KEY=your_api_key_here
// Load from environment
const ocpay = new OCPay(process.env.ONECLICK_API_KEY);
import { OCPay, FeeMode } from '@oneclickdz/ocpay-sdk';

const ocpay = new OCPay(process.env.ONECLICK_API_KEY);

// Create payment link request
const request = {
  productInfo: {
    title: 'Premium Subscription',
    amount: 5000, // Amount in DZD (500 - 500,000)
    description: 'Monthly access to premium features',
  },
  feeMode: FeeMode.NO_FEE, // Merchant pays fees
  successMessage: 'Thank you for your purchase!',
  redirectUrl: 'https://yourstore.com/success?orderId=12345',
};

// Create the payment link
try {
  const response = await ocpay.createLink(request);
  
  // Redirect customer to payment page
  console.log('Payment URL:', response.paymentUrl);
  
  // IMPORTANT: Save this reference!
  console.log('Payment Reference:', response.paymentRef);
  // await saveOrderPaymentRef(orderId, response.paymentRef);
  
} catch (error) {
  if (error instanceof ValidationException) {
    console.error('Validation error:', error.message);
  } else if (error instanceof UnauthorizedException) {
    console.error('Auth error:', error.message);
  } else if (error instanceof ApiException) {
    console.error('API error:', error.message);
  }
}

3. Check Payment Status

import { PaymentStatus } from '@oneclickdz/ocpay-sdk';

// Check payment status using the payment reference
try {
  const status = await ocpay.checkPayment('OCPL-A1B2C3-D4E5');
  
  if (status.status === PaymentStatus.CONFIRMED) {
    // Payment successful - fulfill the order
    console.log('Payment confirmed!');
    console.log('Amount:', status.transactionDetails?.amount, 'DZD');
    await fulfillOrder(orderId);
    
  } else if (status.status === PaymentStatus.FAILED) {
    // Payment failed or expired
    console.log('Payment failed:', status.message);
    await markOrderFailed(orderId);
    
  } else {
    // Still pending - check again later
    console.log('Payment pending...');
    await schedulePolling(orderId);
  }
  
} catch (error) {
  if (error instanceof NotFoundException) {
    console.error('Payment not found');
  } else if (error instanceof PaymentExpiredException) {
    console.error('Payment link expired');
  } else if (error instanceof ApiException) {
    console.error('API error:', error.message);
  }
}

Complete E-commerce Example

Here’s a complete flow for an e-commerce checkout:
import {
  OCPay,
  FeeMode,
  PaymentStatus,
  ValidationException,
  ApiException,
} from '@oneclickdz/ocpay-sdk';

// Initialize SDK
const ocpay = new OCPay(process.env.ONECLICK_API_KEY!);

// Step 1: Create order in your system
const orderId = await createOrder({
  customerId: 123,
  items: [
    { name: 'Product A', price: 5000 },
    { name: 'Product B', price: 3000 },
  ],
  total: 8000,
});

// Step 2: Create payment link
try {
  const response = await ocpay.createLink({
    productInfo: {
      title: `Order #${orderId}`,
      amount: 8000,
      description: `Payment for order #${orderId}`,
    },
    feeMode: FeeMode.NO_FEE,
    successMessage: `Thank you! Your order #${orderId} is being processed.`,
    redirectUrl: `https://yourstore.com/orders/${orderId}/success`,
  });

  // Step 3: Save payment reference to order
  await updateOrder(orderId, {
    paymentRef: response.paymentRef,
    paymentUrl: response.paymentUrl,
    status: 'pending_payment',
  });

  // Step 4: Redirect customer to payment page
  // res.redirect(response.paymentUrl);
  console.log('Redirect to:', response.paymentUrl);
  
} catch (error) {
  console.error('Payment link creation failed:', error.message);
  // showErrorPage('Failed to create payment link. Please try again.');
}

// Step 5: Poll payment status (in background job)
async function checkOrderPayment(orderId: string): Promise<void> {
  const order = await getOrder(orderId);

  if (!order || !order.paymentRef) {
    return;
  }

  try {
    const status = await ocpay.checkPayment(order.paymentRef);

    if (status.status === PaymentStatus.CONFIRMED) {
      // Mark order as paid and fulfill
      await updateOrder(orderId, {
        status: 'paid',
        paidAt: new Date(),
      });
      await fulfillOrder(orderId);
      
    } else if (status.status === PaymentStatus.FAILED) {
      // Mark order as failed
      await updateOrder(orderId, {
        status: 'payment_failed',
      });
    }
    // If pending, do nothing and check again later
    
  } catch (error) {
    console.error('Payment status check failed:', error.message);
  }
}

Framework Integration

Express.js

import express from 'express';
import { OCPay, FeeMode, PaymentStatus } from '@oneclickdz/ocpay-sdk';

const app = express();
const ocpay = new OCPay(process.env.ONECLICK_API_KEY!);

app.use(express.json());

// Create payment endpoint
app.post('/api/orders/:orderId/payment', async (req, res) => {
  const { orderId } = req.params;
  const order = await getOrder(orderId);

  try {
    const response = await ocpay.createLink({
      productInfo: {
        title: `Order #${orderId}`,
        amount: order.total,
      },
      feeMode: FeeMode.NO_FEE,
      redirectUrl: `${req.protocol}://${req.get('host')}/orders/${orderId}/success`,
    });

    await updateOrder(orderId, { paymentRef: response.paymentRef });
    res.json({ paymentUrl: response.paymentUrl });
    
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Check payment status endpoint
app.get('/api/payments/:paymentRef/status', async (req, res) => {
  try {
    const status = await ocpay.checkPayment(req.params.paymentRef);
    res.json(status);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

NestJS

import { Injectable } from '@nestjs/common';
import { OCPay, CreateLinkRequest, FeeMode } from '@oneclickdz/ocpay-sdk';

@Injectable()
export class PaymentService {
  private readonly ocpay: OCPay;

  constructor() {
    this.ocpay = new OCPay(process.env.ONECLICK_API_KEY!);
  }

  async createPaymentLink(orderId: string, amount: number): Promise<string> {
    const response = await this.ocpay.createLink({
      productInfo: {
        title: `Order #${orderId}`,
        amount,
      },
      feeMode: FeeMode.NO_FEE,
      redirectUrl: `https://yourstore.com/orders/${orderId}/success`,
    });

    return response.paymentUrl;
  }

  async checkPaymentStatus(paymentRef: string) {
    return await this.ocpay.checkPayment(paymentRef);
  }
}

Next.js (App Router)

// app/api/orders/[orderId]/payment/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { OCPay, FeeMode } from '@oneclickdz/ocpay-sdk';

const ocpay = new OCPay(process.env.ONECLICK_API_KEY!);

export async function POST(
  request: NextRequest,
  { params }: { params: { orderId: string } }
) {
  try {
    const order = await getOrder(params.orderId);
    
    const response = await ocpay.createLink({
      productInfo: {
        title: `Order #${params.orderId}`,
        amount: order.total,
      },
      feeMode: FeeMode.NO_FEE,
      redirectUrl: `${process.env.NEXT_PUBLIC_URL}/orders/${params.orderId}/success`,
    });

    await updateOrder(params.orderId, { paymentRef: response.paymentRef });
    
    return NextResponse.json({ paymentUrl: response.paymentUrl });
  } catch (error) {
    return NextResponse.json({ error: error.message }, { status: 500 });
  }
}

API Reference

OCPay Class

Main SDK entry point.

Constructor

constructor(accessToken: string, options?: ClientOptions)
Parameters:
  • accessToken (string) - Your API access token
  • options (ClientOptions) - Optional client configuration:
    • timeout (number) - Request timeout in milliseconds (default: 30000)
    • baseURL (string) - Custom base URL (mainly for testing)
    • headers (object) - Additional headers
Example:
const ocpay = new OCPay('your-api-key', {
  timeout: 60000, // 60 seconds
});

Methods

createLink(request: CreateLinkRequest): Promise<CreateLinkResponse> Creates a payment link. checkPayment(paymentRef: string): Promise<CheckPaymentResponse> Checks payment status.

Types & Interfaces

ProductInfo

interface ProductInfo {
  title: string;        // Product name (1-200 chars)
  amount: number;       // Amount in DZD (500 - 500,000)
  description?: string; // Optional (max 1000 chars)
}

CreateLinkRequest

interface CreateLinkRequest {
  productInfo: ProductInfo;
  feeMode?: FeeMode;        // NO_FEE (default), SPLIT_FEE, CUSTOMER_FEE
  successMessage?: string;  // Optional success message
  redirectUrl?: string;     // Optional redirect URL
}
FeeMode Enum:
enum FeeMode {
  NO_FEE = 'NO_FEE',           // Merchant pays (default)
  SPLIT_FEE = 'SPLIT_FEE',     // 50/50 split
  CUSTOMER_FEE = 'CUSTOMER_FEE' // Customer pays
}

CreateLinkResponse

interface CreateLinkResponse {
  paymentLink: PaymentLink;  // Full payment link details
  paymentUrl: string;        // URL to redirect customer
  paymentRef: string;        // Payment reference (SAVE THIS!)
}

CheckPaymentResponse

interface CheckPaymentResponse {
  status: PaymentStatus;            // Payment status enum
  message: string;                  // Status message
  paymentRef: string;               // Payment reference
  transactionDetails?: TransactionDetails; // Details (if available)
}
PaymentStatus Enum:
enum PaymentStatus {
  PENDING = 'PENDING',     // Payment in progress
  CONFIRMED = 'CONFIRMED', // Payment successful
  FAILED = 'FAILED',       // Payment declined/expired
}

Exception Handling

All exceptions extend OCPayException:
ExceptionHTTP CodeWhen Thrown
ValidationException400Invalid request data
UnauthorizedException403Invalid API key
NotFoundException404Payment not found
PaymentExpiredException410Link expired (>20 min)
ApiExceptionVariousOther API errors
All exceptions provide:
try {
  const response = await ocpay.createLink(request);
} catch (error) {
  if (error instanceof ApiException) {
    console.log(error.message);         // Error message
    console.log(error.getStatusCode()); // HTTP status code
    console.log(error.getRequestId());  // Request ID for support
    console.log(error.getErrorData());  // Full error data
  }
}

Important Notes

Merchant Validation Required

Complete merchant validation at oneclickdz.com before using the API

Amount Limits

  • Minimum: 500 DZD
  • Maximum: 500,000 DZD
  • Must be whole numbers (integers)

Fee Structure

Low Fees: 0% on balance, only 1% withdrawal fee
Links expire 20 minutes after creation if payment not initiated.

Payment Status Flow

  1. PENDING - Payment in progress → Poll again later
  2. CONFIRMED - Payment successful → Fulfill order
  3. FAILED - Payment declined/expired → Mark order failed

TypeScript Support

This SDK is written in TypeScript and includes complete type definitions. No need to install @types packages!
import { OCPay, CreateLinkRequest, PaymentStatus } from '@oneclickdz/ocpay-sdk';

// Full IntelliSense and type checking
const request: CreateLinkRequest = {
  productInfo: {
    title: 'Product',
    amount: 5000,
  },
};

JavaScript Usage

The SDK works perfectly with plain JavaScript too:
const { OCPay, FeeMode } = require('@oneclickdz/ocpay-sdk');

const ocpay = new OCPay(process.env.ONECLICK_API_KEY);

async function createPayment() {
  const response = await ocpay.createLink({
    productInfo: {
      title: 'Premium Subscription',
      amount: 5000,
    },
    feeMode: FeeMode.NO_FEE,
  });
  
  console.log('Payment URL:', response.paymentUrl);
}

Testing

Using Sandbox

The API automatically uses sandbox mode for test accounts:
const response = await ocpay.createLink(request);

if (response.paymentLink.isSandbox) {
  console.log('This is a test payment');
}

Best Practices

Store paymentRef immediately after creating the link. You need it to check payment status.
Set up a background job to check payment status every 20 minutes for pending orders.
Catch and handle all exception types appropriately. Log errors for debugging.
Store API keys in environment variables, never commit them to version control.
Always use HTTPS for redirect URLs and your application endpoints.

Support & Resources

Next Steps

OCPay Best Practices

Learn production-ready tips and security best practices