**complete flow explanation** for how a **Sale MTI 0200 transaction** gets processed from temp transaction creation until it's sent to upstream:

## Complete Sale Transaction (MTI 0200) Processing Flow

### **Phase 1: Initial Processing & Temp Transaction Creation**

```elixir
# Entry Point: IncomingMessageProcessor.process_message/2
def process_message(%ISOMsg{mti: "0200"} = iso_message, channel_context) do
```

**1. Pipeline Processing** → **Terminal Validation & Business Logic**
```elixir
# Step 1a: ValidationProcessor validates DE-41, DE-42 (terminal/merchant)
# Step 1b: BusinessLogic.process_message() makes approve/decline decision
case BusinessLogic.process_message(iso_message) do
  {:approve, enriched_message} ->
    # ✅ Transaction APPROVED - Continue to upstream
    Logger.info("Business logic approved transaction")
    {:ok, enriched_message}
  
  {:decline, reason, enriched_message} ->
    # ❌ Transaction DECLINED - Create local response (no upstream)
    Logger.info("Business logic declined transaction: #{inspect(reason)}")
    {:ok, create_decline_response(enriched_message, reason)}
end
```

**2. pos_temp_transaction Creation** (happens during business approval):
```elixir
# Acquirer.create_temp_transaction/1
def create_temp_transaction(attrs) do
  attrs = %{
    s_tid: "TERM001",              # DE-41 Terminal ID from message
    s_mid: "MERCH001",             # DE-42 Merchant ID from message  
    s_tid_stan: "123456",          # DE-11 STAN from message
    mti: "0200",                   # Original MTI (Sale)
    proc_code: "000000",           # DE-3 Processing Code
    total_amount: Decimal.new("10.00"),  # DE-4 Amount
    processing_state: "CREATED",   # Initial state
    acquirer_id: terminal.id       # FK to validated terminal
  }
  
  %PosTempTransaction{}
  |> PosTempTransaction.changeset(attrs)
  |> Repo.insert()                # 💾 DATABASE INSERT
end
```

### **Phase 2: Business Decision Logic**

```elixir
# BusinessLogic.process_message/1 - MTI 0200 Decision Flow
def process_message(%ISOMsg{mti: "0200"} = iso_message) do
  with {:ok, analyzed_message} <- analyze_message_type(iso_message),      # MTI analysis
       {:ok, validated_message} <- validate_business_rules(analyzed_message), # Limits check
       {:ok, risk_assessed_message} <- assess_risk(validated_message),    # Risk scoring
       decision_result <- make_business_decision(risk_assessed_message) do # Final decision
    decision_result
  end
end
```

**Business Decision Logic:**
```elixir
defp make_business_decision(%ISOMsg{} = iso_message) do
  case get_transaction_amount(iso_message) do
    amount when amount > 500_000 ->  # > $5000.00 (high_value_threshold)
      {:refer, add_business_timestamp(iso_message)}    # Manual review needed
    
    amount when amount <= 0 ->
      {:decline, :invalid_amount, add_business_timestamp(iso_message)}
    
    _valid_amount ->
      {:approve, add_business_timestamp(iso_message)}  # ✅ APPROVED for upstream
  end
end
```

### **Phase 3: Upstream Routing (for Approved Transactions)**

**3a. YSP Message Detection:**
```elixir
# Check if YSP message (DE-24 = "782")
case DaProductApp.YSP.MessageProcessor.ysp_message?(iso_message) do
  true ->
    Logger.info("Detected YSP message (DE24=782), applying YSP-specific processing")
    apply_ysp_business_logic(iso_message)
end
```

**3b. YSP Message Processing:**
```elixir
# YSP.MessageProcessor.process_message/2
def process_message(%ISOMsg{mti: "0200"} = iso_message, context) do
  with {:ok, filtered_message} <- filter_supported_fields(iso_message),  # Only YSP fields
       {:ok, transformed_message} <- apply_transaction_transformations(filtered_message, context),
       {:ok, final_message} <- apply_ysp_field_mappings(transformed_message, context) do
    {:ok, final_message}
  end
end
```

**YSP Sale Transformation (MTI 0200):**
```elixir
defp transform_sale_message(%ISOMsg{} = iso_message, _context) do
  # Convert processing code "000001" → "000000" if present
  case ISOMsg.get(iso_message, 3) do
    "000001" ->
      transformed_message = ISOMsg.set(iso_message, 3, "000000")
      {:ok, transformed_message}
    _ ->
      {:ok, iso_message}
  end
end
```

### **Phase 4: Database State Updates**

**4a. Update temp transaction state:**
```elixir
# Update processing_state: "CREATED" → "VALIDATED"  
def update_temp_transaction_status(temp_transaction, "VALIDATED") do
  temp_transaction
  |> PosTempTransaction.state_changeset("VALIDATED")
  |> Repo.update()
end
```

**4b. Pre-upstream send state:**
```elixir
# Before sending to upstream: "VALIDATED" → "SENT_TO_UPSTREAM"
def upstream_request_changeset(pos_temp_transaction, iso_message) do
  pos_temp_transaction
  |> cast(%{}, [])
  |> put_change(:upstream_request_iso, Base.encode64(iso_message))
  |> put_change(:upstream_request_sent_at, DateTime.utc_now())
  |> put_change(:processing_state, "SENT_TO_UPSTREAM")
end
```

### **Phase 5: Upstream Network Communication**

**5a. Route to UpstreamRouter:**
```elixir
# route_to_upstream/2
defp route_to_upstream(%ISOMsg{} = iso_message, channel_context) do
  case UpstreamRouter.route_message(iso_message, channel_context) do
    {:ok, response_message} ->
      Logger.info("Received response from upstream")
      {:ok, response_message}
    
    {:error, reason} ->
      {:error, {:upstream_routing_failed, reason}}
  end
end
```

**5b. UpstreamRouter Processing:**
```elixir
# UpstreamRouter.route_message/2
def route_message(%ISOMsg{} = iso_message, channel_context) do
  with {:ok, upstream_config} <- determine_upstream_network(iso_message, channel_context),
       {:ok, formatted_message} <- format_for_upstream(iso_message, upstream_config),
       {:ok, response_bytes} <- send_to_upstream(formatted_message, upstream_config),
       {:ok, response_message} <- unpack_upstream_response(response_bytes, upstream_config) do
    {:ok, response_message}
  end
end
```

**5c. YSP Network Selection:**
```elixir
# Based on DE-24 = "782", routes to YSP network
ysp_ssl: %{
  host: "localhost",
  port: 5002,
  packager: DaProductApp.MercuryISO8583.Packagers.ISO87BPackager,
  routing_rules: [
    {:field_value, 24, "782"}     # Routes MTI 0200 with DE24="782" to YSP
  ]
}
```

### **Phase 6: Message Transformation & Network Send**

**6a. Format for upstream:**
```elixir
defp format_for_upstream(%ISOMsg{} = iso_message, upstream_config) do
  # Set YSP packager and apply transformations
  upstream_packager = Map.get(upstream_config, :packager)
  formatted_message = ISOMsg.set_packager(iso_message, upstream_packager)
  transformed_message = apply_upstream_transformations(formatted_message, upstream_config)
  {:ok, transformed_message}
end
```

**6b. Network communication:**
```elixir
defp send_to_upstream(%ISOMsg{} = iso_message, upstream_config) do
  with {:ok, packed_bytes} <- ISOMsg.pack(iso_message),              # Pack to bytes
       {:ok, header_bytes} <- add_upstream_header(packed_bytes, upstream_config), # Add TPDU
       {:ok, framed_bytes} <- apply_message_framing(header_bytes, upstream_config), # Length frame
       {:ok, response_bytes} <- send_to_network(framed_bytes, upstream_config) do  # TCP send
    {:ok, response_bytes}
  end
end
```

### **Complete Transaction Lifecycle States**

```mermaid
sequenceDiagram
    participant T as Terminal
    participant IMP as IncomingMessageProcessor
    participant BL as BusinessLogic
    participant DB as pos_temp_transaction
    participant YSP as YSP.MessageProcessor
    participant UR as UpstreamRouter
    participant UP as YSP Network
    
    T->>IMP: ISO8583 MTI 0200 (Sale)
    IMP->>BL: process_message(iso_message)
    BL->>DB: create_temp_transaction(state: "CREATED")
    DB-->>BL: temp_txn.id
    
    BL->>BL: validate_business_rules()
    BL->>BL: assess_risk()
    BL->>BL: make_business_decision()
    
    alt Amount > $5000
        BL-->>IMP: {:refer, enriched_message}
        IMP-->>T: Manual review required
    else Amount <= 0
        BL-->>IMP: {:decline, :invalid_amount, enriched_message}
        IMP-->>T: Decline response (96)
    else Valid Amount
        BL-->>IMP: {:approve, enriched_message}
        IMP->>DB: update_status("VALIDATED")
        
        IMP->>YSP: ysp_message?(DE-24=782?)
        YSP-->>IMP: true (YSP message)
        
        IMP->>YSP: process_message(iso_message)
        YSP->>YSP: transform_sale_message() 
        YSP-->>IMP: transformed_message
        
        IMP->>DB: update_status("SENT_TO_UPSTREAM")
        IMP->>UR: route_message(iso_message, context)
        
        UR->>UR: determine_upstream_network()
        UR->>UR: format_for_upstream()
        UR->>UP: TCP send (packed bytes + TPDU + framing)
        UP-->>UR: Response bytes
        UR->>UR: unpack_upstream_response()
        UR-->>IMP: response_message (MTI 0210)
        
        IMP->>DB: update_status("RESPONSE_RECEIVED")
        IMP-->>T: Sale Response (MTI 0210)
    end
```

### **Key Database State Transitions**

| State | When | Database Fields Updated |
|-------|------|------------------------|
| **"CREATED"** | Initial temp transaction creation | `s_tid`, `s_mid`, `mti`, `total_amount`, `processing_state` |
| **"VALIDATED"** | Business logic approval | `processing_state`, `updated_at` |
| **"SENT_TO_UPSTREAM"** | Before network send | `processing_state`, `upstream_request_iso`, `upstream_request_sent_at` |
| **"WAITING_RESPONSE"** | After network send | `processing_state` |
| **"RESPONSE_RECEIVED"** | Upstream response | `processing_state`, `upstream_response_iso`, `upstream_response_received_at` |
| **"COMPLETED"** | Final processing | `processing_state`, moved to `pos_transaction` table |

This flow demonstrates how your architecture elegantly handles the **complete lifecycle** from terminal validation through business decisions to upstream communication, with full database state tracking throughout the process.