refund-spam
v1.0.0
Published
Ultra Pro advanced fraud detection system for digital course marketplaces — multi-layer AI behavioral fingerprinting, auto-ban, evidence collection & payment gateway integration
Maintainers
Readme
refund-spam
Ultra-Pro Refund Fraud Detection for Digital Course Marketplaces
The Problem
Customers purchase digital courses, download all the content, then file a refund claim — getting the course for free. This pattern repeats across multiple accounts.
refund-spam stops this with a three-layer AI detection pipeline: behavioral analysis, pattern detection, and neural-network fraud scoring — all in a single await guard.check(user) call.
Features
| Feature | Description |
|---------|-------------|
| 3-Layer Detection | Behavioral analysis → rule-based patterns → AI neural network |
| Device Fingerprinting | SHA-256 multi-attribute fingerprint — survives IP/email changes |
| Account Linking | Detects alt-accounts with 75%+ attribute similarity |
| Auto-Ban | Instantly bans confirmed fraudsters across all linked devices |
| Evidence Collection | AES-256 encrypted access logs, download logs, payment info |
| Dispute Filing | Automatically files disputes with Stripe and PayPal |
| Stripe Integration | Full Stripe SDK integration with webhook verification |
| PayPal Integration | Axios-based PayPal REST integration with dispute handling |
| Redis Caching | Optional Redis layer for high-throughput deployments |
| CLI Tools | analyze and migrate CLI commands |
| Event System | EventEmitter API for real-time fraud notifications |
Quick Start
npm install refund-spamrequire('dotenv').config();
const RefundGuard = require('refund-spam');
const guard = new RefundGuard({
apiKey: process.env.REFUND_SPAM_API_KEY,
merchantId: process.env.MERCHANT_ID,
});
const result = await guard.check({
id: 'user_abc123',
email: '[email protected]',
ipAddress: '203.0.113.42',
purchaseCount: 3,
refundCount: 2,
}, {
ai: true,
ban: 'auto',
evidence: 'auto',
});
console.log(result.status); // 'FRAUD_DETECTED'
console.log(result.riskScore); // 88
console.log(result.action); // 'AUTO_BANNED'Installation
# npm
npm install refund-spam
# yarn
yarn add refund-spamRequirements: Node.js ≥ 14, MySQL 5.7+ or PostgreSQL 12+
See the full Installation Guide for database setup, Redis configuration, and Docker support.
Configuration
Copy the environment template:
cp node_modules/refund-spam/.env.example .envMinimum required variables:
REFUND_SPAM_API_KEY=your_api_key_here
MERCHANT_ID=your_merchant_id
DB_TYPE=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=refund_spam
DB_USER=refundspam
DB_PASSWORD=your_db_password
ENCRYPTION_KEY=your_32_byte_hex_key_64_chars_long
JWT_SECRET=your_jwt_secretSee .env.example for all available variables.
Core API
new RefundGuard(cfg)
const guard = new RefundGuard({
apiKey: 'rfg_live_...',
merchantId: 'merch_...',
environment: 'production', // or 'sandbox'
logLevel: 'warn',
});guard.check(user, options?)
Check a user for refund fraud. Returns a CheckResult.
const result = await guard.check(user, {
ai: true, // AI analysis (default: false)
ban: 'auto', // auto-ban confirmed fraud (default: false)
evidence: 'auto', // collect AES-256 evidence (default: false)
threshold: 0.30, // refund rate flag threshold (default: 0.30)
riskScore: 70, // minimum score to auto-ban (default: 70)
});Result shape:
{
userId: 'user_abc123',
status: 'FRAUD_DETECTED', // CLEAN | SUSPICIOUS | HIGH_RISK | FRAUD_DETECTED | BLACKLISTED
riskScore: 88, // 0–100
refundRate: 0.67, // 0.0–1.0
action: 'AUTO_BANNED', // NONE | FLAGGED | AUTO_BANNED
indicators: ['HIGH_REFUND_RATE', 'RAPID_CONTENT_DOWNLOAD'],
linkedAccounts: 2,
evidence: { accessLogs: 47, downloads: 12, encrypted: true },
timestamp: '2024-06-15T14:32:12.000Z'
}guard.analyzeRefundRequest(refundRequest, options?)
Webhook entry point — analyze a refund event from a payment gateway:
const analysis = await guard.analyzeRefundRequest({
userId: 'user_abc123',
refundId: 're_xyz789',
amount: 79.00,
currency: 'usd',
gateway: 'stripe',
raw: stripeEvent,
}, { ai: true, ban: 'auto', evidence: 'auto' });guard.disputeRefund(refundId, options?)
File a dispute with the payment gateway:
await guard.disputeRefund('re_xyz789', {
reason: 'customer_fraud',
evidence: analysis.evidence,
autoSubmit: true,
});guard.integrateWith(gateway, options?)
Get a gateway-specific connector:
const stripeConn = guard.integrateWith('stripe', { apiKey: process.env.STRIPE_SECRET_KEY });
const paypalConn = guard.integrateWith('paypal', { apiKey: process.env.PAYPAL_CLIENT_SECRET });RefundGuard.getInstance(cfg?)
Singleton access — initialize once, use everywhere:
// Initialize once in app.js
RefundGuard.getInstance({ apiKey: '...', merchantId: '...' });
// Reuse in any other file
const guard = RefundGuard.getInstance();Detection Pipeline
User Request
│
▼
RefundGuard
│
▼
DetectionEngine
├── Layer 1: BehaviorAnalyzer (refund rate, speed, content access %)
├── Layer 2: PatternDetector (rule-based indicators)
└── Layer 3: AIAnalyzer (neural network, 85 features, 3 models)
│
▼
RiskScorer (weighted composite score 0–100)
│
├── BanManager (auto-ban + device fingerprint block)
├── EvidenceCollector (AES-256 logs + downloads + payment info)
└── AuditLog (immutable append-only trail)Risk Score → Status:
| Score | Status | Default Action |
|-------|-----------------|----------------|
| 0–29 | CLEAN | NONE |
| 30–49 | SUSPICIOUS | FLAGGED |
| 50–69 | HIGH_RISK | FLAGGED |
| 70–89 | FRAUD_DETECTED| AUTO_BANNED* |
| 90–100| BLACKLISTED | AUTO_BANNED |
*Only when ban: 'auto' is set.
Stripe Integration
// express.raw() MUST come before express.json() for Stripe webhooks
app.use('/webhook/stripe', express.raw({ type: 'application/json' }));
app.use(express.json());
app.post('/webhook/stripe', async (req, res) => {
const event = stripe.webhooks.constructEvent(
req.body,
req.headers['stripe-signature'],
process.env.STRIPE_WEBHOOK_SECRET
);
if (event.type === 'charge.refund.updated') {
const analysis = await guard.analyzeRefundRequest({
userId: event.data.object.metadata.userId,
refundId: event.data.object.id,
gateway: 'stripe',
raw: event,
}, { ai: true, ban: 'auto', evidence: 'auto' });
if (analysis.status === 'FRAUD_DETECTED') {
await guard.disputeRefund(event.data.object.id, { autoSubmit: true });
}
}
res.json({ received: true });
});PayPal Integration
app.post('/webhook/paypal', async (req, res) => {
const { event_type, resource } = req.body;
if (event_type === 'PAYMENT.CAPTURE.REFUNDED') {
const analysis = await guard.analyzeRefundRequest({
userId: resource.custom_id,
refundId: resource.id,
gateway: 'paypal',
raw: req.body,
}, { ai: true, ban: 'auto', evidence: 'auto' });
if (analysis.status === 'FRAUD_DETECTED') {
await guard.disputeRefund(resource.id, { autoSubmit: true });
}
}
res.json({ received: true });
});Events
guard.on('fraud:detected', (result) => notifyAdmin(result));
guard.on('ban:applied', (ban) => logBan(ban));
guard.on('evidence:collected', (evid) => console.log('Evidence:', evid.refundId));
guard.on('check:complete', (result) => metrics.record(result.durationMs));
guard.on('error', (err) => Sentry.captureException(err));CLI
# Analyze a user by ID or email
npx refund-spam-analyze --userId=user_abc123
npx refund-spam-analyze [email protected]
# Database migrations
npx refund-spam-migrate migrate # run pending migrations
npx refund-spam-migrate seed # insert test dataTesting
# Run all tests
npm test
# Unit tests only
npm run test:unit
# Integration tests only
npm run test:integration
# With coverage
npm run test:coverageTests use Jest with --runInBand (sequential) and fully mock all database and gateway dependencies.
Examples
| File | Description |
|------|-------------|
| examples/basic-setup.js | Minimal fraud check |
| examples/with-stripe.js | Stripe webhook server |
| examples/with-paypal.js | PayPal webhook server |
| examples/advanced-config.js | AI + evidence + price-tier thresholds |
| examples/custom-webhooks.js | Combined Stripe + PayPal server |
Documentation
| Document | Description | |----------|-------------| | Installation | Full install, DB setup, Docker | | Quick Start | 5-minute setup guide | | API Reference | All methods, options, return types | | Architecture | Detection pipeline, DB schema, AI subsystem | | Examples | Complete runnable code examples | | Troubleshooting | Common errors and solutions |
Named Exports
const {
RefundGuard, // default export — main facade
DetectionEngine,
AIAnalyzer,
BanManager,
EvidenceCollector,
DatabaseManager,
UserStore,
RefundStore,
CacheManager,
AuditLog,
NotificationManager,
startServer, // starts the built-in Express API server
FraudStatus, // status constants
FraudAction, // action constants
FraudIndicators, // indicator constants
} = require('refund-spam');Fraud Indicators
| Indicator | Description |
|-----------|-------------|
| HIGH_REFUND_RATE | Refund rate exceeds threshold |
| FAST_REFUND_REQUEST | Refund within 48 hours of purchase |
| RAPID_CONTENT_DOWNLOAD | > 80% of content downloaded before refund |
| BINGE_AND_FLEE | All content accessed in one session, then immediate refund |
| LINKED_ACCOUNTS | Device fingerprint matches a flagged account |
Project Structure
refund-spam/
├── src/
│ ├── index.js Entry point + startServer()
│ ├── core/
│ │ ├── RefundGuard.js Main facade class
│ │ ├── DetectionEngine.js Pipeline orchestrator
│ │ └── AIAnalyzer.js AI subsystem
│ ├── detection/ BehaviorAnalyzer, Fingerprinter, PatternDetector, RiskScorer
│ ├── ai/ Models, preprocessing, training
│ ├── security/ BanManager, EncryptionService, AuditLog, AccessControl
│ ├── evidence/ EvidenceCollector, Storage, Exporter, ReportGenerator
│ ├── integrations/ Stripe + PayPal connectors, webhooks, dispute handlers
│ ├── database/ DatabaseManager, UserStore, RefundStore, migrations
│ ├── cache/ CacheManager + RedisAdapter
│ ├── notifications/ Email, Webhook, Alerts
│ ├── api/ Express routes, controllers, middleware
│ ├── utils/ Logger, helpers, validators, constants, errors
│ └── cli/ analyze.js, migrate.js
├── tests/
│ ├── unit/ refundguard, detection, ai, fingerprint
│ ├── integration/ stripe, paypal
│ └── fixtures/ fraudulent_users.json, legitimate_users.json
├── examples/ 5 runnable example files
├── docs/ 6 documentation files
└── .env.example Environment variable templateLicense
MIT © Your Company
Contributing
- Fork the repository
- Create your branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -m 'feat: add my feature' - Push to the branch:
git push origin feature/my-feature - Open a Pull Request
Please ensure all tests pass and coverage remains above 80% before submitting a PR.
