--- title: "Ko-fi Integration Testing Guide" description: "Testing procedures for the Ko-fi to Paper Dynasty n8n workflow with 8 cURL test scenarios, validation scripts, checklists for security/performance/edge cases, and production monitoring guidelines." type: runbook domain: productivity tags: [n8n, ko-fi, paper-dynasty, testing, webhook, curl, validation] --- # 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:** 1. Open workflow in n8n 2. Click "Execute Workflow" button 3. Workflow will wait at Webhook node 4. Use cURL or Postman to send test payload 5. 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:** 1. Ko-fi → Settings → API → Webhooks 2. Set webhook URL to test path 3. Click "Test Webhook" button 4. 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:** 1. Create test products in Ko-fi shop ($0.01 minimum) 2. Make test purchases 3. Verify packs granted in Paper Dynasty 4. Check Discord notifications --- ### Phase 5: Production Deployment Switch to production webhook path and monitor. **Objective:** Deploy to production with confidence **Steps:** 1. Switch webhook path from `/webhook-test/` to `/webhook/` 2. Update Ko-fi webhook URL 3. Monitor first 10 transactions manually 4. 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:** ```bash 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:** ```bash 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:** ```bash 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:** ```bash 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:** ```bash 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:** ```bash 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:** ```bash 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:** ```bash 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` ```javascript // 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` ```python #!/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:** ```bash # 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:** 1. Copy token exactly from Ko-fi dashboard 2. Check n8n credential name matches IF node reference 3. No extra spaces or quotes in token value 4. Re-create credential if needed ### Issue: Team Not Found **Cause:** Discord user ID or team abbrev doesn't exist in PD **Fix:** ```python # 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:** 1. Check API response body in n8n execution log 2. Verify team_id is correct 3. Check pack_type_id is valid 4. Query PD database directly: ```python api.list_packs(team_id=69, opened=False, limit=20) ``` ### Issue: Discord Notification Not Sent **Cause:** Discord webhook URL invalid or permissions issue **Fix:** 1. Test Discord webhook directly: ```bash curl -X POST 'DISCORD_WEBHOOK_URL' \ -H 'Content-Type: application/json' \ -d '{"content": "Test notification"}' ``` 2. Regenerate webhook in Discord if needed 3. 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