Metadata-Version: 2.4
Name: lipana
Version: 1.0.0
Summary: Official Python SDK for Lipana M-Pesa API
Home-page: https://github.com/lipana/lipana-python
Author: Lipana
Author-email: Lipana <dev@lipana.dev>
License: MIT
Project-URL: Homepage, https://lipana.dev
Project-URL: Documentation, https://lipana.dev/docs
Project-URL: Repository, https://github.com/lipana/lipana-python
Project-URL: Issues, https://github.com/lipana/lipana-python/issues
Keywords: lipana,mpesa,payments,kenya,stk-push,api,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: black>=22.0.0; extra == "dev"
Requires-Dist: mypy>=0.991; extra == "dev"
Dynamic: author
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python

# Lipana Python SDK

Official Python SDK for the Lipana M-Pesa API. Type-safe, well-documented, and production-ready.

**Version**: 1.0.0  
**PyPI**: https://pypi.org/project/lipana/  
**Documentation**: https://lipana.dev/docs

## Installation

```bash
pip install lipana
```

Or using poetry:

```bash
poetry add lipana
```

## Quick Start

```python
import os
from lipana import Lipana

# Initialize the SDK
lipana = Lipana(
    api_key=os.getenv('LIPANA_SECRET_KEY'),  # Use secret key for server-side
    environment='production'  # or 'sandbox' for testing
)

# Create a payment link
payment_link = lipana.payment_links.create(
    title='Premium Subscription',
    description='Monthly subscription to our premium features',
    amount=5000,
    currency='KES',
    allow_custom_amount=False,
    success_redirect_url='https://yourwebsite.com/success'
)

print(f'Payment link created: {payment_link["url"]}')

# Initiate STK push payment
stk_response = lipana.transactions.initiate_stk_push(
    phone='+254712345678',
    amount=5000
)

print(f'STK push initiated: {stk_response["transactionId"]}')
```

## Features

- ✅ **Type Hints**: Full type hint support for better IDE autocomplete
- ✅ **Error Handling**: Comprehensive error handling with detailed error messages
- ✅ **Pythonic API**: Clean, Pythonic interface following PEP 8 conventions
- ✅ **Webhooks**: Built-in webhook signature verification utilities

## API Reference

### Transactions

```python
# List all transactions
transactions = lipana.transactions.list(
    status='success',
    limit=50,
    start_date='2024-01-01',
    end_date='2024-12-31'
)

# Get a specific transaction
transaction = lipana.transactions.retrieve('txn_123456')

# Initiate STK push
stk_response = lipana.transactions.initiate_stk_push(
    phone='+254712345678',
    amount=5000
)
```

### Payment Links

```python
# Create a payment link
payment_link = lipana.payment_links.create(
    title='Premium Subscription',
    amount=5000,
    currency='KES'
)

# List payment links
payment_links = lipana.payment_links.list(
    status='active',
    limit=10
)

# Update a payment link
updated_link = lipana.payment_links.update('link_123456', {
    'status': 'inactive'
})

# Delete a payment link
lipana.payment_links.delete('link_123456')
```

### Webhooks

```python
# Get webhook settings
settings = lipana.webhooks.get_settings()

# Update webhook settings
lipana.webhooks.update_settings(
    webhook_url='https://yourwebsite.com/webhooks',
    enabled=True
)

# Verify webhook signature
is_valid = lipana.webhooks.verify(
    request_body,
    request_headers['x-lipana-signature'],
    os.getenv('LIPANA_WEBHOOK_SECRET')
)
```

### API Keys

```python
# List all API keys
api_keys = lipana.api_keys.list()

# Create a new API key
api_key = lipana.api_keys.create(
    name='Production Key',
    environment='production'
)
```

## Error Handling

```python
from lipana import Lipana, LipanaError

try:
    payment = lipana.transactions.initiate_stk_push(
        phone='+254712345678',
        amount=5000
    )
except LipanaError as error:
    if error.is_authentication_error():
        print(f'Authentication failed: {error.message}')
    elif error.is_validation_error():
        print(f'Validation error: {error.errors}')
    elif error.is_rate_limit_error():
        print('Rate limit exceeded')
    elif error.is_server_error():
        print(f'Server error: {error.message}')
    else:
        print(f'Error: {error.message}')
```

## Configuration

### Environment

The SDK supports two environments:

- `production`: For live transactions (default)
  - Base URL: `https://api.lipana.dev/api`
  
- `sandbox`: For testing and development
  - Base URL: `https://api-sandbox.lipana.dev/api`

```python
lipana = Lipana(
    api_key=os.getenv('LIPANA_SECRET_KEY'),
    environment='sandbox'  # or 'production'
)
```

### Custom Base URL

You can override the default base URL:

```python
lipana = Lipana(
    api_key=os.getenv('LIPANA_SECRET_KEY'),
    base_url='https://custom-api.example.com/api'
)
```

## Examples

### Flask Webhook Handler

```python
from flask import Flask, request, jsonify
from lipana import Lipana, LipanaError
import os

app = Flask(__name__)
lipana = Lipana(
    api_key=os.getenv('LIPANA_SECRET_KEY'),
    environment='production'
)

@app.route('/webhooks/lipana', methods=['POST'])
def webhook_handler():
    signature = request.headers.get('x-lipana-signature')
    secret = os.getenv('LIPANA_WEBHOOK_SECRET')
    
    if lipana.webhooks.verify(request.json, signature, secret):
        event = request.json.get('event')
        data = request.json.get('data')
        
        if event == 'transaction.success':
            print(f'Transaction succeeded: {data}')
        elif event == 'transaction.failed':
            print(f'Transaction failed: {data}')
        
        return jsonify({'received': True}), 200
    else:
        return jsonify({'error': 'Invalid signature'}), 401
```

### Django View

```python
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from lipana import Lipana
import os

lipana = Lipana(
    api_key=os.getenv('LIPANA_SECRET_KEY'),
    environment='production'
)

@csrf_exempt
def create_payment_link(request):
    if request.method == 'POST':
        try:
            payment_link = lipana.payment_links.create(
                title=request.POST.get('title'),
                amount=float(request.POST.get('amount')),
                currency='KES'
            )
            return JsonResponse(payment_link)
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)
    return JsonResponse({'error': 'Method not allowed'}, status=405)
```

## Requirements

- Python >= 3.8
- requests >= 2.28.0

## Version History

### 1.0.0 (Current)
- 🎉 Initial release
- ✅ Full Python SDK implementation
- ✅ All API endpoints supported
- ✅ Webhook signature verification
- ✅ Comprehensive error handling
- ✅ Type hints support

## License

MIT

## Support

- **Documentation**: [https://lipana.dev/docs](https://lipana.dev/docs)
- **PyPI Package**: [https://pypi.org/project/lipana/](https://pypi.org/project/lipana/)
- **Issues**: [https://github.com/lipana/lipana-python/issues](https://github.com/lipana/lipana-python/issues)
- **Website**: [https://lipana.dev](https://lipana.dev)

