# Monegasy Payment SDK

![npm version](https://img.shields.io/npm/v/monegasy-js)
![npm downloads](https://img.shields.io/npm/dm/monegasy-js)
![License](https://img.shields.io/npm/l/monegasy-js)

SDK JavaScript officiel pour intégrer les paiements Monegasy à votre application web.

## 📦 Installation

```bash
npm install monegasy-js
```

Ou avec Yarn:

```bash
yarn add monegasy-js
```

Ou via CDN :

```html
<!-- CDN Monegasy (recommandé) -->
<script src="https://cdn.monegasy.com/v1/monegasy-sdk.umd.min.js"></script>

<!-- Ou via jsDelivr -->
<script src="https://cdn.jsdelivr.net/npm/monegasy-js@latest/dist/monegasy-sdk.umd.min.js"></script>

<!-- Ou via unpkg -->
<script src="https://unpkg.com/monegasy-js@latest/dist/monegasy-sdk.umd.min.js"></script>
```

### 🔒 Intégrité Subresource (SRI) — version pinned recommandée

Pour la production, **pinnez la version** et vérifiez l'intégrité du fichier
via l'attribut `integrity`. Cela protège contre un CDN compromis :

```html
<script
  src="https://cdn.jsdelivr.net/npm/monegasy-js@1.0.10/dist/monegasy-sdk.umd.min.js"
  integrity="sha384-PLACEHOLDER_REPLACE_AFTER_BUILD"
  crossorigin="anonymous"
></script>
```

> Le hash SRI exact est généré à chaque release. Récupérez-le sur :
> https://www.srihash.org/ en collant l'URL CDN, ou via :
> ```bash
> openssl dgst -sha384 -binary dist/monegasy-sdk.umd.min.js | openssl base64 -A
> ```

## 🔐 Quel type de clé utiliser ?

Avant de coller votre clé : Monegasy expose **deux types** selon le contexte.

| Type | Préfixe | Pour | Sécurité |
|---|---|---|---|
| **Publishable** | `mk_pub_test_*` / `mk_pub_live_*` | Code **frontend** (sites web, SPA, intégration WordPress) | Restreinte par domaine. Visible publiquement OK. |
| **Secret** | `mk_sec_test_*` / `mk_sec_live_*` | Code **backend** uniquement (serveur, fonctions serverless) | Ne jamais commiter ni exposer côté client. |

Le SDK affichera un warning console si vous utilisez une clé secret ou une clé legacy (`mk_test_*` / `mk_live_*`) dans un navigateur — créez une publishable key restreinte à votre domaine depuis [votre dashboard](https://monegasy.com/merchant/api-keys).

## 🚀 Démarrage Rapide

### 1. Initialiser le SDK

```javascript
import MonegasySDK from "monegasy-js";

const monegasy = new MonegasySDK({
  apiKey: "YOUR_API_KEY",
  sandbox: false, // true pour le mode test
});
```

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

```javascript
await monegasy.renderPaymentButton(
  {
    amount: 50000,
    description: "iPhone 15 Pro",
    buttonText: "Payer avec Monegasy",
    onSuccess: (payment) => {
      console.log("Paiement réussi!", payment);
    },
  },
  "#payment-button"
);
```

## 📚 Documentation

### Configuration

```typescript
interface MonegasyConfig {
  apiKey: string; // Clé API (requis)
  baseURL?: string; // URL de l'API (optionnel)
  webURL?: string; // URL de la page de paiement (optionnel)
  sandbox?: boolean; // Mode test (optionnel)
}
```

### Méthodes

#### createPaymentLink()

Crée un lien de paiement unique.

```javascript
const payment = await monegasy.createPaymentLink({
  amount: 50000, // Montant en Ariary (requis)
  description: "Description", // Description (requis)
  productName: "Produit", // Nom du produit (optionnel)
  productImage: "https://...", // URL image (optionnel)
  metadata: { key: "value" }, // Données custom (optionnel)
  successUrl: "https://...", // URL succès (optionnel)
  cancelUrl: "https://...", // URL annulation (optionnel)
  webhookUrl: "https://...", // URL webhook (optionnel)
  expiresInHours: 24, // Expiration en heures (défaut: 24)
});

console.log(payment.paymentUrl); // URL de paiement web
console.log(payment.mobileDeepLink); // Deep link mobile
```

#### Paiement en plusieurs fois (3x, 4x, acompte+solde)

Vous pouvez proposer à vos clients de payer en plusieurs échéances. Avant ça, activez les modes voulus dans votre tableau de bord marchand sur [monegasy.com/merchant/installments](https://monegasy.com/merchant/installments).

Puis, par lien de paiement, activez la facilité :

```javascript
const payment = await monegasy.createPaymentLink({
  amount: 150000,
  description: "Smartphone Samsung Galaxy A15",
  installments: {
    enabled: true,
    // Optionnel : restreindre aux modes voulus pour CE lien
    allowedModes: ["3x", "4x"],
    // Pour le mode acompte+solde, on peut surcharger ici
    // depositPercentage: 30,
    // balanceDueDays: 7,
  },
});
```

Le client choisit son mode à la confirmation du paiement dans l'app Monegasy. La 1ère échéance (ou l'acompte) est prélevée immédiatement ; les suivantes le sont automatiquement aux dates planifiées.

**Webhooks reçus :**

| Événement                      | Quand                                         |
| ------------------------------ | --------------------------------------------- |
| `installment.plan_started`     | À la création du plan (1ère échéance ok)      |
| `installment.paid`             | À chaque échéance prélevée avec succès        |
| `installment.failed`           | Échéance ratée (solde insuffisant, retry à venir) |
| `installment.permanently_failed` | 3 retries épuisés — recouvrement manuel      |
| `plan.completed`               | Toutes les échéances prélevées                |
| `plan.cancelled`               | Plan annulé par vous ou l'admin               |

Pour écouter ces événements, configurez votre webhook dans le dashboard avec ces noms d'événements.

**Frais :** 0,5 % facturés au client par échéance, par défaut (configurable côté marchand). Vous recevez votre montant net comme pour un paiement classique (commission 1,5 %).

#### getPaymentLink()

Récupère les détails d'un paiement.

```javascript
const payment = await monegasy.getPaymentLink("pl_abc123");
console.log(payment.status); // "pending" | "paid" | "expired" | "cancelled"
```

#### openPaymentPopup()

Ouvre le paiement dans une popup.

```javascript
const popup = monegasy.openPaymentPopup("pl_abc123", {
  width: 500,
  height: 700,
});
```

#### redirectToPayment()

Redirige vers la page de paiement.

```javascript
monegasy.redirectToPayment("pl_abc123");
```

#### renderPaymentButton()

Crée et affiche un bouton de paiement.

```javascript
await monegasy.renderPaymentButton(
  {
    amount: 50000,
    description: "Achat produit",
    buttonText: "Payer maintenant",
    buttonStyle: {
      background: "linear-gradient(to right, #2563eb, #9333ea)",
      borderRadius: "12px",
    },
    onSuccess: (payment) => {
      console.log("✅ Paiement réussi!", payment);
    },
    onError: (error) => {
      console.error("❌ Erreur:", error);
    },
    onCancel: () => {
      console.log("ℹ️ Paiement annulé");
    },
  },
  "#payment-container"
);
```

## 🌐 Utilisation avec Frameworks

### React

```tsx
import { useEffect } from "react";
import MonegasySDK from "monegasy-js";

function PaymentButton({ amount, productName }) {
  useEffect(() => {
    const monegasy = new MonegasySDK({
      apiKey: process.env.REACT_APP_MONEGASY_API_KEY,
      sandbox: false,
    });

    monegasy.renderPaymentButton(
      {
        amount,
        description: `Achat ${productName}`,
        productName,
        onSuccess: (payment) => {
          window.location.href = `/success?id=${payment.linkId}`;
        },
      },
      "#monegasy-button"
    );
  }, [amount, productName]);

  return <div id="monegasy-button"></div>;
}
```

### Vue.js

```vue
<template>
  <div ref="paymentButton"></div>
</template>

<script>
import { onMounted, ref } from "vue";
import MonegasySDK from "monegasy-js";

export default {
  props: ["amount", "productName"],
  setup(props) {
    const paymentButton = ref(null);

    onMounted(() => {
      const monegasy = new MonegasySDK({
        apiKey: import.meta.env.VITE_MONEGASY_API_KEY,
        sandbox: false,
      });

      monegasy.renderPaymentButton(
        {
          amount: props.amount,
          description: `Achat ${props.productName}`,
          productName: props.productName,
        },
        paymentButton.value
      );
    });

    return { paymentButton };
  },
};
</script>
```

### Next.js

```tsx
"use client";

import { useEffect } from "react";
import MonegasySDK from "monegasy-js";

export default function PaymentButton({ amount, productName }) {
  useEffect(() => {
    const monegasy = new MonegasySDK({
      apiKey: process.env.NEXT_PUBLIC_MONEGASY_API_KEY!,
      sandbox: false,
    });

    monegasy.renderPaymentButton(
      {
        amount,
        description: `Achat ${productName}`,
        onSuccess: (payment) => {
          window.location.href = `/success?id=${payment.linkId}`;
        },
      },
      "#monegasy-button"
    );
  }, [amount, productName]);

  return <div id="monegasy-button"></div>;
}
```

## 🔒 Sécurité

- Ne jamais exposer votre clé API publiquement
- Utilisez des variables d'environnement
- Validez toujours les montants côté serveur

## 📖 Documentation Complète

Pour plus d'informations, consultez :

- [Documentation officielle](https://docs.monegasy.com)
- [Guide d'intégration](https://docs.monegasy.com/integration)
- [API Reference](https://docs.monegasy.com/api)

## 🐛 Support

- Email: support@monegasy.com
- GitHub: [Issues](https://github.com/monegasy/sdk/issues)
- Discord: [Communauté Monegasy](https://discord.gg/monegasy)

## 📝 Licence

MIT © Monegasy

---

**Fait avec ❤️ à Madagascar 🇲🇬**
