{
    "registry_version": "1.0.0",
    "released_on": "2026-10-13",
    "planned_allocation": {
        "GP": 16,
        "PH": 14,
        "PT": 14,
        "BH": 12,
        "AZ": 12,
        "WA": 12,
        "CR": 12,
        "NV": 12,
        "SM": 12,
        "GN": 16,
        "QR": 16,
        "AN": 12,
        "IO": 6
    },
    "planned_total": 166,
    "web_runnable_ceiling": 147,
    "parameter_profiles": {
        "P01": {
            "id": "P01",
            "name": "Standard merchant intent",
            "summary": "pa + pn + tr + am + cu",
            "what_it_isolates": "The control. Every other profile is this one plus something, so a failure here is a failure of the destination or the app, never of an optional field.",
            "keys": [
                "pa",
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "prerequisite": "none",
            "prerequisite_text": ""
        },
        "P02": {
            "id": "P02",
            "name": "With transaction note",
            "summary": "P01 + tn",
            "what_it_isolates": "Whether a note is displayed, truncated, stripped or rejected. Note length limits differ sharply between apps.",
            "keys": [
                "pa",
                "pn",
                "tr",
                "am",
                "cu",
                "tn"
            ],
            "prerequisite": "none",
            "prerequisite_text": ""
        },
        "P03": {
            "id": "P03",
            "name": "With merchant category code",
            "summary": "P01 + mc",
            "what_it_isolates": "THE most important comparison in the catalogue. Several apps switch from a person-to-person flow to a merchant flow when mc appears — changing limits, fees and whether the amount can be edited. P01 against P03 on the same app, same destination, same minute is the controlled experiment that shows it.",
            "keys": [
                "pa",
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "prerequisite": "none",
            "prerequisite_text": ""
        },
        "P04": {
            "id": "P04",
            "name": "Category code and note",
            "summary": "P01 + mc + tn",
            "what_it_isolates": "Whether the note survives the merchant flow. Some apps that show a note in a P2P flow drop it in a merchant one.",
            "keys": [
                "pa",
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "tn"
            ],
            "prerequisite": "none",
            "prerequisite_text": ""
        },
        "P05": {
            "id": "P05",
            "name": "Transaction reference URL",
            "summary": "P01 + url",
            "what_it_isolates": "Whether the app surfaces an invoice link, ignores it, or refuses the whole intent because of it.",
            "keys": [
                "pa",
                "pn",
                "tr",
                "am",
                "cu",
                "url"
            ],
            "prerequisite": "none",
            "prerequisite_text": ""
        },
        "P06": {
            "id": "P06",
            "name": "Category code and reference URL",
            "summary": "P01 + mc + url",
            "what_it_isolates": "The combination a real invoice-with-QR produces. Isolates interactions between the merchant flow and the invoice link.",
            "keys": [
                "pa",
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "url"
            ],
            "prerequisite": "none",
            "prerequisite_text": ""
        },
        "P07": {
            "id": "P07",
            "name": "Minimum amount",
            "summary": "P01 + mam",
            "what_it_isolates": "mam constrains an amount the payer may edit. Beside a fixed am it is contradictory, and WHICH ONE each app honours is the finding. The lab warns about the contradiction and sends it anyway — that is the experiment.",
            "keys": [
                "pa",
                "pn",
                "tr",
                "am",
                "cu",
                "mam"
            ],
            "prerequisite": "none",
            "prerequisite_text": ""
        },
        "P08": {
            "id": "P08",
            "name": "Category code and minimum amount",
            "summary": "P01 + mc + mam",
            "what_it_isolates": "Whether the merchant flow changes how mam is treated.",
            "keys": [
                "pa",
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "mam"
            ],
            "prerequisite": "none",
            "prerequisite_text": ""
        },
        "P09": {
            "id": "P09",
            "name": "Documented initiation metadata",
            "summary": "P01 + mode + orgid (+ sign when supplied)",
            "what_it_isolates": "How an app treats a payload that declares an initiation mode and a signing organisation. Only meaningful with real values.",
            "keys": [
                "pa",
                "pn",
                "tr",
                "am",
                "cu",
                "mode",
                "orgid",
                "sign"
            ],
            "prerequisite": "identifiers",
            "prerequisite_text": "Needs an orgid your PSP issued you, and — to be a genuine signed intent — a sign they generated. The lab will not create either. Until you supply them this method cannot run, because sending a made-up orgid tests nothing that exists."
        },
        "P10": {
            "id": "P10",
            "name": "Bank-issued merchant identifiers",
            "summary": "P01 + mid + msid + mtid",
            "what_it_isolates": "Whether an acquirer-issued merchant triple changes the receiving experience.",
            "keys": [
                "pa",
                "pn",
                "tr",
                "am",
                "cu",
                "mid",
                "msid",
                "mtid"
            ],
            "prerequisite": "identifiers",
            "prerequisite_text": "Needs the merchant / store / terminal identifiers your acquirer actually assigned you. An invented mid is not a merchant identifier, it is a string, and a result against one would be meaningless."
        },
        "P11": {
            "id": "P11",
            "name": "Imported exact QR",
            "summary": "The imported QR payload, byte-for-byte",
            "what_it_isolates": "The ground truth. Your bank's own placard, unmodified, against each app — the baseline every edited copy is compared to.",
            "keys": [],
            "prerequisite": "import",
            "prerequisite_text": "Import a QR into this profile first (QR Decoder → Save as exact original)."
        },
        "P12": {
            "id": "P12",
            "name": "Imported exact payment URI",
            "summary": "The imported URI, byte-for-byte",
            "what_it_isolates": "The same ground truth for an intent you were given as a link rather than a QR.",
            "keys": [],
            "prerequisite": "import",
            "prerequisite_text": "Paste an original payment URI into this profile first (QR Decoder → Save as exact original)."
        }
    },
    "launch_mechanisms": {
        "app_targeted": "Addresses one named app directly — on Android through an intent URI naming its package, on iOS through that app's own URI scheme. This is the only mechanism whose result can be attributed to a specific app with confidence.",
        "generic_chooser": "Emits upi://pay and lets the operating system offer whichever apps are installed. What happens next depends on the chooser and on what the operator picks.",
        "app_scheme": "Uses one app's own URI scheme rather than upi://. Only the app that owns the scheme can answer.",
        "dispatch_variant": "Holds the URI constant and changes how the BROWSER is asked to follow it. Browsers block some of these techniques; that blocking is the finding.",
        "exact_replay": "Hands over an imported payload byte-for-byte, with nothing rebuilt and nothing re-encoded.",
        "qr_scan": "Renders the payload as a QR code on screen. The payer scans it with a phone, which is a different code path inside the app from a deep link.",
        "decode_only": "Decodes and inspects. Nothing is launched, no app opens, and no payment is possible.",
        "vendor_web": "A vendor's own web payment integration. These require merchant onboarding and credentials the lab must not fabricate.",
        "native_android": "Requires the companion Android harness, because the behaviour under test is not observable from a browser.",
        "native_ios": "Requires the companion iOS harness."
    },
    "methods": [
        {
            "method_id": "GP-001",
            "group": "GP",
            "name": "Google Pay / Standard merchant intent",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · tez://upi/pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "Google Pay for India developer documentation — UPI deep link / Tez scheme.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Google Pay installed and registered for tez://upi/pay",
                "On Android: Google Pay installed (com.google.android.apps.nbu.paisa.user)."
            ],
            "expected_behaviour": "Google Pay opens on its payment confirmation screen showing the payee and ₹2.00. The control. Every other profile is this one plus something, so a failure here is a failure of the destination or the app, never of an optional field.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them."
            ],
            "implementation": "Android: an intent:// URI naming com.google.android.apps.nbu.paisa.user, with no browser_fallback_url so a failure to open stays visible. iOS: the tez://upi/pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.google.android.apps.nbu.paisa.user",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GP-002",
            "group": "GP",
            "name": "Google Pay / With transaction note",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · tez://upi/pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P02",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "tn"
            ],
            "documentation": "Google Pay for India developer documentation — UPI deep link / Tez scheme.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Google Pay installed and registered for tez://upi/pay",
                "On Android: Google Pay installed (com.google.android.apps.nbu.paisa.user)."
            ],
            "expected_behaviour": "Google Pay opens on its payment confirmation screen showing the payee and ₹2.00. Whether a note is displayed, truncated, stripped or rejected. Note length limits differ sharply between apps.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them."
            ],
            "implementation": "Android: an intent:// URI naming com.google.android.apps.nbu.paisa.user, with no browser_fallback_url so a failure to open stays visible. iOS: the tez://upi/pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.google.android.apps.nbu.paisa.user",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GP-003",
            "group": "GP",
            "name": "Google Pay / With merchant category code",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · tez://upi/pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "Google Pay for India developer documentation — UPI deep link / Tez scheme.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Google Pay installed and registered for tez://upi/pay",
                "On Android: Google Pay installed (com.google.android.apps.nbu.paisa.user)."
            ],
            "expected_behaviour": "Google Pay opens on its payment confirmation screen showing the payee and ₹2.00. THE most important comparison in the catalogue. Several apps switch from a person-to-person flow to a merchant flow when mc appears — changing limits, fees and whether the amount can be edited. P01 against P03 on the same app, same destination, same minute is the controlled experiment that shows it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them."
            ],
            "implementation": "Android: an intent:// URI naming com.google.android.apps.nbu.paisa.user, with no browser_fallback_url so a failure to open stays visible. iOS: the tez://upi/pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.google.android.apps.nbu.paisa.user",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GP-004",
            "group": "GP",
            "name": "Google Pay / Category code and note",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · tez://upi/pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P04",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "tn"
            ],
            "documentation": "Google Pay for India developer documentation — UPI deep link / Tez scheme.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Google Pay installed and registered for tez://upi/pay",
                "On Android: Google Pay installed (com.google.android.apps.nbu.paisa.user)."
            ],
            "expected_behaviour": "Google Pay opens on its payment confirmation screen showing the payee and ₹2.00. Whether the note survives the merchant flow. Some apps that show a note in a P2P flow drop it in a merchant one.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them."
            ],
            "implementation": "Android: an intent:// URI naming com.google.android.apps.nbu.paisa.user, with no browser_fallback_url so a failure to open stays visible. iOS: the tez://upi/pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.google.android.apps.nbu.paisa.user",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GP-005",
            "group": "GP",
            "name": "Google Pay / Transaction reference URL",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · tez://upi/pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P05",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "url"
            ],
            "documentation": "Google Pay for India developer documentation — UPI deep link / Tez scheme.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Google Pay installed and registered for tez://upi/pay",
                "On Android: Google Pay installed (com.google.android.apps.nbu.paisa.user)."
            ],
            "expected_behaviour": "Google Pay opens on its payment confirmation screen showing the payee and ₹2.00. Whether the app surfaces an invoice link, ignores it, or refuses the whole intent because of it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them."
            ],
            "implementation": "Android: an intent:// URI naming com.google.android.apps.nbu.paisa.user, with no browser_fallback_url so a failure to open stays visible. iOS: the tez://upi/pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.google.android.apps.nbu.paisa.user",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GP-006",
            "group": "GP",
            "name": "Google Pay / Category code and reference URL",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · tez://upi/pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P06",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "url"
            ],
            "documentation": "Google Pay for India developer documentation — UPI deep link / Tez scheme.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Google Pay installed and registered for tez://upi/pay",
                "On Android: Google Pay installed (com.google.android.apps.nbu.paisa.user)."
            ],
            "expected_behaviour": "Google Pay opens on its payment confirmation screen showing the payee and ₹2.00. The combination a real invoice-with-QR produces. Isolates interactions between the merchant flow and the invoice link.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them."
            ],
            "implementation": "Android: an intent:// URI naming com.google.android.apps.nbu.paisa.user, with no browser_fallback_url so a failure to open stays visible. iOS: the tez://upi/pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.google.android.apps.nbu.paisa.user",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GP-007",
            "group": "GP",
            "name": "Google Pay / Minimum amount",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · tez://upi/pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P07",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mam"
            ],
            "documentation": "Google Pay for India developer documentation — UPI deep link / Tez scheme.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Google Pay installed and registered for tez://upi/pay",
                "On Android: Google Pay installed (com.google.android.apps.nbu.paisa.user)."
            ],
            "expected_behaviour": "Google Pay opens on its payment confirmation screen showing the payee and ₹2.00. mam constrains an amount the payer may edit. Beside a fixed am it is contradictory, and WHICH ONE each app honours is the finding. The lab warns about the contradiction and sends it anyway — that is the experiment.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them."
            ],
            "implementation": "Android: an intent:// URI naming com.google.android.apps.nbu.paisa.user, with no browser_fallback_url so a failure to open stays visible. iOS: the tez://upi/pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.google.android.apps.nbu.paisa.user",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GP-008",
            "group": "GP",
            "name": "Google Pay / Category code and minimum amount",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · tez://upi/pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P08",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "mam"
            ],
            "documentation": "Google Pay for India developer documentation — UPI deep link / Tez scheme.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Google Pay installed and registered for tez://upi/pay",
                "On Android: Google Pay installed (com.google.android.apps.nbu.paisa.user)."
            ],
            "expected_behaviour": "Google Pay opens on its payment confirmation screen showing the payee and ₹2.00. Whether the merchant flow changes how mam is treated.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them."
            ],
            "implementation": "Android: an intent:// URI naming com.google.android.apps.nbu.paisa.user, with no browser_fallback_url so a failure to open stays visible. iOS: the tez://upi/pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.google.android.apps.nbu.paisa.user",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GP-009",
            "group": "GP",
            "name": "Google Pay / Documented initiation metadata",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · tez://upi/pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P09",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mode",
                "orgid",
                "sign"
            ],
            "documentation": "Google Pay for India developer documentation — UPI deep link / Tez scheme.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs an orgid your PSP issued you, and — to be a genuine signed intent — a sign they generated. The lab will not create either. Until you supply them this method cannot run, because sending a made-up orgid tests nothing that exists.",
                "On iOS: Google Pay installed and registered for tez://upi/pay",
                "On Android: Google Pay installed (com.google.android.apps.nbu.paisa.user)."
            ],
            "expected_behaviour": "Google Pay opens on its payment confirmation screen showing the payee and ₹2.00. How an app treats a payload that declares an initiation mode and a signing organisation. Only meaningful with real values.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them."
            ],
            "implementation": "Android: an intent:// URI naming com.google.android.apps.nbu.paisa.user, with no browser_fallback_url so a failure to open stays visible. iOS: the tez://upi/pay scheme carrying the same query.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.google.android.apps.nbu.paisa.user",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GP-010",
            "group": "GP",
            "name": "Google Pay / Bank-issued merchant identifiers",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · tez://upi/pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P10",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mid",
                "msid",
                "mtid"
            ],
            "documentation": "Google Pay for India developer documentation — UPI deep link / Tez scheme.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs the merchant / store / terminal identifiers your acquirer actually assigned you. An invented mid is not a merchant identifier, it is a string, and a result against one would be meaningless.",
                "On iOS: Google Pay installed and registered for tez://upi/pay",
                "On Android: Google Pay installed (com.google.android.apps.nbu.paisa.user)."
            ],
            "expected_behaviour": "Google Pay opens on its payment confirmation screen showing the payee and ₹2.00. Whether an acquirer-issued merchant triple changes the receiving experience.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them."
            ],
            "implementation": "Android: an intent:// URI naming com.google.android.apps.nbu.paisa.user, with no browser_fallback_url so a failure to open stays visible. iOS: the tez://upi/pay scheme carrying the same query.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.google.android.apps.nbu.paisa.user",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GP-011",
            "group": "GP",
            "name": "Google Pay / Imported exact QR",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · tez://upi/pay (iOS)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "Google Pay for India developer documentation — UPI deep link / Tez scheme.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Import a QR into this profile first (QR Decoder → Save as exact original).",
                "On iOS: Google Pay installed and registered for tez://upi/pay",
                "On Android: Google Pay installed (com.google.android.apps.nbu.paisa.user)."
            ],
            "expected_behaviour": "Google Pay opens on its payment confirmation screen showing the payee and ₹2.00. The ground truth. Your bank's own placard, unmodified, against each app — the baseline every edited copy is compared to.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming com.google.android.apps.nbu.paisa.user, with no browser_fallback_url so a failure to open stays visible. iOS: the tez://upi/pay scheme carrying the same query.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.google.android.apps.nbu.paisa.user",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "GP-012",
            "group": "GP",
            "name": "Google Pay / Imported exact payment URI",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · tez://upi/pay (iOS)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P12",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "Google Pay for India developer documentation — UPI deep link / Tez scheme.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Paste an original payment URI into this profile first (QR Decoder → Save as exact original).",
                "On iOS: Google Pay installed and registered for tez://upi/pay",
                "On Android: Google Pay installed (com.google.android.apps.nbu.paisa.user)."
            ],
            "expected_behaviour": "Google Pay opens on its payment confirmation screen showing the payee and ₹2.00. The same ground truth for an intent you were given as a link rather than a QR.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming com.google.android.apps.nbu.paisa.user, with no browser_fallback_url so a failure to open stays visible. iOS: the tez://upi/pay scheme carrying the same query.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.google.android.apps.nbu.paisa.user",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "PH-001",
            "group": "PH",
            "name": "PhonePe / Standard merchant intent",
            "application": "PhonePe",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · phonepe://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "No public third-party deep-link specification. PhonePe publishes a merchant SDK/PG integration instead.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: PhonePe installed and registered for phonepe://pay",
                "On Android: PhonePe installed (com.phonepe.app)."
            ],
            "expected_behaviour": "PhonePe opens on its payment confirmation screen showing the payee and ₹2.00. The control. Every other profile is this one plus something, so a failure here is a failure of the destination or the app, never of an optional field.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming com.phonepe.app, with no browser_fallback_url so a failure to open stays visible. iOS: the phonepe://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.phonepe.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PH-002",
            "group": "PH",
            "name": "PhonePe / With transaction note",
            "application": "PhonePe",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · phonepe://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P02",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "tn"
            ],
            "documentation": "No public third-party deep-link specification. PhonePe publishes a merchant SDK/PG integration instead.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: PhonePe installed and registered for phonepe://pay",
                "On Android: PhonePe installed (com.phonepe.app)."
            ],
            "expected_behaviour": "PhonePe opens on its payment confirmation screen showing the payee and ₹2.00. Whether a note is displayed, truncated, stripped or rejected. Note length limits differ sharply between apps.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming com.phonepe.app, with no browser_fallback_url so a failure to open stays visible. iOS: the phonepe://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.phonepe.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PH-003",
            "group": "PH",
            "name": "PhonePe / With merchant category code",
            "application": "PhonePe",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · phonepe://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "No public third-party deep-link specification. PhonePe publishes a merchant SDK/PG integration instead.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: PhonePe installed and registered for phonepe://pay",
                "On Android: PhonePe installed (com.phonepe.app)."
            ],
            "expected_behaviour": "PhonePe opens on its payment confirmation screen showing the payee and ₹2.00. THE most important comparison in the catalogue. Several apps switch from a person-to-person flow to a merchant flow when mc appears — changing limits, fees and whether the amount can be edited. P01 against P03 on the same app, same destination, same minute is the controlled experiment that shows it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming com.phonepe.app, with no browser_fallback_url so a failure to open stays visible. iOS: the phonepe://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.phonepe.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PH-004",
            "group": "PH",
            "name": "PhonePe / Category code and note",
            "application": "PhonePe",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · phonepe://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P04",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "tn"
            ],
            "documentation": "No public third-party deep-link specification. PhonePe publishes a merchant SDK/PG integration instead.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: PhonePe installed and registered for phonepe://pay",
                "On Android: PhonePe installed (com.phonepe.app)."
            ],
            "expected_behaviour": "PhonePe opens on its payment confirmation screen showing the payee and ₹2.00. Whether the note survives the merchant flow. Some apps that show a note in a P2P flow drop it in a merchant one.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming com.phonepe.app, with no browser_fallback_url so a failure to open stays visible. iOS: the phonepe://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.phonepe.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PH-005",
            "group": "PH",
            "name": "PhonePe / Transaction reference URL",
            "application": "PhonePe",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · phonepe://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P05",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "url"
            ],
            "documentation": "No public third-party deep-link specification. PhonePe publishes a merchant SDK/PG integration instead.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: PhonePe installed and registered for phonepe://pay",
                "On Android: PhonePe installed (com.phonepe.app)."
            ],
            "expected_behaviour": "PhonePe opens on its payment confirmation screen showing the payee and ₹2.00. Whether the app surfaces an invoice link, ignores it, or refuses the whole intent because of it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming com.phonepe.app, with no browser_fallback_url so a failure to open stays visible. iOS: the phonepe://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.phonepe.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PH-006",
            "group": "PH",
            "name": "PhonePe / Category code and reference URL",
            "application": "PhonePe",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · phonepe://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P06",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "url"
            ],
            "documentation": "No public third-party deep-link specification. PhonePe publishes a merchant SDK/PG integration instead.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: PhonePe installed and registered for phonepe://pay",
                "On Android: PhonePe installed (com.phonepe.app)."
            ],
            "expected_behaviour": "PhonePe opens on its payment confirmation screen showing the payee and ₹2.00. The combination a real invoice-with-QR produces. Isolates interactions between the merchant flow and the invoice link.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming com.phonepe.app, with no browser_fallback_url so a failure to open stays visible. iOS: the phonepe://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.phonepe.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PH-007",
            "group": "PH",
            "name": "PhonePe / Minimum amount",
            "application": "PhonePe",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · phonepe://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P07",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mam"
            ],
            "documentation": "No public third-party deep-link specification. PhonePe publishes a merchant SDK/PG integration instead.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: PhonePe installed and registered for phonepe://pay",
                "On Android: PhonePe installed (com.phonepe.app)."
            ],
            "expected_behaviour": "PhonePe opens on its payment confirmation screen showing the payee and ₹2.00. mam constrains an amount the payer may edit. Beside a fixed am it is contradictory, and WHICH ONE each app honours is the finding. The lab warns about the contradiction and sends it anyway — that is the experiment.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming com.phonepe.app, with no browser_fallback_url so a failure to open stays visible. iOS: the phonepe://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.phonepe.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PH-008",
            "group": "PH",
            "name": "PhonePe / Category code and minimum amount",
            "application": "PhonePe",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · phonepe://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P08",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "mam"
            ],
            "documentation": "No public third-party deep-link specification. PhonePe publishes a merchant SDK/PG integration instead.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: PhonePe installed and registered for phonepe://pay",
                "On Android: PhonePe installed (com.phonepe.app)."
            ],
            "expected_behaviour": "PhonePe opens on its payment confirmation screen showing the payee and ₹2.00. Whether the merchant flow changes how mam is treated.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming com.phonepe.app, with no browser_fallback_url so a failure to open stays visible. iOS: the phonepe://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.phonepe.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PH-009",
            "group": "PH",
            "name": "PhonePe / Documented initiation metadata",
            "application": "PhonePe",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · phonepe://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P09",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mode",
                "orgid",
                "sign"
            ],
            "documentation": "No public third-party deep-link specification. PhonePe publishes a merchant SDK/PG integration instead.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs an orgid your PSP issued you, and — to be a genuine signed intent — a sign they generated. The lab will not create either. Until you supply them this method cannot run, because sending a made-up orgid tests nothing that exists.",
                "On iOS: PhonePe installed and registered for phonepe://pay",
                "On Android: PhonePe installed (com.phonepe.app)."
            ],
            "expected_behaviour": "PhonePe opens on its payment confirmation screen showing the payee and ₹2.00. How an app treats a payload that declares an initiation mode and a signing organisation. Only meaningful with real values.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming com.phonepe.app, with no browser_fallback_url so a failure to open stays visible. iOS: the phonepe://pay scheme carrying the same query.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.phonepe.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PH-010",
            "group": "PH",
            "name": "PhonePe / Bank-issued merchant identifiers",
            "application": "PhonePe",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · phonepe://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P10",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mid",
                "msid",
                "mtid"
            ],
            "documentation": "No public third-party deep-link specification. PhonePe publishes a merchant SDK/PG integration instead.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs the merchant / store / terminal identifiers your acquirer actually assigned you. An invented mid is not a merchant identifier, it is a string, and a result against one would be meaningless.",
                "On iOS: PhonePe installed and registered for phonepe://pay",
                "On Android: PhonePe installed (com.phonepe.app)."
            ],
            "expected_behaviour": "PhonePe opens on its payment confirmation screen showing the payee and ₹2.00. Whether an acquirer-issued merchant triple changes the receiving experience.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming com.phonepe.app, with no browser_fallback_url so a failure to open stays visible. iOS: the phonepe://pay scheme carrying the same query.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.phonepe.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PH-011",
            "group": "PH",
            "name": "PhonePe / Imported exact QR",
            "application": "PhonePe",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · phonepe://pay (iOS)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "No public third-party deep-link specification. PhonePe publishes a merchant SDK/PG integration instead.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Import a QR into this profile first (QR Decoder → Save as exact original).",
                "On iOS: PhonePe installed and registered for phonepe://pay",
                "On Android: PhonePe installed (com.phonepe.app)."
            ],
            "expected_behaviour": "PhonePe opens on its payment confirmation screen showing the payee and ₹2.00. The ground truth. Your bank's own placard, unmodified, against each app — the baseline every edited copy is compared to.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming com.phonepe.app, with no browser_fallback_url so a failure to open stays visible. iOS: the phonepe://pay scheme carrying the same query.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.phonepe.app",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "PH-012",
            "group": "PH",
            "name": "PhonePe / Imported exact payment URI",
            "application": "PhonePe",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · phonepe://pay (iOS)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P12",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "No public third-party deep-link specification. PhonePe publishes a merchant SDK/PG integration instead.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Paste an original payment URI into this profile first (QR Decoder → Save as exact original).",
                "On iOS: PhonePe installed and registered for phonepe://pay",
                "On Android: PhonePe installed (com.phonepe.app)."
            ],
            "expected_behaviour": "PhonePe opens on its payment confirmation screen showing the payee and ₹2.00. The same ground truth for an intent you were given as a link rather than a QR.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming com.phonepe.app, with no browser_fallback_url so a failure to open stays visible. iOS: the phonepe://pay scheme carrying the same query.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.phonepe.app",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "PT-001",
            "group": "PT",
            "name": "Paytm / Standard merchant intent",
            "application": "Paytm",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · paytmmp://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "No public third-party deep-link specification. Paytm publishes a merchant payment gateway with issued credentials.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Paytm installed and registered for paytmmp://pay",
                "On Android: Paytm installed (net.one97.paytm)."
            ],
            "expected_behaviour": "Paytm opens on its payment confirmation screen showing the payee and ₹2.00. The control. Every other profile is this one plus something, so a failure here is a failure of the destination or the app, never of an optional field.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming net.one97.paytm, with no browser_fallback_url so a failure to open stays visible. iOS: the paytmmp://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "net.one97.paytm",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PT-002",
            "group": "PT",
            "name": "Paytm / With transaction note",
            "application": "Paytm",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · paytmmp://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P02",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "tn"
            ],
            "documentation": "No public third-party deep-link specification. Paytm publishes a merchant payment gateway with issued credentials.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Paytm installed and registered for paytmmp://pay",
                "On Android: Paytm installed (net.one97.paytm)."
            ],
            "expected_behaviour": "Paytm opens on its payment confirmation screen showing the payee and ₹2.00. Whether a note is displayed, truncated, stripped or rejected. Note length limits differ sharply between apps.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming net.one97.paytm, with no browser_fallback_url so a failure to open stays visible. iOS: the paytmmp://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "net.one97.paytm",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PT-003",
            "group": "PT",
            "name": "Paytm / With merchant category code",
            "application": "Paytm",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · paytmmp://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "No public third-party deep-link specification. Paytm publishes a merchant payment gateway with issued credentials.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Paytm installed and registered for paytmmp://pay",
                "On Android: Paytm installed (net.one97.paytm)."
            ],
            "expected_behaviour": "Paytm opens on its payment confirmation screen showing the payee and ₹2.00. THE most important comparison in the catalogue. Several apps switch from a person-to-person flow to a merchant flow when mc appears — changing limits, fees and whether the amount can be edited. P01 against P03 on the same app, same destination, same minute is the controlled experiment that shows it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming net.one97.paytm, with no browser_fallback_url so a failure to open stays visible. iOS: the paytmmp://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "net.one97.paytm",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PT-004",
            "group": "PT",
            "name": "Paytm / Category code and note",
            "application": "Paytm",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · paytmmp://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P04",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "tn"
            ],
            "documentation": "No public third-party deep-link specification. Paytm publishes a merchant payment gateway with issued credentials.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Paytm installed and registered for paytmmp://pay",
                "On Android: Paytm installed (net.one97.paytm)."
            ],
            "expected_behaviour": "Paytm opens on its payment confirmation screen showing the payee and ₹2.00. Whether the note survives the merchant flow. Some apps that show a note in a P2P flow drop it in a merchant one.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming net.one97.paytm, with no browser_fallback_url so a failure to open stays visible. iOS: the paytmmp://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "net.one97.paytm",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PT-005",
            "group": "PT",
            "name": "Paytm / Transaction reference URL",
            "application": "Paytm",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · paytmmp://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P05",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "url"
            ],
            "documentation": "No public third-party deep-link specification. Paytm publishes a merchant payment gateway with issued credentials.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Paytm installed and registered for paytmmp://pay",
                "On Android: Paytm installed (net.one97.paytm)."
            ],
            "expected_behaviour": "Paytm opens on its payment confirmation screen showing the payee and ₹2.00. Whether the app surfaces an invoice link, ignores it, or refuses the whole intent because of it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming net.one97.paytm, with no browser_fallback_url so a failure to open stays visible. iOS: the paytmmp://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "net.one97.paytm",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PT-006",
            "group": "PT",
            "name": "Paytm / Category code and reference URL",
            "application": "Paytm",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · paytmmp://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P06",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "url"
            ],
            "documentation": "No public third-party deep-link specification. Paytm publishes a merchant payment gateway with issued credentials.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Paytm installed and registered for paytmmp://pay",
                "On Android: Paytm installed (net.one97.paytm)."
            ],
            "expected_behaviour": "Paytm opens on its payment confirmation screen showing the payee and ₹2.00. The combination a real invoice-with-QR produces. Isolates interactions between the merchant flow and the invoice link.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming net.one97.paytm, with no browser_fallback_url so a failure to open stays visible. iOS: the paytmmp://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "net.one97.paytm",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PT-007",
            "group": "PT",
            "name": "Paytm / Minimum amount",
            "application": "Paytm",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · paytmmp://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P07",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mam"
            ],
            "documentation": "No public third-party deep-link specification. Paytm publishes a merchant payment gateway with issued credentials.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Paytm installed and registered for paytmmp://pay",
                "On Android: Paytm installed (net.one97.paytm)."
            ],
            "expected_behaviour": "Paytm opens on its payment confirmation screen showing the payee and ₹2.00. mam constrains an amount the payer may edit. Beside a fixed am it is contradictory, and WHICH ONE each app honours is the finding. The lab warns about the contradiction and sends it anyway — that is the experiment.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming net.one97.paytm, with no browser_fallback_url so a failure to open stays visible. iOS: the paytmmp://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "net.one97.paytm",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PT-008",
            "group": "PT",
            "name": "Paytm / Category code and minimum amount",
            "application": "Paytm",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · paytmmp://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P08",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "mam"
            ],
            "documentation": "No public third-party deep-link specification. Paytm publishes a merchant payment gateway with issued credentials.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: Paytm installed and registered for paytmmp://pay",
                "On Android: Paytm installed (net.one97.paytm)."
            ],
            "expected_behaviour": "Paytm opens on its payment confirmation screen showing the payee and ₹2.00. Whether the merchant flow changes how mam is treated.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming net.one97.paytm, with no browser_fallback_url so a failure to open stays visible. iOS: the paytmmp://pay scheme carrying the same query.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "net.one97.paytm",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PT-009",
            "group": "PT",
            "name": "Paytm / Documented initiation metadata",
            "application": "Paytm",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · paytmmp://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P09",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mode",
                "orgid",
                "sign"
            ],
            "documentation": "No public third-party deep-link specification. Paytm publishes a merchant payment gateway with issued credentials.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs an orgid your PSP issued you, and — to be a genuine signed intent — a sign they generated. The lab will not create either. Until you supply them this method cannot run, because sending a made-up orgid tests nothing that exists.",
                "On iOS: Paytm installed and registered for paytmmp://pay",
                "On Android: Paytm installed (net.one97.paytm)."
            ],
            "expected_behaviour": "Paytm opens on its payment confirmation screen showing the payee and ₹2.00. How an app treats a payload that declares an initiation mode and a signing organisation. Only meaningful with real values.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming net.one97.paytm, with no browser_fallback_url so a failure to open stays visible. iOS: the paytmmp://pay scheme carrying the same query.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "net.one97.paytm",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PT-010",
            "group": "PT",
            "name": "Paytm / Bank-issued merchant identifiers",
            "application": "Paytm",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · paytmmp://pay (iOS)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P10",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mid",
                "msid",
                "mtid"
            ],
            "documentation": "No public third-party deep-link specification. Paytm publishes a merchant payment gateway with issued credentials.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs the merchant / store / terminal identifiers your acquirer actually assigned you. An invented mid is not a merchant identifier, it is a string, and a result against one would be meaningless.",
                "On iOS: Paytm installed and registered for paytmmp://pay",
                "On Android: Paytm installed (net.one97.paytm)."
            ],
            "expected_behaviour": "Paytm opens on its payment confirmation screen showing the payee and ₹2.00. Whether an acquirer-issued merchant triple changes the receiving experience.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration."
            ],
            "implementation": "Android: an intent:// URI naming net.one97.paytm, with no browser_fallback_url so a failure to open stays visible. iOS: the paytmmp://pay scheme carrying the same query.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "net.one97.paytm",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PT-011",
            "group": "PT",
            "name": "Paytm / Imported exact QR",
            "application": "Paytm",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · paytmmp://pay (iOS)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "No public third-party deep-link specification. Paytm publishes a merchant payment gateway with issued credentials.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Import a QR into this profile first (QR Decoder → Save as exact original).",
                "On iOS: Paytm installed and registered for paytmmp://pay",
                "On Android: Paytm installed (net.one97.paytm)."
            ],
            "expected_behaviour": "Paytm opens on its payment confirmation screen showing the payee and ₹2.00. The ground truth. Your bank's own placard, unmodified, against each app — the baseline every edited copy is compared to.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming net.one97.paytm, with no browser_fallback_url so a failure to open stays visible. iOS: the paytmmp://pay scheme carrying the same query.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "net.one97.paytm",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "PT-012",
            "group": "PT",
            "name": "Paytm / Imported exact payment URI",
            "application": "Paytm",
            "platform": "any",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android) · paytmmp://pay (iOS)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P12",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "No public third-party deep-link specification. Paytm publishes a merchant payment gateway with issued credentials.",
            "documentation_status": "observed",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Paste an original payment URI into this profile first (QR Decoder → Save as exact original).",
                "On iOS: Paytm installed and registered for paytmmp://pay",
                "On Android: Paytm installed (net.one97.paytm)."
            ],
            "expected_behaviour": "Paytm opens on its payment confirmation screen showing the payee and ₹2.00. The same ground truth for an intent you were given as a link rather than a QR.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "The iOS scheme used here is observed, not vendor-documented. A working result is evidence, not a supported integration.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming net.one97.paytm, with no browser_fallback_url so a failure to open stays visible. iOS: the paytmmp://pay scheme carrying the same query.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "net.one97.paytm",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "BH-001",
            "group": "BH",
            "name": "BHIM / Standard merchant intent",
            "application": "BHIM",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "NPCI UPI Linking Specification — BHIM is the reference implementation of the generic upi:// handling.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — BHIM publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: BHIM installed (in.org.npci.upiapp)."
            ],
            "expected_behaviour": "BHIM opens on its payment confirmation screen showing the payee and ₹2.00. The control. Every other profile is this one plus something, so a failure here is a failure of the destination or the app, never of an optional field.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.org.npci.upiapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.org.npci.upiapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "BH-002",
            "group": "BH",
            "name": "BHIM / With transaction note",
            "application": "BHIM",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P02",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "tn"
            ],
            "documentation": "NPCI UPI Linking Specification — BHIM is the reference implementation of the generic upi:// handling.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — BHIM publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: BHIM installed (in.org.npci.upiapp)."
            ],
            "expected_behaviour": "BHIM opens on its payment confirmation screen showing the payee and ₹2.00. Whether a note is displayed, truncated, stripped or rejected. Note length limits differ sharply between apps.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.org.npci.upiapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.org.npci.upiapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "BH-003",
            "group": "BH",
            "name": "BHIM / With merchant category code",
            "application": "BHIM",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "NPCI UPI Linking Specification — BHIM is the reference implementation of the generic upi:// handling.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — BHIM publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: BHIM installed (in.org.npci.upiapp)."
            ],
            "expected_behaviour": "BHIM opens on its payment confirmation screen showing the payee and ₹2.00. THE most important comparison in the catalogue. Several apps switch from a person-to-person flow to a merchant flow when mc appears — changing limits, fees and whether the amount can be edited. P01 against P03 on the same app, same destination, same minute is the controlled experiment that shows it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.org.npci.upiapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.org.npci.upiapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "BH-004",
            "group": "BH",
            "name": "BHIM / Category code and note",
            "application": "BHIM",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P04",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "tn"
            ],
            "documentation": "NPCI UPI Linking Specification — BHIM is the reference implementation of the generic upi:// handling.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — BHIM publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: BHIM installed (in.org.npci.upiapp)."
            ],
            "expected_behaviour": "BHIM opens on its payment confirmation screen showing the payee and ₹2.00. Whether the note survives the merchant flow. Some apps that show a note in a P2P flow drop it in a merchant one.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.org.npci.upiapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.org.npci.upiapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "BH-005",
            "group": "BH",
            "name": "BHIM / Transaction reference URL",
            "application": "BHIM",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P05",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "url"
            ],
            "documentation": "NPCI UPI Linking Specification — BHIM is the reference implementation of the generic upi:// handling.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — BHIM publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: BHIM installed (in.org.npci.upiapp)."
            ],
            "expected_behaviour": "BHIM opens on its payment confirmation screen showing the payee and ₹2.00. Whether the app surfaces an invoice link, ignores it, or refuses the whole intent because of it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.org.npci.upiapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.org.npci.upiapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "BH-006",
            "group": "BH",
            "name": "BHIM / Category code and reference URL",
            "application": "BHIM",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P06",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "url"
            ],
            "documentation": "NPCI UPI Linking Specification — BHIM is the reference implementation of the generic upi:// handling.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — BHIM publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: BHIM installed (in.org.npci.upiapp)."
            ],
            "expected_behaviour": "BHIM opens on its payment confirmation screen showing the payee and ₹2.00. The combination a real invoice-with-QR produces. Isolates interactions between the merchant flow and the invoice link.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.org.npci.upiapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.org.npci.upiapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "BH-007",
            "group": "BH",
            "name": "BHIM / Minimum amount",
            "application": "BHIM",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P07",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mam"
            ],
            "documentation": "NPCI UPI Linking Specification — BHIM is the reference implementation of the generic upi:// handling.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — BHIM publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: BHIM installed (in.org.npci.upiapp)."
            ],
            "expected_behaviour": "BHIM opens on its payment confirmation screen showing the payee and ₹2.00. mam constrains an amount the payer may edit. Beside a fixed am it is contradictory, and WHICH ONE each app honours is the finding. The lab warns about the contradiction and sends it anyway — that is the experiment.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.org.npci.upiapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.org.npci.upiapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "BH-008",
            "group": "BH",
            "name": "BHIM / Category code and minimum amount",
            "application": "BHIM",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P08",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "mam"
            ],
            "documentation": "NPCI UPI Linking Specification — BHIM is the reference implementation of the generic upi:// handling.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — BHIM publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: BHIM installed (in.org.npci.upiapp)."
            ],
            "expected_behaviour": "BHIM opens on its payment confirmation screen showing the payee and ₹2.00. Whether the merchant flow changes how mam is treated.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.org.npci.upiapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.org.npci.upiapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "BH-009",
            "group": "BH",
            "name": "BHIM / Documented initiation metadata",
            "application": "BHIM",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P09",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mode",
                "orgid",
                "sign"
            ],
            "documentation": "NPCI UPI Linking Specification — BHIM is the reference implementation of the generic upi:// handling.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs an orgid your PSP issued you, and — to be a genuine signed intent — a sign they generated. The lab will not create either. Until you supply them this method cannot run, because sending a made-up orgid tests nothing that exists.",
                "On iOS: not addressable — BHIM publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: BHIM installed (in.org.npci.upiapp)."
            ],
            "expected_behaviour": "BHIM opens on its payment confirmation screen showing the payee and ₹2.00. How an app treats a payload that declares an initiation mode and a signing organisation. Only meaningful with real values.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.org.npci.upiapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "in.org.npci.upiapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "BH-010",
            "group": "BH",
            "name": "BHIM / Bank-issued merchant identifiers",
            "application": "BHIM",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P10",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mid",
                "msid",
                "mtid"
            ],
            "documentation": "NPCI UPI Linking Specification — BHIM is the reference implementation of the generic upi:// handling.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs the merchant / store / terminal identifiers your acquirer actually assigned you. An invented mid is not a merchant identifier, it is a string, and a result against one would be meaningless.",
                "On iOS: not addressable — BHIM publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: BHIM installed (in.org.npci.upiapp)."
            ],
            "expected_behaviour": "BHIM opens on its payment confirmation screen showing the payee and ₹2.00. Whether an acquirer-issued merchant triple changes the receiving experience.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.org.npci.upiapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "in.org.npci.upiapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "BH-011",
            "group": "BH",
            "name": "BHIM / Imported exact QR",
            "application": "BHIM",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "NPCI UPI Linking Specification — BHIM is the reference implementation of the generic upi:// handling.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Import a QR into this profile first (QR Decoder → Save as exact original).",
                "On iOS: not addressable — BHIM publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: BHIM installed (in.org.npci.upiapp)."
            ],
            "expected_behaviour": "BHIM opens on its payment confirmation screen showing the payee and ₹2.00. The ground truth. Your bank's own placard, unmodified, against each app — the baseline every edited copy is compared to.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming in.org.npci.upiapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "in.org.npci.upiapp",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "BH-012",
            "group": "BH",
            "name": "BHIM / Imported exact payment URI",
            "application": "BHIM",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P12",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "NPCI UPI Linking Specification — BHIM is the reference implementation of the generic upi:// handling.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Paste an original payment URI into this profile first (QR Decoder → Save as exact original).",
                "On iOS: not addressable — BHIM publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: BHIM installed (in.org.npci.upiapp)."
            ],
            "expected_behaviour": "BHIM opens on its payment confirmation screen showing the payee and ₹2.00. The same ground truth for an intent you were given as a link rather than a QR.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming in.org.npci.upiapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "in.org.npci.upiapp",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "AZ-001",
            "group": "AZ",
            "name": "Amazon Pay / Standard merchant intent",
            "application": "Amazon Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "No public UPI deep-link scheme. Amazon Pay UPI lives inside the Amazon shopping app.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Amazon Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Amazon Pay installed (in.amazon.mShop.android.shopping)."
            ],
            "expected_behaviour": "Amazon Pay opens on its payment confirmation screen showing the payee and ₹2.00. The control. Every other profile is this one plus something, so a failure here is a failure of the destination or the app, never of an optional field.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.amazon.mShop.android.shopping, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.amazon.mShop.android.shopping",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AZ-002",
            "group": "AZ",
            "name": "Amazon Pay / With transaction note",
            "application": "Amazon Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P02",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "tn"
            ],
            "documentation": "No public UPI deep-link scheme. Amazon Pay UPI lives inside the Amazon shopping app.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Amazon Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Amazon Pay installed (in.amazon.mShop.android.shopping)."
            ],
            "expected_behaviour": "Amazon Pay opens on its payment confirmation screen showing the payee and ₹2.00. Whether a note is displayed, truncated, stripped or rejected. Note length limits differ sharply between apps.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.amazon.mShop.android.shopping, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.amazon.mShop.android.shopping",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AZ-003",
            "group": "AZ",
            "name": "Amazon Pay / With merchant category code",
            "application": "Amazon Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "No public UPI deep-link scheme. Amazon Pay UPI lives inside the Amazon shopping app.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Amazon Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Amazon Pay installed (in.amazon.mShop.android.shopping)."
            ],
            "expected_behaviour": "Amazon Pay opens on its payment confirmation screen showing the payee and ₹2.00. THE most important comparison in the catalogue. Several apps switch from a person-to-person flow to a merchant flow when mc appears — changing limits, fees and whether the amount can be edited. P01 against P03 on the same app, same destination, same minute is the controlled experiment that shows it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.amazon.mShop.android.shopping, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.amazon.mShop.android.shopping",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AZ-004",
            "group": "AZ",
            "name": "Amazon Pay / Category code and note",
            "application": "Amazon Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P04",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "tn"
            ],
            "documentation": "No public UPI deep-link scheme. Amazon Pay UPI lives inside the Amazon shopping app.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Amazon Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Amazon Pay installed (in.amazon.mShop.android.shopping)."
            ],
            "expected_behaviour": "Amazon Pay opens on its payment confirmation screen showing the payee and ₹2.00. Whether the note survives the merchant flow. Some apps that show a note in a P2P flow drop it in a merchant one.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.amazon.mShop.android.shopping, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.amazon.mShop.android.shopping",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AZ-005",
            "group": "AZ",
            "name": "Amazon Pay / Transaction reference URL",
            "application": "Amazon Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P05",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "url"
            ],
            "documentation": "No public UPI deep-link scheme. Amazon Pay UPI lives inside the Amazon shopping app.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Amazon Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Amazon Pay installed (in.amazon.mShop.android.shopping)."
            ],
            "expected_behaviour": "Amazon Pay opens on its payment confirmation screen showing the payee and ₹2.00. Whether the app surfaces an invoice link, ignores it, or refuses the whole intent because of it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.amazon.mShop.android.shopping, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.amazon.mShop.android.shopping",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AZ-006",
            "group": "AZ",
            "name": "Amazon Pay / Category code and reference URL",
            "application": "Amazon Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P06",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "url"
            ],
            "documentation": "No public UPI deep-link scheme. Amazon Pay UPI lives inside the Amazon shopping app.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Amazon Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Amazon Pay installed (in.amazon.mShop.android.shopping)."
            ],
            "expected_behaviour": "Amazon Pay opens on its payment confirmation screen showing the payee and ₹2.00. The combination a real invoice-with-QR produces. Isolates interactions between the merchant flow and the invoice link.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.amazon.mShop.android.shopping, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.amazon.mShop.android.shopping",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AZ-007",
            "group": "AZ",
            "name": "Amazon Pay / Minimum amount",
            "application": "Amazon Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P07",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mam"
            ],
            "documentation": "No public UPI deep-link scheme. Amazon Pay UPI lives inside the Amazon shopping app.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Amazon Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Amazon Pay installed (in.amazon.mShop.android.shopping)."
            ],
            "expected_behaviour": "Amazon Pay opens on its payment confirmation screen showing the payee and ₹2.00. mam constrains an amount the payer may edit. Beside a fixed am it is contradictory, and WHICH ONE each app honours is the finding. The lab warns about the contradiction and sends it anyway — that is the experiment.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.amazon.mShop.android.shopping, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.amazon.mShop.android.shopping",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AZ-008",
            "group": "AZ",
            "name": "Amazon Pay / Category code and minimum amount",
            "application": "Amazon Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P08",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "mam"
            ],
            "documentation": "No public UPI deep-link scheme. Amazon Pay UPI lives inside the Amazon shopping app.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Amazon Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Amazon Pay installed (in.amazon.mShop.android.shopping)."
            ],
            "expected_behaviour": "Amazon Pay opens on its payment confirmation screen showing the payee and ₹2.00. Whether the merchant flow changes how mam is treated.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.amazon.mShop.android.shopping, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "in.amazon.mShop.android.shopping",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AZ-009",
            "group": "AZ",
            "name": "Amazon Pay / Documented initiation metadata",
            "application": "Amazon Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P09",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mode",
                "orgid",
                "sign"
            ],
            "documentation": "No public UPI deep-link scheme. Amazon Pay UPI lives inside the Amazon shopping app.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs an orgid your PSP issued you, and — to be a genuine signed intent — a sign they generated. The lab will not create either. Until you supply them this method cannot run, because sending a made-up orgid tests nothing that exists.",
                "On iOS: not addressable — Amazon Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Amazon Pay installed (in.amazon.mShop.android.shopping)."
            ],
            "expected_behaviour": "Amazon Pay opens on its payment confirmation screen showing the payee and ₹2.00. How an app treats a payload that declares an initiation mode and a signing organisation. Only meaningful with real values.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.amazon.mShop.android.shopping, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "in.amazon.mShop.android.shopping",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AZ-010",
            "group": "AZ",
            "name": "Amazon Pay / Bank-issued merchant identifiers",
            "application": "Amazon Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P10",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mid",
                "msid",
                "mtid"
            ],
            "documentation": "No public UPI deep-link scheme. Amazon Pay UPI lives inside the Amazon shopping app.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs the merchant / store / terminal identifiers your acquirer actually assigned you. An invented mid is not a merchant identifier, it is a string, and a result against one would be meaningless.",
                "On iOS: not addressable — Amazon Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Amazon Pay installed (in.amazon.mShop.android.shopping)."
            ],
            "expected_behaviour": "Amazon Pay opens on its payment confirmation screen showing the payee and ₹2.00. Whether an acquirer-issued merchant triple changes the receiving experience.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming in.amazon.mShop.android.shopping, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "in.amazon.mShop.android.shopping",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AZ-011",
            "group": "AZ",
            "name": "Amazon Pay / Imported exact QR",
            "application": "Amazon Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "No public UPI deep-link scheme. Amazon Pay UPI lives inside the Amazon shopping app.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Import a QR into this profile first (QR Decoder → Save as exact original).",
                "On iOS: not addressable — Amazon Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Amazon Pay installed (in.amazon.mShop.android.shopping)."
            ],
            "expected_behaviour": "Amazon Pay opens on its payment confirmation screen showing the payee and ₹2.00. The ground truth. Your bank's own placard, unmodified, against each app — the baseline every edited copy is compared to.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming in.amazon.mShop.android.shopping, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "in.amazon.mShop.android.shopping",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "AZ-012",
            "group": "AZ",
            "name": "Amazon Pay / Imported exact payment URI",
            "application": "Amazon Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P12",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "No public UPI deep-link scheme. Amazon Pay UPI lives inside the Amazon shopping app.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Paste an original payment URI into this profile first (QR Decoder → Save as exact original).",
                "On iOS: not addressable — Amazon Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Amazon Pay installed (in.amazon.mShop.android.shopping)."
            ],
            "expected_behaviour": "Amazon Pay opens on its payment confirmation screen showing the payee and ₹2.00. The same ground truth for an intent you were given as a link rather than a QR.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming in.amazon.mShop.android.shopping, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "in.amazon.mShop.android.shopping",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "WA-001",
            "group": "WA",
            "name": "WhatsApp Pay / Standard merchant intent",
            "application": "WhatsApp Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "No public UPI deep-link scheme. WhatsApp's own wa.me links are messaging links, not payment intents.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — WhatsApp Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: WhatsApp Pay installed (com.whatsapp)."
            ],
            "expected_behaviour": "WhatsApp Pay opens on its payment confirmation screen showing the payee and ₹2.00. The control. Every other profile is this one plus something, so a failure here is a failure of the destination or the app, never of an optional field.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.whatsapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.whatsapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "WA-002",
            "group": "WA",
            "name": "WhatsApp Pay / With transaction note",
            "application": "WhatsApp Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P02",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "tn"
            ],
            "documentation": "No public UPI deep-link scheme. WhatsApp's own wa.me links are messaging links, not payment intents.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — WhatsApp Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: WhatsApp Pay installed (com.whatsapp)."
            ],
            "expected_behaviour": "WhatsApp Pay opens on its payment confirmation screen showing the payee and ₹2.00. Whether a note is displayed, truncated, stripped or rejected. Note length limits differ sharply between apps.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.whatsapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.whatsapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "WA-003",
            "group": "WA",
            "name": "WhatsApp Pay / With merchant category code",
            "application": "WhatsApp Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "No public UPI deep-link scheme. WhatsApp's own wa.me links are messaging links, not payment intents.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — WhatsApp Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: WhatsApp Pay installed (com.whatsapp)."
            ],
            "expected_behaviour": "WhatsApp Pay opens on its payment confirmation screen showing the payee and ₹2.00. THE most important comparison in the catalogue. Several apps switch from a person-to-person flow to a merchant flow when mc appears — changing limits, fees and whether the amount can be edited. P01 against P03 on the same app, same destination, same minute is the controlled experiment that shows it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.whatsapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.whatsapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "WA-004",
            "group": "WA",
            "name": "WhatsApp Pay / Category code and note",
            "application": "WhatsApp Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P04",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "tn"
            ],
            "documentation": "No public UPI deep-link scheme. WhatsApp's own wa.me links are messaging links, not payment intents.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — WhatsApp Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: WhatsApp Pay installed (com.whatsapp)."
            ],
            "expected_behaviour": "WhatsApp Pay opens on its payment confirmation screen showing the payee and ₹2.00. Whether the note survives the merchant flow. Some apps that show a note in a P2P flow drop it in a merchant one.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.whatsapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.whatsapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "WA-005",
            "group": "WA",
            "name": "WhatsApp Pay / Transaction reference URL",
            "application": "WhatsApp Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P05",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "url"
            ],
            "documentation": "No public UPI deep-link scheme. WhatsApp's own wa.me links are messaging links, not payment intents.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — WhatsApp Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: WhatsApp Pay installed (com.whatsapp)."
            ],
            "expected_behaviour": "WhatsApp Pay opens on its payment confirmation screen showing the payee and ₹2.00. Whether the app surfaces an invoice link, ignores it, or refuses the whole intent because of it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.whatsapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.whatsapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "WA-006",
            "group": "WA",
            "name": "WhatsApp Pay / Category code and reference URL",
            "application": "WhatsApp Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P06",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "url"
            ],
            "documentation": "No public UPI deep-link scheme. WhatsApp's own wa.me links are messaging links, not payment intents.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — WhatsApp Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: WhatsApp Pay installed (com.whatsapp)."
            ],
            "expected_behaviour": "WhatsApp Pay opens on its payment confirmation screen showing the payee and ₹2.00. The combination a real invoice-with-QR produces. Isolates interactions between the merchant flow and the invoice link.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.whatsapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.whatsapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "WA-007",
            "group": "WA",
            "name": "WhatsApp Pay / Minimum amount",
            "application": "WhatsApp Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P07",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mam"
            ],
            "documentation": "No public UPI deep-link scheme. WhatsApp's own wa.me links are messaging links, not payment intents.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — WhatsApp Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: WhatsApp Pay installed (com.whatsapp)."
            ],
            "expected_behaviour": "WhatsApp Pay opens on its payment confirmation screen showing the payee and ₹2.00. mam constrains an amount the payer may edit. Beside a fixed am it is contradictory, and WHICH ONE each app honours is the finding. The lab warns about the contradiction and sends it anyway — that is the experiment.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.whatsapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.whatsapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "WA-008",
            "group": "WA",
            "name": "WhatsApp Pay / Category code and minimum amount",
            "application": "WhatsApp Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P08",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "mam"
            ],
            "documentation": "No public UPI deep-link scheme. WhatsApp's own wa.me links are messaging links, not payment intents.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — WhatsApp Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: WhatsApp Pay installed (com.whatsapp)."
            ],
            "expected_behaviour": "WhatsApp Pay opens on its payment confirmation screen showing the payee and ₹2.00. Whether the merchant flow changes how mam is treated.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.whatsapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.whatsapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "WA-009",
            "group": "WA",
            "name": "WhatsApp Pay / Documented initiation metadata",
            "application": "WhatsApp Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P09",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mode",
                "orgid",
                "sign"
            ],
            "documentation": "No public UPI deep-link scheme. WhatsApp's own wa.me links are messaging links, not payment intents.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs an orgid your PSP issued you, and — to be a genuine signed intent — a sign they generated. The lab will not create either. Until you supply them this method cannot run, because sending a made-up orgid tests nothing that exists.",
                "On iOS: not addressable — WhatsApp Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: WhatsApp Pay installed (com.whatsapp)."
            ],
            "expected_behaviour": "WhatsApp Pay opens on its payment confirmation screen showing the payee and ₹2.00. How an app treats a payload that declares an initiation mode and a signing organisation. Only meaningful with real values.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.whatsapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.whatsapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "WA-010",
            "group": "WA",
            "name": "WhatsApp Pay / Bank-issued merchant identifiers",
            "application": "WhatsApp Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P10",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mid",
                "msid",
                "mtid"
            ],
            "documentation": "No public UPI deep-link scheme. WhatsApp's own wa.me links are messaging links, not payment intents.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs the merchant / store / terminal identifiers your acquirer actually assigned you. An invented mid is not a merchant identifier, it is a string, and a result against one would be meaningless.",
                "On iOS: not addressable — WhatsApp Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: WhatsApp Pay installed (com.whatsapp)."
            ],
            "expected_behaviour": "WhatsApp Pay opens on its payment confirmation screen showing the payee and ₹2.00. Whether an acquirer-issued merchant triple changes the receiving experience.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.whatsapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.whatsapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "WA-011",
            "group": "WA",
            "name": "WhatsApp Pay / Imported exact QR",
            "application": "WhatsApp Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "No public UPI deep-link scheme. WhatsApp's own wa.me links are messaging links, not payment intents.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Import a QR into this profile first (QR Decoder → Save as exact original).",
                "On iOS: not addressable — WhatsApp Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: WhatsApp Pay installed (com.whatsapp)."
            ],
            "expected_behaviour": "WhatsApp Pay opens on its payment confirmation screen showing the payee and ₹2.00. The ground truth. Your bank's own placard, unmodified, against each app — the baseline every edited copy is compared to.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming com.whatsapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.whatsapp",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "WA-012",
            "group": "WA",
            "name": "WhatsApp Pay / Imported exact payment URI",
            "application": "WhatsApp Pay",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P12",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "No public UPI deep-link scheme. WhatsApp's own wa.me links are messaging links, not payment intents.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Paste an original payment URI into this profile first (QR Decoder → Save as exact original).",
                "On iOS: not addressable — WhatsApp Pay publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: WhatsApp Pay installed (com.whatsapp)."
            ],
            "expected_behaviour": "WhatsApp Pay opens on its payment confirmation screen showing the payee and ₹2.00. The same ground truth for an intent you were given as a link rather than a QR.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming com.whatsapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.whatsapp",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "CR-001",
            "group": "CR",
            "name": "CRED / Standard merchant intent",
            "application": "CRED",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — CRED publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: CRED installed (com.dreamplug.androidapp)."
            ],
            "expected_behaviour": "CRED opens on its payment confirmation screen showing the payee and ₹2.00. The control. Every other profile is this one plus something, so a failure here is a failure of the destination or the app, never of an optional field.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.dreamplug.androidapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.dreamplug.androidapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "CR-002",
            "group": "CR",
            "name": "CRED / With transaction note",
            "application": "CRED",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P02",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "tn"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — CRED publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: CRED installed (com.dreamplug.androidapp)."
            ],
            "expected_behaviour": "CRED opens on its payment confirmation screen showing the payee and ₹2.00. Whether a note is displayed, truncated, stripped or rejected. Note length limits differ sharply between apps.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.dreamplug.androidapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.dreamplug.androidapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "CR-003",
            "group": "CR",
            "name": "CRED / With merchant category code",
            "application": "CRED",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — CRED publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: CRED installed (com.dreamplug.androidapp)."
            ],
            "expected_behaviour": "CRED opens on its payment confirmation screen showing the payee and ₹2.00. THE most important comparison in the catalogue. Several apps switch from a person-to-person flow to a merchant flow when mc appears — changing limits, fees and whether the amount can be edited. P01 against P03 on the same app, same destination, same minute is the controlled experiment that shows it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.dreamplug.androidapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.dreamplug.androidapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "CR-004",
            "group": "CR",
            "name": "CRED / Category code and note",
            "application": "CRED",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P04",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "tn"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — CRED publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: CRED installed (com.dreamplug.androidapp)."
            ],
            "expected_behaviour": "CRED opens on its payment confirmation screen showing the payee and ₹2.00. Whether the note survives the merchant flow. Some apps that show a note in a P2P flow drop it in a merchant one.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.dreamplug.androidapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.dreamplug.androidapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "CR-005",
            "group": "CR",
            "name": "CRED / Transaction reference URL",
            "application": "CRED",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P05",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "url"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — CRED publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: CRED installed (com.dreamplug.androidapp)."
            ],
            "expected_behaviour": "CRED opens on its payment confirmation screen showing the payee and ₹2.00. Whether the app surfaces an invoice link, ignores it, or refuses the whole intent because of it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.dreamplug.androidapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.dreamplug.androidapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "CR-006",
            "group": "CR",
            "name": "CRED / Category code and reference URL",
            "application": "CRED",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P06",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "url"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — CRED publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: CRED installed (com.dreamplug.androidapp)."
            ],
            "expected_behaviour": "CRED opens on its payment confirmation screen showing the payee and ₹2.00. The combination a real invoice-with-QR produces. Isolates interactions between the merchant flow and the invoice link.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.dreamplug.androidapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.dreamplug.androidapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "CR-007",
            "group": "CR",
            "name": "CRED / Minimum amount",
            "application": "CRED",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P07",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mam"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — CRED publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: CRED installed (com.dreamplug.androidapp)."
            ],
            "expected_behaviour": "CRED opens on its payment confirmation screen showing the payee and ₹2.00. mam constrains an amount the payer may edit. Beside a fixed am it is contradictory, and WHICH ONE each app honours is the finding. The lab warns about the contradiction and sends it anyway — that is the experiment.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.dreamplug.androidapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.dreamplug.androidapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "CR-008",
            "group": "CR",
            "name": "CRED / Category code and minimum amount",
            "application": "CRED",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P08",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "mam"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — CRED publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: CRED installed (com.dreamplug.androidapp)."
            ],
            "expected_behaviour": "CRED opens on its payment confirmation screen showing the payee and ₹2.00. Whether the merchant flow changes how mam is treated.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.dreamplug.androidapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.dreamplug.androidapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "CR-009",
            "group": "CR",
            "name": "CRED / Documented initiation metadata",
            "application": "CRED",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P09",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mode",
                "orgid",
                "sign"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs an orgid your PSP issued you, and — to be a genuine signed intent — a sign they generated. The lab will not create either. Until you supply them this method cannot run, because sending a made-up orgid tests nothing that exists.",
                "On iOS: not addressable — CRED publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: CRED installed (com.dreamplug.androidapp)."
            ],
            "expected_behaviour": "CRED opens on its payment confirmation screen showing the payee and ₹2.00. How an app treats a payload that declares an initiation mode and a signing organisation. Only meaningful with real values.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.dreamplug.androidapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.dreamplug.androidapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "CR-010",
            "group": "CR",
            "name": "CRED / Bank-issued merchant identifiers",
            "application": "CRED",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P10",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mid",
                "msid",
                "mtid"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs the merchant / store / terminal identifiers your acquirer actually assigned you. An invented mid is not a merchant identifier, it is a string, and a result against one would be meaningless.",
                "On iOS: not addressable — CRED publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: CRED installed (com.dreamplug.androidapp)."
            ],
            "expected_behaviour": "CRED opens on its payment confirmation screen showing the payee and ₹2.00. Whether an acquirer-issued merchant triple changes the receiving experience.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.dreamplug.androidapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.dreamplug.androidapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "CR-011",
            "group": "CR",
            "name": "CRED / Imported exact QR",
            "application": "CRED",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Import a QR into this profile first (QR Decoder → Save as exact original).",
                "On iOS: not addressable — CRED publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: CRED installed (com.dreamplug.androidapp)."
            ],
            "expected_behaviour": "CRED opens on its payment confirmation screen showing the payee and ₹2.00. The ground truth. Your bank's own placard, unmodified, against each app — the baseline every edited copy is compared to.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming com.dreamplug.androidapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.dreamplug.androidapp",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "CR-012",
            "group": "CR",
            "name": "CRED / Imported exact payment URI",
            "application": "CRED",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P12",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Paste an original payment URI into this profile first (QR Decoder → Save as exact original).",
                "On iOS: not addressable — CRED publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: CRED installed (com.dreamplug.androidapp)."
            ],
            "expected_behaviour": "CRED opens on its payment confirmation screen showing the payee and ₹2.00. The same ground truth for an intent you were given as a link rather than a QR.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming com.dreamplug.androidapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.dreamplug.androidapp",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "NV-001",
            "group": "NV",
            "name": "Navi / Standard merchant intent",
            "application": "Navi",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Navi publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Navi installed (com.naviapp)."
            ],
            "expected_behaviour": "Navi opens on its payment confirmation screen showing the payee and ₹2.00. The control. Every other profile is this one plus something, so a failure here is a failure of the destination or the app, never of an optional field.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.naviapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.naviapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "NV-002",
            "group": "NV",
            "name": "Navi / With transaction note",
            "application": "Navi",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P02",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "tn"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Navi publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Navi installed (com.naviapp)."
            ],
            "expected_behaviour": "Navi opens on its payment confirmation screen showing the payee and ₹2.00. Whether a note is displayed, truncated, stripped or rejected. Note length limits differ sharply between apps.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.naviapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.naviapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "NV-003",
            "group": "NV",
            "name": "Navi / With merchant category code",
            "application": "Navi",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Navi publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Navi installed (com.naviapp)."
            ],
            "expected_behaviour": "Navi opens on its payment confirmation screen showing the payee and ₹2.00. THE most important comparison in the catalogue. Several apps switch from a person-to-person flow to a merchant flow when mc appears — changing limits, fees and whether the amount can be edited. P01 against P03 on the same app, same destination, same minute is the controlled experiment that shows it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.naviapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.naviapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "NV-004",
            "group": "NV",
            "name": "Navi / Category code and note",
            "application": "Navi",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P04",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "tn"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Navi publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Navi installed (com.naviapp)."
            ],
            "expected_behaviour": "Navi opens on its payment confirmation screen showing the payee and ₹2.00. Whether the note survives the merchant flow. Some apps that show a note in a P2P flow drop it in a merchant one.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.naviapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.naviapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "NV-005",
            "group": "NV",
            "name": "Navi / Transaction reference URL",
            "application": "Navi",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P05",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "url"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Navi publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Navi installed (com.naviapp)."
            ],
            "expected_behaviour": "Navi opens on its payment confirmation screen showing the payee and ₹2.00. Whether the app surfaces an invoice link, ignores it, or refuses the whole intent because of it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.naviapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.naviapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "NV-006",
            "group": "NV",
            "name": "Navi / Category code and reference URL",
            "application": "Navi",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P06",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "url"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Navi publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Navi installed (com.naviapp)."
            ],
            "expected_behaviour": "Navi opens on its payment confirmation screen showing the payee and ₹2.00. The combination a real invoice-with-QR produces. Isolates interactions between the merchant flow and the invoice link.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.naviapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.naviapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "NV-007",
            "group": "NV",
            "name": "Navi / Minimum amount",
            "application": "Navi",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P07",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mam"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Navi publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Navi installed (com.naviapp)."
            ],
            "expected_behaviour": "Navi opens on its payment confirmation screen showing the payee and ₹2.00. mam constrains an amount the payer may edit. Beside a fixed am it is contradictory, and WHICH ONE each app honours is the finding. The lab warns about the contradiction and sends it anyway — that is the experiment.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.naviapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.naviapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "NV-008",
            "group": "NV",
            "name": "Navi / Category code and minimum amount",
            "application": "Navi",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P08",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "mam"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — Navi publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Navi installed (com.naviapp)."
            ],
            "expected_behaviour": "Navi opens on its payment confirmation screen showing the payee and ₹2.00. Whether the merchant flow changes how mam is treated.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.naviapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.naviapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "NV-009",
            "group": "NV",
            "name": "Navi / Documented initiation metadata",
            "application": "Navi",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P09",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mode",
                "orgid",
                "sign"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs an orgid your PSP issued you, and — to be a genuine signed intent — a sign they generated. The lab will not create either. Until you supply them this method cannot run, because sending a made-up orgid tests nothing that exists.",
                "On iOS: not addressable — Navi publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Navi installed (com.naviapp)."
            ],
            "expected_behaviour": "Navi opens on its payment confirmation screen showing the payee and ₹2.00. How an app treats a payload that declares an initiation mode and a signing organisation. Only meaningful with real values.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.naviapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.naviapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "NV-010",
            "group": "NV",
            "name": "Navi / Bank-issued merchant identifiers",
            "application": "Navi",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P10",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mid",
                "msid",
                "mtid"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs the merchant / store / terminal identifiers your acquirer actually assigned you. An invented mid is not a merchant identifier, it is a string, and a result against one would be meaningless.",
                "On iOS: not addressable — Navi publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Navi installed (com.naviapp)."
            ],
            "expected_behaviour": "Navi opens on its payment confirmation screen showing the payee and ₹2.00. Whether an acquirer-issued merchant triple changes the receiving experience.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming com.naviapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.naviapp",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "NV-011",
            "group": "NV",
            "name": "Navi / Imported exact QR",
            "application": "Navi",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Import a QR into this profile first (QR Decoder → Save as exact original).",
                "On iOS: not addressable — Navi publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Navi installed (com.naviapp)."
            ],
            "expected_behaviour": "Navi opens on its payment confirmation screen showing the payee and ₹2.00. The ground truth. Your bank's own placard, unmodified, against each app — the baseline every edited copy is compared to.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming com.naviapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.naviapp",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "NV-012",
            "group": "NV",
            "name": "Navi / Imported exact payment URI",
            "application": "Navi",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P12",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Paste an original payment URI into this profile first (QR Decoder → Save as exact original).",
                "On iOS: not addressable — Navi publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: Navi installed (com.naviapp)."
            ],
            "expected_behaviour": "Navi opens on its payment confirmation screen showing the payee and ₹2.00. The same ground truth for an intent you were given as a link rather than a QR.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming com.naviapp, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "com.naviapp",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "SM-001",
            "group": "SM",
            "name": "super.money / Standard merchant intent",
            "application": "super.money",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — super.money publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: super.money installed (money.super.app)."
            ],
            "expected_behaviour": "super.money opens on its payment confirmation screen showing the payee and ₹2.00. The control. Every other profile is this one plus something, so a failure here is a failure of the destination or the app, never of an optional field.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming money.super.app, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "money.super.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "SM-002",
            "group": "SM",
            "name": "super.money / With transaction note",
            "application": "super.money",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P02",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "tn"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — super.money publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: super.money installed (money.super.app)."
            ],
            "expected_behaviour": "super.money opens on its payment confirmation screen showing the payee and ₹2.00. Whether a note is displayed, truncated, stripped or rejected. Note length limits differ sharply between apps.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming money.super.app, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "money.super.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "SM-003",
            "group": "SM",
            "name": "super.money / With merchant category code",
            "application": "super.money",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — super.money publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: super.money installed (money.super.app)."
            ],
            "expected_behaviour": "super.money opens on its payment confirmation screen showing the payee and ₹2.00. THE most important comparison in the catalogue. Several apps switch from a person-to-person flow to a merchant flow when mc appears — changing limits, fees and whether the amount can be edited. P01 against P03 on the same app, same destination, same minute is the controlled experiment that shows it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming money.super.app, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "money.super.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "SM-004",
            "group": "SM",
            "name": "super.money / Category code and note",
            "application": "super.money",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P04",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "tn"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — super.money publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: super.money installed (money.super.app)."
            ],
            "expected_behaviour": "super.money opens on its payment confirmation screen showing the payee and ₹2.00. Whether the note survives the merchant flow. Some apps that show a note in a P2P flow drop it in a merchant one.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming money.super.app, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "money.super.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "SM-005",
            "group": "SM",
            "name": "super.money / Transaction reference URL",
            "application": "super.money",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P05",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "url"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — super.money publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: super.money installed (money.super.app)."
            ],
            "expected_behaviour": "super.money opens on its payment confirmation screen showing the payee and ₹2.00. Whether the app surfaces an invoice link, ignores it, or refuses the whole intent because of it.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming money.super.app, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "money.super.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "SM-006",
            "group": "SM",
            "name": "super.money / Category code and reference URL",
            "application": "super.money",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P06",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "url"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — super.money publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: super.money installed (money.super.app)."
            ],
            "expected_behaviour": "super.money opens on its payment confirmation screen showing the payee and ₹2.00. The combination a real invoice-with-QR produces. Isolates interactions between the merchant flow and the invoice link.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming money.super.app, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "money.super.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "SM-007",
            "group": "SM",
            "name": "super.money / Minimum amount",
            "application": "super.money",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P07",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mam"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — super.money publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: super.money installed (money.super.app)."
            ],
            "expected_behaviour": "super.money opens on its payment confirmation screen showing the payee and ₹2.00. mam constrains an amount the payer may edit. Beside a fixed am it is contradictory, and WHICH ONE each app honours is the finding. The lab warns about the contradiction and sends it anyway — that is the experiment.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming money.super.app, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "money.super.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "SM-008",
            "group": "SM",
            "name": "super.money / Category code and minimum amount",
            "application": "super.money",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P08",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "mam"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "On iOS: not addressable — super.money publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: super.money installed (money.super.app)."
            ],
            "expected_behaviour": "super.money opens on its payment confirmation screen showing the payee and ₹2.00. Whether the merchant flow changes how mam is treated.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming money.super.app, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "money.super.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "SM-009",
            "group": "SM",
            "name": "super.money / Documented initiation metadata",
            "application": "super.money",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P09",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mode",
                "orgid",
                "sign"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs an orgid your PSP issued you, and — to be a genuine signed intent — a sign they generated. The lab will not create either. Until you supply them this method cannot run, because sending a made-up orgid tests nothing that exists.",
                "On iOS: not addressable — super.money publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: super.money installed (money.super.app)."
            ],
            "expected_behaviour": "super.money opens on its payment confirmation screen showing the payee and ₹2.00. How an app treats a payload that declares an initiation mode and a signing organisation. Only meaningful with real values.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming money.super.app, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "money.super.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "SM-010",
            "group": "SM",
            "name": "super.money / Bank-issued merchant identifiers",
            "application": "super.money",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "app_targeted",
            "parameter_profile": "P10",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mid",
                "msid",
                "mtid"
            ],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Needs the merchant / store / terminal identifiers your acquirer actually assigned you. An invented mid is not a merchant identifier, it is a string, and a result against one would be meaningless.",
                "On iOS: not addressable — super.money publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: super.money installed (money.super.app)."
            ],
            "expected_behaviour": "super.money opens on its payment confirmation screen showing the payee and ₹2.00. Whether an acquirer-issued merchant triple changes the receiving experience.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method."
            ],
            "implementation": "Android: an intent:// URI naming money.super.app, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "money.super.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "SM-011",
            "group": "SM",
            "name": "super.money / Imported exact QR",
            "application": "super.money",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Import a QR into this profile first (QR Decoder → Save as exact original).",
                "On iOS: not addressable — super.money publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: super.money installed (money.super.app)."
            ],
            "expected_behaviour": "super.money opens on its payment confirmation screen showing the payee and ₹2.00. The ground truth. Your bank's own placard, unmodified, against each app — the baseline every edited copy is compared to.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming money.super.app, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "money.super.app",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "SM-012",
            "group": "SM",
            "name": "super.money / Imported exact payment URI",
            "application": "super.money",
            "platform": "android",
            "browser_requirement": "Android: Chrome or any browser that follows intent: URIs. iOS: Safari, only where the app registers a scheme.",
            "uri_scheme": "intent:// (Android only)",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P12",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "No public UPI deep-link specification.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile with a payee address.",
                "Paste an original payment URI into this profile first (QR Decoder → Save as exact original).",
                "On iOS: not addressable — super.money publishes no URI scheme the lab is willing to claim. Use the Generic UPI group (GN) on iPhone.",
                "On Android: super.money installed (money.super.app)."
            ],
            "expected_behaviour": "super.money opens on its payment confirmation screen showing the payee and ₹2.00. The same ground truth for an intent you were given as a link rather than a QR.",
            "known_limitations": [
                "A browser cannot tell you whether an app is installed. \"App did not open\" and \"app is not installed\" look identical from here; AN-004 in the Android harness is what separates them.",
                "Not runnable on iOS at all through this method.",
                "Replays imported bytes. The parameters shown are whatever the original payload contained, not the lab's."
            ],
            "implementation": "Android: an intent:// URI naming money.super.app, with no browser_fallback_url so a failure to open stays visible. iOS: not implemented, because no scheme exists to implement.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "money.super.app",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "GP-013",
            "group": "GP",
            "name": "Google Pay / reached through the generic UPI chooser",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "Any browser that follows upi:// links.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "generic_chooser",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "NPCI UPI Linking Specification — upi:// deep link.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile.",
                "You must choose Google Pay yourself from the chooser; the lab cannot and does not choose for you."
            ],
            "expected_behaviour": "The OS offers every installed UPI app. Selecting Google Pay opens it on the payment screen. Compare against the app-targeted method with the same profile: if the targeted one fails and this one works, the problem is the intent, not the app.",
            "known_limitations": [
                "The result depends on what the operator picked. Attribution is weaker than an app-targeted method, which is exactly why both exist.",
                "On iOS a upi:// link only resolves if some installed app claims the scheme; many do not."
            ],
            "implementation": "An anchor whose href is upi://pay?… built from profile P03.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.google.android.apps.nbu.paisa.user",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GP-014",
            "group": "GP",
            "name": "Google Pay / documented tez:// scheme",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "iOS Safari primarily; also resolvable on Android.",
            "uri_scheme": "tez://upi/pay",
            "launch_mechanism": "app_scheme",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "Google Pay for India developer documentation — the tez:// UPI deep link.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "Google Pay installed."
            ],
            "expected_behaviour": "Google Pay opens directly, without a chooser. This is the ONLY app-specific scheme in the catalogue whose vendor published it for third-party use, which makes it the most trustworthy iOS method here.",
            "known_limitations": [
                "Google has deprecated parts of the Tez-era surface over time; a failure may mean the scheme was withdrawn rather than that the parameters were wrong."
            ],
            "implementation": "An anchor whose href is tez://upi/pay?… built from profile P01.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.google.android.apps.nbu.paisa.user",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GP-015",
            "group": "GP",
            "name": "Google Pay / gpay:// scheme",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "iOS Safari primarily.",
            "uri_scheme": "gpay://upi/pay",
            "launch_mechanism": "app_scheme",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "Observed alongside the documented tez:// scheme; treated as observed rather than documented.",
            "documentation_status": "observed",
            "prerequisites": [
                "Google Pay installed."
            ],
            "expected_behaviour": "Behaves as GP-014. Run both: whether gpay:// and tez:// still resolve to the same place is worth knowing before depending on either.",
            "known_limitations": [
                "Observed, not documented. May stop working without notice."
            ],
            "implementation": "An anchor whose href is gpay://upi/pay?… built from profile P01.",
            "status": "experimental",
            "registry_version": "1.0.0",
            "android_package": "com.google.android.apps.nbu.paisa.user",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GP-016",
            "group": "GP",
            "name": "Google Pay for Web (merchant integration)",
            "application": "Google Pay",
            "platform": "any",
            "browser_requirement": "A browser supporting the Google Pay JavaScript API.",
            "uri_scheme": "(none — JavaScript API)",
            "launch_mechanism": "vendor_web",
            "parameter_profile": "P10",
            "required_fields": [
                "merchant_id",
                "gateway_credentials"
            ],
            "optional_fields": [],
            "documentation": "Google Pay API for Web — requires a Google Pay merchant profile and a supported payment gateway.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "A Google Pay merchant identifier issued to you by Google.",
                "A supported payment gateway with its own credentials.",
                "The lab will not fabricate any of these, so this slot stays unavailable until they exist."
            ],
            "expected_behaviour": "A Google Pay sheet inside the page, with no app switch. This is a genuinely different integration from every other method here — it is listed so the catalogue is honest about what exists, not because the lab can run it today.",
            "known_limitations": [
                "NOT IMPLEMENTED AND NOT RUNNABLE. It needs merchant onboarding the lab has no part in.",
                "Counted in the planned 166 and excluded from the runnable count."
            ],
            "implementation": "Not implemented.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PH-013",
            "group": "PH",
            "name": "PhonePe / reached through the generic UPI chooser",
            "application": "PhonePe",
            "platform": "any",
            "browser_requirement": "Any browser that follows upi:// links.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "generic_chooser",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "NPCI UPI Linking Specification — upi:// deep link.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile.",
                "You must choose PhonePe yourself from the chooser; the lab cannot and does not choose for you."
            ],
            "expected_behaviour": "The OS offers every installed UPI app. Selecting PhonePe opens it on the payment screen. Compare against the app-targeted method with the same profile: if the targeted one fails and this one works, the problem is the intent, not the app.",
            "known_limitations": [
                "The result depends on what the operator picked. Attribution is weaker than an app-targeted method, which is exactly why both exist.",
                "On iOS a upi:// link only resolves if some installed app claims the scheme; many do not."
            ],
            "implementation": "An anchor whose href is upi://pay?… built from profile P03.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "com.phonepe.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PH-014",
            "group": "PH",
            "name": "PhonePe / phonepe:// scheme",
            "application": "PhonePe",
            "platform": "any",
            "browser_requirement": "iOS Safari primarily; also resolvable on Android.",
            "uri_scheme": "phonepe://pay",
            "launch_mechanism": "app_scheme",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "No public PhonePe specification for third-party deep links. The scheme is observed in the wild.",
            "documentation_status": "observed",
            "prerequisites": [
                "PhonePe installed."
            ],
            "expected_behaviour": "PhonePe opens directly if it registers the scheme. A failure here is the EXPECTED outcome if PhonePe does not expose it — and that negative is worth recording, because it is the answer to \"can we deep-link PhonePe on iPhone\".",
            "known_limitations": [
                "UNDOCUMENTED. A working result must not be treated as a supported integration; PhonePe can remove it at any time.",
                "PhonePe's supported path for merchants is their SDK / payment gateway, which is not a deep link and is out of scope for this lab."
            ],
            "implementation": "An anchor whose href is phonepe://pay?… built from profile P01.",
            "status": "experimental",
            "registry_version": "1.0.0",
            "android_package": "com.phonepe.app",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PT-013",
            "group": "PT",
            "name": "Paytm / reached through the generic UPI chooser",
            "application": "Paytm",
            "platform": "any",
            "browser_requirement": "Any browser that follows upi:// links.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "generic_chooser",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "NPCI UPI Linking Specification — upi:// deep link.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile.",
                "You must choose Paytm yourself from the chooser; the lab cannot and does not choose for you."
            ],
            "expected_behaviour": "The OS offers every installed UPI app. Selecting Paytm opens it on the payment screen. Compare against the app-targeted method with the same profile: if the targeted one fails and this one works, the problem is the intent, not the app.",
            "known_limitations": [
                "The result depends on what the operator picked. Attribution is weaker than an app-targeted method, which is exactly why both exist.",
                "On iOS a upi:// link only resolves if some installed app claims the scheme; many do not."
            ],
            "implementation": "An anchor whose href is upi://pay?… built from profile P03.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "net.one97.paytm",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "PT-014",
            "group": "PT",
            "name": "Paytm / paytmmp:// scheme",
            "application": "Paytm",
            "platform": "any",
            "browser_requirement": "iOS Safari primarily; also resolvable on Android.",
            "uri_scheme": "paytmmp://pay",
            "launch_mechanism": "app_scheme",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "No public Paytm specification for third-party deep links. The scheme is observed in the wild.",
            "documentation_status": "observed",
            "prerequisites": [
                "Paytm installed."
            ],
            "expected_behaviour": "Paytm opens directly if it registers the scheme.",
            "known_limitations": [
                "UNDOCUMENTED. Paytm's supported merchant path is their payment gateway with an issued merchant ID — a different integration entirely, and one the lab deliberately does not pretend to implement."
            ],
            "implementation": "An anchor whose href is paytmmp://pay?… built from profile P01.",
            "status": "experimental",
            "registry_version": "1.0.0",
            "android_package": "net.one97.paytm",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GN-001",
            "group": "GN",
            "name": "Generic UPI / Standard merchant intent",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Any browser that follows upi:// links.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "generic_chooser",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "NPCI UPI Linking Specification — upi:// deep link.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile."
            ],
            "expected_behaviour": "The OS offers the installed UPI apps; the one you pick opens on its payment screen. The control. Every other profile is this one plus something, so a failure here is a failure of the destination or the app, never of an optional field.",
            "known_limitations": [
                "This group is the ONLY one that is meaningfully runnable on an iPhone, and even there it depends on an installed app claiming the upi:// scheme.",
                "Attribution is to whichever app the operator selected, which must be recorded with the result."
            ],
            "implementation": "An anchor whose href is upi://pay?… built from P01.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GN-002",
            "group": "GN",
            "name": "Generic UPI / With transaction note",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Any browser that follows upi:// links.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "generic_chooser",
            "parameter_profile": "P02",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "tn"
            ],
            "documentation": "NPCI UPI Linking Specification — upi:// deep link.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile."
            ],
            "expected_behaviour": "The OS offers the installed UPI apps; the one you pick opens on its payment screen. Whether a note is displayed, truncated, stripped or rejected. Note length limits differ sharply between apps.",
            "known_limitations": [
                "This group is the ONLY one that is meaningfully runnable on an iPhone, and even there it depends on an installed app claiming the upi:// scheme.",
                "Attribution is to whichever app the operator selected, which must be recorded with the result."
            ],
            "implementation": "An anchor whose href is upi://pay?… built from P02.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GN-003",
            "group": "GN",
            "name": "Generic UPI / With merchant category code",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Any browser that follows upi:// links.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "generic_chooser",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "NPCI UPI Linking Specification — upi:// deep link.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile."
            ],
            "expected_behaviour": "The OS offers the installed UPI apps; the one you pick opens on its payment screen. THE most important comparison in the catalogue. Several apps switch from a person-to-person flow to a merchant flow when mc appears — changing limits, fees and whether the amount can be edited. P01 against P03 on the same app, same destination, same minute is the controlled experiment that shows it.",
            "known_limitations": [
                "This group is the ONLY one that is meaningfully runnable on an iPhone, and even there it depends on an installed app claiming the upi:// scheme.",
                "Attribution is to whichever app the operator selected, which must be recorded with the result."
            ],
            "implementation": "An anchor whose href is upi://pay?… built from P03.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GN-004",
            "group": "GN",
            "name": "Generic UPI / Category code and note",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Any browser that follows upi:// links.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "generic_chooser",
            "parameter_profile": "P04",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "tn"
            ],
            "documentation": "NPCI UPI Linking Specification — upi:// deep link.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile."
            ],
            "expected_behaviour": "The OS offers the installed UPI apps; the one you pick opens on its payment screen. Whether the note survives the merchant flow. Some apps that show a note in a P2P flow drop it in a merchant one.",
            "known_limitations": [
                "This group is the ONLY one that is meaningfully runnable on an iPhone, and even there it depends on an installed app claiming the upi:// scheme.",
                "Attribution is to whichever app the operator selected, which must be recorded with the result."
            ],
            "implementation": "An anchor whose href is upi://pay?… built from P04.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GN-005",
            "group": "GN",
            "name": "Generic UPI / Transaction reference URL",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Any browser that follows upi:// links.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "generic_chooser",
            "parameter_profile": "P05",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "url"
            ],
            "documentation": "NPCI UPI Linking Specification — upi:// deep link.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile."
            ],
            "expected_behaviour": "The OS offers the installed UPI apps; the one you pick opens on its payment screen. Whether the app surfaces an invoice link, ignores it, or refuses the whole intent because of it.",
            "known_limitations": [
                "This group is the ONLY one that is meaningfully runnable on an iPhone, and even there it depends on an installed app claiming the upi:// scheme.",
                "Attribution is to whichever app the operator selected, which must be recorded with the result."
            ],
            "implementation": "An anchor whose href is upi://pay?… built from P05.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GN-006",
            "group": "GN",
            "name": "Generic UPI / Category code and reference URL",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Any browser that follows upi:// links.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "generic_chooser",
            "parameter_profile": "P06",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "url"
            ],
            "documentation": "NPCI UPI Linking Specification — upi:// deep link.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile."
            ],
            "expected_behaviour": "The OS offers the installed UPI apps; the one you pick opens on its payment screen. The combination a real invoice-with-QR produces. Isolates interactions between the merchant flow and the invoice link.",
            "known_limitations": [
                "This group is the ONLY one that is meaningfully runnable on an iPhone, and even there it depends on an installed app claiming the upi:// scheme.",
                "Attribution is to whichever app the operator selected, which must be recorded with the result."
            ],
            "implementation": "An anchor whose href is upi://pay?… built from P06.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GN-007",
            "group": "GN",
            "name": "Generic UPI / Minimum amount",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Any browser that follows upi:// links.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "generic_chooser",
            "parameter_profile": "P07",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mam"
            ],
            "documentation": "NPCI UPI Linking Specification — upi:// deep link.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile."
            ],
            "expected_behaviour": "The OS offers the installed UPI apps; the one you pick opens on its payment screen. mam constrains an amount the payer may edit. Beside a fixed am it is contradictory, and WHICH ONE each app honours is the finding. The lab warns about the contradiction and sends it anyway — that is the experiment.",
            "known_limitations": [
                "This group is the ONLY one that is meaningfully runnable on an iPhone, and even there it depends on an installed app claiming the upi:// scheme.",
                "Attribution is to whichever app the operator selected, which must be recorded with the result."
            ],
            "implementation": "An anchor whose href is upi://pay?… built from P07.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GN-008",
            "group": "GN",
            "name": "Generic UPI / Category code and minimum amount",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Any browser that follows upi:// links.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "generic_chooser",
            "parameter_profile": "P08",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc",
                "mam"
            ],
            "documentation": "NPCI UPI Linking Specification — upi:// deep link.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile."
            ],
            "expected_behaviour": "The OS offers the installed UPI apps; the one you pick opens on its payment screen. Whether the merchant flow changes how mam is treated.",
            "known_limitations": [
                "This group is the ONLY one that is meaningfully runnable on an iPhone, and even there it depends on an installed app claiming the upi:// scheme.",
                "Attribution is to whichever app the operator selected, which must be recorded with the result."
            ],
            "implementation": "An anchor whose href is upi://pay?… built from P08.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GN-009",
            "group": "GN",
            "name": "Generic UPI / Documented initiation metadata",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Any browser that follows upi:// links.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "generic_chooser",
            "parameter_profile": "P09",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mode",
                "orgid",
                "sign"
            ],
            "documentation": "NPCI UPI Linking Specification — upi:// deep link.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile.",
                "Needs an orgid your PSP issued you, and — to be a genuine signed intent — a sign they generated. The lab will not create either. Until you supply them this method cannot run, because sending a made-up orgid tests nothing that exists."
            ],
            "expected_behaviour": "The OS offers the installed UPI apps; the one you pick opens on its payment screen. How an app treats a payload that declares an initiation mode and a signing organisation. Only meaningful with real values.",
            "known_limitations": [
                "This group is the ONLY one that is meaningfully runnable on an iPhone, and even there it depends on an installed app claiming the upi:// scheme.",
                "Attribution is to whichever app the operator selected, which must be recorded with the result."
            ],
            "implementation": "An anchor whose href is upi://pay?… built from P09.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GN-010",
            "group": "GN",
            "name": "Generic UPI / Bank-issued merchant identifiers",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Any browser that follows upi:// links.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "generic_chooser",
            "parameter_profile": "P10",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mid",
                "msid",
                "mtid"
            ],
            "documentation": "NPCI UPI Linking Specification — upi:// deep link.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile.",
                "Needs the merchant / store / terminal identifiers your acquirer actually assigned you. An invented mid is not a merchant identifier, it is a string, and a result against one would be meaningless."
            ],
            "expected_behaviour": "The OS offers the installed UPI apps; the one you pick opens on its payment screen. Whether an acquirer-issued merchant triple changes the receiving experience.",
            "known_limitations": [
                "This group is the ONLY one that is meaningfully runnable on an iPhone, and even there it depends on an installed app claiming the upi:// scheme.",
                "Attribution is to whichever app the operator selected, which must be recorded with the result."
            ],
            "implementation": "An anchor whose href is upi://pay?… built from P10.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GN-011",
            "group": "GN",
            "name": "Generic UPI / Imported exact QR",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Any browser that follows upi:// links.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "NPCI UPI Linking Specification — upi:// deep link.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile.",
                "Import a QR into this profile first (QR Decoder → Save as exact original)."
            ],
            "expected_behaviour": "The OS offers the installed UPI apps; the one you pick opens on its payment screen. The ground truth. Your bank's own placard, unmodified, against each app — the baseline every edited copy is compared to.",
            "known_limitations": [
                "This group is the ONLY one that is meaningfully runnable on an iPhone, and even there it depends on an installed app claiming the upi:// scheme.",
                "Attribution is to whichever app the operator selected, which must be recorded with the result."
            ],
            "implementation": "An anchor whose href is upi://pay?… built from P11.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "GN-012",
            "group": "GN",
            "name": "Generic UPI / Imported exact payment URI",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Any browser that follows upi:// links.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "exact_replay",
            "parameter_profile": "P12",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "NPCI UPI Linking Specification — upi:// deep link.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile.",
                "Paste an original payment URI into this profile first (QR Decoder → Save as exact original)."
            ],
            "expected_behaviour": "The OS offers the installed UPI apps; the one you pick opens on its payment screen. The same ground truth for an intent you were given as a link rather than a QR.",
            "known_limitations": [
                "This group is the ONLY one that is meaningfully runnable on an iPhone, and even there it depends on an installed app claiming the upi:// scheme.",
                "Attribution is to whichever app the operator selected, which must be recorded with the result."
            ],
            "implementation": "An anchor whose href is upi://pay?… built from P12.",
            "status": "prerequisite",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "GN-013",
            "group": "GN",
            "name": "Generic UPI / dispatch by anchor element click",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Differs by technique — that is the point of the method.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "dispatch_variant",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "Browser behaviour, not a UPI specification. See each browser's external-protocol handling.",
            "documentation_status": "undocumented",
            "prerequisites": [
                "A saved UPI profile."
            ],
            "expected_behaviour": "The baseline, and the only technique that counts as a genuine user gesture everywhere.",
            "known_limitations": [
                "Holds the URI constant and changes only the dispatch, so a difference between GN-013 and this method is a BROWSER difference and never a UPI one."
            ],
            "implementation": "A real <a href=\"upi://…\"> that the operator taps.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GN-014",
            "group": "GN",
            "name": "Generic UPI / dispatch by window.location assignment",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Differs by technique — that is the point of the method.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "dispatch_variant",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "Browser behaviour, not a UPI specification. See each browser's external-protocol handling.",
            "documentation_status": "undocumented",
            "prerequisites": [
                "A saved UPI profile."
            ],
            "expected_behaviour": "Some in-app browsers handle this differently from an anchor. Still inside a user gesture, so it should be allowed.",
            "known_limitations": [
                "Holds the URI constant and changes only the dispatch, so a difference between GN-013 and this method is a BROWSER difference and never a UPI one."
            ],
            "implementation": "Script sets window.location.href to the UPI URI inside the tap handler.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GN-015",
            "group": "GN",
            "name": "Generic UPI / dispatch by hidden iframe src",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Differs by technique — that is the point of the method.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "dispatch_variant",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "Browser behaviour, not a UPI specification. See each browser's external-protocol handling.",
            "documentation_status": "undocumented",
            "prerequisites": [
                "A saved UPI profile."
            ],
            "expected_behaviour": "A legacy technique. Modern browsers block custom-scheme navigation from a non-top-level frame, so FAILURE IS THE EXPECTED RESULT — this method exists to prove the block, because integrations still ship it.",
            "known_limitations": [
                "Holds the URI constant and changes only the dispatch, so a difference between GN-013 and this method is a BROWSER difference and never a UPI one."
            ],
            "implementation": "The URI is assigned to the src of an off-screen iframe.",
            "status": "experimental",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "GN-016",
            "group": "GN",
            "name": "Generic UPI / dispatch by form submission",
            "application": "Any installed UPI app",
            "platform": "any",
            "browser_requirement": "Differs by technique — that is the point of the method.",
            "uri_scheme": "upi://pay",
            "launch_mechanism": "dispatch_variant",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "Browser behaviour, not a UPI specification. See each browser's external-protocol handling.",
            "documentation_status": "undocumented",
            "prerequisites": [
                "A saved UPI profile."
            ],
            "expected_behaviour": "Blocked by the form-action content security policy on any site that sets one, including this lab. The lab therefore reports it as blocked-by-design and explains why, rather than quietly failing.",
            "known_limitations": [
                "Holds the URI constant and changes only the dispatch, so a difference between GN-013 and this method is a BROWSER difference and never a UPI one."
            ],
            "implementation": "A form whose action is the UPI URI is submitted.",
            "status": "experimental",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "QR-001",
            "group": "QR",
            "name": "Decode an uploaded QR image",
            "application": "(no app — decoding only)",
            "platform": "any",
            "browser_requirement": "Any modern browser.",
            "uri_scheme": "(none)",
            "launch_mechanism": "decode_only",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "EMVCo merchant QR specification; NPCI UPI Linking Specification; ISO/IEC 18004 (QR).",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "Something to decode."
            ],
            "expected_behaviour": "Every field in the QR is listed, including any the lab has no definition for.",
            "known_limitations": [
                "Decode-only. No app opens and no money can move, so this method is safe to run as often as you like."
            ],
            "implementation": "The image is decoded IN YOUR BROWSER. Only the decoded text reaches the lab's server — the image itself never leaves your device.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": false
        },
        {
            "method_id": "QR-002",
            "group": "QR",
            "name": "Decode a QR inside a screenshot",
            "application": "(no app — decoding only)",
            "platform": "any",
            "browser_requirement": "Any modern browser.",
            "uri_scheme": "(none)",
            "launch_mechanism": "decode_only",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "EMVCo merchant QR specification; NPCI UPI Linking Specification; ISO/IEC 18004 (QR).",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "Something to decode."
            ],
            "expected_behaviour": "The QR is located within a larger screenshot — surrounding app chrome, a status bar, cropped edges — and decoded.",
            "known_limitations": [
                "Decode-only. No app opens and no money can move, so this method is safe to run as often as you like.",
                "A heavily compressed or small screenshot may not decode. That is a limit of the image, not of the payload."
            ],
            "implementation": "Browser-side locate-then-decode across the full screenshot.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": false
        },
        {
            "method_id": "QR-003",
            "group": "QR",
            "name": "Decode through the device camera",
            "application": "(no app — decoding only)",
            "platform": "any",
            "browser_requirement": "Any modern browser.",
            "uri_scheme": "(none)",
            "launch_mechanism": "decode_only",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "EMVCo merchant QR specification; NPCI UPI Linking Specification; ISO/IEC 18004 (QR).",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "Something to decode."
            ],
            "expected_behaviour": "A live camera scan produces the same decode as an upload.",
            "known_limitations": [
                "Decode-only. No app opens and no money can move, so this method is safe to run as often as you like.",
                "Needs camera permission and a secure context (https). Will not work over plain http except on localhost."
            ],
            "implementation": "getUserMedia into a canvas, decoded frame by frame in the browser. No frame is uploaded.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": false
        },
        {
            "method_id": "QR-004",
            "group": "QR",
            "name": "Decode pasted raw payload text",
            "application": "(no app — decoding only)",
            "platform": "any",
            "browser_requirement": "Any modern browser.",
            "uri_scheme": "(none)",
            "launch_mechanism": "decode_only",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "EMVCo merchant QR specification; NPCI UPI Linking Specification; ISO/IEC 18004 (QR).",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "Something to decode."
            ],
            "expected_behaviour": "A payload typed or pasted as text decodes identically to the same payload scanned from an image.",
            "known_limitations": [
                "Decode-only. No app opens and no money can move, so this method is safe to run as often as you like."
            ],
            "implementation": "Server-side parse of the pasted text through the same parser the image path uses.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": false
        },
        {
            "method_id": "QR-005",
            "group": "QR",
            "name": "Decode a pasted complete payment URI",
            "application": "(no app — decoding only)",
            "platform": "any",
            "browser_requirement": "Any modern browser.",
            "uri_scheme": "(none)",
            "launch_mechanism": "decode_only",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "EMVCo merchant QR specification; NPCI UPI Linking Specification; ISO/IEC 18004 (QR).",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "Something to decode."
            ],
            "expected_behaviour": "A full upi:// URI is parsed into its parameters with order, duplicates and encoding preserved.",
            "known_limitations": [
                "Decode-only. No app opens and no money can move, so this method is safe to run as often as you like."
            ],
            "implementation": "UpiUriParser, which never uses parse_str() and never treats + as a space.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": false
        },
        {
            "method_id": "QR-006",
            "group": "QR",
            "name": "Decode an EMVCo / Bharat QR payload",
            "application": "(no app — decoding only)",
            "platform": "any",
            "browser_requirement": "Any modern browser.",
            "uri_scheme": "(none)",
            "launch_mechanism": "decode_only",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "EMVCo merchant QR specification; NPCI UPI Linking Specification; ISO/IEC 18004 (QR).",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "Something to decode."
            ],
            "expected_behaviour": "A tag-length-value payload is decoded tag by tag, with the UPI merchant-account template located wherever it sits rather than assumed to be tag 26.",
            "known_limitations": [
                "Decode-only. No app opens and no money can move, so this method is safe to run as often as you like.",
                "Card-network templates on a Bharat QR carry values the lab shows raw and does not interpret."
            ],
            "implementation": "EmvCoParser with the full tag dictionary.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": false
        },
        {
            "method_id": "QR-007",
            "group": "QR",
            "name": "Validate an EMVCo checksum",
            "application": "(no app — decoding only)",
            "platform": "any",
            "browser_requirement": "Any modern browser.",
            "uri_scheme": "(none)",
            "launch_mechanism": "decode_only",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "EMVCo merchant QR specification; NPCI UPI Linking Specification; ISO/IEC 18004 (QR).",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "Something to decode."
            ],
            "expected_behaviour": "The CRC-16/CCITT-FALSE in tag 63 is recomputed and compared. A mismatch usually means transcription, not a bad placard.",
            "known_limitations": [
                "Decode-only. No app opens and no money can move, so this method is safe to run as often as you like."
            ],
            "implementation": "CRC recomputed over the payload up to and including the 6304 header.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": false
        },
        {
            "method_id": "QR-008",
            "group": "QR",
            "name": "Preserve unknown parameters",
            "application": "(no app — decoding only)",
            "platform": "any",
            "browser_requirement": "Any modern browser.",
            "uri_scheme": "(none)",
            "launch_mechanism": "decode_only",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "EMVCo merchant QR specification; NPCI UPI Linking Specification; ISO/IEC 18004 (QR).",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "Something to decode."
            ],
            "expected_behaviour": "A payload carrying a parameter the lab has never seen keeps it, in position, with its original encoding — and says so.",
            "known_limitations": [
                "Decode-only. No app opens and no money can move, so this method is safe to run as often as you like."
            ],
            "implementation": "Round-trip assertion against the stored raw bytes.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": false
        },
        {
            "method_id": "QR-009",
            "group": "QR",
            "name": "Detect duplicate parameters",
            "application": "(no app — decoding only)",
            "platform": "any",
            "browser_requirement": "Any modern browser.",
            "uri_scheme": "(none)",
            "launch_mechanism": "decode_only",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "EMVCo merchant QR specification; NPCI UPI Linking Specification; ISO/IEC 18004 (QR).",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "Something to decode."
            ],
            "expected_behaviour": "A payload with the same key twice is reported as such rather than silently collapsed.",
            "known_limitations": [
                "Decode-only. No app opens and no money can move, so this method is safe to run as often as you like.",
                "Apps disagree about which duplicate wins; the lab reports the duplication and does not pick a winner."
            ],
            "implementation": "Duplicate detection over the ordered parameter list.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": false
        },
        {
            "method_id": "QR-010",
            "group": "QR",
            "name": "Percent-encoding fidelity",
            "application": "(no app — decoding only)",
            "platform": "any",
            "browser_requirement": "Any modern browser.",
            "uri_scheme": "(none)",
            "launch_mechanism": "decode_only",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "EMVCo merchant QR specification; NPCI UPI Linking Specification; ISO/IEC 18004 (QR).",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "Something to decode."
            ],
            "expected_behaviour": "Rebuilding the payload from the parsed parts reproduces the original bytes exactly, or the lab tells you precisely where it would not.",
            "known_limitations": [
                "Decode-only. No app opens and no money can move, so this method is safe to run as often as you like."
            ],
            "implementation": "rebuild() compared byte-for-byte against the stored original.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": false
        },
        {
            "method_id": "QR-011",
            "group": "QR",
            "name": "Signed-payload detection",
            "application": "(no app — decoding only)",
            "platform": "any",
            "browser_requirement": "Any modern browser.",
            "uri_scheme": "(none)",
            "launch_mechanism": "decode_only",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "EMVCo merchant QR specification; NPCI UPI Linking Specification; ISO/IEC 18004 (QR).",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "Something to decode."
            ],
            "expected_behaviour": "A payload carrying sign/orgid is identified as signed, and every field whose edit would invalidate the signature is locked in the editable copy.",
            "known_limitations": [
                "Decode-only. No app opens and no money can move, so this method is safe to run as often as you like.",
                "The lab cannot verify a signature — only the issuing PSP holds the key. It reports presence and the consequences of editing, never validity."
            ],
            "implementation": "Signature detection plus the edit-impact analysis in SignatureImpact.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": true,
            "can_move_money": false
        },
        {
            "method_id": "QR-012",
            "group": "QR",
            "name": "Scan a lab-generated unsigned QR",
            "application": "Any UPI app with a scanner",
            "platform": "any",
            "browser_requirement": "The QR is rendered in this browser; the scan happens on a phone.",
            "uri_scheme": "upi://pay (encoded in the QR)",
            "launch_mechanism": "qr_scan",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "NPCI UPI Linking Specification; ISO/IEC 18004.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile.",
                "A second device, or the same phone scanning a screen."
            ],
            "expected_behaviour": "The QR the lab generated from your parameters is scanned by a payment app, which opens on its payment screen.",
            "known_limitations": [
                "A scan is a DIFFERENT CODE PATH inside a payment app from a deep link. An app that accepts a parameter by scan may reject it by intent, and vice versa — that difference is the entire reason this group exists."
            ],
            "implementation": "The URI from the selected profile is encoded as a QR and rendered on screen.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "QR-013",
            "group": "QR",
            "name": "Scan an imported original QR replayed by the lab",
            "application": "Any UPI app with a scanner",
            "platform": "any",
            "browser_requirement": "The QR is rendered in this browser; the scan happens on a phone.",
            "uri_scheme": "upi://pay (encoded in the QR)",
            "launch_mechanism": "qr_scan",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "NPCI UPI Linking Specification; ISO/IEC 18004.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile.",
                "A second device, or the same phone scanning a screen."
            ],
            "expected_behaviour": "The lab re-renders your imported payload byte-for-byte as a QR. Scanning it should be indistinguishable from scanning the original placard — if it is not, the difference is in the image, not the data.",
            "known_limitations": [
                "A scan is a DIFFERENT CODE PATH inside a payment app from a deep link. An app that accepts a parameter by scan may reject it by intent, and vice versa — that difference is the entire reason this group exists.",
                "Requires an imported payload."
            ],
            "implementation": "The stored original bytes are re-encoded as a QR with no rebuild.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": true,
            "can_move_money": true
        },
        {
            "method_id": "QR-014",
            "group": "QR",
            "name": "Compare original against regenerated payload",
            "application": "(no app — decoding only)",
            "platform": "any",
            "browser_requirement": "Any modern browser.",
            "uri_scheme": "(none)",
            "launch_mechanism": "decode_only",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "EMVCo merchant QR specification; NPCI UPI Linking Specification; ISO/IEC 18004 (QR).",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "Something to decode."
            ],
            "expected_behaviour": "A byte-level diff between the imported payload and what the lab would generate from the same visible parameters. Any difference is shown character by character.",
            "known_limitations": [
                "Decode-only. No app opens and no money can move, so this method is safe to run as often as you like."
            ],
            "implementation": "Diff of original bytes against rebuild output.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": true,
            "can_move_money": false
        },
        {
            "method_id": "QR-015",
            "group": "QR",
            "name": "Cross-device scan",
            "application": "Any UPI app with a scanner",
            "platform": "any",
            "browser_requirement": "The QR is rendered in this browser; the scan happens on a phone.",
            "uri_scheme": "upi://pay (encoded in the QR)",
            "launch_mechanism": "qr_scan",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "NPCI UPI Linking Specification; ISO/IEC 18004.",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "A saved UPI profile.",
                "A second device, or the same phone scanning a screen."
            ],
            "expected_behaviour": "The same generated QR scanned from a second phone, to separate \"this app rejects this payload\" from \"this phone has a problem\".",
            "known_limitations": [
                "A scan is a DIFFERENT CODE PATH inside a payment app from a deep link. An app that accepts a parameter by scan may reject it by intent, and vice versa — that difference is the entire reason this group exists.",
                "Needs two devices, each recorded separately in the results matrix."
            ],
            "implementation": "Same QR as QR-012; the result records a second device.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "QR-016",
            "group": "QR",
            "name": "Report an undecodable or proprietary QR",
            "application": "(no app — decoding only)",
            "platform": "any",
            "browser_requirement": "Any modern browser.",
            "uri_scheme": "(none)",
            "launch_mechanism": "decode_only",
            "parameter_profile": "P11",
            "required_fields": [],
            "optional_fields": [],
            "documentation": "EMVCo merchant QR specification; NPCI UPI Linking Specification; ISO/IEC 18004 (QR).",
            "documentation_status": "npci_spec",
            "prerequisites": [
                "Something to decode."
            ],
            "expected_behaviour": "For a QR the lab cannot decode — a vendor format, an encrypted payload, an ordinary web link — it says exactly that, shows the raw contents, and explains the limitation. It does not guess.",
            "known_limitations": [
                "Decode-only. No app opens and no money can move, so this method is safe to run as often as you like.",
                "The lab will NOT fetch a web link found in a QR. Following an arbitrary URL that arrived in a QR is how a diagnostic tool becomes a phishing launcher."
            ],
            "implementation": "PayloadClassifier falls through to an explicit unsupported classification.",
            "status": "active",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": false
        },
        {
            "method_id": "AN-001",
            "group": "AN",
            "name": "Implicit ACTION_VIEW with a upi:// URI",
            "application": "Companion Android harness",
            "platform": "android",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// (via Android Intent)",
            "launch_mechanism": "native_android",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "Android Intent and PackageManager documentation; NPCI UPI Linking Specification.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion Android harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical Android device; an emulator has no payment apps."
            ],
            "expected_behaviour": "The system resolves the intent to whatever UPI apps are installed. Baseline for every other Android method.",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "A browser cannot enumerate installed apps, read an activity result, or learn an app version. Claiming otherwise is the most common lie in this problem space."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md. The harness posts its results to this lab's own API, so a native result lands in the same comparison matrix as a web one.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AN-002",
            "group": "AN",
            "name": "Explicit chooser via Intent.createChooser",
            "application": "Companion Android harness",
            "platform": "android",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// (via Android Intent)",
            "launch_mechanism": "native_android",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "Android Intent and PackageManager documentation; NPCI UPI Linking Specification.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion Android harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical Android device; an emulator has no payment apps."
            ],
            "expected_behaviour": "A chooser appears listing the resolvers, titled by the harness. Distinguishes \"no app handles this\" from \"the chooser was dismissed\".",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "A browser cannot enumerate installed apps, read an activity result, or learn an app version. Claiming otherwise is the most common lie in this problem space."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md. The harness posts its results to this lab's own API, so a native result lands in the same comparison matrix as a web one.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AN-003",
            "group": "AN",
            "name": "Package-targeted explicit intent",
            "application": "Companion Android harness",
            "platform": "android",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// (via Android Intent)",
            "launch_mechanism": "native_android",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "Android Intent and PackageManager documentation; NPCI UPI Linking Specification.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion Android harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical Android device; an emulator has no payment apps."
            ],
            "expected_behaviour": "One named app opens with no chooser. The native equivalent of the browser intent:// methods — run both to find out whether Chrome is the limiting factor.",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "A browser cannot enumerate installed apps, read an activity result, or learn an app version. Claiming otherwise is the most common lie in this problem space."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md. The harness posts its results to this lab's own API, so a native result lands in the same comparison matrix as a web one.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AN-004",
            "group": "AN",
            "name": "Enumerate UPI handlers with queryIntentActivities",
            "application": "Companion Android harness",
            "platform": "android",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// (via Android Intent)",
            "launch_mechanism": "native_android",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "Android Intent and PackageManager documentation; NPCI UPI Linking Specification.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion Android harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical Android device; an emulator has no payment apps."
            ],
            "expected_behaviour": "A list of every installed app that claims upi://, with package names and versions. THE method that turns \"the app did not open\" into a real answer. It is also the only way to confirm the package names this catalogue uses for Navi and super.money.",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "A browser cannot enumerate installed apps, read an activity result, or learn an app version. Claiming otherwise is the most common lie in this problem space."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md. The harness posts its results to this lab's own API, so a native result lands in the same comparison matrix as a web one.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AN-005",
            "group": "AN",
            "name": "Observe the activity result",
            "application": "Companion Android harness",
            "platform": "android",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// (via Android Intent)",
            "launch_mechanism": "native_android",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "Android Intent and PackageManager documentation; NPCI UPI Linking Specification.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion Android harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical Android device; an emulator has no payment apps."
            ],
            "expected_behaviour": "The response the payment app returns to the calling activity is captured verbatim. A browser never sees this. It is the single largest capability gap between the web lab and a native harness.",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "A browser cannot enumerate installed apps, read an activity result, or learn an app version. Claiming otherwise is the most common lie in this problem space."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md. The harness posts its results to this lab's own API, so a native result lands in the same comparison matrix as a web one.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AN-006",
            "group": "AN",
            "name": "Parse the UPI response string",
            "application": "Companion Android harness",
            "platform": "android",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// (via Android Intent)",
            "launch_mechanism": "native_android",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "Android Intent and PackageManager documentation; NPCI UPI Linking Specification.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion Android harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical Android device; an emulator has no payment apps."
            ],
            "expected_behaviour": "txnId, responseCode, Status and txnRef are extracted from the returned string. An app-reported Status=SUCCESS is still only an app report, and the lab labels it as such — see the evidence ladder.",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "A browser cannot enumerate installed apps, read an activity result, or learn an app version. Claiming otherwise is the most common lie in this problem space."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md. The harness posts its results to this lab's own API, so a native result lands in the same comparison matrix as a web one.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AN-007",
            "group": "AN",
            "name": "Capture app version via PackageManager",
            "application": "Companion Android harness",
            "platform": "android",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// (via Android Intent)",
            "launch_mechanism": "native_android",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "Android Intent and PackageManager documentation; NPCI UPI Linking Specification.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion Android harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical Android device; an emulator has no payment apps."
            ],
            "expected_behaviour": "The exact version of each installed payment app. Without this, a result recorded six months apart may be about two different apps.",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "A browser cannot enumerate installed apps, read an activity result, or learn an app version. Claiming otherwise is the most common lie in this problem space."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md. The harness posts its results to this lab's own API, so a native result lands in the same comparison matrix as a web one.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AN-008",
            "group": "AN",
            "name": "Android 11+ package visibility",
            "application": "Companion Android harness",
            "platform": "android",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// (via Android Intent)",
            "launch_mechanism": "native_android",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "Android Intent and PackageManager documentation; NPCI UPI Linking Specification.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion Android harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical Android device; an emulator has no payment apps."
            ],
            "expected_behaviour": "Whether the harness can see payment apps at all under the <queries> restrictions. On Android 11 and later an app that does not declare <queries> gets an empty list, which looks exactly like \"nothing is installed\".",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "A browser cannot enumerate installed apps, read an activity result, or learn an app version. Claiming otherwise is the most common lie in this problem space."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md. The harness posts its results to this lab's own API, so a native result lands in the same comparison matrix as a web one.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AN-009",
            "group": "AN",
            "name": "App-switch and return timing",
            "application": "Companion Android harness",
            "platform": "android",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// (via Android Intent)",
            "launch_mechanism": "native_android",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "Android Intent and PackageManager documentation; NPCI UPI Linking Specification.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion Android harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical Android device; an emulator has no payment apps."
            ],
            "expected_behaviour": "How long the switch out and back takes, and whether the calling activity survives. A calling activity killed during the switch loses the result, which is a real integration failure mode.",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "A browser cannot enumerate installed apps, read an activity result, or learn an app version. Claiming otherwise is the most common lie in this problem space."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md. The harness posts its results to this lab's own API, so a native result lands in the same comparison matrix as a web one.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AN-010",
            "group": "AN",
            "name": "FLAG_ACTIVITY_NEW_TASK behaviour",
            "application": "Companion Android harness",
            "platform": "android",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// (via Android Intent)",
            "launch_mechanism": "native_android",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "Android Intent and PackageManager documentation; NPCI UPI Linking Specification.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion Android harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical Android device; an emulator has no payment apps."
            ],
            "expected_behaviour": "Whether the payment app lands in a separate task and what that does to the return. Affects whether the activity result arrives at all.",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "A browser cannot enumerate installed apps, read an activity result, or learn an app version. Claiming otherwise is the most common lie in this problem space."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md. The harness posts its results to this lab's own API, so a native result lands in the same comparison matrix as a web one.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AN-011",
            "group": "AN",
            "name": "WebView versus Chrome Custom Tab dispatch",
            "application": "Companion Android harness",
            "platform": "android",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// (via Android Intent)",
            "launch_mechanism": "native_android",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "Android Intent and PackageManager documentation; NPCI UPI Linking Specification.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion Android harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical Android device; an emulator has no payment apps."
            ],
            "expected_behaviour": "Whether a upi:// link fires from an embedded WebView, and whether it needs shouldOverrideUrlLoading. Explains a very common \"it works in Chrome but not in our app\" report.",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "A browser cannot enumerate installed apps, read an activity result, or learn an app version. Claiming otherwise is the most common lie in this problem space."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md. The harness posts its results to this lab's own API, so a native result lands in the same comparison matrix as a web one.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "AN-012",
            "group": "AN",
            "name": "Signed intent handling (mode/orgid/sign)",
            "application": "Companion Android harness",
            "platform": "android",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// (via Android Intent)",
            "launch_mechanism": "native_android",
            "parameter_profile": "P03",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu",
                "mc"
            ],
            "documentation": "Android Intent and PackageManager documentation; NPCI UPI Linking Specification.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion Android harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical Android device; an emulator has no payment apps."
            ],
            "expected_behaviour": "How an app treats a genuinely signed payload versus an unsigned one. Needs a real signed payload from a PSP; the harness will not synthesise one.",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "A browser cannot enumerate installed apps, read an activity result, or learn an app version. Claiming otherwise is the most common lie in this problem space."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md. The harness posts its results to this lab's own API, so a native result lands in the same comparison matrix as a web one.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "IO-001",
            "group": "IO",
            "name": "canOpenURL for upi://",
            "application": "Companion iOS harness",
            "platform": "ios",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// and app-specific schemes",
            "launch_mechanism": "native_ios",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "Apple UIApplication and Universal Links documentation.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion iOS harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical iPhone with the payment apps installed.",
                "An Apple developer account to sideload it."
            ],
            "expected_behaviour": "Whether any installed app claims the upi:// scheme. Requires the scheme to be listed in LSApplicationQueriesSchemes; an undeclared scheme always answers false, which is indistinguishable from \"not installed\".",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "iOS restricts scheme queries far more tightly than Android; several questions that are answerable on Android are not answerable at all here."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "IO-002",
            "group": "IO",
            "name": "canOpenURL per app scheme",
            "application": "Companion iOS harness",
            "platform": "ios",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// and app-specific schemes",
            "launch_mechanism": "native_ios",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "Apple UIApplication and Universal Links documentation.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion iOS harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical iPhone with the payment apps installed.",
                "An Apple developer account to sideload it."
            ],
            "expected_behaviour": "Which of the app-specific schemes resolve on this device. iOS allows at most 50 declared query schemes, so a harness must choose which to ask about.",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "iOS restricts scheme queries far more tightly than Android; several questions that are answerable on Android are not answerable at all here."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "IO-003",
            "group": "IO",
            "name": "UIApplication.open with upi://",
            "application": "Companion iOS harness",
            "platform": "ios",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// and app-specific schemes",
            "launch_mechanism": "native_ios",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "Apple UIApplication and Universal Links documentation.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion iOS harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical iPhone with the payment apps installed.",
                "An Apple developer account to sideload it."
            ],
            "expected_behaviour": "Whether iOS hands a upi:// URI to an app, and which one. iOS has no chooser: the first app that registered the scheme wins, and the user cannot pick. This is the deepest behavioural difference from Android.",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "iOS restricts scheme queries far more tightly than Android; several questions that are answerable on Android are not answerable at all here."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "IO-004",
            "group": "IO",
            "name": "UIApplication.open with an app scheme",
            "application": "Companion iOS harness",
            "platform": "ios",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// and app-specific schemes",
            "launch_mechanism": "native_ios",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "Apple UIApplication and Universal Links documentation.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion iOS harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical iPhone with the payment apps installed.",
                "An Apple developer account to sideload it."
            ],
            "expected_behaviour": "Direct launch of a named app. The only reliable way to address a specific app on iOS.",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "iOS restricts scheme queries far more tightly than Android; several questions that are answerable on Android are not answerable at all here."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "IO-005",
            "group": "IO",
            "name": "Universal Link handling",
            "application": "Companion iOS harness",
            "platform": "ios",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// and app-specific schemes",
            "launch_mechanism": "native_ios",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "Apple UIApplication and Universal Links documentation.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion iOS harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical iPhone with the payment apps installed.",
                "An Apple developer account to sideload it."
            ],
            "expected_behaviour": "Whether an https link registered by a payment app opens the app rather than Safari. Universal Links are the Apple-sanctioned path, and the only one that degrades gracefully when the app is absent.",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "iOS restricts scheme queries far more tightly than Android; several questions that are answerable on Android are not answerable at all here."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        },
        {
            "method_id": "IO-006",
            "group": "IO",
            "name": "Return path after payment",
            "application": "Companion iOS harness",
            "platform": "ios",
            "browser_requirement": "None — this is not a browser method.",
            "uri_scheme": "upi:// and app-specific schemes",
            "launch_mechanism": "native_ios",
            "parameter_profile": "P01",
            "required_fields": [
                "pa"
            ],
            "optional_fields": [
                "pn",
                "tr",
                "am",
                "cu"
            ],
            "documentation": "Apple UIApplication and Universal Links documentation.",
            "documentation_status": "vendor_documented",
            "prerequisites": [
                "The companion iOS harness, which is SPECIFIED BUT NOT YET BUILT (docs/NATIVE_HARNESS.md).",
                "A physical iPhone with the payment apps installed.",
                "An Apple developer account to sideload it."
            ],
            "expected_behaviour": "What, if anything, comes back to the calling app. DOCUMENTS A PLATFORM LIMITATION RATHER THAN TESTING A FEATURE: iOS has no activity-result equivalent, so there is no callback unless the payment app implements a return URL. Any iOS integration that assumes a result callback is built on something that does not exist.",
            "known_limitations": [
                "NOT RUNNABLE FROM A BROWSER, AND THE HARNESS DOES NOT EXIST YET. Counted in the planned 166 and excluded from the runnable count.",
                "iOS restricts scheme queries far more tightly than Android; several questions that are answerable on Android are not answerable at all here."
            ],
            "implementation": "Specified in docs/NATIVE_HARNESS.md.",
            "status": "native_only",
            "registry_version": "1.0.0",
            "android_package": "",
            "requires_imported_payload": false,
            "can_move_money": true
        }
    ]
}