payment-integration — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited payment-integration (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
When building or modifying payment flows, integrating payment providers (Stripe, PayPal, Braintree), handling subscriptions, processing refunds, or dealing with any money movement in the system. Also activates for PCI compliance considerations.
Core principle: Idempotency is life — every payment operation must be safe to retry without charging the customer twice. When in doubt, err on the side of NOT charging.
States:
created → processing → succeeded
→ failed → (retry) → processing
succeeded → refund_pending → refunded
succeeded → disputed → dispute_won (funds returned)
→ dispute_lost (funds lost)
State transitions:
- created → processing: charge initiated with provider
- processing → succeeded: provider confirms capture
- processing → failed: provider declines or errors
- succeeded → refund_pending: refund initiated
- refund_pending → refunded: provider confirms refundRules:
Idempotency key format: [user_id]-[order_id]-[attempt_number]
Example: usr_abc123-ord_xyz789-1
Rules:
- Generate idempotency key BEFORE calling payment provider
- Store key in database alongside payment intent
- If retry needed: increment attempt number, generate new key
- Provider stores result by key — retrying same key returns same result
- Key expiry: 24 hours (Stripe default) — don't retry after thatCritical: If the client retries (network timeout, unclear response), the idempotency key ensures no double charge. This is non-negotiable.
1. Verify signature FIRST (reject if invalid — no processing)
2. Respond 200 immediately (within 5 seconds)
3. Process the event ASYNCHRONOUSLY (queue for background processing)
4. Process IDEMPOTENTLY (same webhook delivered twice = same outcome)
5. Handle OUT-OF-ORDER delivery (payment_intent.succeeded before payment_intent.created)Implementation:
POST /webhooks/stripe
1. Verify: stripe.webhooks.constructEvent(body, sig, secret)
2. Dedup: check event.id against processed_events table
3. If already processed: return 200 (idempotent)
4. Queue: enqueue event for async processing
5. Return 200
6. [Async worker]: process event, update payment state, mark as processedRules:
Client-side tokenization flow:
1. User enters card → Stripe.js/Elements captures it
2. Card data goes DIRECTLY to Stripe (never touches your server)
3. Stripe returns a token/PaymentMethod ID
4. Your server uses the token to create charges
Your server NEVER sees: card number, CVV, expiration date
Your PCI scope: SAQ-A (lowest level — just a questionnaire)Rules:
States: trial → active → past_due → canceled → expired
trial → active: trial period ends, first charge succeeds
active → past_due: renewal charge fails
past_due → active: retry succeeds
past_due → canceled: all retries exhausted + grace period ended
canceled → active: user resubscribes (new subscription)Dunning (failed payment recovery):
Day 0: Charge fails → retry immediately
Day 1: Second retry
Day 3: Third retry + email notification ("update payment method")
Day 7: Final retry + urgent email + in-app banner
Day 14: Cancel subscription + final email ("your subscription has ended")Rules:
Every 24 hours:
1. Fetch all payments from provider API (last 48 hours, overlap for safety)
2. Match against internal payment records
3. Flag discrepancies:
- Payment in provider but not in our DB (missed webhook)
- Payment in our DB but not in provider (ghost record)
- Amount mismatch (partial capture, currency conversion)
- Status mismatch (we say succeeded, provider says failed)
4. Auto-resolve simple cases (missed webhook → replay)
5. Alert on unresolvable discrepancies (requires human review)Rules:
Before marking a task done when this skill was active:
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.