Skip to content

fix(upi): M4.3.3 provider verification integrity review — remove currency defaults & status merchant fallback - #33

Open
Satelink-Protocol wants to merge 1 commit into
feature/m4-3-2-financial-integrityfrom
feature/m4-3-3-provider-verification
Open

Satelink-Protocol wants to merge 1 commit into
feature/m4-3-2-financial-integrityfrom
feature/m4-3-3-provider-verification

Conversation

@Satelink-Protocol

Copy link
Copy Markdown
Contributor

Summary

This PR delivers the M4.3.3 Final Provider Verification Integrity Review, closing critical verification fallback vectors, removing manufactured currency defaults, enforcing fail-closed provider merchant verification, documenting Core Banking Solution (CBS) manual refund operational limits, and verifying isolation between client return redirects and payment confirmation.

1. Remove Currency Defaults from Verification Paths

  • Adapter Level (lib/upi/adapter.js):
    • PhonePeAdapter.getPaymentStatus: Extracted currency faithfully from data.currency (data.currency ? String(data.currency).trim().toUpperCase() : null). Removed hardcoded currency: 'INR'.
    • PhonePeAdapter.verifyWebhook: Extracted currency faithfully from data.currency (data.currency !== undefined && data.currency !== null ? String(data.currency).trim().toUpperCase() : null). Removed hardcoded currency: 'INR'.
    • MockUpiAdapter: Propagates explicit currency from simulated status or webhook payload without default.
  • Service Level (lib/services/upi-payments.js):
    • getUpiPaymentStatus: Polling verification passes provider-returned currency directly (currency: gatewayStatus.currency) without defaulting to 'INR'.
    • processUpiWebhook: Webhook processing passes verified currency directly (currency: verified.currency) without defaulting to 'INR'.
    • applySuccessfulUpiPayment: Confirmation logic rejects missing, null, empty, or mismatched currency (missing_currency / currency_mismatch), maintaining fail-closed behavior and recording immutable audit entries.

2. Remove Merchant Identity Fallback in Provider Status Verification

  • Adapter Level (lib/upi/adapter.js):
    • PhonePeAdapter.getPaymentStatus: Removed fallback to this.merchantId. Returns exact provider data data.merchantId ? String(data.merchantId).trim() : null.
    • Disclosed PhonePe v1 API limitation: standard domestic status response does not guarantee echo of merchantId in all configurations; where omitted, it remains null rather than manufacturing identity.
  • Service Level (lib/services/upi-payments.js):
    • applySuccessfulUpiPayment: Enforces strict three-way identity comparison: provider-verified merchant ID (verifiedMerchantId), stored payment intent merchant ID (storedMerchantId), and server-configured merchant ID (configuredMerchantId). Rejects any missing, empty, or mismatched merchant identity before confirmation (merchant_mismatch).

3. Review Provider Status Authenticity & Invariant Gating

  • Verified server-to-server authenticated requests: status polling executes HMAC SHA256 / SHA256 authenticated HTTP calls (X-VERIFY: SHA256(endpoint + saltKey) + '###' + saltIndex).
  • Atomic verification of amount, order ID, merchant identity, and currency in a single transactional gate.
  • Isolation of client return URLs: confirmed that browser redirects (/checkout/upi/return) never confirm payments or create bookings; they merely redirect the user to polling/order status screens.
  • Webhook & polling deduplication remains strictly idempotent.
  • Non-terminal and terminal failure states (pending, failed, disputed, tampered) never create confirmed bookings, tickets, or Telegram invites.

4. Manual Refund Operational Limitation & Attestation

  • Documented Core Banking Solution (CBS) operational limitation: external UTR/reference strings attest operator action and retain audit evidence, but cannot prove external bank ledger clearance without CBS / direct bank statement integration.
  • Labeled manual reconciliation audit entries explicitly with operator_attested: true and bankVerified: false.
  • Gated manual reconciliation exclusively to authenticated active admin sessions with server-side identity resolution; dummy/placeholder references (REFUND123, TEST, 000000, etc.) are rejected.

5. Test Suite Verification

  • UPI Unit/Integration Suite: 37/37 tests passed (including extensive M4.3.3 regression suites for currency, merchant fallback, return URL spoofing, and manual refund attestation).
  • PostgreSQL Full Suite: 470 passed, 2 skipped, 0 failed across all 26 test files.
  • Migration Suite: 8/8 passed.
  • Linter: 140/140 files clean (0 errors).
  • Playwright E2E & Accessibility Suite: 157 passed, 11 skipped, 0 failed across all mobile and desktop viewports.

Governance

  • Base branch: feature/m4-3-2-financial-integrity
  • ENABLE_LIVE_PAYMENTS=false preserved.
  • No live payments or refunds initiated.
  • Stop for independent owner review. Do not merge.

@vercel

vercel Bot commented Nov 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
strangersmeetup Ready Ready Preview Nov 4, 2026 10:11am UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant