refactor: reorganize credit-related imports and enhance user feedback

- Updated import paths for credit-related actions and functions to improve module organization.
- Removed redundant refresh trigger declaration in CreditPackages component.
- Simplified success toast message in CreditPackages and PaymentForm components for clarity.
- Introduced a new credits.ts file to centralize credit management logic and improve maintainability.
This commit is contained in:
javayhu 2025-07-06 00:15:07 +08:00
parent e933844479
commit 75083b32e4
6 changed files with 170 additions and 8 deletions

View File

@ -6,7 +6,7 @@ import {
addRegisterGiftCredits,
consumeCredits,
getUserCredits,
} from '@/lib/credits';
} from '@/credits/credits';
import { getSession } from '@/lib/server';
import { confirmPaymentIntent, createPaymentIntent } from '@/payment';
import { createSafeActionClient } from 'next-safe-action';

View File

@ -19,6 +19,7 @@ export function CreditPackages() {
const [loadingCredits, setLoadingCredits] = useState(true);
const [loadingPackage, setLoadingPackage] = useState<string | null>(null);
const [credits, setCredits] = useState<number | null>(null);
const { refreshTrigger } = useTransactionStore();
const [paymentDialog, setPaymentDialog] = useState<{
isOpen: boolean;
packageId: string | null;
@ -29,8 +30,6 @@ export function CreditPackages() {
clientSecret: null,
});
const { refreshTrigger } = useTransactionStore();
const fetchCredits = async () => {
try {
setLoadingCredits(true);
@ -86,7 +85,7 @@ export function CreditPackages() {
packageId: null,
clientSecret: null,
});
toast.success('Your credits have been added to your account');
toast.success('Credits have been added to your account');
};
const handlePaymentCancel = () => {

View File

@ -116,12 +116,12 @@ function PaymentForm({
if (result?.data?.success) {
console.log('PaymentForm, payment success');
toast.success(`${packageInfo.credits} credits have been added to your account.`);
// Trigger refresh for transaction-dependent UI components
triggerRefresh();
// Show success toast
onPaymentSuccess();
// toast.success(`${packageInfo.credits} credits have been added to your account.`);
} else {
console.error('PaymentForm, payment error:', result?.data?.error);
throw new Error( result?.data?.error || 'Failed to confirm payment' );

163
src/credits/README.md Normal file
View File

@ -0,0 +1,163 @@
# Credit Management System Implementation
## Overview
This document describes the credit management system implementation for the mksaas-template project, which allows users to purchase credits using Stripe payments.
## Features Implemented
### 1. Credit Packages
- Defined credit packages with different tiers (Basic, Standard, Premium, Enterprise)
- Each package includes credits amount, price, and description
- Popular package highlighting
### 2. Payment Integration
- Stripe PaymentIntent integration for credit purchases
- Secure payment processing with webhook verification
- Automatic credit addition upon successful payment
### 3. UI Components
- Credit balance display with refresh functionality
- Credit packages selection interface
- Stripe payment form integration
- Modern, responsive design
### 4. Database Integration
- Credit transaction recording
- User credit balance management
- Proper error handling and validation
## Files Created/Modified
### Core Components
- `src/components/dashboard/credit-packages.tsx` - Main credit packages interface
- `src/components/dashboard/credit-balance.tsx` - Credit balance display
- `src/components/dashboard/stripe-payment-form.tsx` - Stripe payment integration
### Actions & API
- `src/actions/credits.action.ts` - Credit-related server actions
- `src/app/api/webhooks/stripe/route.ts` - Stripe webhook handler
- `src/payment/index.ts` - Payment provider interface (updated)
- `src/payment/types.ts` - Payment types (updated)
### Configuration
- `src/lib/constants.ts` - Credit packages configuration
- `env.example` - Environment variables template
### Pages
- `src/app/[locale]/(protected)/settings/credits/page.tsx` - Credits management page
## Environment Variables Required
Add these to your `.env.local` file:
```env
# Stripe Configuration
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_test_..."
STRIPE_SECRET_KEY="sk_test_..."
STRIPE_WEBHOOK_SECRET="whsec_..."
```
## Setup Instructions
### 1. Stripe Configuration
1. Create a Stripe account at https://dashboard.stripe.com
2. Get your API keys from the Stripe dashboard
3. Set up a webhook endpoint pointing to `/api/webhooks/stripe`
4. Copy the webhook secret and add it to your environment variables
### 2. Database Setup
Make sure your database schema includes the required credit tables as defined in `src/db/schema.ts`.
### 3. Environment Variables
Copy the required environment variables from `env.example` to your `.env.local` file and fill in the values.
## Usage
### For Users
1. Navigate to `/settings/credits`
2. View current credit balance
3. Select a credit package
4. Complete payment using Stripe
5. Credits are automatically added to account
### For Developers
```typescript
// Get user credits
const result = await getCreditsAction();
// Create payment intent
const paymentIntent = await createCreditPaymentIntent({
packageId: 'standard'
});
// Add credits manually
await addCredits({
userId: 'user-id',
amount: 100,
type: 'PURCHASE',
description: 'Credit purchase'
});
```
## Credit Packages Configuration
Edit `src/lib/constants.ts` to modify available credit packages:
```typescript
export const CREDIT_PACKAGES = [
{
id: 'basic',
credits: 100,
price: 9.99,
popular: false,
description: 'Perfect for getting started',
},
// ... more packages
];
```
## Webhook Events
The system handles these Stripe webhook events:
- `payment_intent.succeeded` - Adds credits to user account upon successful payment
## Security Features
1. **Webhook Verification**: All webhook requests are verified using Stripe signatures
2. **Payment Validation**: Amount and package validation before processing
3. **User Authentication**: All credit operations require authenticated users
4. **Metadata Validation**: Payment metadata is validated before processing
## Error Handling
The system includes comprehensive error handling for:
- Invalid payment attempts
- Network failures
- Database errors
- Authentication issues
- Webhook verification failures
## Testing
To test the credit purchase flow:
1. Use Stripe test cards (e.g., `4242424242424242`)
2. Monitor webhook events in Stripe dashboard
3. Check credit balance updates in the application
## Integration Notes
This implementation:
- Uses Next.js server actions for secure server-side operations
- Integrates with existing Drizzle ORM schema
- Follows the existing payment provider pattern
- Maintains consistency with the existing codebase architecture
## Future Enhancements
Potential improvements:
- Credit transaction history display
- Credit expiration management
- Bulk credit operations
- Credit usage analytics
- Subscription-based credit allocation

View File

@ -8,7 +8,7 @@ import {
CREDIT_TRANSACTION_TYPE,
FREE_MONTHLY_CREDITS,
REGISTER_GIFT_CREDITS,
} from './constants';
} from '../lib/constants';
/**
* Get user's current credit balance

View File

@ -7,7 +7,7 @@ import {
findPriceInPlan,
} from '@/lib/price-plan';
import { sendNotification } from '@/notification/notification';
import { addCredits } from '@/lib/credits';
import { addCredits } from '@/credits/credits';
import { CREDIT_TRANSACTION_TYPE } from '@/lib/constants';
import { desc, eq } from 'drizzle-orm';
import { Stripe } from 'stripe';