# Payment Gateway App

A standalone, modular OTP application for payment processing that can be optionally compiled and integrated with CloudLayer.

## Features

- 🚀 **Independent OTP Application** - Runs standalone or integrated with CloudLayer
- 💳 **Payment Initiation** - Create payment transactions via external APIs
- 📊 **Status Tracking** - Real-time payment status monitoring
- 🔌 **Provider Abstraction** - Easily swap payment providers
- 🎨 **Web Interface** - Phoenix LiveView-based UI for payments
- 🔒 **Validation** - Robust input validation and error handling
- 🧪 **Well Tested** - Comprehensive unit and integration tests

## Architecture

```
apps/payment_gateway_app/
├── lib/
│   ├── payment_gateway_app/          # Core business logic
│   │   ├── application.ex            # OTP application
│   │   ├── payment_initiator.ex      # Payment creation
│   │   ├── status_checker.ex         # Status retrieval
│   │   ├── validator.ex              # Input validation
│   │   ├── api_adapter.ex            # Provider interface
│   │   └── providers/                # Payment provider implementations
│   │       ├── payment_provider.ex   # Behaviour definition
│   │       └── mock_provider.ex      # Mock for testing
│   ├── payment_gateway_app_web/      # Web interface
│   │   ├── controllers/              # HTTP controllers
│   │   ├── live/                     # LiveView components
│   │   ├── components/               # Reusable UI components
│   │   ├── router.ex                 # Route definitions
│   │   └── endpoint.ex               # Phoenix endpoint
│   └── payment_gateway_app.ex        # Public API
├── assets/                           # Frontend assets
│   ├── js/                          # JavaScript
│   ├── css/                         # Stylesheets
│   └── tailwind.config.js           # Tailwind configuration
├── config/                          # Configuration files
├── priv/                            # Static assets
└── test/                            # Tests
```

## Installation & Setup

### Prerequisites

- Elixir ~> 1.14
- Phoenix ~> 1.7
- Node.js (for asset compilation)

### Configuration

1. **Enable Payment Gateway App in root mix.exs**

Add to your root `mix.exs` dependencies (if using umbrella structure):

```elixir
def deps do
  [
    {:payment_gateway_app, in_umbrella: true}
  ]
end
```

2. **Environment Configuration**

Set environment variables for payment provider:

```bash
export PG_API_KEY="your_api_key"
export PG_API_SECRET="your_api_secret"
export PG_API_ENDPOINT="https://api.payment-provider.com"
```

Or configure in `config/config.exs`:

```elixir
config :payment_gateway_app,
  api_provider: PaymentGatewayApp.Providers.MockProvider,
  api_key: System.get_env("PG_API_KEY"),
  api_secret: System.get_env("PG_API_SECRET"),
  api_endpoint: "https://api.payment-provider.com"
```

3. **Compile-time Toggle**

To include/exclude the PG app at compile time, you can:

- **Include**: Add to dependencies as shown above
- **Exclude**: Remove from dependencies or comment out

4. **Runtime Toggle**

The app starts automatically when included. To conditionally start:

```elixir
# In your application.ex
children =
  if Application.get_env(:my_app, :enable_payment_gateway, false) do
    [{PaymentGatewayApp.Application, []} | other_children]
  else
    other_children
  end
```

### Setup Commands

```bash
# Install dependencies
cd apps/payment_gateway_app
mix deps.get

# Setup assets
mix assets.setup

# Build assets
mix assets.build

# Run tests
mix test

# Start the application standalone
mix phx.server
```

## Usage

### Public API

The Payment Gateway exposes a simple API that can be called from your main application:

```elixir
# Start a payment
{:ok, payment} = PaymentGatewayApp.start_payment(100.00, "USD", "user_123")
# => {:ok, %{id: "pay_abc...", status: "pending", amount: 100.0, currency: "USD", ...}}

# Check payment status
{:ok, status} = PaymentGatewayApp.get_payment_status("pay_abc...")
# => {:ok, %{id: "pay_abc...", status: "completed", updated_at: ~U[...]}}
```

### Web Interface Routes

When running, the PG app exposes these routes:

- `GET /pgpayments` - Landing page
- `GET /pgpayments/initiate` - Payment initiation form (LiveView)
- `GET /pgpayments/status/:payment_id` - Payment status page (LiveView)

### API Endpoints

For programmatic access:

- `POST /api/pgpayments/initiate` - Create payment (JSON)
- `GET /api/pgpayments/status/:payment_id` - Get status (JSON)

#### API Example

```bash
# Initiate payment
curl -X POST http://localhost:4001/api/pgpayments/initiate \
  -H "Content-Type: application/json" \
  -d '{"amount": 50.0, "currency": "USD", "user_id": "user_abc"}'

# Check status
curl http://localhost:4001/api/pgpayments/status/pay_abc123
```

## Extending with New Providers

To add a new payment provider:

1. Create a new module implementing `PaymentGatewayApp.Providers.PaymentProvider` behaviour:

```elixir
defmodule PaymentGatewayApp.Providers.StripeProvider do
  @behaviour PaymentGatewayApp.Providers.PaymentProvider

  @impl true
  def create_payment(payment_data) do
    # Call Stripe API
  end

  @impl true
  def get_payment_status(payment_id) do
    # Query Stripe API
  end

  @impl true
  def cancel_payment(payment_id) do
    # Cancel via Stripe API
  end
end
```

2. Configure the provider in `config/config.exs`:

```elixir
config :payment_gateway_app,
  api_provider: PaymentGatewayApp.Providers.StripeProvider
```

## Testing

Run the test suite:

```bash
mix test
```

Run specific tests:

```bash
mix test test/payment_gateway_app/validator_test.exs
```

Run with coverage:

```bash
mix test --cover
```

## Development

### Code Quality

```bash
# Format code
mix format

# Run Credo (if available)
mix credo

# Run dialyzer (if available)
mix dialyzer
```

### Live Reloading

When running in development mode, the app supports live reload:

```bash
mix phx.server
```

Visit http://localhost:4001/pgpayments

## Integration with CloudLayer

### Option 1: Umbrella App Structure (Recommended)

```
CloudLayer/
├── apps/
│   ├── da_product_app/          # Main app
│   └── payment_gateway_app/     # PG app
├── config/
├── deps/
└── mix.exs                      # Umbrella project
```

### Option 2: Dependency Integration

Add as a path dependency in main app's `mix.exs`:

```elixir
def deps do
  [
    {:payment_gateway_app, path: "../payment_gateway_app"}
  ]
end
```

### Option 3: Git Dependency

```elixir
def deps do
  [
    {:payment_gateway_app, git: "https://github.com/your-org/payment_gateway_app"}
  ]
end
```

## Configuration Options

| Option | Description | Default |
|--------|-------------|---------|
| `api_provider` | Payment provider module | `MockProvider` |
| `api_key` | Provider API key | `nil` |
| `api_secret` | Provider API secret | `nil` |
| `api_endpoint` | Provider API URL | Provider-specific |

## Security Considerations

- ⚠️ Never commit API keys or secrets
- 🔒 Use environment variables or secret management
- 🔐 Enable HTTPS in production
- 🛡️ Validate all inputs
- 📝 Log security events
- 🔑 Rotate credentials regularly

## Troubleshooting

### Assets not compiling

```bash
cd apps/payment_gateway_app/assets
npm install
cd ..
mix assets.build
```

### Port already in use

Change the port in `config/dev.exs`:

```elixir
config :payment_gateway_app, PaymentGatewayAppWeb.Endpoint,
  http: [ip: {127, 0, 0, 1}, port: 4002]
```

### LiveView not connecting

Ensure the CSRF token is set in your layout:

```html
<meta name="csrf-token" content={get_csrf_token()} />
```

## License

[Your License Here]

## Contributing

1. Fork the repository
2. Create your feature branch
3. Write tests
4. Make your changes
5. Ensure all tests pass
6. Submit a pull request

## Support

For issues or questions:
- Open an issue on GitHub
- Contact the CloudLayer team
