# C\#

<details>

<summary>Without Router - Current Approach</summary>

```csharp
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace AAEcosystem
{
    public class AccountDiscoveryClient
    {
        private const string API_URL = "https://fip-1.dev.sahamati.org.in/v2/Accounts/discover";
        private const string JWS_SIGNATURE = "eyJhbGciOiJSUzI1NiIsImtpZCI6IlRlZ1FhMms3MUlFWlotaEhxcm1ueWFFc3ZvSWloNWdrVUx2SjFfTEhibGsiLCJjcml0IjpbImI2NCJdLCJiNjQiOmZhbHNlfQ..Dux_bx7X-q1YSvyNmZiyPM60ZgaK3MshWBhWeY-bLBeSmxkU5VpH-lQjBjGFW_2opX3ZK5XfF7oPc3wkp-Qj7-qVfgTg53YvGyS3oLbKvkMRHtKa33x5I-0b8BmlMzojtnA_zFfubOJoqZVPpz7BQ4qrazizaF2Z6m3FygNGuAkdbdqtnCgPCjBZ6ibkpyiKR_n_g5FcTOq7fa7JgE6IoMD0R575ssdFbHzcT-IZs0DDqc_DJ0pR7m56z9IlmRZ6kUg99kaYVl6GUHSYPwY9OCbmHa7EbgE5vUdIJjhF3vJDZhYMWCojpbh9KLGSpbHkWG4OY19S-YNJv85FtXZe0Q";
        private const string BEARER_TOKEN = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJsRlByWU4wR3dBQ3YyUzJFVFZyRkVvZVVlc2VzelppQ2xIaVY1M3hrU3JNIn0.eyJleHAiOjE3NDQ5NjgwNDAsImlhdCI6MTc0NDg4MTY0MCwianRpIjoiYzZiZTcyNDAtOWU5Ny00MzYwLTk3OGUtZWI5MTY0MWZiMmMwIiwiaXNzIjoiaHR0cHM6Ly9hcGkuZGV2LnNhaGFtYXRpLm9yZy5pbi9hdXRoL3JlYWxtcy9zYWhhbWF0aSIsInN1YiI6ImIyMzE1MTU3LWRmNzYtNGQzZS04ZjM2LWQ4NzZmY2ViOWFlZiIsInR5cCI6IkJlYXJlciIsImF6cCI6IkFBLVNJTVVMQVRPUiIsImFjciI6IjEiLCJzY29wZSI6ImVtYWlsIG1pY3JvcHJvZmlsZS1qd3QgcHJvZmlsZSBhZGRyZXNzIHBob25lIiwidXBuIjoic2VydmljZS1hY2NvdW50LWFhLXNpbXVsYXRvciIsImNsaWVudElkIjoiQUEtU0lNVUxBVE9SIiwiYWRkcmVzcyI6e30sImNsaWVudEhvc3QiOiIxMC4yMjQuMC4xODIiLCJyb2xlcyI6IkFBIiwic2VjcmV0LWV4cGlyeS10cyI6IjIwMjUtMTItMDRUMTU6MzM6MzQuMDU5MTgzIiwiY2xpZW50QWRkcmVzcyI6IjEwLjIyNC4wLjE4MiJ9.G-ErvIeZUtKkqN4CbaH09Nwzy9fUjKSD18xpNh6y74AQdB8YFfNuhC8m6nxMpDCLY2fUj8sIcQ--Jp-EYDxChSR8kQTbKDmYJzPGRGunO-hkLxPK83R3Q7Byc6KZot1lZlj-Dsv-l5JD0Ay0KpPr4bKqIas5FEZTx2qoA3p6J1CyNbiQ81t4_KxVoO44hmVKPe0FIVNLw9MK04bkHOwO-WMB9DoUX5Y8bBREYgRv_W3QEEC8gcI5vZLnHuBXSZSXQ3MDPSLOq7lGnMsxh5A0YF1Wvfqg3LJjXizMfIfRNMyq2M0eMwHQEWfjLNTEqS6Bd6qkjPREVdhRTTnHaggq9A";
        private const string FIP_ID = "FIP-SIMULATOR";

        private static readonly string REQUEST_BODY = @"{
            ""ver"": ""2.0.0"",
            ""timestamp"": ""2023-06-26T06:41:54.904+0000"",
            ""txnid"": ""f35761ac-4a18-11e8-96ff-0277a9fbfedc2"",
            ""Customer"": {
                ""id"": ""customer_identifier@AA_identifier"",
                ""Identifiers"": [
                    {
                        ""category"": ""STRONG"",
                        ""type"": ""AADHAAR"",
                        ""value"": ""XXXXXXXXXXXXXXXX""
                    }
                ]
            },
            ""FITypes"": [
                ""DEPOSIT""
            ]
        }";

        public static async Task Main(string[] args)
        {
            try
            {
                using var httpClient = new HttpClient();
                httpClient.Timeout = TimeSpan.FromSeconds(10);

                var request = new HttpRequestMessage(HttpMethod.Post, API_URL);
                request.Headers.Add("x-jws-signature", JWS_SIGNATURE);
                request.Headers.Add("x-simulate-res", "Ok");

                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", BEARER_TOKEN);
                request.Content = new StringContent(REQUEST_BODY, Encoding.UTF8, "application/json");

                var response = await httpClient.SendAsync(request);
                var responseBody = await response.Content.ReadAsStringAsync();

                Console.WriteLine($"Response Status Code: {(int)response.StatusCode} {response.StatusCode}");
                Console.WriteLine($"Response Body: {responseBody}");
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine($"Error occurred: {ex.Message}");
                Console.Error.WriteLine(ex.StackTrace);
            }
        }
    }
}

```

</details>

<details>

<summary>With Router Integration - Request</summary>

```csharp
import requests
import json
from datetime import datetime
from typing import Dict, Any

# ==============================
#  Config Metadata
# ==============================
ENTITY_METADATA_FROM_CR = {
    "baseUrl": "http://fip-1.sandbox.sahamati.org.in/fip-simulate",
    "id": "FIP-SIMULATOR"
}
ROUTER_INTEGRATION_HELPER_URL = "https://api.sandbox.sahamati.org.in/router-helper/v1/request/header"


# ==============================
#  Core Functions
# ==============================
def build_discovery_request_body() -> Dict[str, Any]:
    """Creates the ReBIT-defined account discovery request body."""
    return {
        "ver": "2.0.0",
        "timestamp": datetime.utcnow().isoformat(),
        "txnid": "f35761ac-4a18-11e8-96ff-0277a9fbfedc2",
        "Customer": {
            "id": "9766334467@aa_simulator",
            "Identifiers": [
                {
                    "category": "STRONG",
                    "type": "AADHAAR",
                    "value": "XXXXXXXXXXXXXXXX"
                }
            ]
        },
        "FITypes": ["DEPOSIT"]
    }


def get_http_config(base_url: str, route: str, headers: Dict[str, str], data: Dict[str, Any], method_type: str) -> Dict[str, Any]:
    """Builds base HTTP config."""
    return {
        "url": f"{base_url}{route}",
        "headers": headers,
        "json": data,
        "method": method_type
    }


def router_integration_helper(route: str, rebit_request_body: Dict[str, Any]) -> Dict[str, Any]:
    """Calls Router Integration Helper service to get host and x-request-meta."""
    payload = {
        "rebitAPIEndpoint": route,
        "recipientId": ENTITY_METADATA_FROM_CR["id"],
        "customerId": "9766334467@aa_simulator",
        "requestBody": rebit_request_body
    }

    response = requests.post(
        ROUTER_INTEGRATION_HELPER_URL,
        json=payload,
        headers={"Content-Type": "application/json"},
        timeout=30
    )
    response.raise_for_status()
    return response.json()


def add_sahamati_configuration(config: Dict[str, Any], route: str, rebit_request_body: Dict[str, Any]) -> Dict[str, Any]:
    """Updates config with router URL and adds x-request-meta header by calling Router Helper API."""
    header_response = router_integration_helper(route, rebit_request_body)

    baseurl = header_response.get("baseurl")
    if not baseurl:
        raise RuntimeError("Router Helper response missing required field 'baseurl'")

    # Update URL
    config["url"] = f"{baseurl}{route}"
    config.setdefault("headers", {})

    # Add x-request-meta header only if it exists
    x_request_meta = header_response.get("x-request-meta")
    if x_request_meta:
        config["headers"]["x-request-meta"] = x_request_meta

    return config


def execute_discovery_request() -> Dict[str, Any]:
    """Executes account discovery request via Sahamati Router (helper API flow)."""
    route = "/Accounts/discover"
    rebit_request_body = build_discovery_request_body()

    # Step 1: Base config
    config = get_http_config(
        base_url=ENTITY_METADATA_FROM_CR["baseUrl"],
        route=route,
        headers={},
        data=rebit_request_body,
        method_type="POST"
    )

    # Step 2: Add Router configuration (call helper API)
    config = add_sahamati_configuration(config, route, rebit_request_body)

    # Step 3: Execute request
    response = requests.request(**config, timeout=30)
    response.raise_for_status()
    return response.json()


def perform_another_operations(account_discover_response: Dict[str, Any]) -> None:
    """Placeholder for next steps."""
    print("Next steps with response:")
    print(json.dumps(account_discover_response, indent=2))


# ==============================
#  Main Runner
# ==============================
if __name__ == "__main__":
    try:
        response = execute_discovery_request()
        perform_another_operations(response)
        print("✅ Account discovery successful.")
    except Exception as e:
        print(f"❌ Account discovery failed. Reason: {e}")
    finally:
        print("ℹ️ Account discovery completed.")

```

</details>

<details>

<summary>With Router Integration - Response</summary>

```csharp
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

const string ROUTER_RESPONSE_HEADER_URL = "https://api.sandbox.sahamati.org.in/router-helper/v1/response/header";
const string RECIPIENT_ID = "AA-SIMULATOR";

async Task<Dictionary<string, object>> routerIntegrationHelper(Dictionary<string, object> requestBody)
{
    using var client = new HttpClient();
    var json = JsonSerializer.Serialize(requestBody);
    var content = new StringContent(json, Encoding.UTF8, "application/json");
    var resp = await client.PostAsync(ROUTER_RESPONSE_HEADER_URL, content);
    resp.EnsureSuccessStatusCode();
    var respJson = await resp.Content.ReadAsStringAsync();
    return JsonSerializer.Deserialize<Dictionary<string, object>>(respJson);
}

Dictionary<string, object> FetchAccountFromRequestBody(Dictionary<string, object> requestBody)
{
    if (requestBody == null || !requestBody.TryGetValue("Customer", out var customerObj) || customerObj is not JsonElement customerElem || customerElem.ValueKind != JsonValueKind.Object)
        return null;
    if (!customerElem.TryGetProperty("Identifiers", out var identifiersElem) || identifiersElem.ValueKind != JsonValueKind.Array)
        return null;
    foreach (var idElem in identifiersElem.EnumerateArray())
    {
        if (idElem.ValueKind != JsonValueKind.Object) continue;
        var category = idElem.GetProperty("category").GetString();
        var type = idElem.GetProperty("type").GetString();
        var value = idElem.GetProperty("value").GetString();
        if (category == "STRONG" && type == "AADHAAR" && !string.IsNullOrEmpty(value))
        {
            return new Dictionary<string, object>
            {
                ["FIType"] = "DEPOSIT",
                ["accType"] = "SAVINGS",
                ["accRefNumber"] = "BANK11111111",
                ["maskedAccNumber"] = "XXXXXXX3468"
            };
        }
    }
    return null;
}

app.MapPost("/accounts/discover", async (HttpRequest req, HttpResponse res) =>
{
    var incomingRequestBody = await JsonSerializer.DeserializeAsync<Dictionary<string, object>>(req.Body);
    var discoveredAccount = FetchAccountFromRequestBody(incomingRequestBody);
    if (discoveredAccount == null)
    {
        res.StatusCode = 404;
        await res.WriteAsJsonAsync(new { error = "Account not found" });
        return;
    }
    var responseBody = new Dictionary<string, object>
    {
        ["ver"] = "2.0.0",
        ["timestamp"] = "2023-06-26T06:45:54.904+0000",
        ["txnid"] = "f35761ac-4a18-11e8-96ff-0277a9fbfedcs",
        ["DiscoveredAccounts"] = new[] { discoveredAccount }
    };
    var responseHeaderRequestBody = new Dictionary<string, object>
    {
        ["rebitAPIEndpoint"] = "/accounts/discover",
        ["customerId"] = "9977336577@aa_simulator",
        ["recipientId"] = RECIPIENT_ID,
        ["additionalAttributes"] = new Dictionary<string, object>(),
        ["responseBody"] = responseBody
    };
    var responseHeaderResp = await routerIntegrationHelper(responseHeaderRequestBody);
    if (responseHeaderResp.TryGetValue("x-response-meta", out var xResponseMetaObj) && xResponseMetaObj is JsonElement xMetaElem && xMetaElem.ValueKind == JsonValueKind.String && !string.IsNullOrEmpty(xMetaElem.GetString()))
    {
        res.Headers["x-response-meta"] = xMetaElem.GetString();
    }
    res.ContentType = "application/json";
    await res.WriteAsJsonAsync(responseBody);
});

app.Run();


```

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developer.sahamati.org.in/sahamatinet-mvp/integration-steps/integration-with-router/sample-code-snippets/c.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
