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
Metode de Plată Suportate
Credit Cards
Carduri de credit și debit (Visa, Mastercard, Amex)
Apple Pay
Plăți mobile prin Apple Pay
Google Pay
Plăți mobile prin Google Pay
Bank Transfer
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
Creează Cont Stripe
Înregistrează-te pe Stripe și completează profilul de business.
stripe.com → Register → Complete Business ProfileGenerează API Keys
Obține publishable key și secret key pentru integrare.
Configurează Webhooks
Setează endpoint-uri pentru evenimente de plată.
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.