sepay-payments-and-qr

Diagnose and maintain SePay webhook reconciliation and VietQR payment generation flows.

1|Updated May 23, 2026
One-click install
npx skills add https://github.com/palfish-t-i-u/palfish-t-i-u-h-th-ng-ver-2 --skill sepay-payments-and-qr-palfish-t-i-u
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: sepay-payments-and-qr
Source: https://github.com/palfish-t-i-u/palfish-t-i-u-h-th-ng-ver-2/tree/main/.claude/skills/sepay-payments-and-qr
Command: npx skills add https://github.com/palfish-t-i-u/palfish-t-i-u-h-th-ng-ver-2 --skill sepay-payments-and-qr-palfish-t-i-u

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Payment reconciliation in the PalFish GMV system depends on matching SePay bank transfers to payment requests via transfer-content codes, and failures (unmatched transfers, stale QR content, amount discrepancies) are hard to debug without deep knowledge of the webhook pipeline, schema constraints, and cross-repo dependencies. ## Core Features & Use Cases - Webhook & matching pipeline reference: Documents the SePay webhook auth layers (IP whitelist, HMAC-SHA256, API key), the transaction processing order, and match_status semantics (pending, auto_matched, needs_review, ignored, manual_matched). - VietQR generation & stale-content handling: Explains the 40-character addInfo limit, transfer_code encoding, the is_content_stale detection logic, and the refresh-content endpoint. - Diagnostic procedures: Provides a step-by-step SQL workflow to diagnose unmatched transfers, plus gotchas like the pf-revenue cross-repo schema risk and the ambiguous-character fold matching fix. - Use Case: A customer paid but their transfer shows as unmatched; use this Skill to query bank_transactions, identify the match_status failure mode, and decide between cron re-poll or manual match. ## Quick Start Ask the assistant to diagnose why a specific SePay bank transfer did not auto-match its payment request, providing the amount and transaction date.

Frequently Asked Questions about sepay-payments-and-qr

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I diagnose a SePay transfer that did not match a payment request?

Query bank_transactions by amount and date, then read match_status: pending means no transfer_code was found, needs_review means amount mismatch, ignored means mPOS settle noise. Then verify the transfer_code against pending payment_lines and decide between re-running the cron poll or a manual match.

How does SePay webhook authentication work in this system?

The webhook applies three layers in order: IP whitelisting via SEPAY_ALLOWED_IPS, HMAC-SHA256 signature verification over timestamp plus raw body, and an API key fallback against SEPAY_WEBHOOK_SECRET. In production, a missing secret returns HTTP 503, and timestamps older than 300 seconds are rejected.

Why does the VietQR transfer content have a 40-character limit?

The img.vietqr.io service truncates addInfo at exactly 40 characters. The backend falls back through name-shortening tiers (full name, last words, phone plus code, code only) rather than cutting the Base36 transfer_code used for matching.

Can I change the bank_transactions schema safely?

Not without coordination. The separate pf-revenue repo reads bank_transactions from the shared production Supabase database on a 1-5 minute window to sync to Lark Base, so renaming or dropping columns can silently break that sync with no error surfaced in this repo.

Why did a customer transfer with the right code fail to auto-match?

Customers can hand-type ambiguous characters, such as lowercase l instead of uppercase I, which breaks exact matching. The system runs a second-pass fold matching I/L/1 and O/0, but only auto-matches on a unique candidate with exact amount; multiple hits go to manual review.

When should I not use this payment reconciliation skill?

Do not use it for mPOS/Payoo card portal imports, which live in gateway_routes.py and are reconciled manually, or for Zalo/DingTalk payment notifications and general RBAC/auth questions, which are covered by separate skills.