[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EG8SKRZP7J4P46Q1FJ9MPJ":3,"skill-same:01M6EG8SKRZP7J4P46Q1FJ9MPJ":69},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":26,"linkOnly":27,"markdownContent":28,"markdownBody":28,"frontMatter":29,"refName":30,"commitSha":31,"skillDirectory":32,"forksCount":33,"repositoryHtmlUrl":34,"repositoryHomepageUrl":35,"ownerHtmlUrl":36,"ownerBlogUrl":6,"ownerDescription":37,"updatedAt":38,"install":39,"resources":52},"01M6EG8SKRZP7J4P46Q1FJ9MPJ","stripe-testing",null,"ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FTerminalSkills\u002Fskills\u002Fstripe-testing\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[23,24,25],"testing","stripe","stripe testing","2026-11-10 10:12:30",false,"# Stripe Testing\n\n## Overview\n\nThis skill helps you test and debug Stripe payment integrations end-to-end. It covers webhook verification, payment flow simulation using Stripe CLI and test mode, charge failure diagnosis, and subscription lifecycle validation.\n\n## Instructions\n\n### Setting Up the Test Environment\n\n1. Verify Stripe CLI is installed: `stripe --version`\n2. Check for a test API key in environment variables (`STRIPE_SECRET_KEY` starting with `sk_test_`)\n3. If no key is found, instruct the user to set one from the Stripe Dashboard → Developers → API keys\n4. Run `stripe listen --forward-to localhost:\u003Cport>\u002Fwebhooks\u002Fstripe` to forward webhooks locally\n\n### Debugging Failed Charges\n\n1. Ask for the payment intent ID or charge ID (starts with `pi_` or `ch_`)\n2. Retrieve details: `stripe payment_intents retrieve \u003Cid> --api-key $STRIPE_SECRET_KEY`\n3. Check the `last_payment_error` field for the decline reason\n4. Common decline codes and fixes:\n   - `card_declined` → Use test card `4000000000000002` to reproduce\n   - `insufficient_funds` → Test with `4000000000009995`\n   - `expired_card` → Test with `4000000000000069`\n   - `incorrect_cvc` → Test with `4000000000000127`\n5. Check the Events tab: `stripe events list --limit 5 --api-key $STRIPE_SECRET_KEY`\n\n### Testing Webhook Handlers\n\n1. List registered webhook endpoints: `stripe webhook_endpoints list --api-key $STRIPE_SECRET_KEY`\n2. Trigger a specific event: `stripe trigger \u003Cevent_type>` (e.g., `stripe trigger payment_intent.succeeded`)\n3. Verify the local server received and processed the event correctly\n4. Check webhook signature verification in the handler code — look for `stripe.webhooks.constructEvent()`\n5. Common webhook events to test:\n   - `checkout.session.completed`\n   - `invoice.payment_succeeded`\n   - `invoice.payment_failed`\n   - `customer.subscription.updated`\n   - `customer.subscription.deleted`\n\n### Validating Subscription Lifecycle\n\n1. Create a test customer: `stripe customers create --name \"Test User\" --email test@example.com --api-key $STRIPE_SECRET_KEY`\n2. Create a subscription with a test clock for time simulation:\n   ```\n   stripe test_clocks create --frozen-time $(date +%s) --api-key $STRIPE_SECRET_KEY\n   ```\n3. Advance the test clock to simulate billing cycles:\n   ```\n   stripe test_clocks advance \u003Cclock_id> --frozen-time \u003Cfuture_timestamp> --api-key $STRIPE_SECRET_KEY\n   ```\n4. Verify subscription status transitions: `trialing` → `active` → `past_due` → `canceled`\n\n### Reading Server-Side Logs\n\n1. Search the application logs for Stripe-related entries (look for `stripe`, `webhook`, `payment`)\n2. Check for HTTP 4xx\u002F5xx responses to Stripe webhook deliveries\n3. Verify idempotency — duplicate webhook deliveries should not create duplicate records\n\n## Examples\n\n### Example 1: Debug a Failed Checkout\n\n**User prompt:**\n```\nOur checkout is failing for some customers. The last failed payment intent is pi_3OxR2aKX8dVqS71m0abc1234. Can you figure out what's going wrong?\n```\n\n**Agent actions:**\n```bash\nstripe payment_intents retrieve pi_3OxR2aKX8dVqS71m0abc1234 --api-key $STRIPE_SECRET_KEY\n```\n\n**Agent output:**\n```\nPayment Intent pi_3OxR2aKX8dVqS71m0abc1234:\n  Status: requires_payment_method\n  Last error: card_declined (generic_decline)\n  Amount: $49.00 USD\n  Customer: cus_PqR7xYz\n\nAnalysis:\n1. The card was declined with a generic decline — this means the issuing bank refused it\n2. This is NOT a code issue — the customer's bank rejected the charge\n3. Your error handling looks correct — the PI moved to requires_payment_method\n\nRecommendations:\n- Ensure your frontend shows a clear \"card declined\" message\n- Offer alternative payment methods (Apple Pay, Google Pay, bank transfer)\n- Check if you have retry logic for `invoice.payment_failed` webhooks\n```\n\n### Example 2: Verify Webhook Handler Works\n\n**User prompt:**\n```\nI just deployed a new webhook handler for subscription cancellations. Can you test it?\n```\n\n**Agent actions:**\n```bash\nstripe listen --forward-to localhost:3000\u002Fapi\u002Fwebhooks\u002Fstripe &\nstripe trigger customer.subscription.deleted\n```\n\n**Agent output:**\n```\nWebhook forwarding active on localhost:3000\u002Fapi\u002Fwebhooks\u002Fstripe\n\nTriggered: customer.subscription.deleted\n  → Delivered to localhost:3000\u002Fapi\u002Fwebhooks\u002Fstripe [200 OK] in 145ms\n\nVerified:\n✓ Webhook received and acknowledged with 200\n✓ Signature verification passed (using whsec_ signing secret)\n✓ Event type correctly matched to handler\n\nNext steps:\n- Check your database: was the subscription marked as canceled?\n- Verify the customer received a cancellation email\n- Test edge case: trigger it twice to confirm idempotency\n```\n\n## Guidelines\n\n- Always use test mode keys (`sk_test_`) — never use live keys for testing\n- Use Stripe's built-in test card numbers rather than real card data\n- Test clocks are essential for subscription testing — they let you fast-forward time\n- Always verify webhook signature validation is implemented correctly\n- Check for race conditions: webhooks can arrive before the redirect completes\n- Monitor the Stripe Dashboard → Developers → Webhooks for delivery failures\n- Use `--api-key` flag explicitly rather than relying on environment to avoid mistakes\n",{},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002FTerminalSkills\u002Fskills\u002Fstripe-testing",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":7,"skillName":5,"commands":40,"prompt":50,"zipAvailable":51},[41,44,47],{"tool":42,"command":43},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill stripe-testing",{"tool":45,"command":46},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill stripe-testing",{"tool":48,"command":49},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill stripe-testing","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FTerminalSkills\u002Fskills\u002Fstripe-testing\u002FSKILL.md",true,[53,59,65],{"path":54,"resourceType":55,"resourceTypeDesc":56,"sizeBytes":57,"sourceHtmlUrl":58},"checklist.md","REFERENCE","参考文档",1792,"https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start\u002Fblob\u002Fmain\u002F.qwen\u002Fskills\u002Fgds-performance-test\u002Fchecklist.md",{"path":60,"resourceType":61,"resourceTypeDesc":62,"sizeBytes":63,"sourceHtmlUrl":64},"customize.toml","OTHER","其他",1638,"https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start\u002Fblob\u002Fmain\u002F.qwen\u002Fskills\u002Fgds-performance-test\u002Fcustomize.toml",{"path":66,"resourceType":55,"resourceTypeDesc":56,"sizeBytes":67,"sourceHtmlUrl":68},"performance-template.md",5859,"https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start\u002Fblob\u002Fmain\u002F.qwen\u002Fskills\u002Fgds-performance-test\u002Fperformance-template.md",[70,82,92,101,107,114],{"skillNo":71,"name":72,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":73,"categories":74,"keywords":78,"publishedAt":26},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[75],{"categoryNo":76,"categoryName":77,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",[79,80,81],"model","model hierarchy","model hierarchy skill",{"skillNo":83,"name":84,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":88,"publishedAt":26},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[87],{"categoryNo":76,"categoryName":77,"taxonomyType":20,"taxonomyTypeDesc":21},[89,90,91],"MCP","zoom","zoom mcp",{"skillNo":93,"name":94,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":97,"publishedAt":26},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[98,99,100,90],"sdk","zoom apps sdk","apps",{"skillNo":102,"name":103,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":104,"categories":105,"keywords":106,"publishedAt":26},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[103],{"skillNo":108,"name":109,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":110,"categories":111,"keywords":113,"publishedAt":26},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[112],{"categoryNo":76,"categoryName":77,"taxonomyType":20,"taxonomyTypeDesc":21},[109],{"skillNo":115,"name":116,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":119,"publishedAt":26},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[116]]