Credits are the platform currency used to generate AI photos and unlock premium style collections.
Credit System
Credit Costs
Cost per AI photo transformation
One-time cost to unlock premium style packs
Purchasing Credits
Available Credit Packs
Current credit packages for B2C users (prices in ARS):
Starter
500 credits
$4,000 ARS
5 AI generations
Standard
1,100 credits
$8,000 ARS
11 AI generations
(+10% bonus)
Business
1,500 credits
$10,000 ARS
15 AI generations
(+20% bonus)
Payment Integration
MercadoPago integration for Latin America:
const handlePayment = async (pack) => {
const { data } = await supabase.functions.invoke('mercadopago-payment', {
body: {
user_id: session.user.id,
credits: pack.credits,
price: pack.price,
pack_name: pack.name,
redirect_url: window.location.origin
}
});
// Redirect to MercadoPago checkout
window.location.href = data.init_point;
};
Payment Flow
Select Pack
Choose credit amount from pricing page
MercadoPago Redirect
Secure checkout on MercadoPago platform
Payment Processing
Credit card, debit, or cash payment options
Webhook Confirmation
MercadoPago notifies platform of successful payment
Credits Added
Balance updated automatically in user profile
Premium Style Packs
Available Packs
Premium style collections for 3,000 credits each:
John Wick
Superhéroes
Peaky Blinders
Formula 1
8 Styles - 3,000 credits
- Baba Yaga
- The Continental
- High Table Legacy
- Excommunicado
- Desert Assassin
- Ballerina Soul
- Osaka Night
- Last Stand
7 Styles - 3,000 credits
- The Avenger
- Legacy of Thor
- Cosmic Guardian
- Emerald Might
- Justice Knight
- Knight Alt I
- Knight Alt II
4 Styles - 3,000 credits
- Thomas Shelby
- Birmingham Streets
- Garrison Pub
- The Razor Edge
4 Styles - 3,000 credits
- Red Bull Racing
- Ferrari Team
- Mercedes AMG
- Pit Stop Vibe
Unlocking Packs
const handleUnlockPack = async (subCategory) => {
// Verify balance
if (profile.credits < PREMIUM_PACK_PRICE) {
setShowPricing(true);
return;
}
// Update profile
const newUnlockedPacks = [...(profile.unlocked_packs || []), subCategory];
const newCredits = profile.credits - PREMIUM_PACK_PRICE;
const { error } = await supabase
.from('profiles')
.update({
credits: newCredits,
unlocked_packs: newUnlockedPacks
})
.eq('id', session.user.id);
// Confetti celebration!
confetti({
particleCount: 100,
spread: 70,
origin: { y: 0.6 }
});
};
Premium pack unlocks are permanent and non-refundable. Make sure you want the pack before confirming.
Credit Balance Display
Always-visible credit counter in navigation:
<div className="flex items-center gap-2 px-4 py-2 bg-black/40 rounded-full">
<Zap className="w-4 h-4 text-yellow-400" />
<span className="font-bold">{profile.credits.toLocaleString()}</span>
<span className="text-xs text-white/40">créditos</span>
</div>
Low Balance Warning
Alert when credits drop below generation cost:
if (profile.credits < 100) {
return (
<div className="bg-red-500/20 border border-red-500/40 p-4 rounded-xl">
<AlertTriangle className="w-5 h-5" />
<p>Saldo bajo. Recarga créditos para seguir generando.</p>
<button onClick={() => setShowPricing(true)}>Comprar Créditos</button>
</div>
);
}
Partner & Event Credits
Partner Credit Allocation
Partners purchase credits in bulk:
- Minimum: 1,000 credits
- No maximum limit
- Wholesale pricing (contact admin)
- No expiration date
Event Credit Assignment
Partners allocate credits to events:
const handleCreateEvent = async (eventData) => {
// Deduct from partner balance
const newPartnerBalance = partner.credits - eventData.credits_allocated;
// Create event with allocation
await supabase.from('events').insert({
...eventData,
credits_allocated: eventData.credits_allocated,
credits_used: 0,
partner_id: partner.id
});
// Update partner balance
await supabase
.from('partners')
.update({ credits: newPartnerBalance })
.eq('id', partner.id);
};
Credit Top-Up
Add credits to running events:
Open Event
Navigate to event in partner dashboard
Click Top-Up
Credit card icon in event header
Enter Amount
Specify additional credits (1-1000)
Confirm Transfer
Credits moved from partner to event atomically
Credit Consumption
Per Generation
Each AI photo costs 100 credits:
// User generation
await supabase
.from('profiles')
.update({ credits: profile.credits - 100 })
.eq('id', userId);
// Event generation (atomic)
await supabase.rpc('event_generation', {
event_id: eventId,
user_id: userId
});
Refund Policy
Credits refunded if generation fails:
catch (error) {
// Refund on failure
await supabase
.from('profiles')
.update({ credits: profile.credits + 100 })
.eq('id', userId);
showToast('Error en generación. Créditos devueltos.', 'error');
}
Connection timeouts do NOT refund credits - the generation continues in the cloud.
Transaction History
All credit movements logged:
interface Transaction {
id: string;
user_id: string;
amount: number; // Positive = credit, negative = debit
type: 'purchase' | 'generation' | 'pack_unlock' | 'refund' | 'transfer';
details: object;
created_at: timestamp;
}
View in profile history:
const { data: transactions } = await supabase
.from('transactions')
.select('*')
.eq('user_id', userId)
.order('created_at', { ascending: false });
Daily Limits
Free users limited to 2 generations per day:
const today = new Date();
today.setHours(0, 0, 0, 0);
const { count } = await supabase
.from('generations')
.select('*', { count: 'exact', head: true })
.eq('user_id', userId)
.gte('created_at', today.toISOString());
if (count >= 2) {
showToast('Máximo de impresiones del día alcanzado.', 'error');
return;
}
Daily limits reset at midnight (00:00 server time). Premium users and events have no daily limits.