Square enhancements

This commit is contained in:
James Pattinson
2025-11-13 17:41:28 +00:00
parent dac8b43915
commit b8f2d12011
6 changed files with 410 additions and 35 deletions

View File

@@ -190,7 +190,8 @@ async def process_square_payment(
source_id=payment_request.source_id,
idempotency_key=payment_request.idempotency_key,
reference_id=reference_id,
note=payment_request.note or f"Membership payment for {tier.name} - {current_user.email}"
note=payment_request.note or f"Membership payment for {tier.name} - {current_user.email}",
billing_details=payment_request.billing_details
)
if not square_result.get('success'):

View File

@@ -171,6 +171,7 @@ class SquarePaymentRequest(BaseModel):
amount: float = Field(..., gt=0, description="Payment amount in GBP")
idempotency_key: Optional[str] = Field(None, description="Unique key to prevent duplicate payments")
note: Optional[str] = Field(None, description="Optional payment note")
billing_details: Optional[dict] = Field(None, description="Billing address and cardholder name for AVS")
class SquarePaymentResponse(BaseModel):

View File

@@ -35,7 +35,8 @@ class SquareService:
idempotency_key: Optional[str] = None,
customer_id: Optional[str] = None,
reference_id: Optional[str] = None,
note: Optional[str] = None
note: Optional[str] = None,
billing_details: Optional[Dict] = None
) -> Dict:
"""
Create a payment using Square
@@ -47,6 +48,7 @@ class SquareService:
customer_id: Optional Square customer ID
reference_id: Optional reference ID for internal tracking
note: Optional note about the payment
billing_details: Optional billing address and cardholder name for AVS
Returns:
Dict with payment result including payment_id, status, and details
@@ -60,19 +62,49 @@ class SquareService:
# For GBP, this is pence
amount_in_pence = int(amount_money * 100)
# Create payment - pass parameters directly as keyword arguments
result = self.client.payments.create(
source_id=source_id,
idempotency_key=idempotency_key,
amount_money={
# Build payment parameters
payment_params = {
'source_id': source_id,
'idempotency_key': idempotency_key,
'amount_money': {
'amount': amount_in_pence,
'currency': 'GBP'
},
location_id=self.location_id,
customer_id=customer_id if customer_id else None,
reference_id=reference_id if reference_id else None,
note=note if note else None
)
'location_id': self.location_id
}
# Add billing address for AVS if provided
if billing_details:
# Add buyer email if available
if billing_details.get('email'):
payment_params['buyer_email_address'] = billing_details.get('email')
# Build billing address for AVS
billing_address = {}
if billing_details.get('address_line_1'):
billing_address['address_line_1'] = billing_details.get('address_line_1')
if billing_details.get('address_line_2'):
billing_address['address_line_2'] = billing_details.get('address_line_2')
if billing_details.get('city'):
billing_address['locality'] = billing_details.get('city')
if billing_details.get('postal_code'):
billing_address['postal_code'] = billing_details.get('postal_code')
if billing_details.get('country'):
billing_address['country'] = billing_details.get('country')
if billing_address:
payment_params['billing_address'] = billing_address
# Add optional parameters
if customer_id:
payment_params['customer_id'] = customer_id
if reference_id:
payment_params['reference_id'] = reference_id
if note:
payment_params['note'] = note
# Create payment - pass parameters directly as keyword arguments
result = self.client.payments.create(**payment_params)
if result.errors:
# Payment failed - extract user-friendly error messages