From 1cbe37d4a3df12823bd483bf69767d1e76846d9f Mon Sep 17 00:00:00 2001 From: yumoqing Date: Fri, 12 Dec 2025 13:54:26 +0800 Subject: [PATCH] bugfix --- README.md | 13 +++++ json/payment_log.json | 16 +++++ models/payment_log.xlsx | Bin 0 -> 18705 bytes pyproject.toml | 4 ++ setup.cfg | 15 +++++ unipay/{.notify.py.swp => .init.py.swp} | Bin 12288 -> 16384 bytes unipay/init.py | 23 +++++++- unipay/notify.py | 10 ++++ unipay/paylog.py | 48 +++++++++++++++ wwwroot/menu.ui | 15 +++++ wwwroot/recharge.dspy | 9 +++ wwwroot/recharge.ui | 74 ++++++++++++++++++++++++ 12 files changed, 224 insertions(+), 3 deletions(-) create mode 100644 README.md create mode 100644 json/payment_log.json create mode 100644 models/payment_log.xlsx create mode 100644 pyproject.toml create mode 100644 setup.cfg rename unipay/{.notify.py.swp => .init.py.swp} (68%) create mode 100644 unipay/paylog.py create mode 100644 wwwroot/menu.ui create mode 100644 wwwroot/recharge.dspy create mode 100644 wwwroot/recharge.ui diff --git a/README.md b/README.md new file mode 100644 index 0000000..302822e --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# 统一支付 + +支持微信,支付宝,paypal支持 + +## 支付重要信息 +支付重要信息都通过环境变量设置 + +### 微信支付 + +### 支付宝 + +### paypal + diff --git a/json/payment_log.json b/json/payment_log.json new file mode 100644 index 0000000..6b94237 --- /dev/null +++ b/json/payment_log.json @@ -0,0 +1,16 @@ +{ + "tblname": "payment_log", + "title": "充值记录", + "params": { + "sortby": "init_timestamp desc", + "browserfields": { + "exclouded": ["id"], + "logined_userorgid":"customerid", + "alters": { + } + }, + "editexclouded": [ + "id" + ] + } +} diff --git a/models/payment_log.xlsx b/models/payment_log.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..eb4167812368b6d32b038005ee89615ce3f50c29 GIT binary patch literal 18705 zcmeIab97zn+CH4dwr$&LY&J<_+eTx%v2EK%W7|%eMvc)Jzt!%2-n~!HK4W};eq+4v z92sk^Cv)D{#B=MpF+WIyfT99{13>}-0TBTyZb{!Jy#oTO1q@MuAb~Z7ZEc*4ZJcyJ zy4e{!YSX(~TM_1g0#oJy0RxWzzwLkV6Btiglj~!I4L*-`4WVu}n_!O;I(F&VL5}f- z7{<1ZTqIXGi99{EXAyur&9R6-lr3k!eDiTZYY&*IqmBmyWt}w1OLh?jX8*LhY)-zp zh0nu5EU2hbKC3?55B(t`xR@fKIT1pJbJc(xn%IYiY#;0+w9-M()o6c^6cT@M=?!&u zDb=udvj>@@DHN@9$s%H3&wH8qj)HIcBh^c!hK8aJ&6}#4#zJnoXcICl${)`H32&f&7rjxGcgS}j1U6mWzv1of z@-x52+DlH@{yhGfIu8S79tt%J644t$B)Sai7M`8 zZ@T&(twDmQ9SQ&^zP*6}efT$VM$zdq1_p@p7C>5I0OG9cU~J{cK>zde|HSxzvF!fs z)+^#M@y2xVkiiFy>0W`_x3{&+9olW zq(P|90?9=d&Lqogmk(!IqK5@lMy9Ng?7($i_8#>fesbJxfn|7%#AuQJR0qN0leHhG zr6VSQ(&Q`*J&sBm;0TP|;@~c5B^_+uENTpju<)pRPI8Igb~$6N-&TvN){wJg9ySA9 zRB2mC=m`bQaqRqM_vBe3p%N~SVav&|09TU>Y=;r$2=m}nchzGB(r4wxsIHeX4iOI? zeEFKn%P4b}K2FX!KKLY)z%*9LN^PF&?wo`S!$8Ak`DC`}CtiQs!%NGJ#o>~$c+k*S z`r3F<55&*~;EVrM$WC0bjgBBdK$igj3IV`20PgxbUlpim+U9d&dg+?Kfn4#h?I(dI zMx`M)B(5qfj5P4bCxXb;LZ>j1V?^$EpPM2>%8KP%QAk-?5fF5ZT^?w8ucEfr8r1FQ z!6LQR#Pp1c6m)pP%`CZDMa3%6XcVzxkipC(Ega4*Z24$c1$k;hUYY<2s)tZ2l|eIB z#YdnubRnYA=o?cR38KO7(Nxilm}!_sloAg$89%h-bcpZ-3uN^XB}r%1NRZ0*NHvng z(iTIHSF`9W;AzHY2&;a0So~;091cy1&U;|77Dt>f;lH+|DA6|Da|(AE5gAyGz;7UE z_{rA4FkTgnH#QGl+WFnQtLaVHTYqn02TadCEBFCZt6Ck}64yy(+$%)ol?VNsfLH~; z2?=4P3e7vv^8hOy+w{mP`ea^Hd7dNehBCf6AyaB`F*!>%=~e^tP%%bSOP7?37@~BG z)eBq|sM-^zUe(SF0#aDQyQNlxx`ObHP({D_+oHG93XQXL8Q;)I@!QUwxSo}FP<}kq zv!pqnAN|V4&5ZDgpBus7E}HJ6%IR#RbY|%2MMkf%5pKlg2VVJ6B~b8yVCBwX*WMFA z0G-4O7S}A8ybfZGSib*Eu!ca%yaTz}{;$<$5 zMTqmI`&TP%g1G9C!Tr?aQnip_k}NnK>vpDEa{7p+(<>HvWpv`9cTerDKA1ieUrd#GLDPMF_XiSeq_DmtqFGR?@D~ z_#Rgno+{maw{%a&YA#aJs?EqCb*}V0O$U`{GgO3wg<%nUQB}WYCSnXhrG?4n6H6I3 zC0rYI!>&N{rFT=d)*1P&gX^bn0Yeh)bz3hy+ZdtNlaruB@}|JHd|OlJQ~jG0`wUZ; zsoTdxL&vt)E8QFD&tpLP!$kA7^zkiE%?>{Z0MhrL@+tft#U2qLp8^2+#QaM>9nFl5 zog5i{eX;&D02%RXQR$2Tt4Z?%FXlYVZ~DYvNQDT(*|w}~t*_BASZ@Hrf+ys(?0nOY z^+c*QOa+(;|AOO+lQD!1PJJUbgW>P!~*nMv%u{bD3_*i3)lqqM2O1OHm8i{W_H z+H0r*amB6x@c9V}qbIK3J7j(amYbLJF6LmhBzWhoK@7O#&3#?#8hv@ zIB1Ke`xM_N;22 zd@FP0fMC|Kz+A})NFtdyi$tSn7!uK$_#xN64RxBVK;@7>nSJx^`z`Jf_E%uU*-!{b zb0bg*D^h!^Txp3gX~ElGqWn^=1h$-0hrOa-XXDaibJ z*pt|^PAX)Uv%IEi*Fd=wAc5@B!KF2_Al5=@t4=rG_}$?@4auLk$vQ3z-OGqLa9JM6 z<%=e=&bra!K;#-^MnO<=-D_0h>Y+*0e&_M|O^qe6lGo-taX)>1F$mX_$}K6UF#4hj zA*+lbTv)ZBQtZAC?!=t;C*oqVy)L*PZ}=k{`oW)6_ZjPLG_H|qq8fQTbEc9~tsno< z$_-JJA4-D)0g0mgS1DrqQ;NdZeo7IH7euayINyM*PzD*!lGC}=(UD5*P;IDDYn+3c z)Rx!KBsmUbLXDoAQP^9$PsPmhP6^sdfb(nvSELvb*)+7$h)et&!Pc0bP}p@xWeYRi zw;L>6FE!6+Mt;n8XEm{ui7L$pNh=w5#$`(H=O+#+l2cysE@KCD9JR& zv)C(ZJu7R@3=zhR>MY8;yw zT~10{^mb^VBgwndMQxBfdBmJnS(i{Z;AxhVjSPQgA@}I5g;RgZk;Nz<3JC!%vV|3B zxZDSwAcUN>|C*6=dGbl!NIlvZ!A&ODVJH#1OyYRS&7`+~n0^xI zxt9uyry2E0a0L%Q-c^4vM>RH2`Eg_$WOeZdSa$x&n4ZZSa==WOBD%))3^lhHY-8l% z3__4lsupVg)wWN$2|=l?EE#e|v%92G*ZST3URLsJ=Dgl7PD9S;k2bHH-jjR9OVjeZ zRo?e1{MvU6UY|7X93O6Y_jutC%yC_O#5WnlvuvX(p09@YFC}!eqha@emo)DO=-Px! ze=Mz8QPbUdd=GK(TT_dvmC~mjRV!pnGOAF-9Aj3Yim3egiw42rI_qxBsE|=5OQWAU zsP>AS+7uHad2?fHPJ8~H{8f$pTBXc zCzv9#h0}LSxpdMEF{8WKDLzI7tY!#IK&|5TwJ4;clyC_Gc5qlY0<%$=Il}IWSw^|VWRx?C6D9ryjSzda4BUiA#;UZv%ptW4l zui?*g^V>{LzaqVW{m(rA|3m?KKO74Il)p99e^o&2e<+|48-ThDK2LmvPdeWQHB%-Q zTJSG(C@-To-IWOqN}gv=FYEFc$^|8*FG(_#AH3vXxjdhFQK6{=KPY75l5K|~(+i|4 zQ2%!Ga$4#r9)_@vs-+IXwc%HMw|iVZGuT#G4FoLcf5}xTRKhaYQ6k{D)yRgaMO8V+ zyIroysLQi0S}#enC>^I+)XM54KfF!`tC^(uWj;I+9OV`fA{=6TOSSG6A`LxxoAuL} z@&=O1QfP`aSznc(VxB0wCg$qKIbVnVppBayQxzxs7eZ@bX`%o2f(3O7*{P70WZmoa$snv??bA~sCPi253c1S_| z&92?7_o3@Y3EmwwH2V+xH$)RfN4|BJB}mgDfsy>RlJmRktHxR>`Wc`|_^6>Ju)X#g zeV_@WM~3bJX|EO~Gh(Ecsl~T`Z}VpN1F>9pjJ4mD&~tmo{67`?##MjhWW?gvspJ%oA2Cu#uE3wDAo>mysQn!+9yqPa}%US z@N5+A9k^>xU31GHxxH=h4k7lLxQ#c9X3Ke{%#wZ9EvqtAyScLr*S646vY>za0C@}B z4RwZ@1$72v#VQRo-{$vGG^YoYxP{FR5?_YUU!4EL0k~o#sKrF45M!DEs3uA%A-Fus z_YHwE;uv#L$W;|c6^)hFPi5ge)-<3@u8%YxODf9Cd5L%BRM|Cs+aoS^*2;8EnSev{ z(CXf|G?n!(o&+Y{uggI1BXcFPgI z^)n8n`4MZ^x=hH4U_6<7Yqp#2CRWl}cGyuat2=`y*j^huxlZ{>@{3Uk;hEL-hNz76G11BkZ<{@}nG#&A8b&Ob&wPE1ecvyQSh;+!N7=#l<^qw; z3h0#U=?;&h4@Ufv2}G2jt#K$1aa{n`-h*6*VHK3v3L0{Wh5LN?hEcG!8tabBPsF=>Ni#N!;M@v zudVN;n~a2_3fAt=doLomI7?E#z)*W_CEfQ8OEJ`}@aSJ7p+}GHc_^db$j>%IY2ddT z#TnJMTlgHgD^ri#MTB#fKtF~Z=(Zsbcg}VZYAg}VKXk2nxx2;W;i|m0%A3tV)*8bib ztg#a0HC2>i)`HYPJ|g@RoU}{^w+F7T65mvu+oM3(`jg(oc4=~UP)e#?s0*UW+yJet z$uqx{jBv3C59Nb4eZ5X-6Nbs>CoKcYOzDPB=7BG^`Gy-u&wu&bo=G!Ny@ZIOJ_9!p z7McPZ^W-pl!Vyd>#T${Fj}RTOgTDr(g7Tq_K7JX>xFPg@4ObEgHufIm$OM~~jo zNN|RykZzXrgp5I1h&DDN*C|Q+cyfH=tPKN5SBqK#O|?4ou=0=`{GmSyI?ff{ zCNwd>#*$#C9YgKxi_h>D>A}l3;LhayJO!MS4JoPBv3n&JCo}-j8+ih71=Av9NFdhs zfen``YS{b++f>^s6FT!61{b~86pY{qdIroaN%skmHg6sNN42AA(}FbCeOLj}(gqG3 z8jWOpO#bQ5Cj-q`kEItkFcCew*(vL%Kc+j~Pf+4p7uE>E`2Sin7)44$_X;3_RWskb zi%<}OO!Xa%gz2H_FE|JoxtX4$-rOWb)Nb)m{_MWzYgIegC0|x3jtGZSGFq)1A=XF4 z5XEKW(>3{d?xbF~h&n&t_v;!Bjj-TkW-uM4oA^9pNzsLfTvjh?MC5>U-(pCCJL~R? zdn3faW}7k0z{;7xhD2a+5H363m5AXc;s~%IhX>MDyl}$zU%d2tLL>O1ZFmXbZM?_& znVKXWoOwl-$?^~v;8x16ZUN8_-ec9UG<+TvuT0uF3ZEiDK`DG-kO+l=0R3n|7DJhBBCSBB*bO|DWi+_SX{FhuC@4#hHFf@; zzx(dl!+SF5b2G|!JOg@2X&&!Wt%W-~?3$PYg`sXfTu-~ryFd~1P)ce0p=|vf-F45m zP8c)cLCzlh;bH?2=V!H1t9(VIcd#V(QO2A>p9}|4NOxkz6Jzp8rqicKH5ykdNJ9&{ zlJh|4b+Do(eLE?-pC3=wo?iEbJhFRHOHnNdbDjl`29rVugX7bLLQ@YF&+v#>FZJ_c z@Zc`3k33MJpcuHlm3^K^_k*BUQ(zQYg%)FQ4yUwi=n>@>Z!&nX(c%}6Bi$X#r>oz6 zq~Cq4^se8cy)g%Z239k-`CM9GyRmu3wyy?~@aA-Q*64oB24j1ut6S$*p4)}46X5Xj zgX~#v8jL~16>jtrE<|3#a-%J1DF=5;tGBsKv(tU7*YbmmB)7VdD$c}@GlNDjqw&Ki zlues?h|0#+D`c>h4@Svp2IGpY)Jw=tpD*75p~etPD#}kX^NPJIu*Xnf{@TArqCmUA zY6e2G>&1r}T1do}PXR2)ymHAuif9#~c>H;Yzr*!;+T-%R=Q2}#=#w{Jm&e`xqilYEYX?q=(hK;^61yun=(HI zfCRPpCKol+Y9bi$CH6C2+hnMH@ftj2-<5+nDQksAKqxl?8DP z4Cq&8M=Z$PCeM1GzBQBi#_#xi4Y4&uh|ZY&{qqjHWUPsl_NBOafobqt!ptsMZj8Hr zVaG5~u~Cf1I{f`YEk;##YSlZW|#ZD zDam8V;3>7S&Tv3Acla_Pt3Vvn$P=ORHf35#l9Czg?{*`ikQQk{ z`fV-${!ZD8mRoW6n^*oUt*WdI*ZarB*vA+d&g3Is}vB9yU??zD?NP8>!x};jw=>EhNQ-a2-M+LvxnOs zVj4x+G>yuYeW>=BllasD1Cnr3j;SwWf>V3OnAeCINckL(=U0>_++f|vMi|(<*up+Nx@Lk4x&hCOA8k)KQG-MB$SnrqyW?18*R}Aq z8bKw_3VMexw2#DAr1%-zAJwwKV$_ca$!{zcFVr*AsV! zR_r?5AkGbbiBuycKl@7bm>L4UK}(N+3TB5=5$sl1bz@Gt@hU?w&3K|gO;lNyBekoQ z*j7y$U16*&qs@7ZP^!w3p#>g!L7hylw2eUl5q55Lgmx}rV2rhb(}T|<-6a?TxDRCl z&6~y|a1Nzf^Fi>;Xt4~qmQ(e+b@7KP zbZrkDzYNvyc7UXp9r^%ZA$b4$0*~b%9L=?KZ8nvR1?q(|kJ2*lEGYaT%5D316e}t( z=XfWL^@{W}8Y$85vOa+aFT9Lky8s=qv4hDUK$%Wc(mL1E+((~B*CS*+5T+|)Tjgv| zZ9lv`zO*kOZEP+9`61jHfITCf0^+@p#p<}0&POD>?9lG>3!yB#G)`=NOI#5*1 z!x2EXwg>wu7ovHJEU26H0@>>s5x#j6T@VX7z#mOjeweEg zq-YNQ%2x61&&;HUdF60>Fqto^l`?_a6WYQ#c)k2lHt*EOM7^IweJ`A5 zYtyP${rLP)x^t-eV}(HENp{3l`6w>V7278Y%1oz%$-FuAspTasLsDWW;2qjrh@=I4 z%{$>S0!r^Uj}MbqvgnBeq%Up!ZI{cYj~GKuvwh$b4BEkIP9v$v)GMiW?DQ0Cs=VI7 zo#h~vS|Uh6!J!{n%8x{6N7UWEuk8YjABvVuLNw$HoojZV|II(Kik^Y?C4?3AA-e^U z7WPjOT8Wl`e6L)xd|phNIKAdFNuM06TM1VWB^J9jH7Kb!ecxxrCo2pQo&-B25&)Wg zTcXih0-5}^sM@e1sV(j~Hf1$S>QytfG!Vb$<`ALe>sN*pv zM*j@)zlB?#CSqO<_ya)=t7w$c{FrY~PSLA8&22I-QF+?p@hkYQQW>YDOkl#>XLfSH z7XJeebI164B@R8pXZ^rQH0*8ja|U)vk0;8aBx3@a`V_*~u(bfzD9V|~jNs2H$TSEW z#^<@&bvRO4Js#7^B`BT@Cse(+biUo7%c>Et@z?Pb0f}5*mB%60ttkFq>ogJ{C=!|=@Y7$Ji(_y_`7n=?oT#bjQZea^j;)Fcn6 zcBFc071ukyvF7zV+j+9SY-a~LmOM;-3ux5yk&R-0CbT zRrb5(blM%soc)*NI^JeGl=({nTWAW8;|JGSD__{J=p7(fmP_rI#DMWP z+&3MyB514qYHQ421B7$>@F}}2N*lCQB=fh;9wXLDm42mGqQvkJrt9XmZ{eJpi)QYOZ8QJfmvxg zCSugvDTN<3D*~e%ACt9Y8t=l_sc2x?Tgt&Bfz}i(iYrNqQ6Y!z$RtA@626aHz+m$w zN+4NEP8hN^AJf-5xqJv|ir*|jl0iGh-jg5;cxn@Ayct^#)W~b29XWDB4Re+-*-nw=TOI@$Kz9 ziwwKSKp8nch*rGd&dLMpQYUQzc3yYN^$^3=Y0bvRWw`8U$FC~icFo}z z(fxUZxlSnU!@_;MPv$$CD1z3a{Ug2Xl%cfzUF(_&tX``If^fzfkB{i=l%g?}SWJ*z z-&K7*1_{L9`3kcddotYE)Ij-O`)64^;OH0fS67C&3(gR47`u_Ei%FwD(WtC zndlGedhXFC;}pIOzsXzUHQO zI%`xclKSB)?TpGEu&&@$?h&1}F1~|kSB{UPlp{?FD}{2<#soGbo032SQI+jORCY=iQ}QS8$HF*jFn;g zZ4_jWg`ff2GL)%#B`K964jxGC972_cj-#Q@3s3fkj4!euNo+o+3hcCFGhOYbr+P@` z$;oHd%YbhWtf5|5^@*n8-SZm3&P8Mlkx2U|7HY}%%gC6L;7Zn?twV!X(iUciyfGyH zkuUt+;jovS(xC$AlqW$B6x3r zJIWW#O z4*m=x7B^+I@iwBm0{@}m_l_~5uGGw<$xM$A+*pCb)M)!yCjRl5){p zsx(3gVAQTy`H70hwbsc;;ixUVD3-lD()31tfI5y@`lYz-iuupbCLU2NbucnqWo!|j zZxG4AlDcgc13sc!Rvh{>moa!9r@5@(m=kn`#Hiy2%#7GmHdutu zD}*V1LImfTAbkZ{Ve?}#f~s~y20M~X?Or2bBWMU8VTf4FRIJ0Uzg+*Acj}d>BJ?5E zuDVeQV|&(yEX>J~r@$JJ?qQk(E7zXUg_4DTRF9a4epJvTxfBa45?R&o%J-_S*wLdr zK?6&p8|$oVWV&0M#RQ|5f-+QHP0_u|%+_Ko9i{7{iWBPea|&Ru9&>quc3bRNUm?tgrDbI`oVAKOR|bSnQ_{1U;zPP zN$1t`i~q|qpIxzr3tE0v@|5t{4bmZQC-|-G(`qA@v@VUo&E8ybwU5t<^3^~vGpFOi zQT5uh4cOs$Srr!dqf_w>-b}*?9&|qu3D+j0bLSIg{@DxO$YGJM_M${*F^3Qq8q@d9 zt?$<%JhPYuinh|6tY79@USmK5C{rdN{Ct?wr{ae%Gd}aX zb1YD-D@_bww{;yyOM^G7uVAjlbbsGBn8%sFnRvi3yK5ES9CpKNnIy#GKKnwjV}}?O z+(QVZWy^PEnkcD@Zb=$j#i zS1F)siv#j>1hiWL zeiKD-{uO1~m2Jso-w#%pglh~8Ez(KX%HF(&5OWmWL(%=L2eS?`Ylj{-BxxLgjtk78 z(?poarXiI^O;o4Px9~B}sqC{j$W)8`{P_a%KczR@Ugg(%sDilq2M(e&+;&Z1I_7~- zXd7vm*%dLXI7WB73~5>VC3nWF&_?c}&1tba5gOfM2bWS)ZTE!A3GYILf(^VMJhxbB zi!B;pF+^v*3PtQkxl z1r!Phk0&2hucX;C#nNAQL&wvm1_i)EaOTf01tqM@RX7E2bRajS>FKvyEsoUX_i`C%g(1)&tTp@Mj;;B+I4ke%6z{$#m7&SMt*ap?cla*e^u&A)B9$h4=$qp_LLE6;UA zM$c1&F=71aLMpC^BjX269-5gEvd)QZv{zYoVyzgldHg`Yfa08ICv$+QTC zU+oJoiHMi0h3#_|l?{!AM1K7!=eg2Lp``R-W8sKzQAh0b$P(XrqU0-fGj^5Ne3eSd zd8RDvTstT3Q&>FBl?U-qx3dxvuyHXS$`W~;X

ozeJQV?OvLVq%O7ZJBgb?I8CmA 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 literal 0 HcmV?d00001 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..59514a1 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,4 @@ +[build-system] +requires = ["setuptools>=61", "wheel"] +build-backend = "setuptools.build_meta" + diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..59ae3c6 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,15 @@ +[metadata] +name=pricing +version = 0.0.1 +description = A pricing module for online store +author = "yu moqing" +author_email = "yumoqing@gmail.com" +readme = "README.md" +license = "MIT" +[options] +packages = find: +requires_python = ">=3.8" +install_requires = + apppublic + ahserver + sqlor diff --git a/unipay/.notify.py.swp b/unipay/.init.py.swp similarity index 68% rename from unipay/.notify.py.swp rename to unipay/.init.py.swp index 8e3d13513f6374456d7660addc80fb0de97f975e..211d800e624a4af7eb1b6f51f7659a7fbd97eadf 100644 GIT binary patch literal 16384 zcmeI3du$v>9ml7I(q2kR1C%0EmFY&vXLLCyM3sso|KU0=m^$&vuQo){YJEGlx4zq5 z@9x<-MJaBGA4wfMDd~gskv60c(&m8*C{65ENC*T1RKZ^esRGG+b_7x+kl+vg;X6A! z>pMGgT2Vw*%}F2a?aXg}Gy9$Q>|NjH-nJd|>)9;?pW6v}^wc(M%ZBG}y1eTKQZ5ej z(CdDR&ah<<_?vbZ`THGbXj9H}vIQq^6jr2s6b>8Qazn|sTqC(ywiRUE@(NpZs}xWQ ze25B^g8ohSttVT*wq-N-x>37_e(tk9A7Tc|l~O<{pcGIFCv zZzSJAA#aQeT8ytZthjz6zTXgE?G^Fyt-2@$lmbctrGQdEDWDWk3Md7X0!jg;fKosy z@DWtNFbVl2%JnYa@ZMo#1vr!0&G*NP_klaX7r=V(r<)1+88`)wf&%y! zxEtI7{_-h8eh1zJPk>`!3iN<&;4ZKZRBj^V=inJI3%(7$0W#oLuns%{;d{U~a2Hqy z{)&T^UxHV`3*cdJ3kY#Q^CmbBhCvUw7knPPhq{aE4|3A@!wNoYOzwD~$AXe)(|uar zF`3q=b@jBgw03oA8LAbT?;8U=u;W2(f0D}Tr>^IWSSIsmQxnxjS$@z6v__Ij8KZ_3 zQ2fNB&}Za_(jFTwF+a#q(+G_EB;GA#@k0-0>IG*Y4J?z#xdqxpb4Izy?4TVHapJ7* zm2BPixk+RTEADQ0ol^?*z%xvy+fLn{q<9mQQy& zHkzH`m+d??8IO#rSw3FUPGrl;EGKW`Y3m!wMv6LJy71j_{N-@=2T*!p{>5IYt$)r)??_U4%z(AMZ;IW{$XTGi3w zv>x-57J%Lxvm{|634QNo3c5O)Z!&PPVpggGA7!twENY);F-ej}9y z&6oVZDT+d4KDKRE_#nluYuUN0ju%-z5^|4+<=u5jAg0+=Dv|`zV)DXxq4P3Cp_p<~ zDN&*t10TI8ii=BzNS;m(GkP4HmI2(&b=LzQw?T156HX?@WF}pn3KuRu9v*qJG9#wK zsm04D7cP!nojZh;UNXEx<9+)H5%bgX>P<6TOCMroOkj@BM|)eF3Tx{i_l88=s+Su|TfQC708?T3b3>yQ{K@l$CvLMX6w4 zTO7#j8ii{Xhu84P*435#(8D>sIoGE5ZcQpWi!lr9{&=Yv6~HYRLBHb_*QiA9DA(TH z{Xj?Oj-)E9)2*%g+LakOM@@>hm~FtA#)k(!T391|j7K|I+dm(=jRF>zwUTqkU9FvM z&Fw2SFXjhVwgPUvqve~mn#-LInm|j(&Ifo8!@6|g@(fm+BNS^&v1VMFpT{aSS&GrT zWA|U3n-Yu9aQ4jN=}QZ5KOS}0e$OfL$%W5-R?&65plS<5qF7@P&ojcjthn%;V#}^5 zywx5NhT`}0S+Ql1Hr2yy=9+^piM=^Ko<;uZp6~y6VsCy1@cqAhzrTe2{cpiD;At=f z9sv)5JHQ{X=RXE=pb2~t`~yDT1+T~ce#m{Qk5WJ>pcGIFCTK5z>LQi_em(JjCZGt3AXK(u1^H z?IAu5SnVN>kRGHRJn(m41;;RTu~$#yy%sjz@~sywc?G;rm4Ad68~KKP@=$cYw(0^MZ<>{KN-h*%dvo|n6N^m6a|@?yB5T7(V} zt5X+oa4=$*h;(q!?ru*02fdUIB7(dAE|;?;H^iYsh3|tej|;!wFZVuM$h$wYbbXOu zF^i1W8OF*BMc3MSdh+*O#=_ca{OQP5ldG=3TrVsN>#CG1g^H4yFvcF!Yo6%8>Ue)28`}Gi*dPD_2tWV=5P$##AOHafKmY;|_zwj{m9e=T zV{J^;!?R=e+oy_NZ>rtIBp) zL|75tsBZd#KzP~iJGS*e=uzFxUX@YetZF-a+1B?`i+p^#5~rhGYLlaC>`uihWt Gx&H%b?+HQx diff --git a/unipay/init.py b/unipay/init.py index f69b040..4c94113 100644 --- a/unipay/init.py +++ b/unipay/init.py @@ -1,7 +1,8 @@ # init.py import os -from unipay.notify import get_provider +from unipay.notify import get_provider, get_provider_channel from ahserver.serverenv import ServerEnv +from paylog import PaymentLog # 从 env 或配置载入 provider conf(这里只示例) CONF = { @@ -40,8 +41,21 @@ async def create_payment(request, params_kw=None): if provider not in PROVIDERS: return {"error":"unknown provider"} try: - res = await PROVIDERS[provider].create_payment(data) - return res + pl = PaymentLog(request._run_ns) + channel = get_provider_channel(provider) + userid = await get_suer() + orgid = await get_userorgid() + client_ip = request['client_ip'] + # userid, customerid, channel, payment_name, amount, client_ip, currency='CNY' + payment_name = data.payment_name or "充值", + amount = data.amount + currency = data.currency + id = await pl.new_log(userid, orgid, payment_name, amount, client_ip, currency=currency) + if id: + data.out_trade_no = id + res = await PROVIDERS[provider].create_payment(data) + return res + raise Exception('write payment_log error') except Exception as e: return {"error": str(e)} @@ -86,6 +100,9 @@ async def payment_notify(request, callback, params_kw=None): # 这里 data 应包含标准化字段:out_trade_no/status/attach 等 # TODO: 业务幂等处理 # 返回厂商要求的固定成功响应 + logid = data['out_trade_no'] + pl = PaymentLog(request._run_ns) + await pl.payed_log(logid) await callback(request, data) if provider == "wechat": return {"code":"SUCCESS", "message":"OK"} diff --git a/unipay/notify.py b/unipay/notify.py index 3df05a8..2f75d08 100644 --- a/unipay/notify.py +++ b/unipay/notify.py @@ -6,6 +6,16 @@ from .providers.alipay import AlipayGateway from .providers.stripe import StripeGateway # 简单工厂:你可以按需扩展配置注入 + +def get_provider_channel(name:str): + channels = { + "wechat":"0", + "paypal":"1", + "alipay":"2", + "stripe":"3" + } + return channels.get(name, '9') + def get_provider(name: str, conf: Dict): if name == "wechat": return WechatGateway(**conf) diff --git a/unipay/paylog.py b/unipay/paylog.py new file mode 100644 index 0000000..528dcac --- /dev/null +++ b/unipay/paylog.py @@ -0,0 +1,48 @@ +from sqlor.dbpools import DBPools + +class PaymentLog: + def __init__(self, env): + self.db = DBPools() + self.env = env + + async def new_log(self, userid, customerid, channel, payment_name, amount, client_ip, currency='CNY'): + dbname = await self.env.get_module_dbname('unipay') + async with self.db.sqlorContext(dbname) as sor: + ns = { + "id": self.env.uuid(), + "customerid": customerid, + "payment_channel": channel, + "payment_name": payment_name, + "payer_client_ip": client_ip, + "currency": currency, + "payment_status": '0', + "init_timestamp": timestampstr(), + "userid": userid + } + await sor.C('payment_log', ns) + return True + return False + + async def cancel_log(self, logid): + dbname = await self.env.get_module_dbname('unipay') + async with self.db.sqlorContext(dbname) as sor: + ns = { + "id": logid, + "cancel_timestamp": timestampstr() + } + await sor.U('payment_log', ns) + return True + return False + + async def payed_log(self, logid): + dbname = await self.env.get_module_dbname('unipay') + async with self.db.sqlorContext(dbname) as sor: + ns = { + "id": logid, + "payed_timestamp": timestampstr() + } + await sor.U('payment_log', ns) + return True + return False + + diff --git a/wwwroot/menu.ui b/wwwroot/menu.ui new file mode 100644 index 0000000..48fc451 --- /dev/null +++ b/wwwroot/menu.ui @@ -0,0 +1,15 @@ +{ + "widgettype":"Menu", + "items":[ + { + "name":"recharge", + "label":"充值", + "url":"{{entire_url('recharge.ui')}}" + }, + { + "name":"payment_log", + "label":"充值历史", + "url":"{{entire_url('payment_log')}}" + } + ] +} diff --git a/wwwroot/recharge.dspy b/wwwroot/recharge.dspy new file mode 100644 index 0000000..7d08a0d --- /dev/null +++ b/wwwroot/recharge.dspy @@ -0,0 +1,9 @@ +url = await create_payment(request) +return { + "widgettype":"Iframe", + "options":{ + "url": url, + "height": "100%", + "width":"100%" + } +} diff --git a/wwwroot/recharge.ui b/wwwroot/recharge.ui new file mode 100644 index 0000000..2f37383 --- /dev/null +++ b/wwwroot/recharge.ui @@ -0,0 +1,74 @@ +{ + "widgettype":"Form", + "options":{ + "width": "100%", + "height": "100%", + "fields":[ + { + "name":"provider", + "uitype":"code", + "required":true, + "defautvalue":"wechat", + "label":"充值渠道", + "data":[ + { + "value":"wechat", + "text":"微信支付" + }, + { + "value":"alipay", + "text":"支付宝" + } + ] + }, + { + "name":"amount", + "label":"充值金额", + "required":true, + "uitype":"float", + "lenght":18, + "dec":2 + }, + { + "name":"currency", + "label":"币种", + "uitype":"code", + "defaultvalue":"CNY", + "data":[ + { + "value":"CNY", + "text":"人民币" + }, + { + "value":"USD", + "text": "美元" + } + ] + } + + ] + }, + "binds":[ + { + "wid": "self", + "evnet":"submit", + "actiontype":"urlwidget", + "target":"PopupWindow", + "popup_options":{ +{% if params_kw._is_mobile %} + "width": "95%", + "height": "95%", +{% else %} + "width": "50%", + "height": "50%", +{% endif %} + "archor":"cc" + }, + "options":{ + "url":"{{entire_url('recharge.dspy')}}", + "method":"POST", + "params":{} + } + } + ] +}