From 8d134f691bd1c7bf2207a41bcf5b4c0ac0d4edcd Mon Sep 17 00:00:00 2001 From: Edwin Eames Date: Tue, 9 Sep 2025 18:28:41 -0400 Subject: [PATCH] Updated charge close to working --- .gitignore | 4 + __pycache__/config.cpython-39.pyc | Bin 560 -> 0 bytes __pycache__/settings_dev.cpython-39.pyc | Bin 910 -> 0 bytes app/__pycache__/__init__.cpython-39.pyc | Bin 111 -> 0 bytes app/__pycache__/crud.cpython-39.pyc | Bin 2221 -> 0 bytes app/__pycache__/database.cpython-39.pyc | Bin 898 -> 0 bytes app/__pycache__/main.cpython-39.pyc | Bin 836 -> 0 bytes app/__pycache__/models.cpython-39.pyc | Bin 1716 -> 0 bytes app/__pycache__/schemas.cpython-39.pyc | Bin 2933 -> 0 bytes app/crud.py | 17 +-- .../__pycache__/__init__.cpython-39.pyc | Bin 119 -> 0 bytes .../__pycache__/payment.cpython-39.pyc | Bin 4177 -> 0 bytes app/routers/payment.py | 33 ++++-- .../payment_service.cpython-39.pyc | Bin 5426 -> 0 bytes app/services/payment_service.py | 99 +----------------- 15 files changed, 40 insertions(+), 113 deletions(-) create mode 100644 .gitignore delete mode 100644 __pycache__/config.cpython-39.pyc delete mode 100644 __pycache__/settings_dev.cpython-39.pyc delete mode 100644 app/__pycache__/__init__.cpython-39.pyc delete mode 100644 app/__pycache__/crud.cpython-39.pyc delete mode 100644 app/__pycache__/database.cpython-39.pyc delete mode 100644 app/__pycache__/main.cpython-39.pyc delete mode 100644 app/__pycache__/models.cpython-39.pyc delete mode 100644 app/__pycache__/schemas.cpython-39.pyc delete mode 100644 app/routers/__pycache__/__init__.cpython-39.pyc delete mode 100644 app/routers/__pycache__/payment.cpython-39.pyc delete mode 100644 app/services/__pycache__/payment_service.cpython-39.pyc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e58aeba --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +__pycache__/ +*.pyc +*.pyo +*.pyd diff --git a/__pycache__/config.cpython-39.pyc b/__pycache__/config.cpython-39.pyc deleted file mode 100644 index 3614ff2ad5ee30eed9e1044a4c3eb01c2832c7b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 560 zcmZ8e%}T>S5T4omwDb>r0V&?%!TJCqN}GdF8}S$SpoVU&(KH)2QBd@v9()H8^rkQ4 z#oJyz`3jz#jUv@q=7Vp(o!Ob$u-U8u+3VZ$(G>%DH)PT*B1`0Xn?QiT1UN)+jE_vP zCp<)93HuhgC2#{g=Ywv+fZMA<&mW>8KSs5oO5P>U?+7jq3aWMq_wc}O5aAL8J7H?p z)Jt&8u1pMfV8bX5DZNs${wXdgd!=GeDm#$Q*ibm<*9hkP&2?dy>dwzhx5)71S-$OmMoMlNo42xK%U6~%nBkuHr?sA{kd;YfH57t)w!KUYG zCsT1+@MazrMVyZE{Y*)r%;3EB8%yLcOnBp$i|9<(SH_uCg|C!U9@Dnzrp$W*ax4K4)Xr))rf~e|LJv_$|)y4!ztJb8@S5MU8$T(7UI}yWx#9o96%^X7B z1rb`7n!9qnx%0B#tjkgx@SS!`23hRP++g|arvH5UJS3NH5PI@nqj7b;cXhpgbxo6+ zuzWm;O?=;(+vAh{KH{ee5#eZh+fI{ccXf1X- zZ;!(ZP-(Sy4nRv@w$6<9#2(0ct&)fk&Yc;CFv&wW3(#Vk=0yn47tZvrB0z`&7eY|! zjZKqYC$v=C*7SjuY#SrX9+;{H$Chg9%8{BBZjtdODc=@UK2go2bPJ4;Y2Vr3@20yY zDap|nI&)(1)H)t2!`^{dUzSJR8Rj0Ql&v;`3%qT p?9IxtT)KYqS&nnYo&iqN8`2&=B_vios diff --git a/app/__pycache__/__init__.cpython-39.pyc b/app/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 78a8abf52847dd8e4818b8cb7b9adfb11dad2c30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 111 zcmYe~<>g`kf(sW{WPs?$AOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yUSM{ltO-FpiJU c%*!l^kJl@xyv1RYo1apelWGT2{TYZE0LN(+Jpcdz diff --git a/app/__pycache__/crud.cpython-39.pyc b/app/__pycache__/crud.cpython-39.pyc deleted file mode 100644 index 3cfbd432be4cf74ab3f95528a86ba322b22ea87c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2221 zcmbtV&2HO95a#kvvM9-l9mkEExM`cDWq+I^=b|W*yHUVB6uJ;JcV$zdelkm?P@&#( z?Hl-DUkdmk`XYNO(32mamlj3)%}TOZ*+35^wWC>bcKOZBH?wK0)o^hA`sXjF&!PRs zlj>E&}2X7*~+ZI-D%ez?Jw7czKeoyXV-jWab ziE7(*?_k}1xrcR|vVG*l`&Yo~#KP2$l-BuZcqMr5ns6|Zs?esUvr{!l^`&cEd2FI= zqRY`hQIgBd<+Y28bsys;hTeymIp&%`U91sBedb14qv&;+k1il)Tt zO#S6zXA}1FqEuwuT$-SllP)QQ#ic`=`1_;tEFF*S$Y>%D##7TgQDw3O#+zx2Owb)( z<`O5y1n?p+{tsr_z&>$E%mRy^kDNqc`EG*VC$``&e$g zv?yp7+B)i16}9F7EYb335945tG%6__>NG1sB&zd{p)S*MqRnnPDNmCj@>DTl4h67U zUYz9?hV|zgD5cXEGjIpP!+hR8h{n1Myf|jpMsrCC3?t$6R<+uZOh|o@Yhqkl>t<#swSKZ z%_tnDN*6h6Wd%W+3E;TrD0 z=m5`_?s5KaxW{eBy7%9`?`9>gT;RRu&EpwsYrywz0d5N`m!H5~bBrzMzv&BTi?XzY zom0xjh3Rvn?ym8Fhqt$-R?e^Ze~p;fL;93gFGz09t>wzd5`Qgf`;)O;V|LOTQIe(OazctDrSCyF zVxO7qhJtTjgsx>a^EGxY?}*J}99{TzOk2M$(t?l2>A{Ew#D|VqoDAI7jF%5fdj=T~ zXBcr~C+?SKvr_OcQgjlo9?LPCH=KIKC@qP2FL63g3iTBigXTv~(Q!Lo N$Ghw8ZFd@-@E?=R*h>Ha diff --git a/app/__pycache__/database.cpython-39.pyc b/app/__pycache__/database.cpython-39.pyc deleted file mode 100644 index 5caf837785addf7446b18b0cd18440bb0d33787a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 898 zcmYjPOLNmO5SDC5ahyk+wBr+$fj8K?@alsJ$?RcW=v6&b1;tzjf;mxxB9dRFH|L}v|b;&s=j5t|lSoGFzQ zwC3=soSKOZMoG$JSM%av0B+unG*3Yl=n{QJUpg1)7-4jRF3>f;0hC4yv<-WJ-tk`7 zv(>?@C0mJQRyOJJ(J!Ri@Tc4LEtcn{EDGGr&n+2?V#r62T|$=`VS+szdU_4;UiTr5 zpm!$YiBRX-1CBoWPi%_M#pcpzHQXOWTT2d^RyuHGdx@N_MOT2gWHxC{oYCINbD6}j zrYwCq+W?uZlC}@_2ZwL^y}|Hk(ChE*yz9~W9d&R*SMCh>eBA3V1-#mI?%Uh6dFOMm z-#@heR7*?d#k5@h>ikOBVAt(0RH9&RST>qpC?;h&m~x^^s^g-=XDZ`UDW1D6nkS$d Yc>egr4`8gp;<+WY&}(7h5!~?q0bF_RdH?_b diff --git a/app/__pycache__/main.cpython-39.pyc b/app/__pycache__/main.cpython-39.pyc deleted file mode 100644 index 013728c148bdac9e028bbb0e315c8b9d8f6b7bd8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 836 zcmYjP&2H2%5Vn(SlKpMAE%eA9xGabE1u8^Y3BiFpOU&B~4=Csk>0s9g6Q z;8xy;Q?8u)3gyB$p+AmhGBdWv-}l*aIP5VR-+o^&*B)bkT=IBCl)NGbK`?ubqkcT}h&5mC$_RI%=gZWBkUr~9JM8TPN37+_~LT#Z&6=tI1w zj>xH+V6qxx7YD0N=t6J78|$yBGtF#awAzLN45>a^)5)0pcmf+gIV3Rt&aSw43Y*7l zx^+Wn*_7AO8(CHdNAGTUn}?V$vK(n9)CN$MZcQOCH0BkBquGa#$L})$h3C?`WqoBN z%u|z}W(!J#lPrf%HGeS;#84__&gaHv)Up)gHcc%8HOr(b?^bB6mIm(AB}zbBUIu%z z$ZY6DLYb diff --git a/app/__pycache__/models.cpython-39.pyc b/app/__pycache__/models.cpython-39.pyc deleted file mode 100644 index fde198b85965071b0a8895e8437e0043efdee745..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1716 zcmah}J9FGN5GHwi-BYK>NpfD3Dl^w4e;||5*qLP9sIiI+8Vp3hcT@n70zoV1Rw<(& z;)CsLwKWA&+Ac^7x0IB{me8!UGhyNkW$_km5PqX3@d?Ys5+EC~KaqyNNUoWW{- z0l@8SAQm-3)lj5AoxUm!$4LLQKahh!jPkwCxD@!f!=U}ZeM4R1q|dp+^` zu&0l_o_hZnbci4m@7v~0L7#zd&-*eTH{ZqW_u>wAzC-WZ);scg?sFEq{bTRj_HokF zPeFeI=X}P8Fu9S-pS6vxlrUsi?6l_MP2|S4DHSst`m5Nuq|{vecK-y1aQ^|tA0Wzq zV0PvEK@glTKX*B$nkhl48&Rq%-b&OblwP+??sle>T6QVL)-(|mF_0d(sN@ErLT0Qe zs#aU7TXhLN9X#|zC2PP7Cy>L=_p&q(&S~eg)r}^z&TK4vax&@c*JW)|JnG+N3MOSQ zPbgN(-ubMBDKT3XWYN{C*OeBZwz`IKQoE`9$Fkazd6&pIH==3CsHjxU^oEw4?035o zj8{Y5z#N0$iw_6ivAXsPK7)|WxAn##OLJJwH>iYh zGz%xYUk>m7+FFy)=X^p49Niff`V++e5F+C7U9=;_R!2f0@R1DoMj}i+jUt}h#RN%! z{u#c(kNHT52i+55=SNb&)xa}|K~i8Hj7MS|iN)38>e%m{@EorQH@+}TH>|K_rOCuT z8qI|n!=HgmAlI#w2+-xgrL8WnTVbZKWf1rV=LbO<7cW^W?fLT5?4$nx#UY9#6dkI~ z0!_R@$YE^+0BBvA^0lB$A;ihFSTnQg%z3XRj~6zy3pwPZ<_GdMs9940X&gqed67`$K;#DcKtO`l3v*=|lxRJRXz7G&@=G+^Y$O7_q&Gi7m@X!19FH` z{SM#;H&Y`sL(`;hE44B^v@<7kG`CYXb3@lOzBRbR-QNuE3iGKQdf*=KfOmuk-U0V{ z7rd*v58mSec%a*N!TWpwKG60a_zoX}54Al2AMr8xSOgfa&v$9>xF7a)->$X|VB67sd&J>UpoR}6%PSVs z;>oL-nv_zod3{>Q4oEEHB!zf~TUet^{siH{wWVDmKmXv=oAm|h95DWpzu4;K<$Qx8a z@b}~%D@$Ff_*7)9x?7%04;B}t8UcFd2#>FEWcE#M-5%$==(38lK$N+Oc)EBa&iYO9 zB~I~m5fe|1*J5&nU8zOmOrWqFmI`de$fWKNk5iCM0Jn%23)-Nj2LS z_yE=o3#4?RG@&=rggc=tJkh}shWIV&aqJ;h9qvP{{HIpva|iBpRj}rcvJx(#y@v8C z9FTc6lXr*(@w}>wOh}y1D~qG^dWfRaez`bODsEu{`^ox#-90MuO;iSD=UNutegCCk3%!`9x&_6WS` zuVp(NxAs7{-)-%E%_psWp!r_QcQn7&wjXMKy|s@tztQrs<~PCj_4;>-Blr{5KU!o? zb7$g`kg8vs+WPs?$AOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yUSU{ltO-FfPh3 kElDjZ){l?R%*!l^kJl@xyv1RYo1apelWGUj^%;m60I$s$w*UYD diff --git a/app/routers/__pycache__/payment.cpython-39.pyc b/app/routers/__pycache__/payment.cpython-39.pyc deleted file mode 100644 index 1886df49f6a09d2be33603e136fd9de9bd321ea7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4177 zcmaJ^UvC@75x>1V9*?9%Nt9$;wkw|_#|_g&bkim+gd(*f3AWKd7G$|W4+Yp0cO{V~ zkM!QsjTo{hBERabZ%qN`(VrsUW1kB2$zPxkNrB`yd!$Ioc2C;5z1!Kj*_q$`VKhCR zw{ZP?`MV>zXj%WEhsn#s!(EI-G0Wl>XH6@lyWM0hJG5I)=(OC>W%SNzW?Ek8nYr7{ zw*1g<<-(kKX3cz<=Naxb3$3Yesx=)>w~Ar0H51NYJ;Srj+16Y*$1G6_=Y`GvL&kHb zEL^x}@jNd)w|GJ18;d7ScnNQ&_%z;358qrCIWfOv313{o>3N5bj>xOp)ytg=g^L0Huz6{PAJTRQ^a`wn7-+V>>*e*Ldx4!dW zx7}4j>g=ZIh?pmO`u^VD&eoST(NXnwTxL4^NF)hOZJpWccA7%_56xQCd}TvW+0|}M zcDeRiZ7!OL&L*`Z(TWo7^GHSeQ6eB^rV|~vM69Zbkk9Hh5l-#NC{CgpeI)^dtD?iC zMw(4tz(|Ug1x$n$GH!)7XQ9LG(B%$J+w&2gld-osiJ_xtM?8f@e-s9b^@fp(DW!gjvT*XKz7)fEMOz+@gUy7sy zj|lBap}I1zkr_u99guX`z)1QaeM{a|pq!o9@^0U1u!ha;Czvaz;SQKtbFlV_%3#%N zWKURZb9X?)i9Z6DKVbB1I5Xht zJCRI85~w2)jI<99WV>bFtasH>Th@DGbz7)lh`v>`@4daFdJ^EDb|!#Ga3q?rce;6B z9JHnQAgHUKCqWb(w%a_Y9Yyh>2vj?GB1ETbq-ei|0ErGo650=+=y^59_3qG?+j_1l zMMD^{V-_XtxcB~cd#tV$HBo;ic>3ufwt~Y*iN8k2tG(+xY4ikK)SC4eeEY{|tL41T z9z{u{l$6WxNtlNfx=po#a5PAi6g=8VuzrKqvqr@Sobt0J1CX*Suj8h@#Ke!j9KmYU zSg7j6X{vRuXD=RO0$&6zeYx5pZ&XPD?LTt}78AmlmAT41hGBbvU7k%bA9DckHr9HD z3T-t0svs#8N82fGMH4BjQ0peD-4c?tDNJamZN6V4Y>qA;6B-7qpJSq|7p%{|1+Ekj zbi)4Z4BSCx;1N>$tdUVbC+L@GpbAi4xmz}cjy%YLeW zQH7M!bM$2ch>=Ie+8OQ7ADa^YMPw8wl!w+ILu~R6h-K$l5dawf+24CPm)WDgA0+Yi z7AuH8c_=DhO+a99&gEnS>OPFi|A&b}V(MG}wEktEFh)#uUahAmSQ`pyTLgN#017DmG>&K;xZe20p%@?fa8l zeg6yVk>y%y_V~Zd8lbc3t%1u|bA2Shku09$Rrd#E2D!iG z;(U6)W8J|UK(w&kyR*6V+2ea_!R{!%q$Wh(dD<0;3XtJ~32Uwey`|xfy>S)`$eU|{ zc6q&~fcoiF$Pn-H1K9Z@un5n+mA8nZ^qFFAEs%GJ^ZJl;!yu6d6A=WJZVp$^nv$R% zQzix$4E`a7YE-W@{$5S&N3|zwL3u%EI4Ha+O-t zL9rK=vYqB13i=v#ccUwd2@MlkJD4ccdemYI^`4#D1G{gdj-oB&4no5Inkn}MD!vIN z?_4NZlx1ljhL4Qu@r=o+-gcRpZ1?IPaA$92eVAAy>JTR(5yWjmZa3yHZCyw!R<(xu zpgk^BRBx7tnUqpz>PBN`0%bX8l3sZA@Ir0dKQ<+clCjxFolXjs<)LlNx~WWjGFO`H z8!mS{h>~+jv(~F zVMeu0PKE1#kelG>tyCtyR~Z$e%2%Tq4nF_@OnrC_01hOOQ49bG=pz7}xqn%q^&7dr zZ&NQzE;ZtQPv8F-9S4SpLjlJ7`E@SYtZ zwfF@?Ui&{n{tf{NwGEbCBvUfEg?ah5`7t9@y(M(^AOh$*bxH9d$u8!zVKI5yjGFY@ z=Xe!yFEd!t9y)+}d?=~YmJ~qR6>+zv)8Z?sTA9) 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)}") diff --git a/app/services/__pycache__/payment_service.cpython-39.pyc b/app/services/__pycache__/payment_service.cpython-39.pyc deleted file mode 100644 index 466d3e2be8a6d19311a1de5b90b1eda56900d79a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5426 zcmeHLO>7&-72erhE|*J+q)1A(C0pLaj%=m=OY_rIOlH)S|^t_0}|uYjRwoQ!uW>xFN@7T7mHlCHIx3>NjAO(p(~m1wj>4@s zfHU9b%#GLs?)o7xJAuE7^MU6v{*4N1Ad?T#jzSIJ7}3U{Lr%Dci&xS-nI?vZZRI&uD@+>x!!=; zQDBD=@Aw;+>`m9F9`tPQNzb!`hg}AHu=_mdGwy9)k?S;t99%$ovN|!)NyTS8?gp-2IgjA z4%Uuy&IzgkJsImjPepTaZikGF*w~wYst^U*(;%6r%E*j?4#=*`uf_T9nQ>p*t|O=0@`(t-DRGQO$&`uC#(NEc{9%C5`4 zmGt96_f?R67u)VRU!}#71^sityN#{nl}5$b`b?oyaS`m%M({fAlE-`gwaiMTRO`1{ zEn1cu>R1D`O1@4jBlDMv|CX*q=Xc5WKZr6a5oI_>tI=z5X@}sRQQ~8Gu}7s(O1_n} z*OY4tXip#7yUMR0**S0~J70vI<4veZ>r`$}tgDYbyQ@An{4z)_(gxlWI+HnC$4Q8(g+;)4xz>k*g)~q{-Hdoz#G~n5nUKpIMI~_Wl zUQLuZ3;Tf|vSnN3ZgC#);oJ&n2D~$5SDGxcQ#m;&@;!K@yTLey0im}8%90l^{|o<- zANfqr@3d`( zRy@1LacYM}+rhx2uvBC}WOm=>A*1lLOUFJf(M)%fF|_buvO%!70y`NCV6Yi30AuVf zdz}Y8`@mB^i}o*M=Q(S$&K7L$h#7p>aU<14;^p3wCh^e+b3nw`|j?q}m^%w`X zAK^0~RCU@e2JHvieI`mPch{WTcivxXI%_wD?z=rEDi7|hH1DshK3KccbUwKCu_$K( z)CX)^lpz7oPPFQBDiSZi->2@^F| z;rvB04W@Ec>)d~hN ztru>}jAKuS2yU74|IA_*z?vC$mKRBrEcm=NQaQ^O5#qn#oY;&v_~$(*De@C&=t(s6&1{N0 zlGz{yN_QUhF+T;GOBeYZt}+iq)H5P1oAvk^lvzM>7Kx4I6(p}BIfn!>2Y(I8B9aS8 zE+Sb%B4g|ium|u>;g^xfkb4z-*O0t{1S7D_4E#;(y@lj$B<~=>48VVcfFfc02V=cbu^I&WKbR%DXusTxZ)3hD=djCD$$wPN^u29NL*ok zVo6*9ZHg4?BXlH6^*?GT9>$@F*y;HTQQuD zb2iQau9#`I=KH)8a13V8f`=p)*3yYdEj$i^^M^y=SnMT3;aKfuL*X%cFBA%o(er~8 zgpAAo36RNz!q;CQ6t)xmbvSH(3o?-LGgVr$B@lRiNIZygSjovyCr)78aUc>qnX(e# zUJL5mb(z)HD1XsVI0@J<9~760vH<4qp=C1G{uF!Hk^BtF4J0c_evSk`mhhWMjs(($ z)EmwupwjHt{t7DLM?e&)Ka(oez#3Louisv^*3zogl2xnqysC8#)?S(wc?4{LwOgf$ zA>d_sLaq5M>&p1coBXmCCg?-qIao#*$@esF;Gh6NOT3?EDiih49zT6*Q#s(2b)8;%m4rY diff --git a/app/services/payment_service.py b/app/services/payment_service.py index b67aa80..3779325 100644 --- a/app/services/payment_service.py +++ b/app/services/payment_service.py @@ -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