@company-manager/docs
Integrations

Passerelles de Paiement

Guide d'intégration des passerelles de paiement dans Company Manager.

Passerelles de Paiement

Guide complet pour l'intégration des passerelles de paiement dans Company Manager.

Configuration

Stripe

// lib/payment/stripe.ts
import Stripe from 'stripe';

export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
  apiVersion: '2023-10-16',
  typescript: true,
});

export const config = {
  publicKey: process.env.NEXT_PUBLIC_STRIPE_KEY,
  webhookSecret: process.env.STRIPE_WEBHOOK_SECRET,
  paymentMethods: ['card', 'sepa_debit'],
};

PayPal

// lib/payment/paypal.ts
import { PayPalClient } from '@paypal/checkout-server-sdk';

export const paypal = new PayPalClient({
  clientId: process.env.PAYPAL_CLIENT_ID!,
  clientSecret: process.env.PAYPAL_CLIENT_SECRET!,
  environment: process.env.NODE_ENV === 'production' ? 'live' : 'sandbox',
});

Traitement des Paiements

Service de Paiement

// services/PaymentService.ts
class PaymentService {
  async createPayment(order: Order, method: PaymentMethod) {
    switch (method.type) {
      case 'stripe':
        return this.createStripePayment(order);
      case 'paypal':
        return this.createPayPalPayment(order);
      default:
        throw new Error(`Unsupported payment method: ${method.type}`);
    }
  }

  private async createStripePayment(order: Order) {
    const session = await stripe.checkout.sessions.create({
      line_items: order.items.map(this.mapToStripeItem),
      mode: 'payment',
      success_url: `${process.env.NEXT_PUBLIC_URL}/success?session_id={CHECKOUT_SESSION_ID}`,
      cancel_url: `${process.env.NEXT_PUBLIC_URL}/cancel`,
    });

    return { sessionId: session.id };
  }
}

Composants Client

// components/payment/StripeCheckout.tsx
import { loadStripe } from '@stripe/stripe-js';

const stripePromise = loadStripe(config.publicKey);

export const StripeCheckout: React.FC<Props> = ({ sessionId }) => {
  useEffect(() => {
    const redirect = async () => {
      const stripe = await stripePromise;
      await stripe?.redirectToCheckout({ sessionId });
    };
    redirect();
  }, [sessionId]);

  return <LoadingSpinner />;
};

Webhooks

Gestionnaire Stripe

// pages/api/webhooks/stripe.ts
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const sig = req.headers['stripe-signature']!;
  
  try {
    const event = stripe.webhooks.constructEvent(
      req.body,
      sig,
      config.webhookSecret
    );
    
    switch (event.type) {
      case 'payment_intent.succeeded':
        await handlePaymentSuccess(event.data.object);
        break;
      case 'payment_intent.failed':
        await handlePaymentFailure(event.data.object);
        break;
    }
    
    res.json({ received: true });
  } catch (err) {
    res.status(400).send(`Webhook Error: ${err.message}`);
  }
}

Gestionnaire PayPal

// pages/api/webhooks/paypal.ts
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { event_type, resource } = req.body;
  
  try {
    switch (event_type) {
      case 'PAYMENT.CAPTURE.COMPLETED':
        await handlePayPalSuccess(resource);
        break;
      case 'PAYMENT.CAPTURE.DENIED':
        await handlePayPalFailure(resource);
        break;
    }
    
    res.json({ received: true });
  } catch (err) {
    res.status(400).send(`Webhook Error: ${err.message}`);
  }
}

Remboursements

Gestion des Remboursements

// services/RefundService.ts
class RefundService {
  async createRefund(payment: Payment, amount?: number) {
    switch (payment.provider) {
      case 'stripe':
        return this.createStripeRefund(payment, amount);
      case 'paypal':
        return this.createPayPalRefund(payment, amount);
      default:
        throw new Error(`Unsupported provider: ${payment.provider}`);
    }
  }

  private async createStripeRefund(payment: Payment, amount?: number) {
    return stripe.refunds.create({
      payment_intent: payment.providerPaymentId,
      amount,
    });
  }
}

Rapprochement Bancaire

Service de Rapprochement

// services/ReconciliationService.ts
class ReconciliationService {
  async reconcilePayments(startDate: Date, endDate: Date) {
    const [stripePayments, paypalPayments] = await Promise.all([
      this.fetchStripePayments(startDate, endDate),
      this.fetchPayPalPayments(startDate, endDate),
    ]);

    const reconciliation = await this.matchPayments(
      stripePayments,
      paypalPayments
    );

    await this.saveReconciliation(reconciliation);
  }

  private async matchPayments(
    stripePayments: Payment[],
    paypalPayments: Payment[]
  ) {
    // Logique de rapprochement
  }
}

Sécurité

Validation des Paiements

// lib/payment/validation.ts
const validatePayment = (payment: Payment) => {
  // Vérification des montants
  if (payment.amount <= 0) {
    throw new Error('Invalid payment amount');
  }

  // Vérification de la devise
  if (!supportedCurrencies.includes(payment.currency)) {
    throw new Error('Unsupported currency');
  }

  // Vérification de la fraude
  if (payment.risk_score > RISK_THRESHOLD) {
    throw new Error('Payment flagged as risky');
  }
};

Bonnes Pratiques

  1. Sécurité

    • Validation des signatures webhook
    • Vérification des montants
    • Protection contre la fraude
  2. Fiabilité

    • Gestion des erreurs robuste
    • Idempotence des opérations
    • Journalisation complète
  3. Conformité

    • Respect des normes PCI DSS
    • Protection des données sensibles
    • Audit des transactions