Skip to content

💳 Stripe API

Typ: REST API Auth: API Key (Secret + Publishable) Status: ✅ Marktführer Payments


Übersicht

Stripe für: - Anzahlungen (bei Bestellung) - Restzahlung (bei Auslieferung) - Finanzierungs-Raten (monatlich) - Zahlungsaufforderungen per Link - Automatisches Mahnwesen


API Endpoints

Methode Endpunkt Beschreibung Cache TTL
GET /api/payments/customers Alle Kunden 5min
GET /api/payments/customers/:id Kundendetails 1min
POST /api/payments/customers Kunde anlegen -
GET /api/payments/subscriptions Finanzierungs-Raten 1min
POST /api/payments/subscriptions Ratenzahlung erstellen -
POST /api/payments/invoices Rechnung erstellen -
POST /api/payments/payment-links Zahlungslink -
GET /api/payments/balance Kontostand 5min
GET /api/payments/transactions Transaktionen 1min

Stripe Integration für MORELO

import Stripe from 'stripe';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

// Käufer als Kunde anlegen
async function createBuyerCustomer(buyer: {
  name: string;
  email: string;
  phone?: string;
  address: string;
}) {
  return stripe.customers.create({
    name: buyer.name,
    email: buyer.email,
    phone: buyer.phone,
    address: {
      line1: buyer.address,
      country: 'DE'
    },
    metadata: {
      buyerId: buyer.id,
      vehicleId: buyer.vehicleId,
      dealerId: buyer.dealerId
    }
  });
}

// Finanzierungs-Ratenzahlung (Subscription)
async function createFinancingSubscription(
  customerId: string,
  monthlyRate: number,  // in Cents
  startDate: Date,
  durationMonths: number
) {
  // Produkt für das Fahrzeug
  const product = await stripe.products.create({
    name: `MORELO ${vehicleModel} - Finanzierung`,
    metadata: { vehicleId, dealerId }
  });

  // Preis (monatlich)
  const price = await stripe.prices.create({
    product: product.id,
    unit_amount: monthlyRate,
    currency: 'eur',
    recurring: {
      interval: 'month',
      interval_count: 1
    }
  });

  // Subscription mit Laufzeit-Ende
  return stripe.subscriptions.create({
    customer: customerId,
    items: [{ price: price.id }],
    billing_cycle_anchor: Math.floor(startDate.getTime() / 1000),
    cancel_at: Math.floor(new Date(startDate.getTime() + durationMonths * 30 * 24 * 60 * 60 * 1000).getTime() / 1000),
    payment_settings: {
      payment_method_types: ['sepa_debit', 'card']
    },
    metadata: {
      vehicleId,
      type: 'financing',
      durationMonths
    }
  });
}

// Einmalzahlung (Anzahlung, Restzahlung)
async function createVehiclePayment(
  customerId: string,
  amount: number,
  description: string, // "Anzahlung MORELO Palace 90G" oder "Restzahlung"
  vehicleId: string
) {
  const invoice = await stripe.invoices.create({
    customer: customerId,
    auto_advance: true,
    collection_method: 'send_invoice',
    days_until_due: 14,
    metadata: { vehicleId, type: 'vehicle_payment' }
  });

  await stripe.invoiceItems.create({
    customer: customerId,
    invoice: invoice.id,
    amount,
    currency: 'eur',
    description
  });

  return stripe.invoices.sendInvoice(invoice.id);
}

// Zahlungslink für schnelle Anzahlung
async function createDownPaymentLink(
  amount: number,
  vehicleModel: string,
  buyerEmail: string
) {
  const price = await stripe.prices.create({
    unit_amount: amount,
    currency: 'eur',
    product_data: {
      name: `Anzahlung ${vehicleModel}`
    }
  });

  return stripe.paymentLinks.create({
    line_items: [{ price: price.id, quantity: 1 }],
    after_completion: {
      type: 'redirect',
      redirect: { url: 'https://dealer.morelo.de/payment-success' }
    },
    metadata: {
      buyerEmail,
      vehicleModel,
      paymentType: 'down_payment'
    }
  });
}

Webhook Handler

app.post('/webhooks/stripe', async (req, res) => {
  const sig = req.headers['stripe-signature'];
  const event = stripe.webhooks.constructEvent(
    req.body,
    sig,
    process.env.STRIPE_WEBHOOK_SECRET
  );

  switch (event.type) {
    case 'invoice.paid':
      await recordPayment(event.data.object);
      break;

    case 'invoice.payment_failed':
      await handlePaymentFailure(event.data.object);
      break;

    case 'customer.subscription.deleted':
      await handleSubscriptionCancelled(event.data.object);
      break;
  }

  res.json({ received: true });
});

Umgebungsvariablen

# Stripe
STRIPE_SECRET_KEY="sk_live_..."
STRIPE_PUBLISHABLE_KEY="pk_live_..."
STRIPE_WEBHOOK_SECRET="whsec_..."

# Test-Modus
STRIPE_TEST_SECRET_KEY="sk_test_..."
STRIPE_TEST_PUBLISHABLE_KEY="pk_test_..."

Marktführer • SEPA + Karte • Subscriptions • Webhooks