Spaces:
Sleeping
Sleeping
| """ | |
| Razorpay Payment Integration Service | |
| Handles payment processing in sandbox mode | |
| """ | |
| import razorpay | |
| from typing import Dict, Optional | |
| import json | |
| import os | |
| from datetime import datetime | |
| class PaymentService: | |
| """ | |
| Payment service using Razorpay in test mode | |
| """ | |
| def __init__(self, key_id: str, key_secret: str): | |
| """ | |
| Initialize Razorpay client with test credentials | |
| """ | |
| self.client = razorpay.Client(auth=(key_id, key_secret)) | |
| self.client.set_app_details({ | |
| "title": "Smart Parking System", | |
| "version": "1.0.0" | |
| }) | |
| def create_payment_order(self, amount: float, currency: str = "INR", | |
| booking_id: str = None, | |
| notes: Dict = None) -> Dict: | |
| """ | |
| Create a payment order for parking booking | |
| Args: | |
| amount: Amount in rupees (will be converted to paise) | |
| currency: Currency code (default: INR) | |
| booking_id: Reference booking ID | |
| notes: Additional notes/metadata | |
| Returns: | |
| Order details including order_id | |
| """ | |
| try: | |
| # Convert amount to paise (smallest currency unit) | |
| amount_paise = int(amount * 100) | |
| # Prepare order data | |
| order_data = { | |
| 'amount': amount_paise, | |
| 'currency': currency, | |
| 'receipt': f'booking_{booking_id}_{datetime.now().strftime("%Y%m%d%H%M%S")}', | |
| 'payment_capture': 1 # Auto capture payment | |
| } | |
| # Add notes if provided | |
| if notes: | |
| order_data['notes'] = notes | |
| # Create order | |
| order = self.client.order.create(data=order_data) | |
| return { | |
| 'success': True, | |
| 'order_id': order['id'], | |
| 'amount': amount, | |
| 'currency': order['currency'], | |
| 'receipt': order['receipt'], | |
| 'status': order['status'], | |
| 'created_at': order['created_at'] | |
| } | |
| except Exception as e: | |
| return { | |
| 'success': False, | |
| 'error': str(e) | |
| } | |
| def verify_payment_signature(self, order_id: str, payment_id: str, | |
| signature: str, key_secret: str) -> bool: | |
| """ | |
| Verify the payment signature for security | |
| Args: | |
| order_id: Razorpay order ID | |
| payment_id: Razorpay payment ID | |
| signature: Signature to verify | |
| key_secret: Your Razorpay key secret | |
| Returns: | |
| True if signature is valid, False otherwise | |
| """ | |
| try: | |
| params_dict = { | |
| 'razorpay_order_id': order_id, | |
| 'razorpay_payment_id': payment_id, | |
| 'razorpay_signature': signature | |
| } | |
| # Verify signature | |
| self.client.utility.verify_payment_signature(params_dict) | |
| return True | |
| except razorpay.errors.SignatureVerificationError: | |
| return False | |
| except Exception as e: | |
| print(f"Signature verification error: {e}") | |
| return False | |
| def fetch_payment_details(self, payment_id: str) -> Optional[Dict]: | |
| """ | |
| Fetch payment details by payment ID | |
| """ | |
| try: | |
| payment = self.client.payment.fetch(payment_id) | |
| return { | |
| 'payment_id': payment['id'], | |
| 'amount': payment['amount'] / 100, # Convert back to rupees | |
| 'currency': payment['currency'], | |
| 'status': payment['status'], | |
| 'method': payment.get('method', 'unknown'), | |
| 'email': payment.get('email', ''), | |
| 'contact': payment.get('contact', ''), | |
| 'created_at': payment['created_at'] | |
| } | |
| except Exception as e: | |
| print(f"Error fetching payment: {e}") | |
| return None | |
| def refund_payment(self, payment_id: str, amount: Optional[float] = None, | |
| notes: Dict = None) -> Dict: | |
| """ | |
| Initiate a refund for a payment | |
| Args: | |
| payment_id: Razorpay payment ID | |
| amount: Refund amount (if partial, otherwise full refund) | |
| notes: Additional notes | |
| Returns: | |
| Refund details | |
| """ | |
| try: | |
| refund_data = {} | |
| if amount: | |
| refund_data['amount'] = int(amount * 100) # Convert to paise | |
| if notes: | |
| refund_data['notes'] = notes | |
| refund = self.client.payment.refund(payment_id, refund_data) | |
| return { | |
| 'success': True, | |
| 'refund_id': refund['id'], | |
| 'payment_id': refund['payment_id'], | |
| 'amount': refund['amount'] / 100, | |
| 'status': refund['status'], | |
| 'created_at': refund['created_at'] | |
| } | |
| except Exception as e: | |
| return { | |
| 'success': False, | |
| 'error': str(e) | |
| } | |
| def create_payment_link(self, amount: float, description: str, | |
| customer_name: str, customer_contact: str, | |
| customer_email: str, booking_id: str) -> Dict: | |
| """ | |
| Create a payment link for WhatsApp sharing | |
| Args: | |
| amount: Amount in rupees | |
| description: Payment description | |
| customer_name: Customer name | |
| customer_contact: Customer phone number | |
| customer_email: Customer email | |
| booking_id: Reference booking ID | |
| Returns: | |
| Payment link details | |
| """ | |
| try: | |
| link_data = { | |
| 'amount': int(amount * 100), | |
| 'currency': 'INR', | |
| 'description': description, | |
| 'customer': { | |
| 'name': customer_name, | |
| 'contact': customer_contact, | |
| 'email': customer_email | |
| }, | |
| 'notify': { | |
| 'sms': True, | |
| 'email': True | |
| }, | |
| 'reminder_enable': True, | |
| 'callback_url': f'https://your-domain.com/payment/callback/{booking_id}', | |
| 'callback_method': 'get' | |
| } | |
| payment_link = self.client.payment_link.create(data=link_data) | |
| return { | |
| 'success': True, | |
| 'link_id': payment_link['id'], | |
| 'short_url': payment_link['short_url'], | |
| 'amount': amount, | |
| 'status': payment_link['status'], | |
| 'created_at': payment_link['created_at'] | |
| } | |
| except Exception as e: | |
| return { | |
| 'success': False, | |
| 'error': str(e) | |
| } | |
| def capture_payment(self, payment_id: str, amount: float) -> Dict: | |
| """ | |
| Manually capture a payment (if auto-capture is disabled) | |
| """ | |
| try: | |
| amount_paise = int(amount * 100) | |
| payment = self.client.payment.capture(payment_id, amount_paise) | |
| return { | |
| 'success': True, | |
| 'payment_id': payment['id'], | |
| 'amount': payment['amount'] / 100, | |
| 'status': payment['status'] | |
| } | |
| except Exception as e: | |
| return { | |
| 'success': False, | |
| 'error': str(e) | |
| } | |
| class PaymentSimulator: | |
| """ | |
| Simulator for testing payments without actual transactions | |
| Useful for development and testing | |
| """ | |
| def __init__(self): | |
| self.simulated_payments = {} | |
| self.payment_counter = 1000 | |
| def simulate_payment(self, order_id: str, amount: float, | |
| status: str = "captured") -> Dict: | |
| """ | |
| Simulate a payment transaction | |
| """ | |
| payment_id = f"pay_sim_{self.payment_counter}" | |
| self.payment_counter += 1 | |
| payment_data = { | |
| 'payment_id': payment_id, | |
| 'order_id': order_id, | |
| 'amount': amount, | |
| 'status': status, | |
| 'method': 'simulated', | |
| 'timestamp': datetime.now().isoformat() | |
| } | |
| self.simulated_payments[payment_id] = payment_data | |
| return { | |
| 'success': True, | |
| 'payment_id': payment_id, | |
| 'amount': amount, | |
| 'status': status, | |
| 'message': 'Payment simulated successfully' | |
| } | |
| def get_simulated_payment(self, payment_id: str) -> Optional[Dict]: | |
| """ | |
| Retrieve simulated payment details | |
| """ | |
| return self.simulated_payments.get(payment_id) | |
| # Example usage | |
| if __name__ == "__main__": | |
| # Test credentials from CSV | |
| KEY_ID = "rzp_test_RYlqJbc24Sl6jz" | |
| KEY_SECRET = "bghQe0L7iort9vmqb6Jlf8Ec" | |
| # Initialize payment service | |
| payment_service = PaymentService(KEY_ID, KEY_SECRET) | |
| # Example 1: Create payment order | |
| print("Creating payment order...") | |
| order = payment_service.create_payment_order( | |
| amount=50.00, | |
| booking_id="BKG123", | |
| notes={ | |
| 'slot_id': 'A1', | |
| 'duration': '2 hours', | |
| 'vehicle_number': 'DL01AB1234' | |
| } | |
| ) | |
| print(json.dumps(order, indent=2)) | |
| # Example 2: Create payment link (for WhatsApp) | |
| print("\nCreating payment link...") | |
| payment_link = payment_service.create_payment_link( | |
| amount=50.00, | |
| description="Parking Slot A1 - 2 hours", | |
| customer_name="John Doe", | |
| customer_contact="+919876543210", | |
| customer_email="john@example.com", | |
| booking_id="BKG123" | |
| ) | |
| print(json.dumps(payment_link, indent=2)) | |
| # Example 3: Simulate payment (for testing) | |
| print("\nSimulating payment...") | |
| simulator = PaymentSimulator() | |
| simulated = simulator.simulate_payment( | |
| order_id=order.get('order_id', 'test_order'), | |
| amount=50.00 | |
| ) | |
| print(json.dumps(simulated, indent=2)) | |