diff --git a/apps/upi_core/lib/upi_core/special_handlers/acc_ip_08_scenario.ex b/apps/upi_core/lib/upi_core/special_handlers/acc_ip_08_scenario.ex
index 7ef4333..5962531 100644
--- a/apps/upi_core/lib/upi_core/special_handlers/acc_ip_08_scenario.ex
+++ b/apps/upi_core/lib/upi_core/special_handlers/acc_ip_08_scenario.ex
@@ -137,21 +137,30 @@ defmodule UpiCore.SpecialHandlers.AccIp08Scenario do
     # Extract all required fields from parsed_data (from original ReqChkTxn)
     msg_id = generate_msg_id()  # Generate new msgId for response
     req_msg_id = Map.get(parsed_data, :msg_id) || ""
-    txn_id = Map.get(parsed_data, :txn_id) || Map.get(parsed_data, :org_txn_id) || generate_txn_id()
-    org_txn_id = Map.get(parsed_data, :org_txn_id) || txn_id
+    # [RespChkTxn Txn.id / Txn.orgTxnId] CHANGED: echo the ReqChkTxn ids exactly (no orgTxnId <- txnId fallback, no generated TXN... id)
+    # OLD:     txn_id = Map.get(parsed_data, :txn_id) || Map.get(parsed_data, :org_txn_id) || generate_txn_id()
+    # OLD:     org_txn_id = Map.get(parsed_data, :org_txn_id) || txn_id
+    txn_id = Map.get(parsed_data, :txn_id) || ""
+    org_txn_id = Map.get(parsed_data, :org_txn_id) || ""
     timestamp = DateTime.utc_now() |> DateTime.to_iso8601()
 
     # Extract fields from original ReqChkTxn to preserve in RespChkTxn
-    note = Map.get(parsed_data, :note) || "ACCIP08"
+    # [RespChkTxn Txn.note] CHANGED: echo the ReqChkTxn note (no ACCIP08 default)
+    # OLD:     note = Map.get(parsed_data, :note) || "ACCIP08"
+    note = Map.get(parsed_data, :note) || ""
     ref_id = Map.get(parsed_data, :ref_id) || Map.get(parsed_data, :refId) || ""
     ref_url = "https://mercurypay.aritic.app"  # Always use mercurypay URL for ACCIP08
     ref_category = Map.get(parsed_data, :ref_category) || Map.get(parsed_data, :refCategory) || "00"
     cust_ref = Map.get(parsed_data, :cust_ref) || Map.get(parsed_data, :custRef) || ""
     txn_type = Map.get(parsed_data, :txn_type) || Map.get(parsed_data, :type) || "ChkTxn"
     org_msg_id = Map.get(parsed_data, :org_msg_id) || Map.get(parsed_data, :orgMsgId) || ""
-    initiation_mode = Map.get(parsed_data, :initiation_mode) || Map.get(parsed_data, :initiationMode) || "16"
-    purpose = Map.get(parsed_data, :purpose) || "11"
-    sub_type = Map.get(parsed_data, :sub_type) || Map.get(parsed_data, :subType) || "CREDIT"
+    # [RespChkTxn Txn.initiationMode / purpose / subType] CHANGED: echo the ReqChkTxn values (no 16 / 02, 11 and CREDIT defaults)
+    # OLD:     initiation_mode = Map.get(parsed_data, :initiation_mode) || Map.get(parsed_data, :initiationMode) || "16"
+    # OLD:     purpose = Map.get(parsed_data, :purpose) || "11"
+    # OLD:     sub_type = Map.get(parsed_data, :sub_type) || Map.get(parsed_data, :subType) || "CREDIT"
+    initiation_mode = Map.get(parsed_data, :initiation_mode) || Map.get(parsed_data, :initiationMode) || ""
+    purpose = Map.get(parsed_data, :purpose) || ""
+    sub_type = Map.get(parsed_data, :sub_type) || Map.get(parsed_data, :subType) || ""
 
     Logger.info("[AccIp08Scenario] Building X7 response - txn_id=#{txn_id}, note=#{note}")
 
@@ -233,76 +242,104 @@ defmodule UpiCore.SpecialHandlers.AccIp08Scenario do
     end
   end
 
+  # [RespChkTxn <RespChkTxn> template] OLD FUNCTION kept for reference. It hand-built the XML with Ref from the merchant DB row of the scenario VPA and dummy fallbacks: code 000000, IFSC AEBK0087654, acNum AE112233445, accType CURRENT, orgAmount 999.00,
+  # Txn seqNum absent but Head ts / Txn ts in UTC. [RespChkTxn Ref.addr / regName / code / IFSC / acNum / accType / orgAmount] CHANGED: now UpiXmlSchema.generate_resp_chk_txn with ref_data from the stored ReqPay (orgTxnId)
+  # TSD Table 6: Ref values of the original ReqPay; settAmount 0.00 and settCurrency INR on the X7 failure
+  # OLD:   defp generate_x7_resp_chk_txn_xml_internal(response_data) do
+  # OLD:     try do
+  # OLD:       Logger.info("[AccIp08Scenario] Generating X7 RespChkTxn XML matching NPCI format")
+  # OLD:
+  # OLD:       # Get merchant data or use fallback
+  # OLD:       merchant_data = response_data[:merchant_data] || response_data.merchant_data
+  # OLD:
+  # OLD:       # Extract settlement info from response data
+  # OLD:       settlement_currency = response_data[:settlement_currency] || response_data.settlement_currency || "INR"
+  # OLD:       settlement_amount = response_data[:settlement_amount] || response_data.settlement_amount || "0.00"
+  # OLD:
+  # OLD:       # Build ref data
+  # OLD:       ref_data = if merchant_data do
+  # OLD:         amount = case Map.get(merchant_data, :max_transaction_limit) do
+  # OLD:           nil -> "999.00"
+  # OLD:           %Decimal{} = d -> Decimal.to_string(d)
+  # OLD:           val when is_number(val) -> Float.to_string(val)
+  # OLD:           val when is_binary(val) -> val
+  # OLD:           _ -> "999.00"
+  # OLD:         end
+  # OLD:
+  # OLD:         %{
+  # OLD:           addr: to_string(Map.get(merchant_data, :merchant_vpa) || @target_vpa),
+  # OLD:           code: to_string(Map.get(merchant_data, :merchant_code) || "000000"),
+  # OLD:           reg_name: to_string(Map.get(merchant_data, :legal_name) || Map.get(merchant_data, :brand_name) || "NPCI Tester"),
+  # OLD:           ifsc: to_string(Map.get(merchant_data, :settlement_account_ifsc) || "AEBK0087654"),
+  # OLD:           ac_num: to_string(Map.get(merchant_data, :settlement_account_number) || "AE112233445"),
+  # OLD:           acc_type: to_string(Map.get(merchant_data, :settlement_account_type) || "CURRENT"),
+  # OLD:           sett_currency: "INR",  # CRITICAL: For failure cases, settlement currency must be INR
+  # OLD:           org_amount: amount,
+  # OLD:           sett_amount: "0.00"  # CRITICAL: For failure cases, settlement amount must be 0.00
+  # OLD:         }
+  # OLD:       else
+  # OLD:         %{
+  # OLD:           addr: @target_vpa,
+  # OLD:           code: "000000",
+  # OLD:           reg_name: "NPCI Tester",
+  # OLD:           ifsc: "AEBK0087654",
+  # OLD:           ac_num: "AE112233445",
+  # OLD:           acc_type: "CURRENT",
+  # OLD:           sett_currency: "INR",  # CRITICAL: For failure cases, settlement currency must be INR
+  # OLD:           org_amount: "999.00",
+  # OLD:           sett_amount: "0.00"  # CRITICAL: For failure cases, settlement amount must be 0.00
+  # OLD:         }
+  # OLD:       end
+  # OLD:
+  # OLD:       # Generate 6-character approval number (APP + 3 digits, matching ACC_IP_10 pattern)
+  # OLD:       approval_num = "APP" <> String.pad_leading(Integer.to_string(:rand.uniform(1000) - 1), 3, "0")
+  # OLD:
+  # OLD:       # Build XML matching exact NPCI format
+  # OLD:       xml = """
+  # OLD:       <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+  # OLD:       <ns2:RespChkTxn xmlns:ns2="http://npci.org/upi/schema/">
+  # OLD:       <Head ver="2.0" ts="#{response_data.timestamp}" orgId="MER101" msgId="#{response_data.msg_id}" prodType="UPI"/>
+  # OLD:       <Txn id="#{response_data.txn_id}" note="#{response_data.note}" refId="#{response_data.ref_id}" refUrl="#{response_data.ref_url}" refCategory="#{response_data.ref_category}" ts="#{response_data.timestamp}" custRef="#{response_data.cust_ref}" type="#{response_data.txn_type}" orgMsgId="#{response_data.org_msg_id}" orgTxnId="#{response_data.org_txn_id}" initiationMode="#{response_data.initiation_mode}" purpose="#{response_data.purpose}" subType="#{response_data.sub_type}"/>
+  # OLD:       <Resp reqMsgId="#{response_data.req_msg_id}" result="FAILURE" errCode="X7">
+  # OLD:       <Ref type="PAYEE" seqNum="1" addr="#{ref_data.addr}" code="#{ref_data.code}" orgAmount="#{ref_data.org_amount}" respCode="X7" regName="#{ref_data.reg_name}" IFSC="#{ref_data.ifsc}" acNum="#{ref_data.ac_num}" accType="#{ref_data.acc_type}" approvalNum="#{approval_num}" settAmount="#{ref_data.sett_amount}" settCurrency="#{ref_data.sett_currency}" />
+  # OLD:       </Resp>
+  # OLD:       </ns2:RespChkTxn>
+  # OLD:       """
+  # OLD:
+  # OLD:       Logger.info("[AccIp08Scenario] ✅ Generated X7 RespChkTxn XML successfully")
+  # OLD:       Logger.debug("[AccIp08Scenario] XML (first 800 chars): #{String.slice(xml, 0, 800)}")
+  # OLD:       {:ok, String.trim(xml)}
+  # OLD:     rescue
+  # OLD:       e ->
+  # OLD:         Logger.error("[AccIp08Scenario] ❌ Error generating X7 RespChkTxn XML: #{inspect(e)}")
+  # OLD:         Logger.error("[AccIp08Scenario] Stacktrace: #{Exception.format_stacktrace(__STACKTRACE__)}")
+  # OLD:         {:error, "Failed to generate X7 RespChkTxn XML: #{inspect(e)}"}
+  # OLD:     end
+  # OLD:   end
   defp generate_x7_resp_chk_txn_xml_internal(response_data) do
-    try do
-      Logger.info("[AccIp08Scenario] Generating X7 RespChkTxn XML matching NPCI format")
-
-      # Get merchant data or use fallback
-      merchant_data = response_data[:merchant_data] || response_data.merchant_data
-
-      # Extract settlement info from response data
-      settlement_currency = response_data[:settlement_currency] || response_data.settlement_currency || "INR"
-      settlement_amount = response_data[:settlement_amount] || response_data.settlement_amount || "0.00"
-
-      # Build ref data
-      ref_data = if merchant_data do
-        amount = case Map.get(merchant_data, :max_transaction_limit) do
-          nil -> "999.00"
-          %Decimal{} = d -> Decimal.to_string(d)
-          val when is_number(val) -> Float.to_string(val)
-          val when is_binary(val) -> val
-          _ -> "999.00"
-        end
-
-        %{
-          addr: to_string(Map.get(merchant_data, :merchant_vpa) || @target_vpa),
-          code: to_string(Map.get(merchant_data, :merchant_code) || "000000"),
-          reg_name: to_string(Map.get(merchant_data, :legal_name) || Map.get(merchant_data, :brand_name) || "NPCI Tester"),
-          ifsc: to_string(Map.get(merchant_data, :settlement_account_ifsc) || "AEBK0087654"),
-          ac_num: to_string(Map.get(merchant_data, :settlement_account_number) || "AE112233445"),
-          acc_type: to_string(Map.get(merchant_data, :settlement_account_type) || "CURRENT"),
-          sett_currency: "INR",  # CRITICAL: For failure cases, settlement currency must be INR
-          org_amount: amount,
-          sett_amount: "0.00"  # CRITICAL: For failure cases, settlement amount must be 0.00
-        }
-      else
-        %{
-          addr: @target_vpa,
-          code: "000000",
-          reg_name: "NPCI Tester",
-          ifsc: "AEBK0087654",
-          ac_num: "AE112233445",
-          acc_type: "CURRENT",
-          sett_currency: "INR",  # CRITICAL: For failure cases, settlement currency must be INR
-          org_amount: "999.00",
-          sett_amount: "0.00"  # CRITICAL: For failure cases, settlement amount must be 0.00
-        }
-      end
-
-      # Generate 6-character approval number (APP + 3 digits, matching ACC_IP_10 pattern)
-      approval_num = "APP" <> String.pad_leading(Integer.to_string(:rand.uniform(1000) - 1), 3, "0")
-
-      # Build XML matching exact NPCI format
-      xml = """
-      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-      <ns2:RespChkTxn xmlns:ns2="http://npci.org/upi/schema/">
-      <Head ver="2.0" ts="#{response_data.timestamp}" orgId="MER101" msgId="#{response_data.msg_id}" prodType="UPI"/>
-      <Txn id="#{response_data.txn_id}" note="#{response_data.note}" refId="#{response_data.ref_id}" refUrl="#{response_data.ref_url}" refCategory="#{response_data.ref_category}" ts="#{response_data.timestamp}" custRef="#{response_data.cust_ref}" type="#{response_data.txn_type}" orgMsgId="#{response_data.org_msg_id}" orgTxnId="#{response_data.org_txn_id}" initiationMode="#{response_data.initiation_mode}" purpose="#{response_data.purpose}" subType="#{response_data.sub_type}"/>
-      <Resp reqMsgId="#{response_data.req_msg_id}" result="FAILURE" errCode="X7">
-      <Ref type="PAYEE" seqNum="1" addr="#{ref_data.addr}" code="#{ref_data.code}" orgAmount="#{ref_data.org_amount}" respCode="X7" regName="#{ref_data.reg_name}" IFSC="#{ref_data.ifsc}" acNum="#{ref_data.ac_num}" accType="#{ref_data.acc_type}" approvalNum="#{approval_num}" settAmount="#{ref_data.sett_amount}" settCurrency="#{ref_data.sett_currency}" />
-      </Resp>
-      </ns2:RespChkTxn>
-      """
-
-      Logger.info("[AccIp08Scenario] ✅ Generated X7 RespChkTxn XML successfully")
-      Logger.debug("[AccIp08Scenario] XML (first 800 chars): #{String.slice(xml, 0, 800)}")
-      {:ok, String.trim(xml)}
-    rescue
-      e ->
-        Logger.error("[AccIp08Scenario] ❌ Error generating X7 RespChkTxn XML: #{inspect(e)}")
-        Logger.error("[AccIp08Scenario] Stacktrace: #{Exception.format_stacktrace(__STACKTRACE__)}")
-        {:error, "Failed to generate X7 RespChkTxn XML: #{inspect(e)}"}
-    end
+    Logger.info("[AccIp08Scenario] Generating X7 RespChkTxn with UpiXmlSchema.generate_resp_chk_txn")
+
+    stored = ReqPayService.get_by_txn_id(response_data[:org_txn_id])
+    approval_num = "APP" <> String.pad_leading(Integer.to_string(:rand.uniform(1000) - 1), 3, "0")
+    ref_data = UpiCore.UpiXmlSchema.ref_data_from_stored_req_pay(stored, "X7", approval_num)
+
+    UpiCore.UpiXmlSchema.generate_resp_chk_txn(%{
+      org_id: response_data[:org_id] || "MER101",
+      msg_id: response_data[:msg_id],
+      req_msg_id: response_data[:req_msg_id],
+      result: "FAILURE",
+      err_code: "X7",
+      txn_id: response_data[:txn_id],
+      org_txn_id: response_data[:org_txn_id],
+      org_msg_id: response_data[:org_msg_id],
+      note: response_data[:note],
+      ref_id: response_data[:ref_id],
+      cust_ref: response_data[:cust_ref],
+      initiation_mode: response_data[:initiation_mode],
+      purpose: response_data[:purpose],
+      sub_type: response_data[:sub_type],
+      ref_data: ref_data
+    })
   end
 
   defp send_x7_resp_chk_txn_to_npci(resp_xml, txn_id) do
diff --git a/apps/upi_core/lib/upi_core/transactions/req_pay_service.ex b/apps/upi_core/lib/upi_core/transactions/req_pay_service.ex
index 9972572..d96b09a 100644
--- a/apps/upi_core/lib/upi_core/transactions/req_pay_service.ex
+++ b/apps/upi_core/lib/upi_core/transactions/req_pay_service.ex
@@ -304,6 +304,25 @@ defmodule UpiCore.Transactions.ReqPayService do
     |> Repo.one()
   end
 
+  @doc """
+  [RespChkTxn Ref.*] ADDED: the stored ReqPay of a Txn id (a ReqChkTxn's orgTxnId is the ReqPay Txn id); nil when it is not stored or the
+  database is not reachable.
+  """
+  @spec get_by_txn_id(String.t() | nil) :: ReqPay.t() | nil
+  def get_by_txn_id(txn_id) when is_binary(txn_id) and txn_id != "" do
+    ReqPay
+    |> where([r], r.txn_id == ^txn_id)
+    |> order_by([r], desc: r.inserted_at)
+    |> limit(1)
+    |> Repo.one()
+  rescue
+    _ -> nil
+  catch
+    :exit, _ -> nil
+  end
+
+  def get_by_txn_id(_txn_id), do: nil
+
   @doc """
   Get ReqPay with event history.
   """
diff --git a/apps/upi_core/lib/upi_core/upi_xml_schema.ex b/apps/upi_core/lib/upi_core/upi_xml_schema.ex
index 09ec343..8904e9f 100644
--- a/apps/upi_core/lib/upi_core/upi_xml_schema.ex
+++ b/apps/upi_core/lib/upi_core/upi_xml_schema.ex
@@ -1165,6 +1165,8 @@ end
     end
   end
 
+# [RespChkTxn Txn.seqNum] REMOVED: seqNum is not in the RespChkTxn Txn (TSD Table 6); Txn id / note / refId / custRef / orgMsgId / orgTxnId / initiationMode / subType / purpose are echoed and XML-escaped
+# OLD: <Txn id="#{safe_txn_id}" note="#{Map.get(response_data, :note, "")}" refId="#{Map.get(response_data, :ref_id, "")}" refUrl="#{ref_url}" refCategory="00" ts="#{Map.get(response_data, :txn_ts, get_timestamp())}" custRef="#{Map.get(response_data, :cust_ref, "")}" type="ChkTxn" orgMsgId="#{safe_org_msg_id}" orgTxnId="#{safe_org_txn_id}"#{org_txn_date_attr} initiationMode="#{initiation_mode}" purpose="#{purpose}" seqNum="#{Map.get(response_data, :seq_num, "")}" subType="#{sub_type}"/>
   @doc """
   Generate RespChkTxn XML response
   """
@@ -1188,18 +1190,24 @@ end
       |> String.slice(0, 35)
 
     # Normalize/derive subType with a safe default (CREDIT) to satisfy NPCI validation
-    sub_type =
-      case Map.get(response_data, :sub_type) || Map.get(response_data, "sub_type") || Map.get(response_data, :subType) do
-        v when is_binary(v) and v != "" -> String.upcase(String.trim(v))
-        _ -> "CREDIT"
-      end
+    # [RespChkTxn Txn.subType] CHANGED: echo the ReqChkTxn subType (no upcase, no CREDIT default)
+    # TSD Table 6: Txn subType = value received in ReqChkTxn
+    # OLD:     sub_type =
+    # OLD:       case Map.get(response_data, :sub_type) || Map.get(response_data, "sub_type") || Map.get(response_data, :subType) do
+    # OLD:         v when is_binary(v) and v != "" -> String.upcase(String.trim(v))
+    # OLD:         _ -> "CREDIT"
+    # OLD:       end
+    sub_type = Map.get(response_data, :sub_type) || Map.get(response_data, "sub_type") || Map.get(response_data, :subType)
 
     # Ensure initiationMode, txn id and purpose have safe defaults to satisfy NPCI
+    # [RespChkTxn Txn.initiationMode] CHANGED: echo the ReqChkTxn initiationMode (no 16 default)
+    # OLD:     initiation_mode =
+    # OLD:       case Map.get(response_data, :initiation_mode) || Map.get(response_data, :initiationMode) || Map.get(response_data, "initiation_mode") do
+    # OLD:         v when is_binary(v) and v != "" -> v
+    # OLD:         _ -> "16"  # Default to 16 (QR code payment) instead of 01
+    # OLD:       end
     initiation_mode =
-      case Map.get(response_data, :initiation_mode) || Map.get(response_data, :initiationMode) || Map.get(response_data, "initiation_mode") do
-        v when is_binary(v) and v != "" -> v
-        _ -> "16"  # Default to 16 (QR code payment) instead of 01
-      end
+      Map.get(response_data, :initiation_mode) || Map.get(response_data, :initiationMode) || Map.get(response_data, "initiation_mode")
 
     # Txn id must be present and exactly 35 chars: 3-char prefix + 32 hex lowercase chars.
     raw_txn_id =
@@ -1262,35 +1270,48 @@ end
         prefix <> gen_hex.(32)
       end
 
-    purpose =
-      case Map.get(response_data, :purpose) || Map.get(response_data, "purpose") do
-        v when is_binary(v) and v != "" -> v
-        _ -> "11"
-      end
+    # [RespChkTxn Txn.purpose] CHANGED: echo the ReqChkTxn purpose (no 11 default)
+    # OLD:     purpose =
+    # OLD:       case Map.get(response_data, :purpose) || Map.get(response_data, "purpose") do
+    # OLD:         v when is_binary(v) and v != "" -> v
+    # OLD:         _ -> "11"
+    # OLD:       end
+    purpose = Map.get(response_data, :purpose) || Map.get(response_data, "purpose")
 
     Logger.info("Final txn_id for XML: #{txn_id}, length: #{String.length(txn_id)}")
     Logger.info("Final head_msg_id for XML: #{head_msg_id}, length: #{String.length(head_msg_id)}")
 
     # Ensure no nil values in critical fields and validate exact lengths
-    safe_txn_id = case txn_id do
-      nil ->
-        # Generate exactly 35 chars: "MER" (3) + 32 hex chars
-        "MER" <> (:crypto.strong_rand_bytes(16) |> Base.encode16(case: :lower))
-      id when is_binary(id) ->
-        # Ensure existing ID is exactly 35 chars
-        cond do
-          String.length(id) == 35 -> id
-          String.length(id) > 35 -> String.slice(id, 0, 35)
-          String.length(id) < 35 ->
-            # Pad with random hex to reach 35
-            needed = 35 - String.length(id)
-            padding = :crypto.strong_rand_bytes(div(needed + 1, 2)) |> Base.encode16(case: :lower) |> String.slice(0, needed)
-            (id <> padding) |> String.slice(0, 35)
-        end
-      _ ->
-        # Fallback: generate new 35-char ID
-        "MER" <> (:crypto.strong_rand_bytes(16) |> Base.encode16(case: :lower))
-    end
+    # [RespChkTxn Txn.id] CHANGED: echo the ReqChkTxn Txn id exactly (no cleaning, padding with random hex, cutting to 35 or generated MER... id)
+    # TSD Table 6: Txn id = Txn id received in ReqChkTxn
+    # OLD:     safe_txn_id = case txn_id do
+    # OLD:       nil ->
+    # OLD:         # Generate exactly 35 chars: "MER" (3) + 32 hex chars
+    # OLD:         "MER" <> (:crypto.strong_rand_bytes(16) |> Base.encode16(case: :lower))
+    # OLD:       id when is_binary(id) ->
+    # OLD:         # Ensure existing ID is exactly 35 chars
+    # OLD:         cond do
+    # OLD:           String.length(id) == 35 -> id
+    # OLD:           String.length(id) > 35 -> String.slice(id, 0, 35)
+    # OLD:           String.length(id) < 35 ->
+    # OLD:             # Pad with random hex to reach 35
+    # OLD:             needed = 35 - String.length(id)
+    # OLD:             padding = :crypto.strong_rand_bytes(div(needed + 1, 2)) |> Base.encode16(case: :lower) |> String.slice(0, needed)
+    # OLD:             (id <> padding) |> String.slice(0, 35)
+    # OLD:         end
+    # OLD:       _ ->
+    # OLD:         # Fallback: generate new 35-char ID
+    # OLD:         "MER" <> (:crypto.strong_rand_bytes(16) |> Base.encode16(case: :lower))
+    # OLD:     end
+    safe_txn_id =
+      case raw_txn_id do
+        id when is_binary(id) ->
+          id
+
+        _ ->
+          Logger.error("[RespChkTxn Txn.id] ReqChkTxn Txn id is missing - nothing to echo")
+          ""
+      end
 
     safe_head_msg_id = case head_msg_id do
       nil ->
@@ -1315,12 +1336,13 @@ end
     Logger.info("Safe txn_id: #{safe_txn_id}, length: #{String.length(safe_txn_id)}")
     Logger.info("Safe head_msg_id: #{safe_head_msg_id}, length: #{String.length(safe_head_msg_id)}")
 
-    # Final validation: Ensure both IDs are exactly 35 characters
-    if String.length(safe_txn_id) != 35 do
-      Logger.error("CRITICAL: Transaction ID length is #{String.length(safe_txn_id)}, expected 35. ID: #{safe_txn_id}")
-      safe_txn_id = "MER" <> (:crypto.strong_rand_bytes(16) |> Base.encode16(case: :lower))
-      Logger.info("Generated fallback txn_id: #{safe_txn_id}, length: #{String.length(safe_txn_id)}")
-    end
+    # [RespChkTxn Txn.id length check] REMOVED: it logged CRITICAL and generated a MER... id for any id that is not 35 chars (the generated value was never used)
+    # OLD:     # Final validation: Ensure both IDs are exactly 35 characters
+    # OLD:     if String.length(safe_txn_id) != 35 do
+    # OLD:       Logger.error("CRITICAL: Transaction ID length is #{String.length(safe_txn_id)}, expected 35. ID: #{safe_txn_id}")
+    # OLD:       safe_txn_id = "MER" <> (:crypto.strong_rand_bytes(16) |> Base.encode16(case: :lower))
+    # OLD:       Logger.info("Generated fallback txn_id: #{safe_txn_id}, length: #{String.length(safe_txn_id)}")
+    # OLD:     end
 
     # Remove orgTxnDate, set refCategory/refUrl, use ref_data from RespPay
     ref_url = get_psp_ref_url() || "https://mercurypay.aritic.app"
@@ -1337,16 +1359,51 @@ end
     ref_data = Map.get(response_data, :ref_data) || %{}
 
     # Determine settlement currency: AED for international, INR for domestic
-    sett_currency = Map.get(ref_data, :sett_currency) || Map.get(response_data, :sett_currency) || "AED"
+    # [RespChkTxn Ref.settCurrency] CHANGED: always INR (was ref_data / response_data, defaulting to AED)
+    # TSD Table 6: settCurrency = INR
+    # OLD:     sett_currency = Map.get(ref_data, :sett_currency) || Map.get(response_data, :sett_currency) || "AED"
+    sett_currency = "INR"
 
     # Build <Ref> block using ref_data from RespPay
-    ref_block = "<Ref type=\"PAYEE\" seqNum=\"1\" addr=\"#{Map.get(ref_data, :addr, "")}\" code=\"#{Map.get(ref_data, :code, "")}\" orgAmount=\"#{Map.get(ref_data, :org_amount, "0.00")}\" respCode=\"#{Map.get(ref_data, :resp_code, "00")}\" regName=\"#{Map.get(ref_data, :regName, "")}\" IFSC=\"#{Map.get(ref_data, :ifsc, "")}\" acNum=\"#{Map.get(ref_data, :ac_num, "")}\" accType=\"#{Map.get(ref_data, :acc_type, "CURRENT")}\" approvalNum=\"#{Map.get(ref_data, :approval_num, "")}\" settAmount=\"#{Map.get(ref_data, :sett_amount, "0.00")}\" settCurrency=\"#{sett_currency}\" />"
+    # [RespChkTxn Ref.*] CHANGED: orgAmount with 2 decimals, settAmount = orgAmount when respCode is 00 else 0.00, no invented defaults (respCode 00, accType CURRENT, orgAmount 0.00)
+    # Ref addr / code / regName / IFSC / acNum / accType come from ref_data, which callers now build from the stored ReqPay
+    # TSD Table 6: Ref values of the original ReqPay; settAmount 0.00 on failure
+    # OLD:     ref_block = "<Ref type=\"PAYEE\" seqNum=\"1\" addr=\"#{Map.get(ref_data, :addr, "")}\" code=\"#{Map.get(ref_data, :code, "")}\" orgAmount=\"#{Map.get(ref_data, :org_amount, "0.00")}\" respCode=\"#{Map.get(ref_data, :resp_code, "00")}\" regName=\"#{Map.get(ref_data, :regName, "")}\" IFSC=\"#{Map.get(ref_data, :ifsc, "")}\" acNum=\"#{Map.get(ref_data, :ac_num, "")}\" accType=\"#{Map.get(ref_data, :acc_type, "CURRENT")}\" approvalNum=\"#{Map.get(ref_data, :approval_num, "")}\" settAmount=\"#{Map.get(ref_data, :sett_amount, "0.00")}\" settCurrency=\"#{sett_currency}\" />"
+    ref_resp_code = Map.get(ref_data, :resp_code)
+
+    if ref_resp_code in [nil, ""],
+      do: Logger.error("[RespChkTxn Ref.respCode] no respCode in ref_data - sending it empty")
+
+    ref_org_amount = NpciFormat.format_amount(Map.get(ref_data, :org_amount))
+
+    if is_nil(ref_org_amount),
+      do: Logger.error("[RespChkTxn Ref.orgAmount] no amount in ref_data - sending it empty")
+
+    ref_sett_amount = if ref_resp_code == "00", do: ref_org_amount || "", else: "0.00"
+    ra = fn name, value -> " #{name}=\"#{NpciFormat.xml_attr(value)}\"" end
+
+    ref_block =
+      "<Ref type=\"PAYEE\" seqNum=\"1\"" <>
+        ra.("addr", Map.get(ref_data, :addr)) <>
+        ra.("code", Map.get(ref_data, :code)) <>
+        ra.("orgAmount", ref_org_amount) <>
+        ra.("respCode", ref_resp_code) <>
+        # [RespChkTxn Ref.regName] CHANGED: accept ref_data :reg_name too (the error-response ref_data used :reg_name, so regName was always empty)
+        # OLD:         ra.("regName", Map.get(ref_data, :regName)) <>
+        ra.("regName", Map.get(ref_data, :regName) || Map.get(ref_data, :reg_name)) <>
+        ra.("IFSC", Map.get(ref_data, :ifsc)) <>
+        ra.("acNum", Map.get(ref_data, :ac_num)) <>
+        ra.("accType", Map.get(ref_data, :acc_type)) <>
+        ra.("approvalNum", Map.get(ref_data, :approval_num)) <>
+        ra.("settAmount", ref_sett_amount) <>
+        ra.("settCurrency", sett_currency) <>
+        " />"
 
     xml = ~s"""
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <ns2:RespChkTxn xmlns:ns2="http://npci.org/upi/schema/">
 <Head ver="#{Map.get(response_data, :ver, "2.0")}" ts="#{Map.get(response_data, :ts, get_timestamp())}" orgId="#{Map.get(response_data, :org_id, get_psp_org_id())}" msgId="#{safe_head_msg_id}" prodType="#{Map.get(response_data, :prod_type, "UPI")}"/>
-<Txn id="#{safe_txn_id}" note="#{Map.get(response_data, :note, "")}" refId="#{Map.get(response_data, :ref_id, "")}" refUrl="#{ref_url}" refCategory="00" ts="#{Map.get(response_data, :txn_ts, get_timestamp())}" custRef="#{Map.get(response_data, :cust_ref, "")}" type="ChkTxn" orgMsgId="#{safe_org_msg_id}" orgTxnId="#{safe_org_txn_id}"#{org_txn_date_attr} initiationMode="#{initiation_mode}" purpose="#{purpose}" seqNum="#{Map.get(response_data, :seq_num, "")}" subType="#{sub_type}"/>
+<Txn id="#{NpciFormat.xml_attr(safe_txn_id)}" note="#{NpciFormat.xml_attr(Map.get(response_data, :note, ""))}" refId="#{NpciFormat.xml_attr(Map.get(response_data, :ref_id, ""))}" refUrl="#{ref_url}" refCategory="00" ts="#{Map.get(response_data, :txn_ts, get_timestamp())}" custRef="#{NpciFormat.xml_attr(Map.get(response_data, :cust_ref, ""))}" type="ChkTxn" orgMsgId="#{NpciFormat.xml_attr(safe_org_msg_id)}" orgTxnId="#{NpciFormat.xml_attr(safe_org_txn_id)}"#{org_txn_date_attr} initiationMode="#{NpciFormat.xml_attr(initiation_mode)}" purpose="#{NpciFormat.xml_attr(purpose)}" subType="#{NpciFormat.xml_attr(sub_type)}"/>
 <Resp reqMsgId="#{Map.get(response_data, :req_msg_id, "")}" result="#{Map.get(response_data, :result, "SUCCESS")}"#{if Map.get(response_data, :result, "SUCCESS") != "SUCCESS", do: " errCode=\"#{Map.get(response_data, :err_code)}\"", else: ""}>
 #{ref_block}
 </Resp>
@@ -1359,6 +1416,62 @@ end
     {:ok, String.trim(xml)}
   end
 
+  @doc """
+  [RespChkTxn Ref.respCode] ADDED: Ref respCode of a stored transaction. Credited (status "success" / state "credit_success") -> "00";
+  pending / processing / deemed -> "BT"; failure / reversed (or anything else) -> the error code stored on the transaction (`failure_code`).
+  No "U69" default: when no code is stored the code is sent empty and an error is logged.
+  TSD Table 6: Ref respCode = result of the original transaction.
+  """
+  def chk_txn_resp_code(transaction) do
+    status = transaction |> Map.get(:status) |> to_string() |> String.downcase()
+    state = transaction |> Map.get(:current_state) |> to_string() |> String.downcase()
+
+    cond do
+      status in ["success", "succeeded"] or state in ["credit_success", "credited", "success"] ->
+        "00"
+
+      status in ["pending", "processing", "deemed"] ->
+        "BT"
+
+      true ->
+        case Map.get(transaction, :failure_code) do
+          code when is_binary(code) and code != "" ->
+            code
+
+          _ ->
+            Logger.error("[RespChkTxn Ref.respCode] transaction status #{inspect(status)} has no stored error code - sending respCode empty")
+            ""
+        end
+    end
+  end
+  @doc """
+  [RespChkTxn Ref.*] ADDED: builds the `ref_data` map of `generate_resp_chk_txn/1` from a stored ReqPay row (`UpiCore.Transactions.ReqPay`
+  or any map with those fields): addr, code (MCC), regName (= Payee name), IFSC, acNum, accType, orgAmount. Nothing is invented: a field the
+  stored ReqPay does not have stays nil. `resp_code` is the Ref respCode ("00" for a credited transaction, the stored error code otherwise).
+  """
+  def ref_data_from_stored_req_pay(stored, resp_code, approval_num \\ nil) do
+    stored = stored || %{}
+
+    amount =
+      case Map.get(stored, :amount) do
+        %Decimal{} = d -> Decimal.to_string(d)
+        other -> other
+      end
+
+    %{
+      addr: Map.get(stored, :payee_addr),
+      code: Map.get(stored, :merchant_category_code),
+      org_amount: amount,
+      resp_code: resp_code,
+      regName: Map.get(stored, :payee_name),
+      ifsc: Map.get(stored, :payee_ifsc),
+      ac_num: Map.get(stored, :payee_account_number),
+      acc_type: Map.get(stored, :payee_account_type),
+      approval_num: approval_num,
+      sett_currency: "INR"
+    }
+  end
+
   @doc """
   Parse ReqHbt XML with full UPI specification compliance
   Expected format:
diff --git a/apps/upi_core/test/upi_core/resp_chk_txn_test.exs b/apps/upi_core/test/upi_core/resp_chk_txn_test.exs
new file mode 100644
index 0000000..b2c9608
--- /dev/null
+++ b/apps/upi_core/test/upi_core/resp_chk_txn_test.exs
@@ -0,0 +1,237 @@
+defmodule UpiCore.RespChkTxnTest do
+  use ExUnit.Case, async: false
+
+  import SweetXml
+
+  alias UpiCore.Repo
+  alias UpiCore.Transactions.ReqPay
+  alias UpiCore.UpiXmlSchema
+  alias UpiCore.SpecialHandlers.AccIp08Scenario
+
+  @org_txn_id "ORGTXNPAY0000000000000000000000001"
+
+  setup do
+    {:ok, _} = Application.ensure_all_started(:upi_core)
+    pid = Ecto.Adapters.SQL.Sandbox.start_owner!(Repo, shared: true)
+    on_exit(fn -> Ecto.Adapters.SQL.Sandbox.stop_owner(pid) end)
+    :ok
+  end
+
+  defp insert_req_pay do
+    {:ok, req_pay} =
+      %ReqPay{}
+      |> ReqPay.changeset(%{
+        msg_id: "STOREDREQPAYMSG0000000000000000001",
+        txn_id: @org_txn_id,
+        org_id: "NPCI",
+        amount: Decimal.new("5"),
+        currency: "INR",
+        status: "PROCESSED",
+        validation_type: "DOMESTIC",
+        payee_addr: "restaurant@mercury",
+        payee_name: "NPCI Tester",
+        merchant_category_code: "5812",
+        payee_ifsc: "TEST0000001",
+        payee_account_number: "123456789012345678",
+        payee_account_type: "SAVINGS"
+      })
+      |> Repo.insert()
+
+    req_pay
+  end
+
+  # the parsed ReqChkTxn
+  @req_chk %{
+    msg_id: "NPCIREQCHKTXN000000000000000000001",
+    txn_id: "NPCICHKTXNID-LONGER-THAN-35-CHARS-AND-NOT-HEX",
+    org_txn_id: @org_txn_id,
+    org_msg_id: "NPCIORGMSGID00000000000000000001",
+    note: "ACC_IP-07 check.note",
+    ref_id: "REFCHK0001",
+    cust_ref: "CUSTREF07",
+    initiation_mode: "16",
+    purpose: "62",
+    sub_type: "PAY"
+  }
+
+  defp response_data(overrides \\ %{}) do
+    Map.merge(
+      %{
+        org_id: "MER101",
+        msg_id: "MER00000000000000000000000000000001",
+        req_msg_id: @req_chk.msg_id,
+        result: "SUCCESS",
+        err_code: "00",
+        txn_id: @req_chk.txn_id,
+        org_txn_id: @req_chk.org_txn_id,
+        org_msg_id: @req_chk.org_msg_id,
+        note: @req_chk.note,
+        ref_id: @req_chk.ref_id,
+        cust_ref: @req_chk.cust_ref,
+        initiation_mode: "16",
+        purpose: "62",
+        sub_type: "PAY",
+        seq_num: "999999",
+        ref_data: nil
+      },
+      overrides
+    )
+  end
+
+  defp gen(data) do
+    {:ok, xml} = UpiXmlSchema.generate_resp_chk_txn(data)
+    xml
+  end
+
+  defp attr(xml, path), do: xpath(xml, ~x"#{path}"s)
+  @txn "//*[local-name()='Txn']"
+  @ref "//*[local-name()='Ref']"
+
+  describe "generate_resp_chk_txn/1" do
+    setup do
+      stored = %{
+        payee_addr: "restaurant@mercury",
+        payee_name: "NPCI Tester",
+        merchant_category_code: "5812",
+        payee_ifsc: "TEST0000001",
+        payee_account_number: "123456789012345678",
+        payee_account_type: "SAVINGS",
+        amount: Decimal.new("5")
+      }
+
+      %{stored: stored}
+    end
+
+    test "Txn echoes the ReqChkTxn and has no seqNum", %{stored: stored} do
+      xml = gen(response_data(%{ref_data: UpiXmlSchema.ref_data_from_stored_req_pay(stored, "00", "APP001")}))
+      assert attr(xml, @txn <> "/@id") == @req_chk.txn_id
+      assert attr(xml, @txn <> "/@note") == "ACC_IP-07 check.note"
+      assert attr(xml, @txn <> "/@refId") == "REFCHK0001"
+      assert attr(xml, @txn <> "/@custRef") == "CUSTREF07"
+      assert attr(xml, @txn <> "/@orgMsgId") == @req_chk.org_msg_id
+      assert attr(xml, @txn <> "/@orgTxnId") == @org_txn_id
+      assert attr(xml, @txn <> "/@initiationMode") == "16"
+      assert attr(xml, @txn <> "/@subType") == "PAY"
+      assert attr(xml, @txn <> "/@purpose") == "62"
+      refute xml =~ "seqNum=\"999999\""
+      assert attr(xml, "count(" <> @txn <> "/@seqNum)") == "0"
+    end
+
+    test "credited: respCode 00, Ref from the stored ReqPay, orgAmount 5.00 = settAmount, INR", %{stored: stored} do
+      xml = gen(response_data(%{ref_data: UpiXmlSchema.ref_data_from_stored_req_pay(stored, "00", "APP001")}))
+      assert attr(xml, @ref <> "/@respCode") == "00"
+      assert attr(xml, @ref <> "/@addr") == "restaurant@mercury"
+      assert attr(xml, @ref <> "/@regName") == "NPCI Tester"
+      assert attr(xml, @ref <> "/@code") == "5812"
+      assert attr(xml, @ref <> "/@IFSC") == "TEST0000001"
+      assert attr(xml, @ref <> "/@acNum") == "123456789012345678"
+      assert attr(xml, @ref <> "/@accType") == "SAVINGS"
+      assert attr(xml, @ref <> "/@orgAmount") == "5.00"
+      assert attr(xml, @ref <> "/@settAmount") == "5.00"
+      assert attr(xml, @ref <> "/@settCurrency") == "INR"
+      refute xml =~ "U69"
+    end
+
+    test "failed: stored error code, settAmount 0.00, settCurrency INR (not AED)", %{stored: stored} do
+      ref = UpiXmlSchema.ref_data_from_stored_req_pay(stored, "X7", "APP001")
+      xml = gen(response_data(%{result: "FAILURE", err_code: "X7", ref_data: ref}))
+      assert attr(xml, "//*[local-name()='Resp']/@errCode") == "X7"
+      assert attr(xml, @ref <> "/@respCode") == "X7"
+      assert attr(xml, @ref <> "/@orgAmount") == "5.00"
+      assert attr(xml, @ref <> "/@settAmount") == "0.00"
+      assert attr(xml, @ref <> "/@settCurrency") == "INR"
+    end
+
+    test "no invented Ref values when ref_data is empty" do
+      xml = gen(response_data(%{ref_data: %{}}))
+      assert attr(xml, @ref <> "/@code") == ""
+      assert attr(xml, @ref <> "/@accType") == ""
+      assert attr(xml, @ref <> "/@respCode") == ""
+      assert attr(xml, @ref <> "/@settCurrency") == "INR"
+      refute xml =~ ~s(code="000000")
+      refute xml =~ "CURRENT"
+    end
+
+    test "the :reg_name key of the error-response ref_data is honoured" do
+      xml = gen(response_data(%{ref_data: %{reg_name: "Via reg_name key", resp_code: "00", org_amount: "1"}}))
+      assert attr(xml, @ref <> "/@regName") == "Via reg_name key"
+      assert attr(xml, @ref <> "/@orgAmount") == "1.00"
+    end
+
+    test "echoed values are XML-escaped" do
+      xml = gen(response_data(%{note: ~s(a&b "c"), ref_data: %{}}))
+      assert attr(xml, @txn <> "/@note") == ~s(a&b "c")
+    end
+  end
+
+  describe "chk_txn_resp_code/1" do
+    test "credited transaction -> 00 (never U69)" do
+      assert UpiXmlSchema.chk_txn_resp_code(%{status: "success", current_state: "credit_success"}) == "00"
+      assert UpiXmlSchema.chk_txn_resp_code(%{status: "success"}) == "00"
+      assert UpiXmlSchema.chk_txn_resp_code(%{status: "pending", current_state: "credit_success"}) == "00"
+    end
+
+    test "failed transaction -> the stored error code" do
+      assert UpiXmlSchema.chk_txn_resp_code(%{status: "failure", failure_code: "U30"}) == "U30"
+      assert UpiXmlSchema.chk_txn_resp_code(%{status: "reversed", failure_code: "X7"}) == "X7"
+    end
+
+    test "pending / processing / deemed -> BT" do
+      for s <- ["pending", "processing", "deemed"], do: assert(UpiXmlSchema.chk_txn_resp_code(%{status: s}) == "BT")
+    end
+
+    test "failed or unknown transaction with no stored code -> empty, never U69" do
+      assert UpiXmlSchema.chk_txn_resp_code(%{status: "failure"}) == ""
+      assert UpiXmlSchema.chk_txn_resp_code(%{status: "whatever"}) == ""
+      assert UpiXmlSchema.chk_txn_resp_code(%{}) == ""
+    end
+  end
+
+  describe "ref_data_from_stored_req_pay/3" do
+    test "nothing stored -> nothing invented" do
+      ref = UpiXmlSchema.ref_data_from_stored_req_pay(nil, "X7")
+      assert ref.resp_code == "X7"
+      assert ref.sett_currency == "INR"
+      assert ref.addr == nil and ref.code == nil and ref.regName == nil and ref.acc_type == nil
+    end
+  end
+
+  describe "ACC_IP_08 X7 RespChkTxn (core)" do
+    test "Ref from the stored ReqPay, X7, settAmount 0.00, INR, Txn echoed with no defaults" do
+      insert_req_pay()
+      {:ok, xml} = AccIp08Scenario.generate_x7_resp_chk_txn_xml(Map.put(@req_chk, :payee_addr, "accip08@mercury"))
+
+      assert attr(xml, "//*[local-name()='Resp']/@result") == "FAILURE"
+      assert attr(xml, "//*[local-name()='Resp']/@errCode") == "X7"
+      assert attr(xml, @ref <> "/@respCode") == "X7"
+      assert attr(xml, @ref <> "/@addr") == "restaurant@mercury"
+      assert attr(xml, @ref <> "/@regName") == "NPCI Tester"
+      assert attr(xml, @ref <> "/@code") == "5812"
+      assert attr(xml, @ref <> "/@IFSC") == "TEST0000001"
+      assert attr(xml, @ref <> "/@acNum") == "123456789012345678"
+      assert attr(xml, @ref <> "/@orgAmount") == "5.00"
+      assert attr(xml, @ref <> "/@settAmount") == "0.00"
+      assert attr(xml, @ref <> "/@settCurrency") == "INR"
+      assert attr(xml, @txn <> "/@id") == @req_chk.txn_id
+      assert attr(xml, @txn <> "/@note") == "ACC_IP-07 check.note"
+      assert attr(xml, @txn <> "/@initiationMode") == "16"
+      assert attr(xml, @txn <> "/@subType") == "PAY"
+      assert attr(xml, @txn <> "/@purpose") == "62"
+      refute xml =~ "AEBK0087654"
+      refute xml =~ "999.00"
+      refute xml =~ ~s(code="000000")
+    end
+
+    test "no stored ReqPay -> empty Ref values, still no dummies, and defaults are not injected into the Txn" do
+      parsed = Map.drop(@req_chk, [:note, :initiation_mode, :purpose, :sub_type])
+      {:ok, xml} = AccIp08Scenario.generate_x7_resp_chk_txn_xml(parsed)
+      assert attr(xml, @ref <> "/@code") == ""
+      assert attr(xml, @ref <> "/@acNum") == ""
+      assert attr(xml, @txn <> "/@note") == ""
+      assert attr(xml, @txn <> "/@initiationMode") == ""
+      assert attr(xml, @txn <> "/@subType") == ""
+      refute xml =~ "ACCIP08"
+      refute xml =~ "CREDIT"
+    end
+  end
+end
diff --git a/apps/upi_dynamic/lib/upi_dynamic/special_handlers/acc_ip_08_scenario.ex b/apps/upi_dynamic/lib/upi_dynamic/special_handlers/acc_ip_08_scenario.ex
index 27cc480..7f79d2e 100644
--- a/apps/upi_dynamic/lib/upi_dynamic/special_handlers/acc_ip_08_scenario.ex
+++ b/apps/upi_dynamic/lib/upi_dynamic/special_handlers/acc_ip_08_scenario.ex
@@ -137,21 +137,30 @@ defmodule UpiDynamic.SpecialHandlers.AccIp08Scenario do
     # Extract all required fields from parsed_data (from original ReqChkTxn)
     msg_id = generate_msg_id()  # Generate new msgId for response
     req_msg_id = Map.get(parsed_data, :msg_id) || ""
-    txn_id = Map.get(parsed_data, :txn_id) || Map.get(parsed_data, :org_txn_id) || generate_txn_id()
-    org_txn_id = Map.get(parsed_data, :org_txn_id) || txn_id
+    # [RespChkTxn Txn.id / Txn.orgTxnId] CHANGED: echo the ReqChkTxn ids exactly (no orgTxnId <- txnId fallback, no generated TXN... id)
+    # OLD:     txn_id = Map.get(parsed_data, :txn_id) || Map.get(parsed_data, :org_txn_id) || generate_txn_id()
+    # OLD:     org_txn_id = Map.get(parsed_data, :org_txn_id) || txn_id
+    txn_id = Map.get(parsed_data, :txn_id) || ""
+    org_txn_id = Map.get(parsed_data, :org_txn_id) || ""
     timestamp = DateTime.utc_now() |> DateTime.to_iso8601()
 
     # Extract fields from original ReqChkTxn to preserve in RespChkTxn
-    note = Map.get(parsed_data, :note) || "ACCIP08"
+    # [RespChkTxn Txn.note] CHANGED: echo the ReqChkTxn note (no ACCIP08 default)
+    # OLD:     note = Map.get(parsed_data, :note) || "ACCIP08"
+    note = Map.get(parsed_data, :note) || ""
     ref_id = Map.get(parsed_data, :ref_id) || Map.get(parsed_data, :refId) || ""
     ref_url = "https://mercurypay.aritic.app"  # Always use mercurypay URL for ACCIP08
     ref_category = Map.get(parsed_data, :ref_category) || Map.get(parsed_data, :refCategory) || "00"
     cust_ref = Map.get(parsed_data, :cust_ref) || Map.get(parsed_data, :custRef) || ""
     txn_type = Map.get(parsed_data, :txn_type) || Map.get(parsed_data, :type) || "ChkTxn"
     org_msg_id = Map.get(parsed_data, :org_msg_id) || Map.get(parsed_data, :orgMsgId) || ""
-    initiation_mode = Map.get(parsed_data, :initiation_mode) || Map.get(parsed_data, :initiationMode) || "16"
-    purpose = Map.get(parsed_data, :purpose) || "11"
-    sub_type = Map.get(parsed_data, :sub_type) || Map.get(parsed_data, :subType) || "CREDIT"
+    # [RespChkTxn Txn.initiationMode / purpose / subType] CHANGED: echo the ReqChkTxn values (no 16 / 02, 11 and CREDIT defaults)
+    # OLD:     initiation_mode = Map.get(parsed_data, :initiation_mode) || Map.get(parsed_data, :initiationMode) || "16"
+    # OLD:     purpose = Map.get(parsed_data, :purpose) || "11"
+    # OLD:     sub_type = Map.get(parsed_data, :sub_type) || Map.get(parsed_data, :subType) || "CREDIT"
+    initiation_mode = Map.get(parsed_data, :initiation_mode) || Map.get(parsed_data, :initiationMode) || ""
+    purpose = Map.get(parsed_data, :purpose) || ""
+    sub_type = Map.get(parsed_data, :sub_type) || Map.get(parsed_data, :subType) || ""
 
     Logger.info("[AccIp08Scenario] Building X7 response - txn_id=#{txn_id}, note=#{note}")
 
@@ -233,76 +242,104 @@ defmodule UpiDynamic.SpecialHandlers.AccIp08Scenario do
     end
   end
 
+  # [RespChkTxn <RespChkTxn> template] OLD FUNCTION kept for reference. It hand-built the XML with Ref from the merchant DB row of the scenario VPA and dummy fallbacks: code 000000, IFSC AEBK0087654, acNum AE112233445, accType CURRENT, orgAmount 999.00,
+  # Txn seqNum absent but Head ts / Txn ts in UTC. [RespChkTxn Ref.addr / regName / code / IFSC / acNum / accType / orgAmount] CHANGED: now UpiXmlSchema.generate_resp_chk_txn with ref_data from the stored ReqPay (orgTxnId)
+  # TSD Table 6: Ref values of the original ReqPay; settAmount 0.00 and settCurrency INR on the X7 failure
+  # OLD:   defp generate_x7_resp_chk_txn_xml_internal(response_data) do
+  # OLD:     try do
+  # OLD:       Logger.info("[AccIp08Scenario] Generating X7 RespChkTxn XML matching NPCI format")
+  # OLD:
+  # OLD:       # Get merchant data or use fallback
+  # OLD:       merchant_data = response_data[:merchant_data] || response_data.merchant_data
+  # OLD:
+  # OLD:       # Extract settlement info from response data
+  # OLD:       settlement_currency = response_data[:settlement_currency] || response_data.settlement_currency || "INR"
+  # OLD:       settlement_amount = response_data[:settlement_amount] || response_data.settlement_amount || "0.00"
+  # OLD:
+  # OLD:       # Build ref data
+  # OLD:       ref_data = if merchant_data do
+  # OLD:         amount = case Map.get(merchant_data, :max_transaction_limit) do
+  # OLD:           nil -> "999.00"
+  # OLD:           %Decimal{} = d -> Decimal.to_string(d)
+  # OLD:           val when is_number(val) -> Float.to_string(val)
+  # OLD:           val when is_binary(val) -> val
+  # OLD:           _ -> "999.00"
+  # OLD:         end
+  # OLD:
+  # OLD:         %{
+  # OLD:           addr: to_string(Map.get(merchant_data, :merchant_vpa) || @target_vpa),
+  # OLD:           code: to_string(Map.get(merchant_data, :merchant_code) || "000000"),
+  # OLD:           reg_name: to_string(Map.get(merchant_data, :legal_name) || Map.get(merchant_data, :brand_name) || "NPCI Tester"),
+  # OLD:           ifsc: to_string(Map.get(merchant_data, :settlement_account_ifsc) || "AEBK0087654"),
+  # OLD:           ac_num: to_string(Map.get(merchant_data, :settlement_account_number) || "AE112233445"),
+  # OLD:           acc_type: to_string(Map.get(merchant_data, :settlement_account_type) || "CURRENT"),
+  # OLD:           sett_currency: "INR",  # CRITICAL: For failure cases, settlement currency must be INR
+  # OLD:           org_amount: amount,
+  # OLD:           sett_amount: "0.00"  # CRITICAL: For failure cases, settlement amount must be 0.00
+  # OLD:         }
+  # OLD:       else
+  # OLD:         %{
+  # OLD:           addr: @target_vpa,
+  # OLD:           code: "000000",
+  # OLD:           reg_name: "NPCI Tester",
+  # OLD:           ifsc: "AEBK0087654",
+  # OLD:           ac_num: "AE112233445",
+  # OLD:           acc_type: "CURRENT",
+  # OLD:           sett_currency: "INR",  # CRITICAL: For failure cases, settlement currency must be INR
+  # OLD:           org_amount: "999.00",
+  # OLD:           sett_amount: "0.00"  # CRITICAL: For failure cases, settlement amount must be 0.00
+  # OLD:         }
+  # OLD:       end
+  # OLD:
+  # OLD:       # Generate 6-character approval number (APP + 3 digits, matching ACC_IP_10 pattern)
+  # OLD:       approval_num = "APP" <> String.pad_leading(Integer.to_string(:rand.uniform(1000) - 1), 3, "0")
+  # OLD:
+  # OLD:       # Build XML matching exact NPCI format
+  # OLD:       xml = """
+  # OLD:       <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+  # OLD:       <ns2:RespChkTxn xmlns:ns2="http://npci.org/upi/schema/">
+  # OLD:       <Head ver="2.0" ts="#{response_data.timestamp}" orgId="MER101" msgId="#{response_data.msg_id}" prodType="UPI"/>
+  # OLD:       <Txn id="#{response_data.txn_id}" note="#{response_data.note}" refId="#{response_data.ref_id}" refUrl="#{response_data.ref_url}" refCategory="#{response_data.ref_category}" ts="#{response_data.timestamp}" custRef="#{response_data.cust_ref}" type="#{response_data.txn_type}" orgMsgId="#{response_data.org_msg_id}" orgTxnId="#{response_data.org_txn_id}" initiationMode="#{response_data.initiation_mode}" purpose="#{response_data.purpose}" subType="#{response_data.sub_type}"/>
+  # OLD:       <Resp reqMsgId="#{response_data.req_msg_id}" result="FAILURE" errCode="X7">
+  # OLD:       <Ref type="PAYEE" seqNum="1" addr="#{ref_data.addr}" code="#{ref_data.code}" orgAmount="#{ref_data.org_amount}" respCode="X7" regName="#{ref_data.reg_name}" IFSC="#{ref_data.ifsc}" acNum="#{ref_data.ac_num}" accType="#{ref_data.acc_type}" approvalNum="#{approval_num}" settAmount="#{ref_data.sett_amount}" settCurrency="#{ref_data.sett_currency}" />
+  # OLD:       </Resp>
+  # OLD:       </ns2:RespChkTxn>
+  # OLD:       """
+  # OLD:
+  # OLD:       Logger.info("[AccIp08Scenario] ✅ Generated X7 RespChkTxn XML successfully")
+  # OLD:       Logger.debug("[AccIp08Scenario] XML (first 800 chars): #{String.slice(xml, 0, 800)}")
+  # OLD:       {:ok, String.trim(xml)}
+  # OLD:     rescue
+  # OLD:       e ->
+  # OLD:         Logger.error("[AccIp08Scenario] ❌ Error generating X7 RespChkTxn XML: #{inspect(e)}")
+  # OLD:         Logger.error("[AccIp08Scenario] Stacktrace: #{Exception.format_stacktrace(__STACKTRACE__)}")
+  # OLD:         {:error, "Failed to generate X7 RespChkTxn XML: #{inspect(e)}"}
+  # OLD:     end
+  # OLD:   end
   defp generate_x7_resp_chk_txn_xml_internal(response_data) do
-    try do
-      Logger.info("[AccIp08Scenario] Generating X7 RespChkTxn XML matching NPCI format")
-
-      # Get merchant data or use fallback
-      merchant_data = response_data[:merchant_data] || response_data.merchant_data
-
-      # Extract settlement info from response data
-      settlement_currency = response_data[:settlement_currency] || response_data.settlement_currency || "INR"
-      settlement_amount = response_data[:settlement_amount] || response_data.settlement_amount || "0.00"
-
-      # Build ref data
-      ref_data = if merchant_data do
-        amount = case Map.get(merchant_data, :max_transaction_limit) do
-          nil -> "999.00"
-          %Decimal{} = d -> Decimal.to_string(d)
-          val when is_number(val) -> Float.to_string(val)
-          val when is_binary(val) -> val
-          _ -> "999.00"
-        end
-
-        %{
-          addr: to_string(Map.get(merchant_data, :merchant_vpa) || @target_vpa),
-          code: to_string(Map.get(merchant_data, :merchant_code) || "000000"),
-          reg_name: to_string(Map.get(merchant_data, :legal_name) || Map.get(merchant_data, :brand_name) || "NPCI Tester"),
-          ifsc: to_string(Map.get(merchant_data, :settlement_account_ifsc) || "AEBK0087654"),
-          ac_num: to_string(Map.get(merchant_data, :settlement_account_number) || "AE112233445"),
-          acc_type: to_string(Map.get(merchant_data, :settlement_account_type) || "CURRENT"),
-          sett_currency: "INR",  # CRITICAL: For failure cases, settlement currency must be INR
-          org_amount: amount,
-          sett_amount: "0.00"  # CRITICAL: For failure cases, settlement amount must be 0.00
-        }
-      else
-        %{
-          addr: @target_vpa,
-          code: "000000",
-          reg_name: "NPCI Tester",
-          ifsc: "AEBK0087654",
-          ac_num: "AE112233445",
-          acc_type: "CURRENT",
-          sett_currency: "INR",  # CRITICAL: For failure cases, settlement currency must be INR
-          org_amount: "999.00",
-          sett_amount: "0.00"  # CRITICAL: For failure cases, settlement amount must be 0.00
-        }
-      end
-
-      # Generate 6-character approval number (APP + 3 digits, matching ACC_IP_10 pattern)
-      approval_num = "APP" <> String.pad_leading(Integer.to_string(:rand.uniform(1000) - 1), 3, "0")
-
-      # Build XML matching exact NPCI format
-      xml = """
-      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-      <ns2:RespChkTxn xmlns:ns2="http://npci.org/upi/schema/">
-      <Head ver="2.0" ts="#{response_data.timestamp}" orgId="MER101" msgId="#{response_data.msg_id}" prodType="UPI"/>
-      <Txn id="#{response_data.txn_id}" note="#{response_data.note}" refId="#{response_data.ref_id}" refUrl="#{response_data.ref_url}" refCategory="#{response_data.ref_category}" ts="#{response_data.timestamp}" custRef="#{response_data.cust_ref}" type="#{response_data.txn_type}" orgMsgId="#{response_data.org_msg_id}" orgTxnId="#{response_data.org_txn_id}" initiationMode="#{response_data.initiation_mode}" purpose="#{response_data.purpose}" subType="#{response_data.sub_type}"/>
-      <Resp reqMsgId="#{response_data.req_msg_id}" result="FAILURE" errCode="X7">
-      <Ref type="PAYEE" seqNum="1" addr="#{ref_data.addr}" code="#{ref_data.code}" orgAmount="#{ref_data.org_amount}" respCode="X7" regName="#{ref_data.reg_name}" IFSC="#{ref_data.ifsc}" acNum="#{ref_data.ac_num}" accType="#{ref_data.acc_type}" approvalNum="#{approval_num}" settAmount="#{ref_data.sett_amount}" settCurrency="#{ref_data.sett_currency}" />
-      </Resp>
-      </ns2:RespChkTxn>
-      """
-
-      Logger.info("[AccIp08Scenario] ✅ Generated X7 RespChkTxn XML successfully")
-      Logger.debug("[AccIp08Scenario] XML (first 800 chars): #{String.slice(xml, 0, 800)}")
-      {:ok, String.trim(xml)}
-    rescue
-      e ->
-        Logger.error("[AccIp08Scenario] ❌ Error generating X7 RespChkTxn XML: #{inspect(e)}")
-        Logger.error("[AccIp08Scenario] Stacktrace: #{Exception.format_stacktrace(__STACKTRACE__)}")
-        {:error, "Failed to generate X7 RespChkTxn XML: #{inspect(e)}"}
-    end
+    Logger.info("[AccIp08Scenario] Generating X7 RespChkTxn with UpiXmlSchema.generate_resp_chk_txn")
+
+    stored = ReqPayService.get_by_txn_id(response_data[:org_txn_id])
+    approval_num = "APP" <> String.pad_leading(Integer.to_string(:rand.uniform(1000) - 1), 3, "0")
+    ref_data = UpiCore.UpiXmlSchema.ref_data_from_stored_req_pay(stored, "X7", approval_num)
+
+    UpiCore.UpiXmlSchema.generate_resp_chk_txn(%{
+      org_id: response_data[:org_id] || "MER101",
+      msg_id: response_data[:msg_id],
+      req_msg_id: response_data[:req_msg_id],
+      result: "FAILURE",
+      err_code: "X7",
+      txn_id: response_data[:txn_id],
+      org_txn_id: response_data[:org_txn_id],
+      org_msg_id: response_data[:org_msg_id],
+      note: response_data[:note],
+      ref_id: response_data[:ref_id],
+      cust_ref: response_data[:cust_ref],
+      initiation_mode: response_data[:initiation_mode],
+      purpose: response_data[:purpose],
+      sub_type: response_data[:sub_type],
+      ref_data: ref_data
+    })
   end
 
   defp send_x7_resp_chk_txn_to_npci(resp_xml, txn_id) do
diff --git a/apps/upi_dynamic/lib/upi_dynamic/upi_transaction_manager.ex b/apps/upi_dynamic/lib/upi_dynamic/upi_transaction_manager.ex
index cdf47bb..bf91774 100644
--- a/apps/upi_dynamic/lib/upi_dynamic/upi_transaction_manager.ex
+++ b/apps/upi_dynamic/lib/upi_dynamic/upi_transaction_manager.ex
@@ -1874,7 +1874,9 @@ end
                   _ -> nil
                 end
 
-              seq_num =
+              # [RespChkTxn Txn.seqNum] CHANGED: seqNum is no longer sent in RespChkTxn (TSD Table 6), so the variable is only read for logging / not used
+              # OLD:               seq_num =
+              _seq_num =
                 case parsed_data do
                   %{} = pd ->
                     Map.get(pd, :seq_num) || Map.get(pd, "seq_num") || Map.get(pd, :seqNum) || Map.get(pd, "seqNum") ||
@@ -2004,7 +2006,8 @@ end
                 note: note || "",
                 cust_ref: cust_ref || "",
                 initiation_mode: initiation_mode || "",
-                seq_num: seq_num || UpiXmlSchema.generate_numeric_seq_num(),
+                # [RespChkTxn Txn.seqNum] REMOVED: seqNum is not in the RespChkTxn Txn (TSD Table 6)
+                # OLD:                 seq_num: seq_num || UpiXmlSchema.generate_numeric_seq_num(),
                 purpose: purpose || "",
                 status: status,
                 currency: Map.get(transaction, :currency) || "INR",
@@ -2333,7 +2336,9 @@ end
                 _ -> nil
               end
 
-            seq_num =
+            # [RespChkTxn Txn.seqNum] CHANGED: seqNum is no longer sent in RespChkTxn (TSD Table 6), so the variable is only read for logging / not used
+            # OLD:             seq_num =
+            _seq_num =
               case parsed_data do
                 %{} = pd ->
                   Map.get(pd, :seq_num) || Map.get(pd, "seq_num") || Map.get(pd, :seqNum) || Map.get(pd, "seqNum") ||
@@ -2393,7 +2398,8 @@ end
                 note: note || "",
                 cust_ref: cust_ref || "",
                 initiation_mode: initiation_mode || "",
-                seq_num: seq_num || UpiXmlSchema.generate_numeric_seq_num(),
+                # [RespChkTxn Txn.seqNum] REMOVED: seqNum is not in the RespChkTxn Txn (TSD Table 6)
+                # OLD:                 seq_num: seq_num || UpiXmlSchema.generate_numeric_seq_num(),
                 purpose: purpose || "",
                 status: status,
                 currency: Map.get(transaction, :currency) || "INR",
@@ -2442,19 +2448,23 @@ end
                   Logger.info("  merchant_category_code: #{inspect(req_pay.merchant_category_code)}")
 
                   # Build ref_data from req_pays fields
-                  extracted_ref_data = %{
-                    addr: req_pay.payee_addr || "",
-                    regName: req_pay.payee_name || "",
-                    code: req_pay.merchant_category_code || "000000",
-                    org_amount: to_string(req_pay.amount || "0.00"),
-                    resp_code: "00",
-                    ifsc: req_pay.payee_ifsc || "",
-                    ac_num: req_pay.payee_account_number || "",
-                    acc_type: req_pay.payee_account_type || "CURRENT",
-                    approval_num: generate_approval_number(),
-                    sett_amount: to_string(req_pay.amount || "0.00"),
-                    sett_currency: req_pay.currency || "INR"
-                  }
+                  # [RespChkTxn Ref.*] CHANGED: ref_data from the stored ReqPay with the transaction's real respCode (was respCode "00" always, code default 000000, accType default CURRENT, settCurrency = ReqPay currency)
+                  # TSD Table 6: Ref addr / code / regName / IFSC / acNum / accType = stored ReqPay Payee; settCurrency INR
+                  # OLD:                   extracted_ref_data = %{
+                  # OLD:                     addr: req_pay.payee_addr || "",
+                  # OLD:                     regName: req_pay.payee_name || "",
+                  # OLD:                     code: req_pay.merchant_category_code || "000000",
+                  # OLD:                     org_amount: to_string(req_pay.amount || "0.00"),
+                  # OLD:                     resp_code: "00",
+                  # OLD:                     ifsc: req_pay.payee_ifsc || "",
+                  # OLD:                     ac_num: req_pay.payee_account_number || "",
+                  # OLD:                     acc_type: req_pay.payee_account_type || "CURRENT",
+                  # OLD:                     approval_num: generate_approval_number(),
+                  # OLD:                     sett_amount: to_string(req_pay.amount || "0.00"),
+                  # OLD:                     sett_currency: req_pay.currency || "INR"
+                  # OLD:                   }
+                  extracted_ref_data =
+                    UpiXmlSchema.ref_data_from_stored_req_pay(req_pay, determine_resp_code_for_ref(transaction), generate_approval_number())
                   Logger.info("✅ Built ref_data from req_pays: #{inspect(extracted_ref_data)}")
                   extracted_ref_data
 
@@ -2733,7 +2743,8 @@ end
         note: Map.get(parsed_data, :note) || Map.get(parsed_data, "note") || "",
         cust_ref: Map.get(parsed_data, :cust_ref) || Map.get(parsed_data, "cust_ref") || "",
         initiation_mode: Map.get(parsed_data, :initiation_mode) || Map.get(parsed_data, "initiation_mode") || "",
-        seq_num: UpiXmlSchema.generate_numeric_seq_num(),
+        # [RespChkTxn Txn.seqNum] REMOVED: seqNum is not in the RespChkTxn Txn (TSD Table 6)
+        # OLD:         seq_num: UpiXmlSchema.generate_numeric_seq_num(),
         purpose: Map.get(parsed_data, :purpose) || Map.get(parsed_data, "purpose") || "",
         status: Map.get(parsed_data, :status) || Map.get(parsed_data, "status") || "PENDING",
         currency: Map.get(parsed_data, :currency) || Map.get(parsed_data, "currency") || "INR",
@@ -3908,18 +3919,32 @@ end
     Logger.info("Response Data txn_id: #{inspect(response_data.txn_id)}, length: #{String.length(response_data.txn_id || "")}")
 
     # Build ref_data from error response_data for RespChkTxn
+    # [RespChkTxn Ref.*] CHANGED: key regName (was reg_name, so regName was always empty); no invented 000000 / CURRENT defaults; respCode = the error code
+    # OLD:     ref_data = %{
+    # OLD:       addr: Map.get(response_data, :addr) || "",
+    # OLD:       code: Map.get(response_data, :code) || "000000",
+    # OLD:       org_amount: Map.get(response_data, :org_amount) || "0.00",
+    # OLD:       resp_code: Map.get(response_data, :resp_code) || error_code,
+    # OLD:       reg_name: Map.get(response_data, :reg_name) || "",
+    # OLD:       ifsc: Map.get(response_data, :ifsc) || "",
+    # OLD:       ac_num: Map.get(response_data, :ac_num) || "",
+    # OLD:       acc_type: Map.get(response_data, :acc_type) || "CURRENT",
+    # OLD:       approval_num: Map.get(response_data, :approval_num) || "",
+    # OLD:       sett_amount: Map.get(response_data, :sett_amount) || "0.00",
+    # OLD:       sett_currency: Map.get(response_data, :sett_currency) || "INR"
+    # OLD:     }
     ref_data = %{
       addr: Map.get(response_data, :addr) || "",
-      code: Map.get(response_data, :code) || "000000",
+      code: Map.get(response_data, :code),
       org_amount: Map.get(response_data, :org_amount) || "0.00",
       resp_code: Map.get(response_data, :resp_code) || error_code,
-      reg_name: Map.get(response_data, :reg_name) || "",
+      regName: Map.get(response_data, :reg_name) || "",
       ifsc: Map.get(response_data, :ifsc) || "",
       ac_num: Map.get(response_data, :ac_num) || "",
-      acc_type: Map.get(response_data, :acc_type) || "CURRENT",
+      acc_type: Map.get(response_data, :acc_type),
       approval_num: Map.get(response_data, :approval_num) || "",
       sett_amount: Map.get(response_data, :sett_amount) || "0.00",
-      sett_currency: Map.get(response_data, :sett_currency) || "INR"
+      sett_currency: "INR"
     }
     response_data_with_ref = Map.put(response_data, :ref_data, ref_data)
 
@@ -5517,13 +5542,17 @@ end
     Map.get(req_pay, :payee_addr) || Map.get(transaction, :payee_addr) || ""
   end
 
-  defp get_merchant_code_for_ref(merchant, req_pay) do
-    cond do
-      merchant && Map.get(merchant, :merchant_code) -> merchant.merchant_code
-      merchant && Map.get(merchant, :mid) -> merchant.mid
-      req_pay && Map.get(req_pay, :merchant_category_code) -> req_pay.merchant_category_code
-      true -> "000000"
-    end
+  # [RespChkTxn Ref.code] CHANGED: only the stored ReqPay MCC (merchant_code / mid are internal ids, not an MCC; no 000000 default)
+  # OLD:   defp get_merchant_code_for_ref(merchant, req_pay) do
+  # OLD:     cond do
+  # OLD:       merchant && Map.get(merchant, :merchant_code) -> merchant.merchant_code
+  # OLD:       merchant && Map.get(merchant, :mid) -> merchant.mid
+  # OLD:       req_pay && Map.get(req_pay, :merchant_category_code) -> req_pay.merchant_category_code
+  # OLD:       true -> "000000"
+  # OLD:     end
+  # OLD:   end
+  defp get_merchant_code_for_ref(_merchant, req_pay) do
+    if req_pay, do: Map.get(req_pay, :merchant_category_code)
   end
 
   defp get_amount_for_ref(req_pay, transaction) do
@@ -5534,53 +5563,90 @@ end
     end
   end
 
+  # [RespChkTxn Ref.respCode] CHANGED: transaction status is lowercase (success / failure / ...), so the uppercase match always fell to U69; now credited -> 00, failed -> stored failure_code
+  # (UpiXmlSchema.chk_txn_resp_code/1)
+  # OLD:   defp determine_resp_code_for_ref(transaction) do
+  # OLD:     case Map.get(transaction, :status) do
+  # OLD:       "SUCCESS" -> "00"
+  # OLD:       "FAILED" -> "U30"
+  # OLD:       "PENDING" -> "BT"
+  # OLD:       _ -> "U69"
+  # OLD:     end
+  # OLD:   end
   defp determine_resp_code_for_ref(transaction) do
-    case Map.get(transaction, :status) do
-      "SUCCESS" -> "00"
-      "FAILED" -> "U30"
-      "PENDING" -> "BT"
-      _ -> "U69"
-    end
+    UpiXmlSchema.chk_txn_resp_code(transaction)
   end
 
-  defp get_merchant_name_for_ref(merchant, req_pay, transaction) do
+  # [RespChkTxn Ref.regName] CHANGED: the stored ReqPay Payee name first (not the merchant legal / brand name), no "Unknown Merchant"
+  # OLD:   defp get_merchant_name_for_ref(merchant, req_pay, transaction) do
+  # OLD:     cond do
+  # OLD:       merchant && Map.get(merchant, :legal_name) && merchant.legal_name != "" -> merchant.legal_name
+  # OLD:       merchant && Map.get(merchant, :brand_name) && merchant.brand_name != "" -> merchant.brand_name
+  # OLD:       merchant && Map.get(merchant, :name) && merchant.name != "" -> merchant.name
+  # OLD:       req_pay && Map.get(req_pay, :payee_name) && req_pay.payee_name != "" -> req_pay.payee_name
+  # OLD:       transaction && Map.get(transaction, :payee_name) -> transaction.payee_name
+  # OLD:       true -> "Unknown Merchant"
+  # OLD:     end
+  # OLD:   end
+  defp get_merchant_name_for_ref(_merchant, req_pay, transaction) do
     cond do
-      merchant && Map.get(merchant, :legal_name) && merchant.legal_name != "" -> merchant.legal_name
-      merchant && Map.get(merchant, :brand_name) && merchant.brand_name != "" -> merchant.brand_name
-      merchant && Map.get(merchant, :name) && merchant.name != "" -> merchant.name
       req_pay && Map.get(req_pay, :payee_name) && req_pay.payee_name != "" -> req_pay.payee_name
-      transaction && Map.get(transaction, :payee_name) -> transaction.payee_name
-      true -> "Unknown Merchant"
+      transaction && Map.get(transaction, :payee_name) && transaction.payee_name != "" -> transaction.payee_name
+      true -> nil
     end
   end
 
+  # [RespChkTxn Ref.IFSC / acNum / accType] CHANGED: the stored ReqPay Payee account first (merchant DB only as a fallback), no CURRENT default
+  # OLD:   defp get_ifsc_for_ref(merchant, req_pay) do
+  # OLD:     cond do
+  # OLD:       merchant && Map.get(merchant, :settlement_account_ifsc) && merchant.settlement_account_ifsc != "" ->
+  # OLD:         merchant.settlement_account_ifsc
+  # OLD:       req_pay && Map.get(req_pay, :payee_ifsc) && req_pay.payee_ifsc != "" ->
+  # OLD:         req_pay.payee_ifsc
+  # OLD:       true -> ""
+  # OLD:     end
+  # OLD:   end
+  # OLD:
+  # OLD:   defp get_account_number_for_ref(merchant, req_pay) do
+  # OLD:     cond do
+  # OLD:       merchant && Map.get(merchant, :settlement_account_number) && merchant.settlement_account_number != "" ->
+  # OLD:         merchant.settlement_account_number
+  # OLD:       req_pay && Map.get(req_pay, :payee_account_number) && req_pay.payee_account_number != "" ->
+  # OLD:         req_pay.payee_account_number
+  # OLD:       true -> ""
+  # OLD:     end
+  # OLD:   end
+  # OLD:
+  # OLD:   defp get_account_type_for_ref(merchant, req_pay) do
+  # OLD:     cond do
+  # OLD:       merchant && Map.get(merchant, :settlement_account_type) && merchant.settlement_account_type != "" ->
+  # OLD:         merchant.settlement_account_type
+  # OLD:       req_pay && Map.get(req_pay, :payee_account_type) && req_pay.payee_account_type != "" ->
+  # OLD:         req_pay.payee_account_type
+  # OLD:       true -> "CURRENT"
+  # OLD:     end
+  # OLD:   end
   defp get_ifsc_for_ref(merchant, req_pay) do
     cond do
-      merchant && Map.get(merchant, :settlement_account_ifsc) && merchant.settlement_account_ifsc != "" ->
-        merchant.settlement_account_ifsc
-      req_pay && Map.get(req_pay, :payee_ifsc) && req_pay.payee_ifsc != "" ->
-        req_pay.payee_ifsc
+      req_pay && Map.get(req_pay, :payee_ifsc) && req_pay.payee_ifsc != "" -> req_pay.payee_ifsc
+      merchant && Map.get(merchant, :settlement_account_ifsc) && merchant.settlement_account_ifsc != "" -> merchant.settlement_account_ifsc
       true -> ""
     end
   end
 
   defp get_account_number_for_ref(merchant, req_pay) do
     cond do
-      merchant && Map.get(merchant, :settlement_account_number) && merchant.settlement_account_number != "" ->
-        merchant.settlement_account_number
-      req_pay && Map.get(req_pay, :payee_account_number) && req_pay.payee_account_number != "" ->
-        req_pay.payee_account_number
+      req_pay && Map.get(req_pay, :payee_account_number) && req_pay.payee_account_number != "" -> req_pay.payee_account_number
+      merchant && Map.get(merchant, :settlement_account_number) && merchant.settlement_account_number != "" -> merchant.settlement_account_number
       true -> ""
     end
   end
 
   defp get_account_type_for_ref(merchant, req_pay) do
     cond do
-      merchant && Map.get(merchant, :settlement_account_type) && merchant.settlement_account_type != "" ->
-        merchant.settlement_account_type
-      req_pay && Map.get(req_pay, :payee_account_type) && req_pay.payee_account_type != "" ->
-        req_pay.payee_account_type
-      true -> "CURRENT"
+      req_pay && Map.get(req_pay, :payee_account_type) && req_pay.payee_account_type != "" -> req_pay.payee_account_type
+      merchant && Map.get(merchant, :settlement_account_type) && merchant.settlement_account_type != "" -> merchant.settlement_account_type
+      true -> nil
     end
   end
 
@@ -5601,21 +5667,24 @@ end
     end
   end
 
-  defp get_settlement_currency_for_ref(merchant, req_pay, transaction) do
-    cond do
-      # For international payments, prioritize foreign_currency
-      transaction && Map.get(transaction, :foreign_currency) && transaction.foreign_currency != "" && transaction.foreign_currency != "INR" ->
-        transaction.foreign_currency
-      # Then check merchant settings (but skip if INR)
-      merchant && Map.get(merchant, :currency) && merchant.currency != "" && merchant.currency != "INR" ->
-        merchant.currency
-      merchant && Map.get(merchant, :settlement_currency) && merchant.settlement_currency != "" && merchant.settlement_currency != "INR" ->
-        merchant.settlement_currency
-      # Check req_pay (but skip if INR)
-      req_pay && Map.get(req_pay, :currency) && req_pay.currency != "" && req_pay.currency != "INR" ->
-        req_pay.currency
-      # Default to AED for international platform
-      true -> "AED"
-    end
-  end
+  # [RespChkTxn Ref.settCurrency] CHANGED: always INR (was foreign currency / merchant currency, default AED)
+  # TSD Table 6: settCurrency = INR
+  # OLD:   defp get_settlement_currency_for_ref(merchant, req_pay, transaction) do
+  # OLD:     cond do
+  # OLD:       # For international payments, prioritize foreign_currency
+  # OLD:       transaction && Map.get(transaction, :foreign_currency) && transaction.foreign_currency != "" && transaction.foreign_currency != "INR" ->
+  # OLD:         transaction.foreign_currency
+  # OLD:       # Then check merchant settings (but skip if INR)
+  # OLD:       merchant && Map.get(merchant, :currency) && merchant.currency != "" && merchant.currency != "INR" ->
+  # OLD:         merchant.currency
+  # OLD:       merchant && Map.get(merchant, :settlement_currency) && merchant.settlement_currency != "" && merchant.settlement_currency != "INR" ->
+  # OLD:         merchant.settlement_currency
+  # OLD:       # Check req_pay (but skip if INR)
+  # OLD:       req_pay && Map.get(req_pay, :currency) && req_pay.currency != "" && req_pay.currency != "INR" ->
+  # OLD:         req_pay.currency
+  # OLD:       # Default to AED for international platform
+  # OLD:       true -> "AED"
+  # OLD:     end
+  # OLD:   end
+  defp get_settlement_currency_for_ref(_merchant, _req_pay, _transaction), do: "INR"
 end
diff --git a/apps/upi_dynamic/test/upi_dynamic/resp_chk_txn_test.exs b/apps/upi_dynamic/test/upi_dynamic/resp_chk_txn_test.exs
new file mode 100644
index 0000000..7db36ed
--- /dev/null
+++ b/apps/upi_dynamic/test/upi_dynamic/resp_chk_txn_test.exs
@@ -0,0 +1,68 @@
+defmodule UpiDynamic.RespChkTxnTest do
+  use ExUnit.Case, async: false
+
+  import SweetXml
+
+  alias UpiCore.Repo
+  alias UpiCore.Transactions.ReqPay
+
+  @org_txn_id "ORGTXNPAY0000000000000000000000001"
+
+  setup do
+    {:ok, _} = Application.ensure_all_started(:upi_core)
+    pid = Ecto.Adapters.SQL.Sandbox.start_owner!(Repo, shared: true)
+    on_exit(fn -> Ecto.Adapters.SQL.Sandbox.stop_owner(pid) end)
+
+    {:ok, _} =
+      %ReqPay{}
+      |> ReqPay.changeset(%{
+        msg_id: "STOREDREQPAYMSG0000000000000000001",
+        txn_id: @org_txn_id,
+        org_id: "NPCI",
+        amount: Decimal.new("5"),
+        currency: "INR",
+        status: "PROCESSED",
+        validation_type: "DOMESTIC",
+        payee_addr: "restaurant@mercury",
+        payee_name: "NPCI Tester",
+        merchant_category_code: "5812",
+        payee_ifsc: "TEST0000001",
+        payee_account_number: "123456789012345678",
+        payee_account_type: "SAVINGS"
+      })
+      |> Repo.insert()
+
+    :ok
+  end
+
+  defp attr(xml, path), do: xpath(xml, ~x"#{path}"s)
+  @ref "//*[local-name()='Ref']"
+
+  test "ACC_IP_08 (dynamic copy): X7 RespChkTxn Ref from the stored ReqPay, no dummy values" do
+    parsed = %{
+      msg_id: "NPCIREQCHKTXN000000000000000000001",
+      txn_id: "NPCICHKTXNID-LONGER-THAN-35-CHARS-AND-NOT-HEX",
+      org_txn_id: @org_txn_id,
+      org_msg_id: "NPCIORGMSGID00000000000000000001",
+      note: "ACC_IP-08",
+      ref_id: "REFCHK0001",
+      cust_ref: "CUSTREF08",
+      initiation_mode: "16",
+      purpose: "11",
+      sub_type: "PAY"
+    }
+
+    {:ok, xml} = UpiDynamic.SpecialHandlers.AccIp08Scenario.generate_x7_resp_chk_txn_xml(parsed)
+    assert attr(xml, "//*[local-name()='Resp']/@errCode") == "X7"
+    assert attr(xml, @ref <> "/@respCode") == "X7"
+    assert attr(xml, @ref <> "/@code") == "5812"
+    assert attr(xml, @ref <> "/@regName") == "NPCI Tester"
+    assert attr(xml, @ref <> "/@acNum") == "123456789012345678"
+    assert attr(xml, @ref <> "/@orgAmount") == "5.00"
+    assert attr(xml, @ref <> "/@settAmount") == "0.00"
+    assert attr(xml, @ref <> "/@settCurrency") == "INR"
+    assert attr(xml, "//*[local-name()='Txn']/@id") == parsed.txn_id
+    refute xml =~ "AEBK0087654"
+    refute xml =~ ~s(code="000000")
+  end
+end
diff --git a/apps/upi_static/lib/upi_static/special_handlers/static_acc_ip_08_scenario.ex b/apps/upi_static/lib/upi_static/special_handlers/static_acc_ip_08_scenario.ex
index 01662ce..d7b7bb3 100644
--- a/apps/upi_static/lib/upi_static/special_handlers/static_acc_ip_08_scenario.ex
+++ b/apps/upi_static/lib/upi_static/special_handlers/static_acc_ip_08_scenario.ex
@@ -295,21 +295,30 @@ defmodule UpiStatic.SpecialHandlers.StaticAccIp08Scenario do
     # Extract all required fields from parsed_data (from original ReqChkTxn)
     msg_id = generate_msg_id()
     req_msg_id = Map.get(parsed_data, :msg_id) || ""
-    txn_id = Map.get(parsed_data, :txn_id) || Map.get(parsed_data, :org_txn_id) || generate_txn_id()
-    org_txn_id = Map.get(parsed_data, :org_txn_id) || txn_id
+    # [RespChkTxn Txn.id / Txn.orgTxnId] CHANGED: echo the ReqChkTxn ids exactly (no orgTxnId <- txnId fallback, no generated TXN... id)
+    # OLD:     txn_id = Map.get(parsed_data, :txn_id) || Map.get(parsed_data, :org_txn_id) || generate_txn_id()
+    # OLD:     org_txn_id = Map.get(parsed_data, :org_txn_id) || txn_id
+    txn_id = Map.get(parsed_data, :txn_id) || ""
+    org_txn_id = Map.get(parsed_data, :org_txn_id) || ""
     timestamp = DateTime.utc_now() |> DateTime.to_iso8601()
 
     # Extract fields from original ReqChkTxn to preserve in RespChkTxn
-    note = Map.get(parsed_data, :note) || "ACCIP08"
+    # [RespChkTxn Txn.note] CHANGED: echo the ReqChkTxn note (no ACCIP08 default)
+    # OLD:     note = Map.get(parsed_data, :note) || "ACCIP08"
+    note = Map.get(parsed_data, :note) || ""
     ref_id = Map.get(parsed_data, :ref_id) || Map.get(parsed_data, :refId) || ""
     ref_url = "https://merstatic.aritic.app"
     ref_category = Map.get(parsed_data, :ref_category) || Map.get(parsed_data, :refCategory) || "00"
     cust_ref = Map.get(parsed_data, :cust_ref) || Map.get(parsed_data, :custRef) || ""
     txn_type = Map.get(parsed_data, :txn_type) || Map.get(parsed_data, :type) || "ChkTxn"
     org_msg_id = Map.get(parsed_data, :org_msg_id) || Map.get(parsed_data, :orgMsgId) || ""
-    initiation_mode = Map.get(parsed_data, :initiation_mode) || Map.get(parsed_data, :initiationMode) || "02"
-    purpose = Map.get(parsed_data, :purpose) || "11"
-    sub_type = Map.get(parsed_data, :sub_type) || Map.get(parsed_data, :subType) || "CREDIT"
+    # [RespChkTxn Txn.initiationMode / purpose / subType] CHANGED: echo the ReqChkTxn values (no 16 / 02, 11 and CREDIT defaults)
+    # OLD:     initiation_mode = Map.get(parsed_data, :initiation_mode) || Map.get(parsed_data, :initiationMode) || "02"
+    # OLD:     purpose = Map.get(parsed_data, :purpose) || "11"
+    # OLD:     sub_type = Map.get(parsed_data, :sub_type) || Map.get(parsed_data, :subType) || "CREDIT"
+    initiation_mode = Map.get(parsed_data, :initiation_mode) || Map.get(parsed_data, :initiationMode) || ""
+    purpose = Map.get(parsed_data, :purpose) || ""
+    sub_type = Map.get(parsed_data, :sub_type) || Map.get(parsed_data, :subType) || ""
 
     Logger.info("[StaticAccIp08Scenario] Building X7 response - txn_id=#{txn_id}, note=#{note}")
 
@@ -389,72 +398,100 @@ defmodule UpiStatic.SpecialHandlers.StaticAccIp08Scenario do
     end
   end
 
+  # [RespChkTxn <RespChkTxn> template] OLD FUNCTION kept for reference. It hand-built the XML with Ref from the merchant DB row of the scenario VPA and dummy fallbacks: code 000000, IFSC AEBK0087654, acNum AE112233445, accType CURRENT, orgAmount 999.00,
+  # Txn seqNum absent but Head ts / Txn ts in UTC. [RespChkTxn Ref.addr / regName / code / IFSC / acNum / accType / orgAmount] CHANGED: now UpiXmlSchema.generate_resp_chk_txn with ref_data from the stored ReqPay (orgTxnId)
+  # TSD Table 6: Ref values of the original ReqPay; settAmount 0.00 and settCurrency INR on the X7 failure
+  # OLD:   defp generate_x7_resp_chk_txn_xml_internal(response_data) do
+  # OLD:     try do
+  # OLD:       Logger.info("[StaticAccIp08Scenario] Generating X7 RespChkTxn XML matching NPCI format")
+  # OLD:
+  # OLD:       merchant_data = response_data[:merchant_data] || response_data.merchant_data
+  # OLD:       _settlement_currency = response_data[:settlement_currency] || response_data.settlement_currency || "INR"
+  # OLD:
+  # OLD:       # Build ref data
+  # OLD:       ref_data = if merchant_data do
+  # OLD:         amount = case Map.get(merchant_data, :max_transaction_limit) do
+  # OLD:           nil -> "999.00"
+  # OLD:           %Decimal{} = d -> Decimal.to_string(d)
+  # OLD:           val when is_number(val) -> Float.to_string(val)
+  # OLD:           val when is_binary(val) -> val
+  # OLD:           _ -> "999.00"
+  # OLD:         end
+  # OLD:
+  # OLD:         %{
+  # OLD:           addr: to_string(Map.get(merchant_data, :merchant_vpa) || @target_vpa),
+  # OLD:           code: to_string(Map.get(merchant_data, :merchant_code) || "000000"),
+  # OLD:           reg_name: to_string(Map.get(merchant_data, :legal_name) || Map.get(merchant_data, :brand_name) || "Static QR Tester"),
+  # OLD:           ifsc: to_string(Map.get(merchant_data, :settlement_account_ifsc) || "AEBK0087654"),
+  # OLD:           ac_num: to_string(Map.get(merchant_data, :settlement_account_number) || "AE112233445"),
+  # OLD:           acc_type: to_string(Map.get(merchant_data, :settlement_account_type) || "CURRENT"),
+  # OLD:           sett_currency: "INR",
+  # OLD:           org_amount: amount,
+  # OLD:           sett_amount: "0.00"
+  # OLD:         }
+  # OLD:       else
+  # OLD:         %{
+  # OLD:           addr: @target_vpa,
+  # OLD:           code: "000000",
+  # OLD:           reg_name: "Static QR Tester",
+  # OLD:           ifsc: "AEBK0087654",
+  # OLD:           ac_num: "AE112233445",
+  # OLD:           acc_type: "CURRENT",
+  # OLD:           sett_currency: "INR",
+  # OLD:           org_amount: "999.00",
+  # OLD:           sett_amount: "0.00"
+  # OLD:         }
+  # OLD:       end
+  # OLD:
+  # OLD:       # Generate approval number
+  # OLD:       approval_num = "APP" <> String.pad_leading(Integer.to_string(:rand.uniform(1000) - 1), 3, "0")
+  # OLD:
+  # OLD:       # Build XML with static orgId
+  # OLD:       xml = """
+  # OLD:       <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+  # OLD:       <ns2:RespChkTxn xmlns:ns2="http://npci.org/upi/schema/">
+  # OLD:       <Head ver="2.0" ts="#{response_data.timestamp}" orgId="#{response_data.org_id}" msgId="#{response_data.msg_id}" prodType="UPI"/>
+  # OLD:       <Txn id="#{response_data.txn_id}" note="#{response_data.note}" refId="#{response_data.ref_id}" refUrl="#{response_data.ref_url}" refCategory="#{response_data.ref_category}" ts="#{response_data.timestamp}" custRef="#{response_data.cust_ref}" type="#{response_data.txn_type}" orgMsgId="#{response_data.org_msg_id}" orgTxnId="#{response_data.org_txn_id}" initiationMode="#{response_data.initiation_mode}" purpose="#{response_data.purpose}" subType="#{response_data.sub_type}"/>
+  # OLD:       <Resp reqMsgId="#{response_data.req_msg_id}" result="FAILURE" errCode="X7">
+  # OLD:       <Ref type="PAYEE" seqNum="1" addr="#{ref_data.addr}" code="#{ref_data.code}" orgAmount="#{ref_data.org_amount}" respCode="X7" regName="#{ref_data.reg_name}" IFSC="#{ref_data.ifsc}" acNum="#{ref_data.ac_num}" accType="#{ref_data.acc_type}" approvalNum="#{approval_num}" settAmount="#{ref_data.sett_amount}" settCurrency="#{ref_data.sett_currency}" />
+  # OLD:       </Resp>
+  # OLD:       </ns2:RespChkTxn>
+  # OLD:       """
+  # OLD:
+  # OLD:       Logger.info("[StaticAccIp08Scenario] ✅ Generated X7 RespChkTxn XML successfully")
+  # OLD:       Logger.debug("[StaticAccIp08Scenario] XML (first 800 chars): #{String.slice(xml, 0, 800)}")
+  # OLD:       {:ok, String.trim(xml)}
+  # OLD:     rescue
+  # OLD:       e ->
+  # OLD:         Logger.error("[StaticAccIp08Scenario] ❌ Error generating X7 RespChkTxn XML: #{inspect(e)}")
+  # OLD:         Logger.error("[StaticAccIp08Scenario] Stacktrace: #{Exception.format_stacktrace(__STACKTRACE__)}")
+  # OLD:         {:error, "Failed to generate X7 RespChkTxn XML: #{inspect(e)}"}
+  # OLD:     end
+  # OLD:   end
   defp generate_x7_resp_chk_txn_xml_internal(response_data) do
-    try do
-      Logger.info("[StaticAccIp08Scenario] Generating X7 RespChkTxn XML matching NPCI format")
-
-      merchant_data = response_data[:merchant_data] || response_data.merchant_data
-      _settlement_currency = response_data[:settlement_currency] || response_data.settlement_currency || "INR"
-
-      # Build ref data
-      ref_data = if merchant_data do
-        amount = case Map.get(merchant_data, :max_transaction_limit) do
-          nil -> "999.00"
-          %Decimal{} = d -> Decimal.to_string(d)
-          val when is_number(val) -> Float.to_string(val)
-          val when is_binary(val) -> val
-          _ -> "999.00"
-        end
-
-        %{
-          addr: to_string(Map.get(merchant_data, :merchant_vpa) || @target_vpa),
-          code: to_string(Map.get(merchant_data, :merchant_code) || "000000"),
-          reg_name: to_string(Map.get(merchant_data, :legal_name) || Map.get(merchant_data, :brand_name) || "Static QR Tester"),
-          ifsc: to_string(Map.get(merchant_data, :settlement_account_ifsc) || "AEBK0087654"),
-          ac_num: to_string(Map.get(merchant_data, :settlement_account_number) || "AE112233445"),
-          acc_type: to_string(Map.get(merchant_data, :settlement_account_type) || "CURRENT"),
-          sett_currency: "INR",
-          org_amount: amount,
-          sett_amount: "0.00"
-        }
-      else
-        %{
-          addr: @target_vpa,
-          code: "000000",
-          reg_name: "Static QR Tester",
-          ifsc: "AEBK0087654",
-          ac_num: "AE112233445",
-          acc_type: "CURRENT",
-          sett_currency: "INR",
-          org_amount: "999.00",
-          sett_amount: "0.00"
-        }
-      end
-
-      # Generate approval number
-      approval_num = "APP" <> String.pad_leading(Integer.to_string(:rand.uniform(1000) - 1), 3, "0")
-
-      # Build XML with static orgId
-      xml = """
-      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-      <ns2:RespChkTxn xmlns:ns2="http://npci.org/upi/schema/">
-      <Head ver="2.0" ts="#{response_data.timestamp}" orgId="#{response_data.org_id}" msgId="#{response_data.msg_id}" prodType="UPI"/>
-      <Txn id="#{response_data.txn_id}" note="#{response_data.note}" refId="#{response_data.ref_id}" refUrl="#{response_data.ref_url}" refCategory="#{response_data.ref_category}" ts="#{response_data.timestamp}" custRef="#{response_data.cust_ref}" type="#{response_data.txn_type}" orgMsgId="#{response_data.org_msg_id}" orgTxnId="#{response_data.org_txn_id}" initiationMode="#{response_data.initiation_mode}" purpose="#{response_data.purpose}" subType="#{response_data.sub_type}"/>
-      <Resp reqMsgId="#{response_data.req_msg_id}" result="FAILURE" errCode="X7">
-      <Ref type="PAYEE" seqNum="1" addr="#{ref_data.addr}" code="#{ref_data.code}" orgAmount="#{ref_data.org_amount}" respCode="X7" regName="#{ref_data.reg_name}" IFSC="#{ref_data.ifsc}" acNum="#{ref_data.ac_num}" accType="#{ref_data.acc_type}" approvalNum="#{approval_num}" settAmount="#{ref_data.sett_amount}" settCurrency="#{ref_data.sett_currency}" />
-      </Resp>
-      </ns2:RespChkTxn>
-      """
-
-      Logger.info("[StaticAccIp08Scenario] ✅ Generated X7 RespChkTxn XML successfully")
-      Logger.debug("[StaticAccIp08Scenario] XML (first 800 chars): #{String.slice(xml, 0, 800)}")
-      {:ok, String.trim(xml)}
-    rescue
-      e ->
-        Logger.error("[StaticAccIp08Scenario] ❌ Error generating X7 RespChkTxn XML: #{inspect(e)}")
-        Logger.error("[StaticAccIp08Scenario] Stacktrace: #{Exception.format_stacktrace(__STACKTRACE__)}")
-        {:error, "Failed to generate X7 RespChkTxn XML: #{inspect(e)}"}
-    end
+    Logger.info("[StaticAccIp08Scenario] Generating X7 RespChkTxn with UpiXmlSchema.generate_resp_chk_txn")
+
+    stored = ReqPayService.get_by_txn_id(response_data[:org_txn_id])
+    approval_num = "APP" <> String.pad_leading(Integer.to_string(:rand.uniform(1000) - 1), 3, "0")
+    ref_data = UpiCore.UpiXmlSchema.ref_data_from_stored_req_pay(stored, "X7", approval_num)
+
+    UpiCore.UpiXmlSchema.generate_resp_chk_txn(%{
+      org_id: response_data[:org_id] || "MER101",
+      msg_id: response_data[:msg_id],
+      req_msg_id: response_data[:req_msg_id],
+      result: "FAILURE",
+      err_code: "X7",
+      txn_id: response_data[:txn_id],
+      org_txn_id: response_data[:org_txn_id],
+      org_msg_id: response_data[:org_msg_id],
+      note: response_data[:note],
+      ref_id: response_data[:ref_id],
+      cust_ref: response_data[:cust_ref],
+      initiation_mode: response_data[:initiation_mode],
+      purpose: response_data[:purpose],
+      sub_type: response_data[:sub_type],
+      ref_data: ref_data
+    })
   end
 
   defp send_x7_resp_chk_txn_to_npci(resp_xml, txn_id) do
diff --git a/apps/upi_static/lib/upi_static/static_qr_transaction_manager.ex b/apps/upi_static/lib/upi_static/static_qr_transaction_manager.ex
index d1632a5..84f2747 100644
--- a/apps/upi_static/lib/upi_static/static_qr_transaction_manager.ex
+++ b/apps/upi_static/lib/upi_static/static_qr_transaction_manager.ex
@@ -2050,13 +2050,18 @@ defmodule UpiStatic.StaticQrTransactionManager do
       ref_url: Map.get(parsed_data, :ref_url) || "",
       note: Map.get(parsed_data, :note) || "",
       cust_ref: Map.get(parsed_data, :cust_ref) || "",
-      initiation_mode: Map.get(parsed_data, :initiation_mode) || "02",
-      seq_num: generate_seq_num(),
+      # [RespChkTxn Txn.initiationMode / Txn.seqNum] CHANGED: echo the ReqChkTxn initiationMode (no 02 default); seqNum REMOVED (not in TSD Table 6)
+      # OLD:       initiation_mode: Map.get(parsed_data, :initiation_mode) || "02",
+      # OLD:       seq_num: generate_seq_num(),
+      initiation_mode: Map.get(parsed_data, :initiation_mode),
       purpose: Map.get(parsed_data, :purpose) || "",
       status: "FAILED",
       currency: Map.get(parsed_data, :currency) || "INR",
       amount: "0.00",
-      sub_type: ""
+      # [RespChkTxn Txn.subType / Ref] CHANGED: echo the ReqChkTxn subType (was ""); Ref from the stored ReqPay (ref_data was missing, so Ref was empty)
+      # OLD:       sub_type: ""
+      sub_type: Map.get(parsed_data, :sub_type),
+      ref_data: static_chktxn_ref_data(parsed_data, error_code)
     }
 
     case UpiXmlSchema.generate_resp_chk_txn(response_data) do
@@ -2089,16 +2094,29 @@ defmodule UpiStatic.StaticQrTransactionManager do
       ref_url: Map.get(parsed_data, :ref_url) || "",
       note: Map.get(parsed_data, :note) || "",
       cust_ref: Map.get(parsed_data, :cust_ref) || "",
-      initiation_mode: Map.get(parsed_data, :initiation_mode) || "02",
-      seq_num: generate_seq_num(),
+      # [RespChkTxn Txn.initiationMode / Txn.seqNum] CHANGED: echo the ReqChkTxn initiationMode (no 02 default); seqNum REMOVED (not in TSD Table 6)
+      # OLD:       initiation_mode: Map.get(parsed_data, :initiation_mode) || "02",
+      # OLD:       seq_num: generate_seq_num(),
+      initiation_mode: Map.get(parsed_data, :initiation_mode),
       purpose: Map.get(parsed_data, :purpose) || "",
       status: transaction.status || "PENDING",
       currency: transaction.currency || "INR",
       amount: Decimal.to_string(transaction.inr_amount || Decimal.new("0.00")),
-      sub_type: ""
+      # [RespChkTxn Txn.subType / Ref] CHANGED: echo the ReqChkTxn subType (was ""); Ref from the stored ReqPay with the transaction's real respCode (ref_data was missing, so Ref was empty)
+      # OLD:       sub_type: ""
+      sub_type: Map.get(parsed_data, :sub_type),
+      ref_data: static_chktxn_ref_data(parsed_data, UpiXmlSchema.chk_txn_resp_code(transaction), transaction)
     }
   end
 
+  # [RespChkTxn Ref.*] ADDED: ref_data for the static RespChkTxn, built from the stored ReqPay (by the ReqChkTxn orgTxnId / transaction org_txn_id)
+  defp static_chktxn_ref_data(parsed_data, resp_code, transaction \\ nil) do
+    org_txn_id =
+      (transaction && Map.get(transaction, :org_txn_id)) || Map.get(parsed_data, :org_txn_id)
+
+    UpiXmlSchema.ref_data_from_stored_req_pay(ReqPayService.get_by_txn_id(org_txn_id), resp_code, generate_approval_number())
+  end
+
   defp send_resp_chk_txn_to_npci(resp_xml, parsed_data, org_id) do
     Logger.info("[StaticQR-RespChkTxn] Sending RespChkTxn to NPCI - org_id=#{org_id}")
 
@@ -2144,9 +2162,10 @@ defmodule UpiStatic.StaticQrTransactionManager do
       {:error, "Exception: #{inspect(e)}"}
   end
 
-  defp generate_seq_num do
-    UpiXmlSchema.generate_numeric_seq_num()
-  end
+  # [RespChkTxn Txn.seqNum] REMOVED: generate_seq_num is unused now - seqNum is not part of RespChkTxn (TSD Table 6)
+  # OLD:   defp generate_seq_num do
+  # OLD:     UpiXmlSchema.generate_numeric_seq_num()
+  # OLD:   end
 
   # --- Transaction Creation for Static QR ---
   @doc """
diff --git a/apps/upi_static/test/upi_static/resp_chk_txn_test.exs b/apps/upi_static/test/upi_static/resp_chk_txn_test.exs
new file mode 100644
index 0000000..216eb1e
--- /dev/null
+++ b/apps/upi_static/test/upi_static/resp_chk_txn_test.exs
@@ -0,0 +1,70 @@
+defmodule UpiStatic.RespChkTxnTest do
+  use ExUnit.Case, async: false
+
+  import SweetXml
+
+  alias UpiCore.Repo
+  alias UpiCore.Transactions.ReqPay
+
+  @org_txn_id "ORGTXNPAY0000000000000000000000002"
+
+  setup do
+    {:ok, _} = Application.ensure_all_started(:upi_core)
+    pid = Ecto.Adapters.SQL.Sandbox.start_owner!(Repo, shared: true)
+    on_exit(fn -> Ecto.Adapters.SQL.Sandbox.stop_owner(pid) end)
+
+    {:ok, _} =
+      %ReqPay{}
+      |> ReqPay.changeset(%{
+        msg_id: "STOREDREQPAYMSG0000000000000000002",
+        txn_id: @org_txn_id,
+        org_id: "NPCI",
+        amount: Decimal.new("5"),
+        currency: "INR",
+        status: "PROCESSED",
+        validation_type: "DOMESTIC",
+        payee_addr: "shop@mercury",
+        payee_name: "NPCI Static Tester",
+        merchant_category_code: "5812",
+        payee_ifsc: "TEST0000002",
+        payee_account_number: "TESTACNUM0020",
+        payee_account_type: "CURRENT"
+      })
+      |> Repo.insert()
+
+    :ok
+  end
+
+  defp attr(xml, path), do: xpath(xml, ~x"#{path}"s)
+  @ref "//*[local-name()='Ref']"
+
+  @parsed %{
+    msg_id: "NPCIREQCHKTXN000000000000000000002",
+    txn_id: "NPCICHKTXNID-STATIC-0002",
+    org_txn_id: @org_txn_id,
+    org_msg_id: "NPCIORGMSGID00000000000000000002",
+    note: "ACC_IP-08",
+    ref_id: "REFCHK0002",
+    cust_ref: "CUSTREF08",
+    initiation_mode: "02",
+    purpose: "11",
+    sub_type: "PAY"
+  }
+
+  test "ACC_IP_08 (static copy): X7 RespChkTxn Ref from the stored ReqPay, no dummy values" do
+    {:ok, xml} = UpiStatic.SpecialHandlers.StaticAccIp08Scenario.generate_x7_resp_chk_txn_xml(@parsed)
+    assert attr(xml, "//*[local-name()='Resp']/@errCode") == "X7"
+    assert attr(xml, @ref <> "/@respCode") == "X7"
+    assert attr(xml, @ref <> "/@addr") == "shop@mercury"
+    assert attr(xml, @ref <> "/@code") == "5812"
+    assert attr(xml, @ref <> "/@regName") == "NPCI Static Tester"
+    assert attr(xml, @ref <> "/@IFSC") == "TEST0000002"
+    assert attr(xml, @ref <> "/@settAmount") == "0.00"
+    assert attr(xml, @ref <> "/@settCurrency") == "INR"
+    assert attr(xml, "//*[local-name()='Txn']/@initiationMode") == "02"
+    assert attr(xml, "//*[local-name()='Txn']/@subType") == "PAY"
+    refute xml =~ "Static QR Tester"
+    refute xml =~ "AEBK0087654"
+    refute xml =~ ~s(code="000000")
+  end
+end
