Agent Skills
› NeverSight/learn-skills.dev
› payment-credit-system
payment-credit-system
GitHub指导Dukaan AI实现支付流程、信用扣减及Razorpay集成。包含订阅计划与广告包定价、信用规则,以及Flutter端与Worker端的订单创建和支付验证API交互规范。
Trigger Scenarios
实现支付功能
管理信用额度
处理订阅续费
接入Razorpay
Install
npx skills add NeverSight/learn-skills.dev --skill payment-credit-system -g -y
SKILL.md
Frontmatter
{
"name": "payment-credit-system",
"description": "Use this skill whenever implementing payment flows, credit deduction, subscription management, or Razorpay integration in Dukaan AI. Contains the exact plans, pricing, credit rules, Razorpay flow, and Worker API contract for payments."
}
Dukaan AI — Payment & Credit System
Plans Reference (Hard-coded in Flutter)
| Tier | Price | Monthly Ads | Key Features |
|---|---|---|---|
| Free | ₹0 | 3/month | Basic BG styles only |
| Dukaan | ₹99/month | 30/month | All BG styles, Hindi captions |
| Vyapaar | ₹199/month | 100/month | Everything + Khata + Catalogue |
| Utsav | ₹499/month | 500/month | Everything + bulk WhatsApp |
Ad Packs (One-time Purchase)
| Pack | Price | Credits |
|---|---|---|
| Chhota | ₹29 | 10 ads |
| Bada | ₹59 | 25 ads |
| Super | ₹99 | 50 ads |
Credit Rules
- 1 credit = 1 ad generated (background removal + background generation = 1 credit)
- Caption regeneration: free (no credit deduction)
- Catalogue creation: 2 credits
- UPI poster: free
- Khata entry: free
- Monthly plans reset credits on billing anniversary, not calendar month
- Free tier: 3 lifetime credits (no reset)
Razorpay Payment Flow
Step 1: Flutter requests order from Worker
// In PaymentRepository
final orderResponse = await cloudflareClient.post('/api/create-order', body: {
'userId': userId,
'planId': planId, // 'dukaan_monthly' | 'ad_pack_chhota' etc.
'amountPaise': amountPaise, // e.g. 9900 for ₹99
});
// Returns: { orderId, amount, currency: 'INR', keyId }
Step 2: Flutter opens Razorpay checkout
// In RazorpayDatasource
final options = {
'key': orderResponse.keyId,
'order_id': orderResponse.orderId,
'amount': orderResponse.amount,
'currency': 'INR',
'name': 'Dukaan AI',
'description': planDisplayName,
'prefill': {
'contact': userPhone,
},
'theme': {'color': '#FF6F00'},
'method': {'upi': true, 'card': false, 'netbanking': false, 'wallet': false},
};
_razorpay.open(options);
Step 3: Flutter sends payment result to Worker for verification
// In PaymentRepository — called in _handlePaymentSuccess callback
final verifyResponse = await cloudflareClient.post('/api/verify-payment', body: {
'userId': userId,
'razorpayOrderId': payment.orderId,
'razorpayPaymentId': payment.paymentId,
'razorpaySignature': payment.signature,
});
// On success: Worker updates DB tier/credits, returns { success, newTier, newCredits }
Step 4: Flutter invalidates providers
// After successful verification
ref.invalidate(profileProvider); // refreshes credits + tier
ref.invalidate(pricingProvider); // refreshes plan display
// Navigate to payment_success_screen
Worker: create-order Contract
Request (POST /api/create-order):
{
"userId": "uuid",
"planId": "dukaan_monthly",
"amountPaise": 9900
}
Response (success):
{
"success": true,
"data": {
"orderId": "order_xxx",
"amount": 9900,
"currency": "INR",
"keyId": "rzp_live_xxx"
}
}
Worker: verify-payment Contract
Request (POST /api/verify-payment):
{
"userId": "uuid",
"razorpayOrderId": "order_xxx",
"razorpayPaymentId": "pay_xxx",
"razorpaySignature": "hmac_hex"
}
Response (success):
{
"success": true,
"data": {
"newTier": "dukaan",
"newCredits": 30
}
}
CreditGuard Usage
Before any credit-consuming operation:
// lib/core/utils/credit_guard.dart
// Always call this before generateAd(), createCatalogue()
await CreditGuard.check(ref);
// Throws AppException.noCredits if credits_remaining == 0
// The exception is caught by AsyncValue.guard() and shows NoCreditsSheet
Plan IDs (Exact Strings — Never Change)
// Used in API calls and DB
'free'
'dukaan_monthly'
'vyapaar_monthly'
'utsav_monthly'
'ad_pack_chhota' // 10 credits, ₹29
'ad_pack_bada' // 25 credits, ₹59
'ad_pack_super' // 50 credits, ₹99
Copilot Rules
- Never update credits_remaining directly from Flutter — always via Worker verify-payment
- UPI-only checkout —
method: { upi: true, card: false }— target audience pays via UPI - Always invalidate profileProvider after payment — so credit display updates everywhere
- HMAC verification is mandatory — never trust Flutter-side payment confirmation
- Insert pending transaction before Razorpay order — so we have a record even if user closes app
Version History
- e0220ca Current 2026-07-05 23:21


