xiaohongshu
xiaohongshu
jvzoo-integration
Expert JVZoo integration specialist for building backend systems that handle JVZoo purchases, create user accounts, manage software licenses, and process IPN notifications. Use when implementing JVZoo product licensing, account creation workflows, payment processing, refund handling, or connectin...
Full skill instructions
Expert guidance for building production-ready JVZoo integrations that handle purchases, license management, and account creation.
JVZoo integration involves three core components:
Your IPN endpoint must:
Always verify IPN authenticity using SHA-1 hash:
Verification Hash = SHA1(secretKey + "|" + transactionId + "|" + amount + "|" + productId)
Compare this hash with the cverify parameter sent by JVZoo. Never process unverified IPNs.
Transaction Info:
ctransaction - Transaction ID (use as idempotency key)ctransaction_type - SALE, RFND (refund), CGBK (chargeback), INSTAL (recurring), CANCEL-REBILLctransreceipt - JVZoo receipt numbercproditem - Product ID (your product identifier)cprodtype - STANDARD, RECURRING, etc.Customer Info:
ccustemail - Customer email (primary identifier)ccustname - Customer full nameccustcc - Customer country codeccuststate - Customer state/regionFinancial Info:
ctransamount - Sale amountctransaffiliate - Affiliate commissionctransvendor - Your earningsVerification:
cverify - SHA-1 hash for verificationfunction verifyIPN(ipnData, secretKey) {
const { ctransaction, ctransamount, cproditem, cverify } = ipnData;
const hash = crypto
.createHash('sha1')
.update(`${secretKey}|${ctransaction}|${ctransamount}|${cproditem}`)
.digest('hex')
.toUpperCase();
return hash === cverify.toUpperCase();
}
async function isDuplicateTransaction(transactionId) {
// Query database for existing transaction
const existing = await db.transactions.findOne({
jvzoo_transaction_id: transactionId
});
return !!existing;
}
async function processNewSale(ipnData) {
const { ccustemail, ccustname, cproditem, ctransaction } = ipnData;
// Find or create user
let user = await db.users.findOne({ email: ccustemail });
if (!user) {
user = await db.users.create({
email: ccustemail,
name: ccustname,
created_via: 'jvzoo',
jvzoo_transaction: ctransaction
});
}
return user;
}
function generateLicenseKey(userId, productId, transactionId) {
const timestamp = Date.now();
const data = `${userId}:${productId}:${transactionId}:${timestamp}`;
const hash = crypto
.createHash('sha256')
.update(data + process.env.LICENSE_SECRET)
.digest('hex');
// Format: XXXX-XXXX-XXXX-XXXX
return hash.substring(0, 16).toUpperCase().match(/.{1,4}/g).join('-');
}
async function createLicense(userId, productId, ipnData) {
const licenseKey = generateLicenseKey(
userId,
productId,
ipnData.ctransaction
);
const license = await db.licenses.create({
user_id: userId,
product_id: productId,
license_key: licenseKey,
jvzoo_transaction: ipnData.ctransaction,
jvzoo_receipt: ipnData.ctransreceipt,
status: 'active',
purchase_date: new Date(),
transaction_type: ipnData.ctransaction_type
});
// Send email with license key and login details
await sendWelcomeEmail(userId, licenseKey);
return license;
}
case 'SALE':
await processNewSale(ipnData);
await createLicense(user.id, ipnData.cproditem, ipnData);
break;
case 'RFND':
await db.licenses.update(
{ jvzoo_transaction: ipnData.ctransaction },
{ status: 'refunded', refunded_at: new Date() }
);
await revokeAccess(user.id);
break;
case 'CGBK':
await db.licenses.update(
{ jvzoo_transaction: ipnData.ctransaction },
{ status: 'chargeback', chargeback_at: new Date() }
);
await revokeAccess(user.id);
break;
case 'INSTAL':
await db.licenses.update(
{ jvzoo_transaction: ipnData.ctransaction },
{
status: 'active',
last_payment: new Date(),
payment_count: { $inc: 1 }
}
);
break;
case 'CANCEL-REBILL':
await db.licenses.update(
{ jvzoo_transaction: ipnData.ctransaction },
{
status: 'cancelled',
cancelled_at: new Date()
}
);
// Grace period before revoking access
await scheduleAccessRevocation(user.id, 30); // 30 days
break;
Build an API endpoint your software calls to validate licenses:
// POST /api/validate-license
async function validateLicense(req, res) {
const { license_key, email } = req.body;
const license = await db.licenses.findOne({
license_key: license_key,
status: 'active'
});
if (!license) {
return res.json({ valid: false, error: 'Invalid license' });
}
const user = await db.users.findById(license.user_id);
if (user.email !== email) {
return res.json({ valid: false, error: 'Email mismatch' });
}
// Update last validation timestamp
await db.licenses.update(
{ _id: license._id },
{ last_validated: new Date() }
);
return res.json({
valid: true,
license: {
product_id: license.product_id,
expiry_date: license.expiry_date,
features: license.features
}
});
}
CREATE TABLE users (
id UUID PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255),
created_via VARCHAR(50),
jvzoo_transaction VARCHAR(255),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE licenses (
id UUID PRIMARY KEY,
user_id UUID REFERENCES users(id),
product_id VARCHAR(100) NOT NULL,
license_key VARCHAR(50) UNIQUE NOT NULL,
jvzoo_transaction VARCHAR(255) UNIQUE NOT NULL,
jvzoo_receipt VARCHAR(255),
status VARCHAR(50) NOT NULL, -- active, refunded, chargeback, cancelled
purchase_date TIMESTAMP NOT NULL,
expiry_date TIMESTAMP,
last_validated TIMESTAMP,
transaction_type VARCHAR(50),
refunded_at TIMESTAMP,
chargeback_at TIMESTAMP,
cancelled_at TIMESTAMP,
payment_count INTEGER DEFAULT 1,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE jvzoo_transactions (
id UUID PRIMARY KEY,
jvzoo_transaction_id VARCHAR(255) UNIQUE NOT NULL,
transaction_type VARCHAR(50) NOT NULL,
product_id VARCHAR(100) NOT NULL,
customer_email VARCHAR(255) NOT NULL,
amount DECIMAL(10,2),
raw_ipn_data JSONB,
processed BOOLEAN DEFAULT FALSE,
processed_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW()
);
Map JVZoo product IDs to your internal product identifiers:
const PRODUCT_MAPPING = {
'123456': {
name: 'AI Ranker Pro - Basic',
features: ['feature1', 'feature2'],
internal_id: 'ai-ranker-basic'
},
'123457': {
name: 'AI Ranker Pro - Premium',
features: ['feature1', 'feature2', 'feature3', 'feature4'],
internal_id: 'ai-ranker-premium'
},
'123458': {
name: 'Callfluent AI - Starter',
features: ['100-calls', 'basic-voices'],
internal_id: 'callfluent-starter'
}
};
function getProductConfig(jvzooProductId) {
return PRODUCT_MAPPING[jvzooProductId] || null;
}
Never hardcode credentials:
JVZOO_SECRET_KEY=your_secret_key_here
LICENSE_SECRET=separate_key_for_license_generation
DATABASE_URL=your_database_connection
SMTP_API_KEY=email_service_key
Protect your IPN endpoint from abuse:
const rateLimit = require('express-rate-limit');
const ipnLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // Max 100 requests per IP
message: 'Too many requests from this IP'
});
app.post('/ipn', ipnLimiter, handleIPN);
Always validate and sanitize IPN data:
function sanitizeIPNData(data) {
return {
ctransaction: String(data.ctransaction || '').trim(),
ccustemail: String(data.ccustemail || '').toLowerCase().trim(),
ccustname: String(data.ccustname || '').trim(),
cproditem: String(data.cproditem || '').trim(),
ctransamount: parseFloat(data.ctransamount || 0),
// ... sanitize all fields
};
}
Always return 200 OK to prevent retries, but log errors:
app.post('/ipn', async (req, res) => {
try {
// Always acknowledge receipt
res.status(200).send('OK');
// Process asynchronously
await processIPN(req.body);
} catch (error) {
// Log error but don't tell JVZoo about it
console.error('IPN Processing Error:', error);
await logError(error, req.body);
}
});
JVZoo provides test IPNs. Look for test indicators:
function isTestTransaction(ipnData) {
return ipnData.ctransaction.toLowerCase().includes('test') ||
ipnData.ccustemail.toLowerCase().includes('test');
}
Send test IPN to your endpoint:
curl -X POST https://yoursite.com/ipn \
-d "ctransaction=TEST123456" \
-d "[email protected]" \
-d "ccustname=Test User" \
-d "cproditem=123456" \
-d "ctransamount=97.00" \
-d "ctransaction_type=SALE" \
-d "cverify=YOUR_CALCULATED_HASH"
See references/nodejs-implementation.md for complete Express.js example with middleware, error handling, and database integration.
See references/python-implementation.md for FastAPI implementation with async handling and Pydantic validation.
See references/nextjs-implementation.md for serverless implementation using Next.js API routes with Supabase.
IPN not being received:
Hash verification failing:
Duplicate accounts created:
ctransactionLicense validation failing:
For fastest implementation, use scripts/setup_ipn_endpoint.js to generate boilerplate IPN handler with your framework of choice (Express, FastAPI, Next.js).
See references/deployment-guide.md for production deployment considerations including SSL, monitoring, logging, and backup strategies.
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience