- Add CONTEXT.md with ADHD-optimized task management patterns - Add troubleshooting guide for productivity tools - Add n8n workflow documentation including Ko-fi integration - Document n8n at LXC 210 (10.10.0.210) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
18 KiB
Ko-fi → Paper Dynasty Testing Guide
Comprehensive testing guide for the Ko-fi integration workflow.
Testing Phases
Phase 1: Local Development Testing
Test n8n workflow logic without involving Ko-fi.
Objective: Validate workflow nodes process data correctly
Method: Manual execution in n8n UI
Steps:
- Open workflow in n8n
- Click "Execute Workflow" button
- Workflow will wait at Webhook node
- Use cURL or Postman to send test payload
- Review execution results node-by-node
Phase 2: Webhook Testing with cURL
Test webhook endpoint with simulated Ko-fi payloads.
Objective: Verify webhook receives and parses Ko-fi data
Test URL: https://n8n.manticorum.com/webhook-test/kofi-paperdy
Phase 3: Ko-fi Test Webhook
Use Ko-fi's built-in webhook tester.
Objective: Validate integration with Ko-fi's actual webhook system
Steps:
- Ko-fi → Settings → API → Webhooks
- Set webhook URL to test path
- Click "Test Webhook" button
- Review n8n execution logs
Phase 4: Test Purchases
Make real purchases with test products.
Objective: End-to-end validation with real Ko-fi data
Steps:
- Create test products in Ko-fi shop ($0.01 minimum)
- Make test purchases
- Verify packs granted in Paper Dynasty
- Check Discord notifications
Phase 5: Production Deployment
Switch to production webhook path and monitor.
Objective: Deploy to production with confidence
Steps:
- Switch webhook path from
/webhook-test/to/webhook/ - Update Ko-fi webhook URL
- Monitor first 10 transactions manually
- Verify all flows working correctly
Test Payloads
Test 1: Basic Order with Discord User ID
Scenario: User with linked Discord account purchases 5 standard packs
cURL Command:
curl -X POST 'https://n8n.manticorum.com/webhook-test/kofi-paperdy' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'data={
"verification_token": "YOUR_KOFI_TOKEN_HERE",
"message_id": "test-001-discord",
"timestamp": "2025-11-13T12:00:00Z",
"type": "Shop Order",
"is_public": true,
"from_name": "Test Customer Discord",
"message": "Thanks for the packs!",
"amount": "5.00",
"url": "https://ko-fi.com/Home/CoffeeShop?txid=test-001",
"email": "[email protected]",
"currency": "USD",
"is_subscription_payment": false,
"is_first_subscription_payment": false,
"kofi_transaction_id": "test-001-discord-userid",
"shop_items": [
{
"direct_link_code": "pack-standard-5",
"variation_name": "5-Pack Standard",
"quantity": 1
}
],
"tier_name": null,
"shipping": null,
"discord_username": "TestUser#1234",
"discord_userid": "012345678901234567"
}'
Expected Result:
- ✅ Token validated
- ✅ Team found via discord_userid → gmid lookup
- ✅ 5 standard packs granted to team
- ✅ Success Discord notification sent
Test 2: Order with Team Abbrev in Message
Scenario: User without Discord link includes team abbreviation in message
cURL Command:
curl -X POST 'https://n8n.manticorum.com/webhook-test/kofi-paperdy' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'data={
"verification_token": "YOUR_KOFI_TOKEN_HERE",
"message_id": "test-002-abbrev",
"timestamp": "2025-11-13T12:05:00Z",
"type": "Shop Order",
"is_public": true,
"from_name": "Test Customer Abbrev",
"message": "Team: SKB - Thanks!",
"amount": "10.00",
"url": "https://ko-fi.com/Home/CoffeeShop?txid=test-002",
"email": "[email protected]",
"currency": "USD",
"is_subscription_payment": false,
"is_first_subscription_payment": false,
"kofi_transaction_id": "test-002-team-abbrev",
"shop_items": [
{
"direct_link_code": "pack-premium-10",
"variation_name": "10-Pack Premium",
"quantity": 1
}
],
"tier_name": null,
"shipping": null,
"discord_username": null,
"discord_userid": null
}'
Expected Result:
- ✅ Token validated
- ✅ Team "SKB" extracted from message
- ✅ Team found via abbrev lookup
- ✅ 10 premium packs granted to team
- ✅ Success Discord notification sent
Test 3: Multiple Items in Single Order
Scenario: User purchases multiple product types in one transaction
cURL Command:
curl -X POST 'https://n8n.manticorum.com/webhook-test/kofi-paperdy' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'data={
"verification_token": "YOUR_KOFI_TOKEN_HERE",
"message_id": "test-003-multi",
"timestamp": "2025-11-13T12:10:00Z",
"type": "Shop Order",
"is_public": true,
"from_name": "Test Customer Multi",
"message": "CAR",
"amount": "25.00",
"url": "https://ko-fi.com/Home/CoffeeShop?txid=test-003",
"email": "[email protected]",
"currency": "USD",
"is_subscription_payment": false,
"is_first_subscription_payment": false,
"kofi_transaction_id": "test-003-multiple-items",
"shop_items": [
{
"direct_link_code": "pack-standard-5",
"variation_name": "5-Pack Standard",
"quantity": 2
},
{
"direct_link_code": "pack-premium-5",
"variation_name": "5-Pack Premium",
"quantity": 1
},
{
"direct_link_code": "pack-team-choice",
"variation_name": "Team Choice Pack",
"quantity": 1
}
],
"tier_name": null,
"shipping": null,
"discord_username": null,
"discord_userid": null
}'
Expected Result:
- ✅ Token validated
- ✅ Team "CAR" found via abbrev
- ✅ 15 total packs granted (10 standard + 5 premium + 1 team choice)
- ✅ Success Discord notification with itemized list
Test 4: Team Not Found (Manual Review)
Scenario: User provides neither Discord ID nor valid team abbrev
cURL Command:
curl -X POST 'https://n8n.manticorum.com/webhook-test/kofi-paperdy' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'data={
"verification_token": "YOUR_KOFI_TOKEN_HERE",
"message_id": "test-004-unknown",
"timestamp": "2025-11-13T12:15:00Z",
"type": "Shop Order",
"is_public": true,
"from_name": "Unknown User",
"message": "I love Paper Dynasty!",
"amount": "5.00",
"url": "https://ko-fi.com/Home/CoffeeShop?txid=test-004",
"email": "[email protected]",
"currency": "USD",
"is_subscription_payment": false,
"is_first_subscription_payment": false,
"kofi_transaction_id": "test-004-manual-review",
"shop_items": [
{
"direct_link_code": "pack-standard-5",
"variation_name": "5-Pack Standard",
"quantity": 1
}
],
"tier_name": null,
"shipping": null,
"discord_username": null,
"discord_userid": null
}'
Expected Result:
- ✅ Token validated
- ❌ No team identified
- ⚠️ Manual review Discord notification sent with @here mention
- ⚠️ Admin grants packs manually after identifying user
Test 5: Unknown Product Code
Scenario: Ko-fi product code not in mapping
cURL Command:
curl -X POST 'https://n8n.manticorum.com/webhook-test/kofi-paperdy' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'data={
"verification_token": "YOUR_KOFI_TOKEN_HERE",
"message_id": "test-005-unknown-product",
"timestamp": "2025-11-13T12:20:00Z",
"type": "Shop Order",
"is_public": true,
"from_name": "Test Unknown Product",
"message": "SKB",
"amount": "99.99",
"url": "https://ko-fi.com/Home/CoffeeShop?txid=test-005",
"email": "[email protected]",
"currency": "USD",
"is_subscription_payment": false,
"is_first_subscription_payment": false,
"kofi_transaction_id": "test-005-unknown-product",
"shop_items": [
{
"direct_link_code": "pack-does-not-exist",
"variation_name": "Mystery Pack",
"quantity": 1
}
],
"tier_name": null,
"shipping": null,
"discord_username": null,
"discord_userid": null
}'
Expected Result:
- ✅ Token validated
- ✅ Team "SKB" found
- ❌ Product code "pack-does-not-exist" not in mapping
- ⚠️ Manual review Discord notification
- ⚠️ Admin adds product to mapping or processes manually
Test 6: Invalid Verification Token
Scenario: Test security - invalid Ko-fi token
cURL Command:
curl -X POST 'https://n8n.manticorum.com/webhook-test/kofi-paperdy' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'data={
"verification_token": "INVALID-TOKEN-12345",
"message_id": "test-006-invalid",
"timestamp": "2025-11-13T12:25:00Z",
"type": "Shop Order",
"is_public": true,
"from_name": "Hacker Attempt",
"message": "SKB",
"amount": "1000.00",
"url": "https://ko-fi.com/Home/CoffeeShop?txid=test-006",
"email": "[email protected]",
"currency": "USD",
"kofi_transaction_id": "test-006-security",
"shop_items": [
{
"direct_link_code": "pack-standard-5",
"variation_name": "5-Pack Standard",
"quantity": 100
}
],
"discord_userid": null
}'
Expected Result:
- ❌ Token validation fails
- ⛔ Workflow stops at validation node
- ⛔ NO packs granted
- ⛔ NO Discord notification (security - don't reveal valid tokens)
Test 7: Non-Shop Order Type
Scenario: Ko-fi sends donation (not shop order)
cURL Command:
curl -X POST 'https://n8n.manticorum.com/webhook-test/kofi-paperdy' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'data={
"verification_token": "YOUR_KOFI_TOKEN_HERE",
"message_id": "test-007-donation",
"timestamp": "2025-11-13T12:30:00Z",
"type": "Donation",
"is_public": true,
"from_name": "Generous Donor",
"message": "Keep up the great work!",
"amount": "10.00",
"url": "https://ko-fi.com/Home/CoffeeShop?txid=test-007",
"email": "[email protected]",
"currency": "USD",
"is_subscription_payment": false,
"kofi_transaction_id": "test-007-donation",
"shop_items": null,
"discord_userid": null
}'
Expected Result:
- ✅ Token validated
- ℹ️ Type is "Donation" not "Shop Order"
- ⏭️ Workflow skips processing (no packs to grant)
- ✅ Returns 200 OK to Ko-fi
Test 8: Monthly Subscription Payment
Scenario: Recurring subscription payment
cURL Command:
curl -X POST 'https://n8n.manticorum.com/webhook-test/kofi-paperdy' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'data={
"verification_token": "YOUR_KOFI_TOKEN_HERE",
"message_id": "test-008-subscription",
"timestamp": "2025-11-13T12:35:00Z",
"type": "Subscription",
"is_public": true,
"from_name": "Monthly Subscriber",
"message": "PPD",
"amount": "5.00",
"url": "https://ko-fi.com/Home/CoffeeShop?txid=test-008",
"email": "[email protected]",
"currency": "USD",
"is_subscription_payment": true,
"is_first_subscription_payment": false,
"kofi_transaction_id": "test-008-subscription",
"shop_items": [
{
"direct_link_code": "sub-monthly-standard",
"variation_name": "Monthly Standard Subscription",
"quantity": 1
}
],
"tier_name": "Standard Member",
"discord_username": "Subscriber#5678",
"discord_userid": "987654321098765432"
}'
Expected Result:
- ✅ Token validated
- ✅ Subscription payment processed as shop order
- ✅ 5 standard packs granted
- ✅ Success notification includes subscription tier
Testing Checklist
Pre-Deployment Testing
- Test 1: Basic order with Discord user ID ✅
- Test 2: Order with team abbrev in message ✅
- Test 3: Multiple items in single order ✅
- Test 4: Team not found (manual review) ⚠️
- Test 5: Unknown product code ⚠️
- Test 6: Invalid verification token ❌
- Test 7: Non-shop order type (donation) ⏭️
- Test 8: Monthly subscription payment ✅
Integration Testing
- Ko-fi webhook test button works
- Discord notifications received in correct channel
- Discord @here mentions work for errors
- Paper Dynasty API grants packs correctly
- API retry logic works (simulate timeout)
- Multiple webhooks handled concurrently
Security Testing
- Invalid tokens rejected
- No sensitive data in Discord notifications
- Webhook accessible only via HTTPS
- n8n basic auth required for UI access
- Credentials encrypted in n8n database
Performance Testing
- Webhook responds within 5 seconds
- Paper Dynasty API calls timeout correctly
- Large orders (20+ items) process successfully
- Concurrent webhooks don't cause issues
Edge Cases
- Empty shop_items array
- Null discord_userid and message fields
- Special characters in team abbrev
- Very large quantity (100+ packs)
- Product with quantity: 0
- Duplicate message_id (Ko-fi retry)
Monitoring & Alerts
- Success notifications readable
- Error notifications actionable
- Manual review requests clear
- n8n execution logs captured
- Failed executions visible in n8n UI
Validation Scripts
Verify Ko-fi Webhook Format
Script: validate-kofi-payload.js
// Run in n8n Code node or standalone Node.js
function validateKofiPayload(payload) {
const required = [
'verification_token',
'message_id',
'timestamp',
'type',
'from_name',
'amount',
'email',
'currency',
'kofi_transaction_id'
];
const missing = required.filter(field => !payload[field]);
if (missing.length > 0) {
throw new Error(`Missing required fields: ${missing.join(', ')}`);
}
if (payload.type === 'Shop Order' && !payload.shop_items) {
throw new Error('Shop Order missing shop_items array');
}
console.log('✅ Payload valid');
return true;
}
// Test
const testPayload = JSON.parse($json.body.data);
validateKofiPayload(testPayload);
Verify Paper Dynasty Pack Grant
Script: verify-pack-grant.py
#!/usr/bin/env python3
"""Verify packs were granted in Paper Dynasty"""
from api_client import PaperDynastyAPI
from datetime import datetime, timezone
api = PaperDynastyAPI(environment='prod', verbose=True)
# Get packs created in last hour
recent_packs = api.list_packs(opened=False, new_to_old=True, limit=100)
# Filter by timestamp
one_hour_ago = datetime.now(timezone.utc).timestamp() - 3600
for pack in recent_packs:
pack_time = pack.get('created_at', 0) / 1000
if pack_time > one_hour_ago:
team = api.get_team(team_id=pack['team'])
print(f"✅ Pack {pack['id']} granted to {team['abbrev']} at {datetime.fromtimestamp(pack_time)}")
Common Issues During Testing
Issue: Webhook 404 Not Found
Cause: Workflow not active or wrong webhook path
Fix:
# Check workflow is active in n8n UI
# Verify webhook path: n8n → Workflow → Webhook node → Path
# Test webhook accessibility
curl -I https://n8n.manticorum.com/webhook-test/kofi-paperdy
# Should return: 200 OK or 400 Bad Request (not 404)
Issue: Token Validation Failing
Cause: Token mismatch or credential not configured
Fix:
- Copy token exactly from Ko-fi dashboard
- Check n8n credential name matches IF node reference
- No extra spaces or quotes in token value
- Re-create credential if needed
Issue: Team Not Found
Cause: Discord user ID or team abbrev doesn't exist in PD
Fix:
# Check if discord_userid exists in PD
api.get('teams', params={'gmid': '012345678901234567'})
# Check if team abbrev exists
api.get('teams', params={'abbrev': 'SKB'})
# If not found, update user's PD profile or use manual review
Issue: Packs Not Granted
Cause: API request succeeded but packs not visible
Fix:
- Check API response body in n8n execution log
- Verify team_id is correct
- Check pack_type_id is valid
- Query PD database directly:
api.list_packs(team_id=69, opened=False, limit=20)
Issue: Discord Notification Not Sent
Cause: Discord webhook URL invalid or permissions issue
Fix:
- Test Discord webhook directly:
curl -X POST 'DISCORD_WEBHOOK_URL' \ -H 'Content-Type: application/json' \ -d '{"content": "Test notification"}' - Regenerate webhook in Discord if needed
- Update n8n credential with new URL
Production Monitoring
Daily Checks
- Review n8n execution logs (filter by workflow)
- Check for failed executions
- Review manual review Discord notifications
- Verify all orders processed successfully
Weekly Checks
- Review unknown product codes
- Update product mapping for new Ko-fi products
- Check Paper Dynasty pack distribution accuracy
- Review API response times
Monthly Checks
- Test disaster recovery procedure
- Backup n8n database
- Rotate Ko-fi verification token
- Update documentation with lessons learned
References
- Main Workflow Documentation:
kofi-paper-dynasty.md - Product Mapping Template:
kofi-product-mapping-template.json - Ko-fi Webhook Docs: https://help.ko-fi.com/hc/en-us/articles/360004162298
- Paper Dynasty API:
/home/cal/.claude/skills/paper-dynasty/SKILL.md
Change Log
2025-11-13 - Initial Version
- Created comprehensive testing guide
- Defined 8 test scenarios with cURL commands
- Added validation scripts and troubleshooting
- Documented testing checklist and monitoring procedures