Inapoi la Integrari
💳

Stripe Integration

Integrează VAI Portal cu Stripe pentru procesare automată a plăților, managementul abonamentelor și tranzacții securizate direct din conversațiile AI.

Payment Processing

Procesează plăți direct din conversațiile cu agenții AI.

Secure Transactions

Tranzacții securizate cu conformitate PCI DSS.

Real-time Validation

Validare instantanee a cardurilor și conturilor.

Smart Routing

Rutează automat plățile către metodele preferate.

Arhitectura Integrării

VAI Portal

AI Conversations

Stripe API

Payment Processing

Stripe

Payment Gateway

REST API & Webhooks

Metode de Plată Suportate

Credit Cards

Suportat
2.9% + 30¢

Carduri de credit și debit (Visa, Mastercard, Amex)

Apple Pay

Suportat
2.9% + 30¢

Plăți mobile prin Apple Pay

Google Pay

Suportat
2.9% + 30¢

Plăți mobile prin Google Pay

Bank Transfer

Nu

Transferuri bancare directe

Cazuri de Utilizare

Product Purchases

Vinde produse și servicii direct prin conversații AI.


      VAI Agent → Product Selection → Stripe Payment → Order Confirmation
           ↓              ↓              ↓
      Cart Build    Payment Form    Transaction Complete
    

Subscription Management

Gestionează abonamente și plăți recurente.


      VAI Agent → Subscription Plan → Stripe Billing → Active Subscription
           ↓              ↓              ↓
      Plan Selection   Payment Setup   Recurring Billing
    

Service Payments

Colectează plăți pentru servicii și consultanță.


      VAI Agent → Service Quote → Stripe Checkout → Payment Processed
           ↓              ↓              ↓
      Price Quote   Payment Link    Service Confirmation
    

Exemple de Implementare

Stripe Payment Integration

// Stripe Payment Integration for VAI Portal
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

class StripePaymentIntegration {
  constructor() {
    this.stripe = stripe;
  }

  async createPaymentIntentFromVAI(paymentData) {
    const {
      amount,
      currency = 'ron',
      customerEmail,
      conversationId,
      agentType,
      productDetails,
      metadata = {}
    } = paymentData;

    try {
      // Create or retrieve customer
      const customer = await this.getOrCreateCustomer(customerEmail, metadata);

      // Create payment intent
      const paymentIntent = await this.stripe.paymentIntents.create({
        amount: this.convertToCents(amount),
        currency: currency,
        customer: customer.id,
        metadata: {
          conversation_id: conversationId,
          agent_type: agentType,
          product_details: JSON.stringify(productDetails),
          source: 'vai_agent',
          ...metadata
        },
        automatic_payment_methods: {
          enabled: true
        },
        payment_method_types: ['card', 'apple_pay', 'google_pay']
      });

      // Log payment intent creation
      await this.logPaymentEvent('payment_intent_created', {
        paymentIntentId: paymentIntent.id,
        conversationId,
        amount,
        currency,
        customerEmail
      });

      return {
        success: true,
        clientSecret: paymentIntent.client_secret,
        paymentIntentId: paymentIntent.id,
        amount: amount,
        currency: currency,
        customer: {
          id: customer.id,
          email: customer.email
        }
      };

    } catch (error) {
      console.error('Error creating payment intent:', error);
      return {
        success: false,
        error: error.message,
        code: error.code
      };
    }
  }

  async getOrCreateCustomer(email, metadata = {}) {
    try {
      // Search for existing customer
      const existingCustomers = await this.stripe.customers.list({
        email: email,
        limit: 1
      });

      if (existingCustomers.data.length > 0) {
        return existingCustomers.data[0];
      }

      // Create new customer
      const customer = await this.stripe.customers.create({
        email: email,
        metadata: {
          source: 'vai_portal',
          created_by: 'ai_agent',
          ...metadata
        }
      });

      return customer;

    } catch (error) {
      console.error('Error managing customer:', error);
      throw error;
    }
  }

  async createCheckoutSessionFromVAI(checkoutData) {
    const {
      items,
      customerEmail,
      conversationId,
      agentType,
      successUrl,
      cancelUrl,
      metadata = {}
    } = checkoutData;

    try {
      const customer = await this.getOrCreateCustomer(customerEmail, metadata);

      // Create line items
      const lineItems = items.map(item => ({
        price_data: {
          currency: item.currency || 'ron',
          product_data: {
            name: item.name,
            description: item.description || '',
            metadata: {
              conversation_id: conversationId,
              agent_type: agentType
            }
          },
          unit_amount: this.convertToCents(item.price)
        },
        quantity: item.quantity || 1
      }));

      // Create checkout session
      const session = await this.stripe.checkout.sessions.create({
        customer: customer.id,
        payment_method_types: ['card'],
        line_items: lineItems,
        mode: 'payment',
        success_url: successUrl || `${process.env.VAI_PORTAL_URL}/payment/success?session_id={CHECKOUT_SESSION_ID}`,
        cancel_url: cancelUrl || `${process.env.VAI_PORTAL_URL}/payment/cancel?session_id={CHECKOUT_SESSION_ID}`,
        metadata: {
          conversation_id: conversationId,
          agent_type: agentType,
          source: 'vai_agent',
          ...metadata
        },
        allow_promotion_codes: true,
        billing_address_collection: 'auto',
        customer_update: {
          address: 'auto'
        }
      });

      // Log checkout session creation
      await this.logPaymentEvent('checkout_session_created', {
        sessionId: session.id,
        conversationId,
        items: items,
        totalAmount: items.reduce((sum, item) => sum + (item.price * (item.quantity || 1)), 0)
      });

      return {
        success: true,
        checkoutUrl: session.url,
        sessionId: session.id
      };

    } catch (error) {
      console.error('Error creating checkout session:', error);
      return {
        success: false,
        error: error.message,
        code: error.code
      };
    }
  }

  async createSubscriptionFromVAI(subscriptionData) {
    const {
      priceId,
      customerEmail,
      conversationId,
      agentType,
      trialPeriodDays = 0,
      metadata = {}
    } = subscriptionData;

    try {
      const customer = await this.getOrCreateCustomer(customerEmail, metadata);

      // Create subscription
      const subscription = await this.stripe.subscriptions.create({
        customer: customer.id,
        items: [{
          price: priceId
        }],
        trial_period_days: trialPeriodDays,
        metadata: {
          conversation_id: conversationId,
          agent_type: agentType,
          source: 'vai_agent',
          ...metadata
        },
        payment_behavior: 'default_incomplete',
        payment_settings: {
          save_default_payment_method: 'on_subscription',
          payment_method_types: ['card']
        },
        expand: ['latest_invoice.payment_intent']
      });

      // Log subscription creation
      await this.logPaymentEvent('subscription_created', {
        subscriptionId: subscription.id,
        conversationId,
        priceId,
        trialPeriodDays
      });

      return {
        success: true,
        subscriptionId: subscription.id,
        clientSecret: subscription.latest_invoice.payment_intent.client_secret,
        status: subscription.status,
        current_period_start: subscription.current_period_start,
        current_period_end: subscription.current_period_end
      };

    } catch (error) {
      console.error('Error creating subscription:', error);
      return {
        success: false,
        error: error.message,
        code: error.code
      };
    }
  }

  async confirmPayment(paymentIntentId) {
    try {
      const paymentIntent = await this.stripe.paymentIntents.retrieve(paymentIntentId);

      if (paymentIntent.status === 'succeeded') {
        // Update VAI system with payment confirmation
        await this.updateVAIWithPaymentStatus(paymentIntent, 'confirmed');

        // Send confirmation to user
        await this.sendPaymentConfirmation(paymentIntent);

        return {
          success: true,
          status: paymentIntent.status,
          amount: paymentIntent.amount,
          currency: paymentIntent.currency,
          paymentMethod: paymentIntent.payment_method
        };
      } else {
        return {
          success: false,
          status: paymentIntent.status,
          message: 'Payment not completed'
        };
      }

    } catch (error) {
      console.error('Error confirming payment:', error);
      return {
        success: false,
        error: error.message
      };
    }
  }

  async processWebhook(event, signature) {
    try {
      const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;
      const eventVerified = this.stripe.webhooks.constructEvent(
        event,
        signature,
        webhookSecret
      );

      switch (eventVerified.type) {
        case 'payment_intent.succeeded':
          await this.handlePaymentSuccess(eventVerified.data.object);
          break;
        case 'payment_intent.payment_failed':
          await this.handlePaymentFailure(eventVerified.data.object);
          break;
        case 'invoice.payment_succeeded':
          await this.handleSubscriptionPayment(eventVerified.data.object);
          break;
        case 'customer.subscription.created':
          await this.handleSubscriptionCreated(eventVerified.data.object);
          break;
        default:
          console.log(`Unhandled event type: ${eventVerified.type}`);
      }

      return { success: true };

    } catch (error) {
      console.error('Webhook processing error:', error);
      return { success: false, error: error.message };
    }
  }

  async handlePaymentSuccess(paymentIntent) {
    try {
      const conversationId = paymentIntent.metadata.conversation_id;
      const agentType = paymentIntent.metadata.agent_type;

      // Update VAI system
      await fetch(`${process.env.VAI_API_URL}/payments/confirm`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${process.env.VAI_API_KEY}`
        },
        body: JSON.stringify({
          payment_intent_id: paymentIntent.id,
          conversation_id: conversationId,
          amount: paymentIntent.amount / 100,
          currency: paymentIntent.currency,
          status: 'succeeded',
          payment_method: paymentIntent.payment_method,
          customer_id: paymentIntent.customer,
          timestamp: new Date().toISOString()
        })
      });

      // Trigger post-payment actions in VAI
      await this.triggerPostPaymentActions(paymentIntent);

    } catch (error) {
      console.error('Error handling payment success:', error);
    }
  }

  async handlePaymentFailure(paymentIntent) {
    try {
      const conversationId = paymentIntent.metadata.conversation_id;

      // Update VAI system with failure
      await fetch(`${process.env.VAI_API_URL}/payments/failed`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${process.env.VAI_API_KEY}`
        },
        body: JSON.stringify({
          payment_intent_id: paymentIntent.id,
          conversation_id: conversationId,
          amount: paymentIntent.amount / 100,
          currency: paymentIntent.currency,
          status: 'failed',
          last_payment_error: paymentIntent.last_payment_error,
          timestamp: new Date().toISOString()
        })
      });

      // Schedule follow-up conversation
      await this.schedulePaymentFollowUp(paymentIntent);

    } catch (error) {
      console.error('Error handling payment failure:', error);
    }
  }

  async triggerPostPaymentActions(paymentIntent) {
    const { metadata } = paymentIntent;
    const productDetails = JSON.parse(metadata.product_details || '{}');

    try {
      // Send order confirmation
      await this.sendOrderConfirmation(paymentIntent, productDetails);

      // Update inventory if applicable
      if (productDetails.type === 'product') {
        await this.updateInventory(productDetails);
      }

      // Schedule delivery/service
      if (productDetails.requires_delivery) {
        await this.scheduleDelivery(paymentIntent, productDetails);
      }

      // Create follow-up tasks
      await this.createFollowUpTasks(paymentIntent, productDetails);

    } catch (error) {
      console.error('Error triggering post-payment actions:', error);
    }
  }

  async sendPaymentConfirmation(paymentIntent) {
    try {
      await fetch(`${process.env.VAI_API_URL}/email/send`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${process.env.VAI_API_KEY}`
        },
        body: JSON.stringify({
          to: paymentIntent.receipt_email,
          subject: 'Confirmare plată VAI Portal',
          template: 'payment_confirmation',
          data: {
            amount: (paymentIntent.amount / 100).toFixed(2),
            currency: paymentIntent.currency.toUpperCase(),
            payment_id: paymentIntent.id,
            date: new Date().toLocaleDateString('ro-RO')
          }
        })
      });
    } catch (error) {
      console.error('Error sending payment confirmation:', error);
    }
  }

  convertToCents(amount) {
    return Math.round(amount * 100);
  }

  async logPaymentEvent(eventType, data) {
    try {
      await fetch(`${process.env.VAI_API_URL}/analytics/log`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${process.env.VAI_API_KEY}`
        },
        body: JSON.stringify({
          event_type: eventType,
          platform: 'stripe',
          data: data,
          timestamp: new Date().toISOString()
        })
      });
    } catch (error) {
      console.error('Error logging payment event:', error);
    }
  }

  async getPaymentMethods(customerId) {
    try {
      const paymentMethods = await this.stripe.paymentMethods.list({
        customer: customerId,
        type: 'card'
      });

      return paymentMethods.data.map(method => ({
        id: method.id,
        type: method.type,
        card: {
          brand: method.card.brand,
          last4: method.card.last4,
          exp_month: method.card.exp_month,
          exp_year: method.card.exp_year
        },
        created: method.created
      }));

    } catch (error) {
      console.error('Error getting payment methods:', error);
      return [];
    }
  }

  async createRefund(paymentIntentId, amount = null, reason = 'requested_by_customer') {
    try {
      const refundData = {
        payment_intent: paymentIntentId,
        reason: reason
      };

      if (amount) {
        refundData.amount = this.convertToCents(amount);
      }

      const refund = await this.stripe.refunds.create(refundData);

      await this.logPaymentEvent('refund_created', {
        refundId: refund.id,
        paymentIntentId,
        amount: refund.amount / 100,
        reason
      });

      return {
        success: true,
        refundId: refund.id,
        amount: refund.amount / 100,
        status: refund.status
      };

    } catch (error) {
      console.error('Error creating refund:', error);
      return {
        success: false,
        error: error.message
      };
    }
  }
}

module.exports = StripePaymentIntegration;

Stripe Webhook Handler

// Stripe Webhook Handler for VAI Portal
const express = require('express');
const StripePaymentIntegration = require('./stripe-payment-integration');
const app = express();
app.use(express.raw({ type: 'application/json' }));

const stripeIntegration = new StripePaymentIntegration();

// Webhook endpoint
app.post('/webhooks/stripe', async (req, res) => {
  const sig = req.headers['stripe-signature'];
  const body = req.body;

  try {
    const result = await stripeIntegration.processWebhook(body, sig);
    
    if (result.success) {
      res.status(200).json({ received: true });
    } else {
      res.status(400).json({ error: result.error });
    }
    
  } catch (error) {
    console.error('Webhook error:', error);
    res.status(400).json({ error: error.message });
  }
});

// Payment intent creation endpoint
app.post('/api/stripe/payment-intent', async (req, res) => {
  try {
    const result = await stripeIntegration.createPaymentIntentFromVAI(req.body);
    res.json(result);
  } catch (error) {
    console.error('Error creating payment intent:', error);
    res.status(500).json({ error: 'Failed to create payment intent' });
  }
});

// Checkout session creation endpoint
app.post('/api/stripe/checkout', async (req, res) => {
  try {
    const result = await stripeIntegration.createCheckoutSessionFromVAI(req.body);
    res.json(result);
  } catch (error) {
    console.error('Error creating checkout session:', error);
    res.status(500).json({ error: 'Failed to create checkout session' });
  }
});

// Subscription creation endpoint
app.post('/api/stripe/subscription', async (req, res) => {
  try {
    const result = await stripeIntegration.createSubscriptionFromVAI(req.body);
    res.json(result);
  } catch (error) {
    console.error('Error creating subscription:', error);
    res.status(500).json({ error: 'Failed to create subscription' });
  }
});

// Payment confirmation endpoint
app.get('/api/stripe/confirm/:paymentIntentId', async (req, res) => {
  try {
    const { paymentIntentId } = req.params;
    const result = await stripeIntegration.confirmPayment(paymentIntentId);
    res.json(result);
  } catch (error) {
    console.error('Error confirming payment:', error);
    res.status(500).json({ error: 'Failed to confirm payment' });
  }
});

// Get customer payment methods
app.get('/api/stripe/payment-methods/:customerId', async (req, res) => {
  try {
    const { customerId } = req.params;
    const paymentMethods = await stripeIntegration.getPaymentMethods(customerId);
    res.json({ success: true, paymentMethods });
  } catch (error) {
    console.error('Error getting payment methods:', error);
    res.status(500).json({ error: 'Failed to get payment methods' });
  }
});

// Create refund endpoint
app.post('/api/stripe/refund', async (req, res) => {
  try {
    const { paymentIntentId, amount, reason } = req.body;
    const result = await stripeIntegration.createRefund(paymentIntentId, amount, reason);
    res.json(result);
  } catch (error) {
    console.error('Error creating refund:', error);
    res.status(500).json({ error: 'Failed to create refund' });
  }
});

// Payment success page
app.get('/payment/success', async (req, res) => {
  const { session_id } = req.query;
  
  try {
    // Verify session and get details
    const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
    const session = await stripe.checkout.sessions.retrieve(session_id);
    
    // Render success page with details
    res.render('payment-success', {
      session: session,
      success: true
    });
    
  } catch (error) {
    console.error('Error rendering success page:', error);
    res.render('payment-error', { error: 'Payment verification failed' });
  }
});

// Payment cancel page
app.get('/payment/cancel', async (req, res) => {
  const { session_id } = req.query;
  
  try {
    const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
    const session = await stripe.checkout.sessions.retrieve(session_id);
    
    res.render('payment-cancelled', {
      session: session,
      message: 'Payment was cancelled. You can try again.'
    });
    
  } catch (error) {
    console.error('Error rendering cancel page:', error);
    res.render('payment-error', { error: 'Could not retrieve session details' });
  }
});

const PORT = process.env.PORT || 3003;
app.listen(PORT, () => {
  console.log(`Stripe webhook server running on port ${PORT}`);
});

Ghid de Configurare

1

Creează Cont Stripe

Înregistrează-te pe Stripe și completează profilul de business.

stripe.com → Register → Complete Business Profile
2

Generează API Keys

Obține publishable key și secret key pentru integrare.

3

Configurează Webhooks

Setează endpoint-uri pentru evenimente de plată.

4

Testează Plățile

Folosește test cards pentru a verifica integrarea.

Beneficii

Plăți Instantanee

Procesare rapidă direct din conversații.

Securitate Maximă

Conformitate PCI DSS și protecție datelor.

Global Reach

Suport pentru multiple valute și țări.

Analytics Complet

Rapoarte detaliate despre tranzacții.

Pregătit pentru Stripe?

Integrează VAI Portal cu Stripe pentru a procesa plăți automatizat și a-ți monetiza conversațiile AI.