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

# Intégration SDK Node.js

> Guide de configuration rapide pour le SDK Navio Node.js/TypeScript

## Vue d'ensemble

Le SDK Navio Node.js fournit une interface moderne et typée pour intégrer les paiements Navio dans vos applications Node.js et TypeScript. Conçu avec TypeScript et async/await pour la meilleure expérience développeur.

<CardGroup cols={2}>
  <Card title="TypeScript natif" icon="shield-check" color="#0D9373">
    Support TypeScript complet avec définitions de types exhaustives
  </Card>

  <Card title="Basé sur les Promises" icon="clock" color="#0D9373">
    Support natif des Promises avec async/await
  </Card>

  <Card title="API simple" icon="code" color="#0D9373">
    Interface claire et intuitive
  </Card>

  <Card title="Gestion des erreurs" icon="circle-exclamation" color="#0D9373">
    Exceptions personnalisées pour chaque type d'erreur
  </Card>
</CardGroup>

## Prérequis

* Node.js 16.0.0 ou supérieur
* npm, yarn ou pnpm

## Installation

Installez via npm :

```bash theme={null}
npm install @oneclickdz/ocpay-sdk
```

Ou avec yarn :

```bash theme={null}
yarn add @oneclickdz/ocpay-sdk
```

Ou avec pnpm :

```bash theme={null}
pnpm add @oneclickdz/ocpay-sdk
```

## Démarrage rapide

### 1. Initialiser le SDK

```typescript theme={null}
import { OCPay } from '@oneclickdz/ocpay-sdk';

// Initialize with your API access token
const ocpay = new OCPay('your-api-access-token');
```

<Warning>
  Stockez votre clé API dans des variables d'environnement, jamais dans le code
</Warning>

```bash theme={null}
# .env file
ONECLICK_API_KEY=your_api_key_here
```

```typescript theme={null}
// Load from environment
const ocpay = new OCPay(process.env.ONECLICK_API_KEY);
```

### 2. Créer un lien de paiement

```typescript theme={null}
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. Vérifier le statut du paiement

```typescript theme={null}
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);
  }
}
```

## Exemple e-commerce complet

Voici un flux complet pour un paiement e-commerce :

```typescript theme={null}
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);
  }
}
```

## Intégration avec les frameworks

### Express.js

```typescript theme={null}
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

```typescript theme={null}
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)

```typescript theme={null}
// 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 });
  }
}
```

## Référence API

### Classe OCPay

Point d'entrée principal du SDK.

#### Constructeur

```typescript theme={null}
constructor(accessToken: string, options?: ClientOptions)
```

**Paramètres :**

* `accessToken` (string) - Votre token d'accès API
* `options` (ClientOptions) - Configuration optionnelle du client :
  * `timeout` (number) - Délai de la requête en millisecondes (défaut : 30000)
  * `baseURL` (string) - URL de base personnalisée (principalement pour les tests)
  * `headers` (object) - En-têtes supplémentaires

**Exemple :**

```typescript theme={null}
const ocpay = new OCPay('your-api-key', {
  timeout: 60000, // 60 seconds
});
```

#### Méthodes

`createLink(request: CreateLinkRequest): Promise<CreateLinkResponse>`

Crée un lien de paiement.

`checkPayment(paymentRef: string): Promise<CheckPaymentResponse>`

Vérifie le statut d'un paiement.

### Types & Interfaces

#### ProductInfo

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

#### CreateLinkRequest

```typescript theme={null}
interface CreateLinkRequest {
  productInfo: ProductInfo;
  feeMode?: FeeMode;        // NO_FEE (default), SPLIT_FEE, CUSTOMER_FEE
  successMessage?: string;  // Optional success message
  redirectUrl?: string;     // Optional redirect URL
}
```

**Enum FeeMode :**

```typescript theme={null}
enum FeeMode {
  NO_FEE = 'NO_FEE',           // Merchant pays (default)
  SPLIT_FEE = 'SPLIT_FEE',     // 50/50 split
  CUSTOMER_FEE = 'CUSTOMER_FEE' // Customer pays
}
```

#### CreateLinkResponse

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

#### CheckPaymentResponse

```typescript theme={null}
interface CheckPaymentResponse {
  status: PaymentStatus;            // Payment status enum
  message: string;                  // Status message
  paymentRef: string;               // Payment reference
  transactionDetails?: TransactionDetails; // Details (if available)
}
```

**Enum PaymentStatus :**

```typescript theme={null}
enum PaymentStatus {
  PENDING = 'PENDING',     // Payment in progress
  CONFIRMED = 'CONFIRMED', // Payment successful
  FAILED = 'FAILED',       // Payment declined/expired
}
```

### Gestion des exceptions

Toutes les exceptions héritent de `OCPayException` :

| Exception                 | Code HTTP | Déclenchée quand             |
| ------------------------- | --------- | ---------------------------- |
| `ValidationException`     | 400       | Données de requête invalides |
| `UnauthorizedException`   | 403       | Clé API invalide             |
| `NotFoundException`       | 404       | Paiement introuvable         |
| `PaymentExpiredException` | 410       | Lien expiré (>20 min)        |
| `ApiException`            | Divers    | Autres erreurs API           |

Toutes les exceptions fournissent :

```typescript theme={null}
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
  }
}
```

## Notes importantes

### Validation du marchand requise

<Warning>
  Complétez la validation du marchand sur [oneclickdz.com](https://app.oneclickdz.com/profile) avant d'utiliser l'API
</Warning>

### Limites de montant

* **Minimum** : 500 DZD
* **Maximum** : 500 000 DZD
* Doit être un nombre entier

### Structure des frais

<Info>
  **Frais réduits** : 0% sur le solde, seulement 1% de frais de retrait
</Info>

### Expiration du lien de paiement

Les liens expirent **20 minutes** après leur création si le paiement n'est pas initié.

### Flux des statuts de paiement

1. **PENDING** - Paiement en cours → Revérifier plus tard
2. **CONFIRMED** - Paiement réussi → Honorer la commande
3. **FAILED** - Paiement refusé/expiré → Marquer la commande comme échouée

## Support TypeScript

Ce SDK est écrit en TypeScript et inclut des définitions de types complètes. Pas besoin d'installer des packages `@types` !

```typescript theme={null}
import { OCPay, CreateLinkRequest, PaymentStatus } from '@oneclickdz/ocpay-sdk';

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

## Utilisation en JavaScript

Le SDK fonctionne parfaitement avec du JavaScript ordinaire :

```javascript theme={null}
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);
}
```

## Tests

### Utilisation du Sandbox

L'API utilise automatiquement le mode sandbox pour les comptes de test :

```typescript theme={null}
const response = await ocpay.createLink(request);

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

## Meilleures pratiques

<AccordionGroup>
  <Accordion title="Toujours sauvegarder la référence de paiement" icon="database">
    Stockez `paymentRef` immédiatement après la création du lien. Vous en aurez besoin pour vérifier le statut du paiement.
  </Accordion>

  <Accordion title="Vérifier le statut du paiement" icon="clock">
    Configurez une tâche de fond pour vérifier le statut du paiement toutes les 20 minutes pour les commandes en attente.
  </Accordion>

  <Accordion title="Gérer toutes les exceptions" icon="shield-halved">
    Capturez et gérez tous les types d'exceptions de manière appropriée. Journalisez les erreurs pour le débogage.
  </Accordion>

  <Accordion title="Sécuriser votre clé API" icon="key">
    Stockez les clés API dans des variables d'environnement, ne les committez jamais dans le contrôle de version.
  </Accordion>

  <Accordion title="Utiliser HTTPS uniquement" icon="lock">
    Utilisez toujours HTTPS pour les URLs de redirection et les endpoints de votre application.
  </Accordion>
</AccordionGroup>

## Support & Ressources

<CardGroup cols={2}>
  <Card title="Dépôt GitHub" icon="github" href="https://github.com/oneclickdz/ocpay-nodejs-sdk">
    Code source, exemples et problèmes
  </Card>

  <Card title="Documentation API" icon="book" href="/fr/api-reference/ocpay/create-link">
    Référence API détaillée
  </Card>

  <Card title="Package npm" icon="npm" href="https://www.npmjs.com/package/@oneclickdz/ocpay-sdk">
    Voir sur le registre npm
  </Card>

  <Card title="Contacter le support" icon="headset" href="/fr/contact">
    Obtenez l'aide de notre équipe
  </Card>
</CardGroup>

## Prochaines étapes

<Card title="Meilleures pratiques OCPay" icon="star" href="/fr/ocpay-guides/4-best-practices">
  Découvrez les conseils de production et les meilleures pratiques de sécurité
</Card>
