Import Uuid
Import Uuid
import datetime
from typing import Dict, List, Optional
from enum import Enum
import hashlib
import json
class PaymentStatus(Enum):
PENDING = "pending"
AUTHORIZED = "authorized"
CAPTURED = "captured"
FAILED = "failed"
REFUNDED = "refunded"
VOIDED = "voided"
class PaymentMethod(Enum):
CREDIT_CARD = "credit_card"
DEBIT_CARD = "debit_card"
BANK_TRANSFER = "bank_transfer"
DIGITAL_WALLET = "digital_wallet"
class CreditCard:
def __init__(self, card_number: str, expiry_month: int, expiry_year: int, cvv:
str, holder_name: str):
self.card_number = self._mask_card_number(card_number)
self.expiry_month = expiry_month
self.expiry_year = expiry_year
self.cvv = "***" # Store securely or don't store at all
self.holder_name = holder_name
self._validate()
current_year = datetime.datetime.now().year
if not (current_year <= self.expiry_year <= current_year + 10):
raise ValueError("Invalid expiry year")
return True
class Transaction:
def __init__(self,
amount: float,
currency: str,
payment_method: PaymentMethod,
payment_details: Dict,
merchant_id: str,
customer_id: Optional[str] = None,
description: Optional[str] = None):
self.transaction_id = str(uuid.uuid4())
self.amount = amount
self.currency = currency
self.payment_method = payment_method
self.payment_details = payment_details
self.merchant_id = merchant_id
self.customer_id = customer_id
self.description = description
self.status = PaymentStatus.PENDING
self.created_at = datetime.datetime.now()
self.updated_at = self.created_at
self.error_message = None
class PaymentGateway:
def __init__(self, gateway_name: str, api_key: str, api_secret: str):
self.gateway_name = gateway_name
self.api_key = api_key
self.api_secret = api_secret
self.transactions: List[Transaction] = []
transaction.update_status(PaymentStatus.AUTHORIZED)
self.transactions.append(transaction)
return {
"success": True,
"transaction_id": transaction.transaction_id,
"status": transaction.status.value
}
except Exception as e:
transaction.update_status(PaymentStatus.FAILED, str(e))
self.transactions.append(transaction)
return {
"success": False,
"transaction_id": transaction.transaction_id,
"status": transaction.status.value,
"error": str(e)
}
if not transaction:
return {"success": False, "error": "Transaction not found"}
if transaction.status != PaymentStatus.AUTHORIZED:
return {"success": False, "error": f"Transaction in invalid state:
{transaction.status.value}"}
try:
# Simulate actual capture with payment processor
self._simulate_external_capture(transaction, capture_amount)
transaction.update_status(PaymentStatus.CAPTURED)
return {
"success": True,
"transaction_id": transaction.transaction_id,
"status": transaction.status.value,
"amount_captured": capture_amount
}
except Exception as e:
transaction.update_status(PaymentStatus.FAILED, str(e))
return {
"success": False,
"transaction_id": transaction.transaction_id,
"status": transaction.status.value,
"error": str(e)
}
if not transaction:
return {"success": False, "error": "Transaction not found"}
if transaction.status != PaymentStatus.AUTHORIZED:
return {"success": False, "error": f"Cannot void transaction in state:
{transaction.status.value}"}
try:
# Simulate communication with payment processor to void
self._simulate_external_void(transaction)
transaction.update_status(PaymentStatus.VOIDED)
return {
"success": True,
"transaction_id": transaction.transaction_id,
"status": transaction.status.value
}
except Exception as e:
return {
"success": False,
"transaction_id": transaction.transaction_id,
"error": str(e)
}
if not transaction:
return {"success": False, "error": "Transaction not found"}
if transaction.status != PaymentStatus.CAPTURED:
return {"success": False, "error": f"Cannot refund transaction in
state: {transaction.status.value}"}
try:
# Simulate communication with payment processor for refund
self._simulate_external_refund(transaction, refund_amount)
transaction.update_status(PaymentStatus.REFUNDED)
return {
"success": True,
"transaction_id": transaction.transaction_id,
"status": transaction.status.value,
"amount_refunded": refund_amount
}
except Exception as e:
return {
"success": False,
"transaction_id": transaction.transaction_id,
"error": str(e)
}
if not transaction:
return None
return transaction.to_dict()
# Example usage
def main():
# Initialize payment gateway
gateway = PaymentGateway(
gateway_name="Example Payment Gateway",
api_key="live_api_key_123456",
api_secret="live_api_secret_abcdef"
)
# Create a transaction
transaction = Transaction(
amount=99.99,
currency="USD",
payment_method=PaymentMethod.CREDIT_CARD,
payment_details={
"card_number": card.card_number,
"expiry_month": card.expiry_month,
"expiry_year": card.expiry_year,
"holder_name": card.holder_name
},
merchant_id="merchant_12345",
customer_id="customer_6789",
description="Purchase of Premium Subscription"
)
if auth_result["success"]:
transaction_id = auth_result["transaction_id"]
# Process refund
print("\n4. Refunding payment...")
refund_result = gateway.refund(transaction_id, 50.00)
print(f"Refund result: {refund_result}")
auth_result2 = gateway.authorize(transaction2)
print(f"Authorization result: {auth_result2}")
if auth_result2["success"]:
transaction_id2 = auth_result2["transaction_id"]
except ValueError as e:
print(f"Error: {e}")
if __name__ == "__main__":
main()
======================
Core Components
CreditCard Class
Handles credit card information with proper security (masking card numbers, never
storing CVV)
Performs basic validation on card details
In a real implementation, would include more comprehensive validation using
algorithms like Luhn's
Transaction Class
PaymentGateway Class
Authorization
Capture
Void
Refund
Security Features
Simulation Logic
The code includes "simulation" methods that would, in a real implementation,
communicate with external payment processors:
_simulate_external_auth
_simulate_external_capture
_simulate_external_void
_simulate_external_refund
In a production environment, these would make API calls to payment processors like
Stripe, PayPal, or Adyen.
Example Usage
The main() function demonstrates a complete payment flow: