claude-home/productivity/n8n/workflows/kofi-testing-guide.md
Cal Corum 4b7eca8a46
All checks were successful
Reindex Knowledge Base / reindex (push) Successful in 3s
docs: add YAML frontmatter to all 151 markdown files
Adds title, description, type, domain, and tags frontmatter to every
doc for improved KB semantic search. The description field is prepended
to every search chunk, and domain/type/tags enable filtered queries.

Type values: context, guide, runbook, reference, troubleshooting
Domain values match directory structure (networking, docker, etc.)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 09:00:44 -05:00

676 lines
18 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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