Updated charge close to working

This commit is contained in:
2025-09-09 18:28:41 -04:00
parent 8c37b6aeab
commit 8d134f691b
15 changed files with 40 additions and 113 deletions
+4
View File
@@ -0,0 +1,4 @@
__pycache__/
*.pyc
*.pyo
*.pyd
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+4 -3
View File
@@ -12,8 +12,8 @@ def get_customers(db: Session, skip: int = 0, limit: int = 100):
def create_transaction(db: Session, transaction: schemas.TransactionBase, customer_id: int, status: int, auth_net_transaction_id: str = None):
db_transaction = models.Transaction(
preauthorize_amount=transaction.preauthorize_amount,
charge_amount=transaction.charge_amount,
preauthorize_amount=transaction.preauthorize_amount if status == 0 else 0, # Only save pre-auth amount if approved
charge_amount=transaction.charge_amount if transaction.transaction_type != 0 or status == 0 else 0, # Only save charge amount for charges if approved
transaction_type=transaction.transaction_type,
customer_id=customer_id,
status=status,
@@ -50,7 +50,8 @@ def update_transaction_for_capture(db: Session, auth_net_transaction_id: str, ch
if not transaction:
return None
transaction.charge_amount = charge_amount
# Set charge_amount only if approved (status == 0), otherwise set to 0
transaction.charge_amount = charge_amount if status == 0 else 0
transaction.transaction_type = 3 # capture
transaction.status = status
if rejection_reason:
Binary file not shown.
Binary file not shown.
+24 -9
View File
@@ -34,19 +34,39 @@ def _parse_authnet_response(response: Optional[AuthNetResponse]) -> Tuple[Transa
Parses the response from the Authorize.Net service.
(This is the same helper from before, it's a good change to keep)
"""
if response and hasattr(response, 'messages') and response.messages.resultCode == "Ok":
if response is not None and hasattr(response, 'messages') and response.messages.resultCode == "Ok":
status = TransactionStatus.APPROVED
auth_net_transaction_id = str(response.transactionResponse.transId) if hasattr(response, 'transactionResponse') else None
rejection_reason = None
else:
status = TransactionStatus.DECLINED
auth_net_transaction_id = None
if hasattr(response, '_rejection_reason'):
# Improved rejection reason extraction
rejection_reason = "Payment declined by gateway."
if hasattr(response, '_rejection_reason') and response._rejection_reason:
rejection_reason = str(response._rejection_reason)
elif response is not None:
# Check transaction response for errors
if hasattr(response, 'transactionResponse') and response.transactionResponse:
tr = response.transactionResponse
if hasattr(tr, 'errors') and tr.errors:
for error in tr.errors:
if hasattr(error, 'errorCode') and hasattr(error, 'errorText'):
error_code = error.errorCode.text if error.errorCode else "Unknown"
error_text = error.errorText.text if error.errorText else "No error details"
rejection_reason = f"{error_code}: {error_text}"
break
elif hasattr(tr, 'messages') and tr.messages:
if len(tr.messages) > 0:
msg = tr.messages[0]
if hasattr(msg, 'code') and hasattr(msg, 'description'):
code = msg.code.text if msg.code else "Unknown"
desc = msg.description.text if msg.description else "No description"
rejection_reason = f"{code}: {desc}"
elif response is None:
rejection_reason = "No response received from payment gateway."
else:
rejection_reason = "Payment declined by gateway."
return status, auth_net_transaction_id, rejection_reason
@@ -74,9 +94,6 @@ def authorize_card(customer_id: int, transaction: schemas.TransactionAuthorize,
@router.post("/charge/{customer_id}", response_model=schemas.Transaction)
def charge_card(customer_id: int, transaction: schemas.TransactionCreate, db: Session = Depends(database.get_db)):
# Add debug logging
print(f"DEBUG: Received charge request for customer_id: {customer_id}")
print(f"DEBUG: Transaction data: {transaction.dict() if hasattr(transaction, 'dict') else transaction}")
try:
auth_net_response = payment_service.charge_credit_card(transaction)
@@ -90,7 +107,6 @@ def charge_card(customer_id: int, transaction: schemas.TransactionCreate, db: Se
card_id=transaction.card_id,
rejection_reason=rejection_reason
)
print(f"DEBUG: Transaction data to create: {transaction_data.dict()}")
result = crud.create_transaction(
db=db,
@@ -99,7 +115,6 @@ def charge_card(customer_id: int, transaction: schemas.TransactionCreate, db: Se
status=status,
auth_net_transaction_id=auth_net_transaction_id
)
print(f"DEBUG: Created transaction: {result.dict()}")
return result
except Exception as e:
print(f"DEBUG: Exception in charge_card: {str(e)}")
+3 -96
View File
@@ -55,46 +55,15 @@ def charge_credit_card(transaction: schemas.TransactionCreate):
response = controller.getresponse()
# Extract rejection reason if payment failed
rejection_reason = None
# Log response status if payment failed
if response is not None and response.messages is not None:
logger.info(f"Charge response: {response.messages.resultCode}")
# If payment was declined (resultCode is "Error"), extract error details
if response.messages.resultCode == "Error":
rejection_reason = "Authorize.Net Charge Error"
if hasattr(response.messages, 'message'):
try:
if len(response.messages.message) > 0:
for msg in response.messages.message:
if hasattr(msg, 'code') and hasattr(msg, 'text'):
# Convert lxml StringElement objects to Python strings
code_str = msg.code.text if msg.code else "Unknown"
text_str = msg.text.text if msg.text else "No details available"
rejection_reason = f"{code_str}: {text_str}"
break # Use the first error message
elif hasattr(msg, 'text'):
# Convert lxml StringElement to Python string
text_str = msg.text.text if msg.text else "No details available"
rejection_reason = f"Error: {text_str}"
break
else:
rejection_reason = "Charge declined - no specific error details available"
except Exception as e:
rejection_reason = f"Charge declined - error details could not be parsed: {str(e)}"
else:
rejection_reason = "Charge declined - no error message available"
if hasattr(response.messages, 'message') and len(response.messages.message) > 0:
for msg in response.messages.message:
logger.info(f"Message: {msg.text.text if msg.text else 'No message text'}")
else:
logger.error("No response from Authorize.net")
rejection_reason = "No response received from Authorize.Net"
# Attach rejection reason to response for the router to use
if response is not None:
response._rejection_reason = rejection_reason
return response
@@ -128,46 +97,15 @@ def authorize_credit_card(transaction: schemas.TransactionAuthorize):
response = controller.getresponse()
# Extract rejection reason if payment failed
rejection_reason = None
# Log response status
if response is not None and response.messages is not None:
logger.info(f"Preauthorization response: {response.messages.resultCode}")
# If payment was declined (resultCode is "Error"), extract error details
if response.messages.resultCode == "Error":
rejection_reason = "Authorize.Net Error"
if hasattr(response.messages, 'message'):
try:
if len(response.messages.message) > 0:
for msg in response.messages.message:
if hasattr(msg, 'code') and hasattr(msg, 'text'):
# Convert lxml StringElement objects to Python strings
code_str = msg.code.text if msg.code else "Unknown"
text_str = msg.text.text if msg.text else "No details available"
rejection_reason = f"{code_str}: {text_str}"
break # Use the first error message
elif hasattr(msg, 'text'):
# Convert lxml StringElement to Python string
text_str = msg.text.text if msg.text else "No details available"
rejection_reason = f"Error: {text_str}"
break
else:
rejection_reason = "Payment declined - no specific error details available"
except Exception as e:
rejection_reason = f"Payment declined - error details could not be parsed: {str(e)}"
else:
rejection_reason = "Payment declined - no error message available"
if hasattr(response.messages, 'message') and len(response.messages.message) > 0:
for msg in response.messages.message:
logger.info(f"Message: {msg.text.text if msg.text else 'No message text'}")
else:
logger.error("No response from Authorize.net for preauthorization")
rejection_reason = "No response received from Authorize.Net"
# Attach rejection reason to response for the router to use
if response is not None:
response._rejection_reason = rejection_reason
return response
@@ -191,45 +129,14 @@ def capture_authorized_transaction(transaction: schemas.TransactionCapture):
response = controller.getresponse()
# Extract rejection reason if capture failed
rejection_reason = None
# Log response status
if response is not None and response.messages is not None:
logger.info(f"Capture response: {response.messages.resultCode}")
# If capture was declined (resultCode is "Error"), extract error details
if response.messages.resultCode == "Error":
rejection_reason = "Authorize.Net Capture Error"
if hasattr(response.messages, 'message'):
try:
if len(response.messages.message) > 0:
for msg in response.messages.message:
if hasattr(msg, 'code') and hasattr(msg, 'text'):
# Convert lxml StringElement objects to Python strings
code_str = msg.code.text if msg.code else "Unknown"
text_str = msg.text.text if msg.text else "No details available"
rejection_reason = f"{code_str}: {text_str}"
break # Use the first error message
elif hasattr(msg, 'text'):
# Convert lxml StringElement to Python string
text_str = msg.text.text if msg.text else "No details available"
rejection_reason = f"Error: {text_str}"
break
else:
rejection_reason = "Capture declined - no specific error details available"
except Exception as e:
rejection_reason = f"Capture declined - error details could not be parsed: {str(e)}"
else:
rejection_reason = "Capture declined - no error message available"
if hasattr(response.messages, 'message') and len(response.messages.message) > 0:
for msg in response.messages.message:
logger.info(f"Message: {msg.text.text if msg.text else 'No message text'}")
else:
logger.error("No response from Authorize.net for capture")
rejection_reason = "No response received from Authorize.Net for capture"
# Attach rejection reason to response for the router to use
if response is not None:
response._rejection_reason = rejection_reason
return response