# UPI PSP API Documentation

## Overview

This is a UPI Payment Service Provider (PSP) implementation built with Elixir/Phoenix, following the UPI Acceptance Model specifications. The system handles international payment processing with QR validation, transaction orchestration, and timeout management.

## Architecture

### Core Components

1. **QR Validation**: XML parsing and validation of UPI QR codes
2. **Transaction Orchestration**: State machine for payment processing
3. **Partner Integration**: Adapter pattern for international partner APIs
4. **Event Logging**: Hash-chained events for audit trails
5. **Timeout Management**: Automated ChkTxn and reversal handling

### Transaction States

- `initiated` → `debit_secured` → `credit_pending` → `success`
- Timeout escalation: `credit_pending` → `chktxn_pending` → `reversal_pending` → `deemed`

## API Endpoints

# Updated API Endpoints - Clear Separation

## 🏛️ NPCI → PSP Interface (Official UPI APIs)
**Base URL**: `/api/v1/upi/*`
**Purpose**: Handle official NPCI UPI protocol messages

| Method | Endpoint | Purpose | NPCI API |
|--------|----------|---------|----------|
| POST | `/upi/validate-qr` | QR validation from NPCI | ReqValQR |
| POST | `/upi/process-payment` | Payment processing from NPCI | ReqPay |
| POST | `/upi/check-transaction` | Status check from NPCI | ReqChkTxn |
| POST | `/upi/heartbeat` | Health check from NPCI | ReqHbt |

## 🤝 Partner → PSP Interface (Business APIs)
**Base URL**: `/api/v1/qr-*`
**Purpose**: Handle partner business operations

| Method | Endpoint | Purpose | Use Case |
|--------|----------|---------|----------|
| POST | `/qr-generate` | Generate QR for partner's merchant | Partner creates dynamic QR |
| GET | `/qr-status/:id` | Check QR status and details | Partner monitors QR usage |

## ✅ Benefits of New Naming:

1. **🎯 Clear Purpose**: Immediately obvious what each API does
2. **🏗️ Logical Grouping**: NPCI APIs vs Partner APIs clearly separated  
3. **📚 Better Documentation**: Self-documenting endpoint names
4. **🔧 Easier Maintenance**: No confusion about which API handles what
5. **🚀 Future Scalability**: Easy to add more partner APIs under `/qr-*` pattern

### QR Validation

#### Create QR Validation
```bash
POST /qr-validation
Content-Type: application/json

{
  "xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><ReqValQr>...</ReqValQr>"
}
```

**Response:**
```json
{
  "success": true,
  "data": {
    "id": 1,
    "ver_token": "VER123456",
    "status": "valid",
    "payee_addr": "merchant@axis",
    "payee_mid": "MERCHANT001",
    "fx_quotes": 2
  },
  "message": "QR validation processed successfully"
}
```

#### Get QR Validation
```bash
GET /qr-validation/:id
```

### Transactions

#### Create Transaction
```bash
POST /transactions
Content-Type: application/json

{
  "payer_addr": "user@paytm",
  "payee_addr": "merchant@axis", 
  "payee_mid": "MERCHANT001",
  "foreign_amount": "100.00",
  "foreign_currency": "USD",
  "fx_rate": "83.25",
  "markup_pct": "2.5",
  "ver_token": "VER123456"
}
```

**Response:**
```json
{
  "success": true,
  "data": {
    "id": 1,
    "org_txn_id": "TXN-a1b2c3d4",
    "payer_addr": "user@paytm",
    "payee_addr": "merchant@axis",
    "foreign_amount": "100.00",
    "foreign_currency": "USD",
    "fx_rate": "83.25",
    "markup_pct": "2.5",
    "inr_amount": "8525.00",
    "current_state": "credit_pending",
    "status": "pending",
    "credit_requested_at": "2025-08-11T10:30:00Z"
  },
  "message": "Transaction initiated successfully"
}
```

### NPCI Callback Endpoints

These endpoints are called by NPCI as per UPI International specification:

#### Check Transaction Status (ReqChkTxn)
```bash
POST /npci/check-transaction
Content-Type: application/xml

<?xml version="1.0" encoding="UTF-8"?>
<upi:ReqChkTxn xmlns:upi="http://npci.org/upi/schema/">
  <Head ver="2.0" ts="2025-08-11T10:30:00Z" orgId="NPCI" msgId="CHK123456"/>
  <Txn id="CHK123" orgTxnId="TXN-a1b2c3d4" type="ChkTxn" subType="CREDIT"/>
</upi:ReqChkTxn>
```

**Response (XML):**
```xml
<upi:RespChkTxn xmlns:upi="http://npci.org/upi/schema/">
  <Head ver="2.0" ts="2025-08-11T10:30:15Z" orgId="MERCURYPSP" msgId="CHK789"/>
  <Resp reqMsgId="CHK123456" result="SUCCESS" errCode="">
    <Ref type="PAYEE" respCode="CS" settAmount="100.00" settCurrency="USD"/>
  </Resp>
</upi:RespChkTxn>
```

#### Process Reversal (ReqPay REVERSAL)
```bash
POST /npci/reversal-request
Content-Type: application/xml

<?xml version="1.0" encoding="UTF-8"?>
<upi:ReqPay xmlns:upi="http://npci.org/upi/schema/">
  <Head ver="2.0" ts="2025-08-11T10:30:00Z" orgId="NPCI" msgId="REV123456"/>
  <Txn id="REV123" type="REVERSAL" orgTxnId="TXN-a1b2c3d4"/>
</upi:ReqPay>
```

#### Heartbeat Check (ReqHbt)
```bash
POST /npci/heartbeat
Content-Type: application/xml

<?xml version="1.0" encoding="UTF-8"?>
<upi:ReqHbt xmlns:upi="http://npci.org/upi/schema/">
  <Head ver="2.0" ts="2025-08-11T10:30:00Z" orgId="NPCI" msgId="HBT123456"/>
</upi:ReqHbt>
```

### Transactions#### Get Transaction
```bash
GET /transactions/:org_txn_id
```

**Response includes events:**
```json
{
  "success": true,
  "data": {
    "org_txn_id": "TXN-a1b2c3d4",
    "current_state": "credit_pending",
    "events": [
      {
        "seq": 1,
        "event_type": "txn_initiated",
        "payload": {"org_txn_id": "TXN-a1b2c3d4"},
        "hash": "ABC123...",
        "prev_hash": null,
        "inserted_at": "2025-08-11T10:29:00Z"
      },
      {
        "seq": 2,
        "event_type": "debit_secured", 
        "payload": {"debit_secured_at": "2025-08-11T10:29:30Z"},
        "hash": "DEF456...",
        "prev_hash": "ABC123...",
        "inserted_at": "2025-08-11T10:29:30Z"
      }
    ]
  }
}
```

#### List Transactions
```bash
GET /transactions?status=pending&current_state=credit_pending
```

#### Simulate Credit Success
```bash
POST /transactions/:org_txn_id/credit-success
```

## Database Schema

### Key Tables

1. **qr_validations**: QR validation records
2. **qr_validation_events**: Hash-chained events for QR validation
3. **fx_quotes**: Foreign exchange rates
4. **merchants**: Merchant information
5. **merchant_invoices**: Separate invoice tracking
6. **transactions**: Transaction records
7. **transaction_events**: Hash-chained transaction events
8. **followup_requests**: ChkTxn/reversal scheduling

### Event Hash Chain

Events are hash-chained for tamper detection:
```
hash(prev_hash + seq + event_type + payload + timestamp)
```

## Running the Application

### Prerequisites
- Elixir 1.17+
- Phoenix 1.7+
- MySQL 8.0+

### Setup
```bash
# Install dependencies
mix deps.get

# Create and migrate database
mix ecto.create
mix ecto.migrate

# Start the server
mix phx.server
```

### Testing
```bash
# Run the API test script
./test_api.sh

# Run unit tests  
mix test
```

## Configuration

### Database (config/dev.exs)
```elixir
config :da_product_app, DaProductApp.Repo,
  username: "root",
  password: "password",
  hostname: "localhost",
  database: "da_product_app_dev"
```

### SaaS Kit (config/dev.exs)
```elixir
config :da_product_app, :saas_kit,
  api_key: "your-api-key",
  base_url: "https://api.saaskit.com",
  webhook_secret: "your-webhook-secret"
```

## Partner Integration

### Adapter Pattern
```elixir
defmodule YourPartner do
  @behaviour DaProductApp.Adapters.InternationalPartnerBehaviour
  
  def credit_request(params), do: # Your implementation
  def check_txn(params), do: # Your implementation  
  def reversal_request(params), do: # Your implementation
end
```

### Response Format
```elixir
{:ok, %{code: "CS", payload: %{partner_status: "SUCCESS"}}}
{:error, reason}
```

## Monitoring

### Watchdog Process
- Runs every 5 seconds
- Processes expired follow-up requests
- Handles timeout escalation

### Event Logging
- All state changes logged as events
- Hash chain verification available
- Audit trail for compliance

## Error Handling

### Common Error Responses
```json
{
  "success": false,
  "error": "validation_failed",
  "errors": {
    "foreign_amount": ["must be > 0"],
    "org_txn_id": ["can't be blank"]
  },
  "message": "Validation failed"
}
```

### HTTP Status Codes
- `200`: Success
- `201`: Created
- `400`: Bad Request
- `404`: Not Found
- `422`: Unprocessable Entity
- `500`: Internal Server Error

## Development Roadmap

### Phase 4 Completed ✅
- REST API endpoints
- JSON request/response handling
- Transaction listing and filtering
- Credit success simulation

### Next Steps
- [ ] Complete XML parser (full UPI spec coverage)
- [ ] Real partner adapter implementations
- [ ] Webhook endpoints for partner callbacks
- [ ] Rate limiting and authentication
- [ ] Comprehensive test suite
- [ ] Performance monitoring
- [ ] Deployment configuration

## Support

For questions or issues, check the codebase documentation or create an issue in the project repository.
