From 3dcc192621673baa32a42e3ee73ec3d86f0b7509 Mon Sep 17 00:00:00 2001 From: Rene Vergara A Date: Fri, 23 Dec 2022 14:45:41 -0500 Subject: [PATCH] ZGo Payment Gateway v1.1 --- README.md | 58 +++++ ZGoPmtGwy.md | 34 +++ assets/zgo-icon-full_50px.png | Bin 0 -> 1319 bytes assets/zgo-icon-full_6pct.png | Bin 0 -> 1021 bytes assets/zgopmtgwy_logo.png | Bin 0 -> 18690 bytes assets/zgopmtsrv_50px.png | Bin 0 -> 11766 bytes changelog.md | 11 + zgopmtgwy.php | 415 ++++++++++++++++++++++++++++++++++ 8 files changed, 518 insertions(+) create mode 100644 README.md create mode 100644 ZGoPmtGwy.md create mode 100644 assets/zgo-icon-full_50px.png create mode 100644 assets/zgo-icon-full_6pct.png create mode 100644 assets/zgopmtgwy_logo.png create mode 100644 assets/zgopmtsrv_50px.png create mode 100644 changelog.md create mode 100644 zgopmtgwy.php diff --git a/README.md b/README.md new file mode 100644 index 0000000..6b14669 --- /dev/null +++ b/README.md @@ -0,0 +1,58 @@ +# ZGo Payment Gateway plugin for Woocommerce + +Contributors: +Tags: WordPres, WooCommerce, payments, ecommerce, e-commerce, store, sales, sell, shop, shopping, cart, checkout +Requires at least : Wordpress 6, WooCommerce 7 +Tested up to: WordPress 6.1.1, WooComerce 7.1,0 +Requires PHP: 7.1 +Stable tag: 1.0 + + +ZGo's payment processing solution for WooCommerce. This plugin implements a payment gateway to let buyers pay with Zcash + +## Description + +To Do + +## Installation + +1. Get your ZGo's OwnerID and Token for Woocommerce from your ZGo Shop Account +2. Download the `zgopmtggwy` installation package from Gitlab??? `/wp-content/plugins/` directory. +3. In WooCommerce Settings page go to the Payment Gateways tab, then click on "ZGo Payment", you will be redirected to ZGo Payment Settings page +4. Fill the ZGo OwnerId and ZGo Token fields +5. Click "Save changes" and return to WooCommerce Payments Tab +6. Check "Enable" button. The credentials will be verified and the plugin will be activated if they are confirmed. + +## Usage + +To Do + +## Support + +To Do + +## Roadmap + + +If you have ideas for releases in the future, it is a good idea to list them in the README. + +## Contributing +State if you are open to contributions and what your requirements are for accepting them. + +For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. + +You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. + +## Authors and acknowledgment + +To Do + +## License + +License: GPLv2 +License URI: http://www.gnu.org/licenses/gpl-2.0.html + + +## Project status + +Development \ No newline at end of file diff --git a/ZGoPmtGwy.md b/ZGoPmtGwy.md new file mode 100644 index 0000000..e2335b2 --- /dev/null +++ b/ZGoPmtGwy.md @@ -0,0 +1,34 @@ + +# Table of Contents + +#### What is ZGo Payment Gateway for *WooCommerce* +#### How it Works? +#### System Requirements +#### Installing ZGo Payment Gateway + +## What is ZGo Payment Gateway for *WooCommerce* + +ZGo Payment Gateway for Woocomerce is a Plugin that allows a WooCommerce based online store, to receive payments using Zcash. + +The Plugin connects WooCommerce Online Store with ZGo Backend to provide customers with an easy way to pay using a phone wallet. + +## How it Works + +The payment flow is showed bellow: + +![ZGo PmtService Flow](ZGo_PmtGwy_Flow.png "ZGo PmtService Flow") + +Figure 1 – ZGo Payment GateWay Flow + +The payment flow showed in Figure 1, includes the transaction confirmation and also marking customer's order as paid in WooComerce store database. ZGo Backend monitors the payment transaction and once it detects at least 5 blockchain confirmations, will report this to ZGo Payment Plugin. + +## System Requirements + +ZGo Business Account + +WooComerce Based Online Store + + +## ZGo Payment Gateway Installation + +### Configuring WooCommerce Store diff --git a/assets/zgo-icon-full_50px.png b/assets/zgo-icon-full_50px.png new file mode 100644 index 0000000000000000000000000000000000000000..7996f233fa4f855963549c905c6066a9aff31b57 GIT binary patch literal 1319 zcmV+?1=#wDP)4Tx04UFukxM8>!EE!6Qn#L%vg?sOqq2^xGy(1e- zWveVaHeL%GYql1)N-2+$ot+i2k*@!_qh?a0oI0If-#OpcIp2ZcLB_P)@-DFKoD(03 zYE#oQTIDk})YCvKt-9%E2V=1@N{)|P0&2bKR9XCQ)Fu~P69Ss>fSGl2!t=s?tGTS= z9pSLKs3(O_g*zO%pzyuYjXb|7PWv2GnPDdp9}*4=Yw033ir8FqEa6_^NYb(;KRA`= zq~bNjR%XTgxu<$zXu+PGP`b<(Mi^zB7#apEERi8cr>wRpE^*n9mhd_go;oLv?)V;jylpy?s2JGw8G$qc4a@OmQOG!2c{P(7RP?Ps6kJ4i@ZV^^@d2kmLe zo-6V0s^Z@MJmdFA^c#Ana;jn_zjFWp010qNS#tmY3ljhU3ljkVnw%H_00T=&L_t(& zL+zT|OH@%5hkvWgn#{7$3Jr$P?6cQK;uWKY0N88B z1T!*`$7bxdK~9*9)y`Dr($LHNm>Ip!XeQYpSwT;bbR%nm*j4M3c`b=*FgV|=*u50L zgGf85?Wc%CIJF?5eDI#*pt8v_p+rXnym1_;qg^HtPU&mq${PI;27Y|AdkBZXL3mIh zX#P4eMYsz%b3i0U@QPGy0s7^M=)w1{fZje4ixDUY7Yqf>TO+23tw!B`k$8etq;e~e z+fPIfZn^~e@LVjOq(Qi_7&K?4m?E8>rWyxD+$66^`W>kqO@;hRxaYV!)|B5Wz z3G~hp(Sxtmfm%O``QsUcOGbmHRfs8KwjmUt8W!)0RM(n!dW-16ji-QbEnw>% z(3FK@inO-@4aY>1VAkNd?{26LtxAS(}5+lVReM8{d1EBGo^ z9rWUXSd3sn@&|(!tQS$lry7<(L3r^NAe06tDEAvdubaifEP`-AP=LbU8t}eG&BOrIt25Vte*K^Hc88lA5>dc*e?PvOSKGV?CVP5z?^P=U=?Ri4Tx04UFukxM8>!EE!6Qn#L%vg?sOqq2^xGy(1e- zWveVaHeL%GYql1)N-2+$ot+i2k*@!_qh?a0oI0If-#OpcIp2ZcLB_P)@-DFKoD(03 zYE#oQTIDk})YCvKt-9%E2V=1@N{)|P0&2bKR9XCQ)Fu~P69Ss>fSGl2!t=s?tGTS= z9pSLKs3(O_g*zO%pzyuYjXb|7PWv2GnPDdp9}*4=Yw033ir8FqEa6_^NYb(;KRA`= zq~bNjR%XTgxu<$zXu+PGP`b<(Mi^zB7#apEERi8cr>wRpE^*n9mhd_go;oLv?)V;jylpy?s2JGw8G$qc4a@OmQOG!2c{P(7RP?Ps6kJ4i@ZV^^@d2kmLe zo-6V0s^Z@MJmdFA^c#Ana;jn_zjFWp010qNS#tmY3ljhU3ljkVnw%H_00JRNL_t(Y zOTCsmXca*ehW``al9=S;s|kpTMLjutOL25-A=w5DkmFNN$qP04`qQOL`CluB#5^BB;$h7yiGxCYEj)5?V| zuLC+yQZiul1LXApB_%Sd3=*nrZ_}wZiO^&qlBYF_kppGv~r;$&_ib_88H1F^6)w(CKak%+aVja z(8AFdMcc_^v=~3s4sO}sP04_7Uu-RJQ4+jRZS4e_HqkQRX)o}#L`g_OZKuk0ODdx00000NkvXXu0mjf_hQiG literal 0 HcmV?d00001 diff --git a/assets/zgopmtgwy_logo.png b/assets/zgopmtgwy_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b30d93ddd3e9d9758a090f4d1299331f89a4298d GIT binary patch literal 18690 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 literal 0 HcmV?d00001 diff --git a/assets/zgopmtsrv_50px.png b/assets/zgopmtsrv_50px.png new file mode 100644 index 0000000000000000000000000000000000000000..3d87420cd6d6716339623e22d6d2cbffdefa2455 GIT binary patch literal 11766 zcmeHscTg4E@-A6&7D*ym$vNjJS+Zo=zy>xs=Zs{KoFr!?qhut5Ad*p%2uMaGg9L%~ zww`m(IrqI^)vH_e-hX$hX3xy(?r(K}-K%TQtSEK0$2geem$zz{JgJ>r94%pXP--`CCnz=43ucLc;I&Zl(kjWQ)g=s=-!9<1HQ1kP)EyjL1!+lmN$RYD@% z^>OQF_P`Sq|Gc@4`FfHI&fK?7w&J>#HJ)?^&W!Kg4({GsAs@t#IsPaq5SDO^eYR}9 zGaYa9r(w687bF6*%Y?;8{(Emol>XYl% z2&>O9tNX3Ww?X0qM^OQ5CF7@q6Wm0j>*^b2o#f9_t8!)S#ZJilRG0mznFk+s`JE3Q z{B*r~kFPbyP8@&%3HN$dRsWpCQu{io^BNuNCPHjiZy!gOHvFBcKBwrt2Yg7s;hsH7@+W0Z|EA>SD&fn<)n$^?Tb$QM5lYf zI}#^4TwW9>u9%luIx701>dk0pZ#34mo_DIwQ$zoss?2*0_FKjtU+m9iDsr~fgguU# z%5puf#>@SCubOKmB3}Yownc@Vo?{-Hw+6%UjBi)^iFuGnjE-gBK0={)QyF=qPxMKYl;u_BUGXT zJS)v}*WyjXuDN}~qC)$MEm`MlEt!M#xb(p#K7|tVHhCh0{e;gG##%GT*S@b|kGqWt zc78X)<@EZ|FgYeZJrCOxUyR>yWnNQEHp$?u9W$7n*LF9gwybaUWXPy@G;3O`@3hX{ zkBOcb_wXy7TJ9Tt_kCCeQ#Hla+jdf4}EGD2Lr%|t|dhjCl;O)e_F>@`Q zx259IRIBlBE1{pGem16GH21{b9jDRI6wG=;xhitT+EeJi8(U;iiu7?x$k7rfFvmLL zqiEN`*|M;E;M8uH`?uTT*}&b8pX8nj*>fLhyZ;OvC7zH7c2Vj`oWPOiaMwNXV2Hl! zH%=n_QB0RA=tgTQGG`%=ZQLq-F#*e6GpX#9D0sjsm|$Kw^I^CX_LCtLLaq*ybHP`R zS@}4N4h+%PuKW_yb7-Q?B+1?lb?5C8SE_AeZ+{+rcyM#t-ni!|jZ_=u!y~YKU6ud7 z;?%WM>~QZUbw!Hg&7yOzz8W&^!qC1&`By#J+LTR5`45HrsZ+;GC|o4VrFhO^lWVJx zAQ*yXQ|RMo!sT48)0 zpBYTC=RNo;z7yF$;u4yGa9Q1!OeZ&IACI_>e4C&6z_m(VwZB#0!el(1S>X`hXTTqI z(vHdhfLrV=Df2yWp)V ztM`S5>5MZLiW(xJiRlLeQcg-up)4uNp7`ZWug2FFDYu4@^HAgBq&$HUElB6Vetko> zD`B|FP`8RFUE!N2k<|&(hz9d<2E|;1lslGV zn~(-etnoW$8YxiGR>L1;RMKQ@{j-`1L&++sb&HuxwpmRw!=r34PDd4Ju_&|H(|NDn zcD**ld1S|;lF`qV^fqFu>r;!i+L6uZVIq+$xC;m?U+bHk*y7gTlhUBY$}%gocG%6L zr=*%#P7UsU)5euF{uGFWl&h1&G2EKrTE&X)MiC1mY>O(U=AN_BEU_!OC7Ty#lH_|{ z)W#*pbg{a`N}4iPrBETg6%JwcK1<9`HOwZe(-o>i^JnSsC~L4&!Y%Ma^WGeibyuTA zTf^S&g8N4kOvS6Q#I+kY7KA(W8%&(r2fX6x zhK6O;3wa~Qhv;UyiFOdHlz18w#u&tS8ikCPP|RG-JqV}v%GvD;il5j0qN|h~Cxw?o zwPN3HVqT9F$?P1m=$>lR!mLGRTC_>bit78?iydEj;Ir4_DByk9=7^z}<|;BOz{uE{ z$CCDlT7)5fr=WAt7Cj?<*tc)Mulba=MWcjMEEMvhJctJ^XIxNTUQ*N3T{T@nHLI8@ zPf8+I?kqWyLHde~+sIj6hu3z`-xI}FGSuvjEuxLh9pcz^mqNA5fQ=6Yr8##4ek|FW z&fRN86h$PdCymX)cU8bzLcC0V6S@l5og`vlcq?Fv$S)pK zfZV}KP=aVC5Hw3VjTjz-?xM&du}*lEuQ6tUQ*K*j=u@AM_92EDY08-^L6u1Jwck3z zhDxJk7ZDBy1!9`P)zry;GrFin|DgggH#Q=#tbriiajPhYjae9Sey~Bne^UOM~t zC?c=ku~I(_3c{&V#&0Wii_yzez$uyNR zEbFBjy6TL1!JIYWNfXIcm?R$I6QrH!O7{UB4D6Hz=~2mQg29dgicI(UI}M-8>vBRh zudZl8F(tmOV?}N+b8#dHYSj}K+@QbOcs*l$Ct_YA&$si&_?2qnHIzpA(Lo3J?m(!Q@84V9^cr#IJfoDi99k| zaLVV3UdA@;Vv?iyggRcDjnGKVz+U41B4;qR9?O|1WLcg&1xFXfU|8Sck$mi01#0Ad zDFV|noc6CT90KyoR<5WCViUZQgLRT}%IAvj@}pZaM9ru3GsP3Cil831+c#3(N0DP) zNK>p?uv8)=A=50!P{5&9WL+1D+m@JyAWlkD(Ve13J}xIaIuKo%z=4>3rODI7Jw2BX zVJPBQL9>L7tGvlCV)%I*{F*ZR(+V0f`h=aUWz^JW)W|pdOx5F!yi43hGvDchHK!=D z!iW6cu)7n6bs7olmIV3TPfrWj()rP+zFf88=4%e!lUw`dJ9Lhvf~YbhM}McJPv`C( zO!Ac|=F_F1Ss@>~nQaPE%gtPW_4yRbM^>dX%ve?TyMvH0YF|Zd(ea-%A5ZS`;oP3_ zQ-!)HqYqJc%lMpV&$73?Nqazpt!qNXM18nH)Sfq{k(XxJ@; zt$OL9NT$g2gnrF~)yZ7@SJ0JBNlqCHX}?#gL_r2b_aOsZ{M|jF@0_}#vFCee5gG%` z!?Ig5=M%yUDy!dGU z!q_B@OT-+80?b8~c~()DiU*s8+0?4?l=ZXf{k#wQl6Oc-(1T408W1COA0Onuo;+?z zH)>7@4KLrAU5dkMrG5Oh?XFE=XzY{^=^S!mtTH~0l@j4xhd5?@*f8#-My4q_A-UM_ zL(ktG(~9z?I2w8ka3yF8O}T z;e}$^+B6Sph?WHLumi5@{G`sI4zc~qNAwX}m>l6>QW32zEkqmKweX*#o!IC#)p@9| z674K9z0>8iIFjnVv-dRL7n&~iN~<`v9#b{KpdzPUk3m+k>qt%$xjC{WjWPqb8XMxl z>Jo^UOmnHfo>_hY`&m-vSEiCW<%5^yR@5&a;szaEw8py%N1$G43=G}tKbn165VEx| zuEmXyi4|QX*V@H5oq_V>xO=r20duK@lpqCDp`S&)TW+$PD^1B#1B=QeNZCVvbItV8 zr!03(A{CZWlcKq~uMvswkg=K@B*HNmUo0pL<|@6!CJ(XKuk^Zsa7-Y4uXe;I36aZU zL1%k@FP2`5J-H&$d-HK)#vqGj52vWKkBWtof#xb9cLmf!qX0paY61WIyBJfH3e+=w zXT<(fORSUDpqErR`1JIh_#UccSQ!KY&xK>|7eszbEyH=FZ4XN%Oy&?pjf{FZx`$e$ zXL2gfwO)ZklY+c6L%=Fb$Z*O0>09~snvUi~v}W~7zlkeO3}PSc9pNi#l*afVPpQB} zwd9M3cI;{O9_^hEu6ruykvnX*p6fp$vptS!LmeO?%odP*QzsKr!zD@V@~M=MXrLqi zjVgcS6Ltj@vZUm09MqTGc%|*!xhUcnwhf|8{QFejt?uZuynoitc>aN8Z+R)rO(7P2 zD}#)oR6>{8Iy@v&{aO@X{;_xu?IUiIw8$WC8k=NH<^)&=ON7y2axtp4IW}3V1rIq{ zv+@j$*i}OHehm$h)NO%+l+*M|7?1WlL~+UXI5y)~{)L4ntXFi|)=eG)dNBKs4MZt8 zRW|L%hZpT@Uu?*3?v0N=5mfM$zFJG%BjQITaYk7X^&&*=pj3L|yRQR%6_?mp!a>;L zejZ6&I7I!TXajnx2N3>{Vn9?b;z{6ok1MYN*&6{RHPlvcyE*R_~&Z(^4PfwvQ|XNiQ?y> zx(&BsYmUH0sm8E#=zxX^`Ghxw%`CbYqa2j86Bt^*YGVI9ONvlQu31Qk^X~@obx$V(XX~Q2VYe72+wOqd1>-e`8A3F?e5x5l5dh0 z*lxpAZyfG#ad-N7axE7T*Rj{$uhq5}p1;rWxdrjSY?K8iKT#mhj0FYFO z{LlhzXNZJ_sbMkZe4kRmAvmg#raUBJidarCH$(_zzvv_D*I;oI|z#>-c6E0Ji=7A(EeFflE>idho(2zqW8Tam5e%lLr-NB+yX zlNRMX^d^oM*Jo?9ab_h_aW4kbS-b(AflAZO%! zTjJX@^@N7x5+BdGL(_#){oV+~C`L(Sp|DJD$FJL_SnFoaoekBYdkmwT4$=WIlelGj zuG~U)RfexzDluJ^vCu6=-eYQi!&)$B{XV1)a=75 zf}k3U6Pw+9a@^i75IR@jw5e0QHQ$a}kU<^}=1M?(s3H zS04=?9ug`>cUMch*)=xDWW%K##`7kdsunuV5Sz;{0V1>{S#cj59u;v(7@qEbDT>b* z!R_3A%gO|KUSiR$Nc6=)7_3RzPZP+0Ves}i_u|;@3l9utJ9id4a3@tBX4^Zfcwu|2 zj@Q7o+)q^7;r9@Nt3^$uS9)Y|zgBZ9Y-YtQOx`dpk7%Oe?e%D-waeazfWlY)d%h}x z1V@jXZ^U}No>a$=LAUwt+P}4Q;}EA{?Q>0{(+|hDMD26Vbr4XYtC}Tbq2S&{Ew*V- zf3GY>+K&r4p-5wVoR8Ivl?H`L~-bl2}!WT z7Q0V`>xpz*f2sWtyW~{8B_7ID!-h*dACFJ8T*NzfI@IRY7d5hyxcY;#+wz2jHS^f) z+aI4%(Do&%SvTOdE_KixXWOZ?L6E1+XmrvJJU&f);kzC+i^HG6=PcI7$59sIfMUC1 zhlYwR5=Qc!Y;lB(q#N1KzJHg*Ri4JzY4&!#?AKB+Ib6ZxZ)*zQ=Y5rs87KKE;nO zl+apa)bSSeh@u_orAeKl7c0;CrZV%rkYM<-Hx7tyUyfmh6mqf(6b$0L=OpH$_fmD5 zT6fiwAKpyzwcMrk%Mi_uH;O90nCcLEeJtdp!CcHI{eZNm3IcO~svd5B;raN!&_j1u z_Dv}^nX&}o5F}-C@_6VJA|)%{Mo`{hQ~*BDns}k_MmHULBz5INhaRd$L~F%BO0mS@K3TPTdYgR-)L{M>=j5g;^RnWnXC)C8fFP zjHhU_MqZR9puvozVgdzl_p96DGOJvU(b-ZvFZ9Yfvl1}Znj9V*KOfOb|J1vcX5e+8 z9b08+zPGewdmg?v=4pP?LvO!F7jdMdi@4j-zIJ;wTIEmM*O05k`~`FBw!ou{57X~E zhl~@rBn|K%zd7EFr!g}9RC?@tM}uSA?85}3Z<_#7V+dYxnas=Sc#VV-zeOjLL*U=t=5P$OyGRYRIGVuQreu>nThJ^bSgVzk<5FT4xSTG)L6gRyUHk zcyPTx!>pp_rT7(P;^(U1gCfag_6ZxovGe-12DP9S9w(^V^(RKo6Gfk*BDwgW9{ZKm zwxU3>O4Vz~(OM^Se2?aHp0^L0{_$-<~+Q!>| zw)_4(S84BhkWuQ=#I$2q4&Pz(g28vv^i)-Z%^mI8Ar_8iP|t-VG2GjP%R%dZF3)6b0G^_32{tOFJU-< zJ=6_C?PYK0;417TM*ACA7=Hh2n1h!3w~Cvs7_FYFI<<_W3zV9dotK@HP0kDE!A&cU zNiFJPVJWOBEB_}1{7H<~+Re>Ln1jR9)05qkhuzV|ii1l?NQi@zn}eI14X(lF>h0hL z@nUmurTYc(2Zk)v)!YT<`cx6QiYt%c=k6pS_c+>R<25wl&dFhK&+$(SS2sBiILMz4{f`!|+VBlY4o#@5qq~baRL%qH;70dP2n+MS?48_Q z?0$!1Va@@ygWAJYUE#BG{o9m}6;;*$viL=T70ll0w-uc1f75h>S^iDdzxnn{@;jV= zIs!NU3-{l&{}uahWw@5As<5o1x%)5o6lKL|f6Xs!;b;!C5dM8Dz+=WIWX{ja#>d5P z#>NYQ^0S%oKrGmV%z3zY_=LNPGK$~Z7x1x9wA{~E;dd+Va|W(J6gajz5j38zZMU*=pQLp zfVslw_x?Tf$BNQ|I{)$X$DOExnI1YQ6Z@VYYNgz~X*nsGzSA%gHa;riduT^%jmJRvSn zDJwXSaIWCx`I{^1N52!r^zXiST0?(j0Ztej7bn}_gmM2#7{{LhbNuQV|B6_YznbBnoc(G${~wP(bMgOi1~~M8C;5-~{V!errRzUp;6GCS zZ*~2buK$RE|48}2)%E|3F3i7Qr=Sk-e?gw`m!(RaQb_~^qzQEuZ8`9i76d*8Q~lt} z6!)nx4=scxIPBA zH{dB9FkuCj{J>fWK>2_P3(%tj!);)&5yZj3><3^a0F0PGf<5T20$*pr`5Cx82jAAg z>@X;a1b$i|Hwf5?fmkcBzYT_(!TT1F>I&Qxfu{F7lw`70_n@$NQi>4m@K6ef40h3#5C1<2_)( z13JpV%{6eA1-_cVoExOM120uzzzE{)KyDx?jRIw{pg0mlLxF=7=&1oUDL|hdm~nxY z0&sQ&3Z8@OpTJQH1n2;NZQ!N=R_B2kCs_Xs`szSe1(+THuQNeIHi$9@_7WgS4-`HJ zyBpvcE0`Yz2j9T;HQ3t%+biI37xcdddh`G$41Sz~7%R|Q1B{u$<`S5B53>EiU=tX5 z3p!tcOm7gN3(il0;UjQ$3Bn;@YZ<)s0me+AG#bndgT+Zu904YKK~)kkdg3sfiDIeqnfN)cAbpeu`z~OiB z+!)M_fVX8J(Gi>;f}`)Cr4aaQ0cSbzeG`Nl16xr5;RL2^puH5>h=RNz;3y5ctAV>B zO*Kn3{38N}lY+i00smSb_^q-dBkp4 zUf0Tt|ME6e^Xlqf0D3yN#Y*S*ET#69Pn?L2*NMBbdRO?FwG*n84T z3?`=>#L^4oru4wJQiwaf1c+?q@9Xou9l9-4$!YiG56Qn2b&m5=gi?R)ZMRRgXwYwK zz?Sq(3s*etxJq&lkgZ*9tEny$G(4~OZ7vtfCTGN|@Ur4b^fZ~Nm}WQ*d}@=Y#=8@w_62YyyGmLnDu9r3TXEpHBr9BGxBdE|}u$R8J9eis=K4jXxKx zO%5Y1oyu7u$@#SXNPVwd-yc(TqmncdO}n`uns@vr&thCQ)G#h0K!)z6w3Svuvf>#- zjPP4G)SSrg{)3+;gRTh$gILZBU(xD+-SbqA^bj<0pNcT%@yz5syA$u)G^b8>+p4sA zo-q=!;jg|CqK_7<7re@r%T)-KYKp+^ViP}(IbIpOq)gkm5=w^_i`=(6UEi_#I4q!y s;PB|ykyI5T>fK0gG=7SGvvrNw(%*XEk*T8%uLJ}|IW^fDY15GZ1*BXom;e9( literal 0 HcmV?d00001 diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..a2775f1 --- /dev/null +++ b/changelog.md @@ -0,0 +1,11 @@ +*** Changelog *** +# ZGo Payment Plugin for WooCommerce + +## Version 0.2 - 2022-11-07 +* Initial alpha release +Uses test authentication and payent REST API () + +## Version 0.4 - 2022-11-18 +integration to ZGo's Authentication End Point in test mode + + diff --git a/zgopmtgwy.php b/zgopmtgwy.php new file mode 100644 index 0000000..e90a057 --- /dev/null +++ b/zgopmtgwy.php @@ -0,0 +1,415 @@ +console_log("Gateway constructor accesed."); + + $this->console_log('Create zgo_payments table if not exists...'); + // + // Create payments table in WordPress database + // + $sql = 'create table if not exists zgo_payments (' . + 'pmt_orderid varchar(64),' . + 'pmt_wc_order varchar(20),' . + 'pmt_wc_custname varchar(100),' . + 'pmt_accepted varchar(30),' . + 'pmt_confirmed varchar(30),' . + 'pmt_amount double (12,2) not null default 0.0,' . + 'pmt_rate double (8,2) not null default 0.0,' . + 'pmt_zec double (12,8) not null default 0.0,' . + 'pmt_wc_paid int not null default 0,' . + 'unique pmt_orderix (pmt_orderid, pmt_wc_order) )'; + $this->console_log('Create table Query -> ' . $sql); + $wpdb->query($sql); + $this->console_log('zgopayments Table created in MySQL ...'); + + $iconurl = plugin_dir_url( __FILE__ ) . + 'assets/zgo-icon-full_6pct.png'; + + $this->siteURL = get_site_url(); + $this->console_log("Site URL: " . $this->siteURL); + + $this->domain = 'zgopmt'; + + $this->id = "zgo_payment"; + $this->icon = $iconurl; + $this->has_fields = false; + $this->method_title = __('ZGo Payment', + $this->domain); + $this->method_description = __('ZGo Payment - Accept payments using Zcash.', $this->domain); + // Load the settings. + $this->init_form_fields(); + $this->init_settings(); + + $this->title = $this->get_option('title'); + $this->description = $this->get_option('description'); + $this->instructions = $this->get_option('instructions', $this->description ); + $this->zgoownerid = $this->get_option('zgoownerid'); + $this->zgotoken = $this->get_option('zgotoken'); + + // Actions + add_action('woocommerce_update_options_payment_gateways_' . + $this->id, + array( $this, 'process_admin_options' ) ); + + add_action( 'woocommerce_thankyou_' . $this->id, array( $this, 'thankyou_page' ) ); + + if ( ! $this->is_valid_for_use() ) + $this->enabled = false; + /** + * Add the webhook for payment confirmation from ZGo + */ + add_action( 'woocommerce_api_zpmtcallback', array($this,'zconfirm')); + } + + public function init_form_fields() { + + $this->form_fields = apply_filters( + 'woo_zgopmtsrv_fields', array( + 'enabled' => array( + 'title' => __('Enable/Disable', + $this->domain ), + 'type' => 'checkbox', + 'label' => __('Enable payments with Zcash', $this->domain ), + 'default' => 'yes' + ), + 'title' => array( + 'title' => __( 'ZGo Payment Service title', + $this->domain ), + 'type' => 'text', + 'default' => __( 'ZGo Payment Gateway', + $this->domain ), + 'desc_tip' => true, + 'description' => __( 'Add a new title for the ZGo Payment Service that your customers will see when they are in the checkout page', + $this->domain ), + ), + 'description' => array( + 'title' => __( 'ZGo Payment Service Confirmation', + $this->domain ), + 'type' => 'textarea', + 'default' => __( 'Pay with Zcash, ZGo will report your payment as soon as it gets confirmed. Normally it takes about 5 minutes.
Read more...', + $this->domain ), + 'desc_tip' => true, + 'description' => __('Payment confirmation description that the customer will see on your checkout.', + $this->domain ), + ), + 'instructions' => array( + 'title' => __('Instructions', + $this->domain ), + 'type' => 'textarea', + 'default' => __('Default instrctions', + $this->domain ), + 'desc_tip' => true, + 'description' => __('Instruction that will be added to the Thank You page and order email', + $this->domain ), + ), + 'zgoownerid' => array( + 'title' => __( 'ZGo OwnerId', + $this->domain ), + 'type' => 'text', + 'default' => __( ' ', + $this->domain ), + 'desc_tip' => true, + 'description' => __( 'Type or paste your ZGo Account Owner Id (Found in your ZGo Shop Settings)', + $this->domain ), + ), + 'zgotoken' => array( + 'title' => __( 'ZGo Token', + $this->domain ), + 'type' => 'text', + 'default' => __( ' ', + $this->domain ), + 'desc_tip' => true, + 'description' => __( 'Type or paste your ZGo Token (Found in your ZGo Shop Settings)', + $this->domain ), + ), + ) + ); + } + + /* + * Check if configuration is valid + */ + public function is_valid_for_use() { + + $isvalid = false; + + if ( isset($this->zgoownerid) && + ($this->zgoownerid !== '') ) { + + $url = 'https://test.zgo.cash/auth?ownerid=' . + $this->zgoownerid . '&token=' . + $this->zgotoken . '&siteurl=' . + $this->base64url_encode($this->siteURL); + + $this->console_log('URL -> ' . $url ); + + $response = wp_remote_get($url); + $this->console_log(json_encode($response)); + + $httpcode = wp_remote_retrieve_response_code( $response ); + $this->console_log('Status Code -> ' . $httpcode ); + + switch ( $httpcode ) { + case 200: + $body = wp_remote_retrieve_body( $response ); + $oid = json_decode($body); + $this->console_log('Body -> ' . $body); + $isvalid = $oid->{'authorized'}; + break; + case 202: + $body = wp_remote_retrieve_body($response ); + $oid = json_decode($body); + $this->console_log('message -> ' . $oid->{'message'}); + break; + default: + $this->console_log('Conection error..'); + break; + } + } + return $isvalid; + } + + /* + * Process Payment + */ + public function process_payment( $order_id ) { + + global $wpdb; + + $this->console_log('Site URL ->' . $this->siteURL); + $this->console_log('Processing payment for order ' . $order_id); + + $order = wc_get_order( $order_id ); +// $wc_order = wc_get_product($order_id); + $wc_order_key = $order->get_order_key(); + + $this->console_log('Order ' . $order_id . ' key = ' . $wc_order_key); + + $url = 'https://test.zgo.cash/woopayment' . + '?ownerid=' . $this->zgoownerid . + '&token=' . $this->zgotoken . + '&order_id=' . $order_id . + '¤cy=' . strtolower($order->get_currency()) . + '&amount=' . $order->get_total() . + '&date=' . date_format($order->get_date_created(),'Y-m-d') . + '&siteurl=' . $this->base64url_encode($this->siteURL) . + '&orderkey=' . $wc_order_key; + + //'&orderkey=' . ; + + $this->console_log('ZGoPayment URL -> ' . $url); + $this->console_log('Calling wp_remote_get()'); + $response = wp_remote_get($url); + $httpcode = wp_remote_retrieve_response_code( $response ); + + $this->console_log('Status Code ->' . $httpcode ); + + switch ( $httpcode ) { + case 200: + wc_add_notice( 'Order on hold, please wait for confirmation'); + $order->update_status('on_hold',__('Awaiting payment confirmation','woocommerce')); + $this->console_log('Order ' . $order_id . ' status set to ON_HOLD'); + + $body = wp_remote_retrieve_body( $response ); + $this->console_log('res. body = ' . $body); + + $oid = json_decode($body); + $zgoOrderid = $oid->{'order'}; + $this->console_log('ZGo order = ' . $zgoOrderid); + // + // Save ZGo Order ID and Cart order + // + $this->console_log("Preparing SQL insert statement"); + $sql = "replace into zgo_payments (" . + "pmt_orderid," . + "pmt_wc_order," . + "pmt_wc_custname," . + "pmt_accepted," . + "pmt_confirmed," . + "pmt_amount," . + "pmt_rate," . + "pmt_zec," . + "pmt_wc_paid) values ('" . + $zgoOrderid . "','" . + $order_id . "','" . + $order->get_billing_first_name() . " " . + $order->get_billing_last_name() . "','" . + date('Y-m-d H:i:s') . "','',". + $order->get_total() . + ",0,0,0)"; + $this->console_log($sql); + $wpdb->query($sql); + + // Remove cart. + WC()->cart->empty_cart(); + + $this->console_log($this->get_return_url( $order )); + + return array( + 'result' => 'success', + 'redirect' => 'https://dev.zgo.cash/invoice/' . $zgoOrderid, + ); + break; + case 202: + $body = wp_remote_retrieve_body( $response ); + $this->console_log('res. body = ' . $body); + + $msg = json_decode($body); + $this->console_log('Order ' . $order_id . ' -> ZGo Order Generation Error : ' . $msg->{'message'}); + + $order->update_status('failed',__('Order ' . $order_id . ' -> ZGo Order Generation Error : ' . $msg->{'message'},'woocommerce')); + + break; + default: + return; + } + } + + /** + * Confirm payment and complete order + */ + public function zconfirm() { + + global $wpdb; + + $this->console_log('zconfirm called '); + + $token = $_GET['token']; + $zgoOrderid = $_GET['orderid']; + $orderid = $_GET['wc_orderid']; + $totalzec = $_GET['totalzec']; + $rate = $_GET['rate']; + $order = wc_get_order( $orderid ); + + $sql = "select * from zgo_payments where pmt_wc_order = '" . $orderid . "';"; + $this->console_log('SQL -> ' . $sql); + $result = $wpdb->get_row($sql,OBJECT); + if ( ! is_null($result) ) { + + $this->console_log('Query successfull...'); + $this->console_log('totalzec -> ', $totalzec); + $this->console_log('rate -> ', $rate); + $this->console_log('pmt_wc_paid=' . $result->pmt_wc_paid); + $this->console_log('local token -> ' . $this->zgotoken); + $this->console_log('received token -> ' . $token); + $this->console_log('zgoOrderid -> ' . $zgoOrderid); + $this->console_log('pmt_orderid -> ' . $result->pmt_orderid); + + if ( ( $token == $this->zgotoken ) + && ( $result->pmt_orderid == $zgoOrderid ) + && ( $result->pmt_wc_paid == '0' ) ) { + $this->console_log('Test successfull...'); + $this->console_log('Order status -> ' . $order->get_status()); + switch ( $order->get_status() ) { + case 'pending': + case 'failed': + $this->console_log('Confirming payment for order ' . $orderid); + $order->payment_complete(); + $order->reduce_order_stock(); + // + // Mark order as completed in ZGo DB + // + $sql = "update zgo_payments set " . + "pmt_confirmed='" . date('Y-m-d H:i:s') . + "', pmt_rate=" . $rate . + ", pmt_zec=" . $totalzec . + ", pmt_wc_paid=1 " . + " where pmt_wc_order='" . $orderid . "';"; +/* + $this->zpmtdb->exec($sql); +*/ + $this->console_log($sql); + $wpdb->query($sql); + $this->console_log('Order marked as paid in zgo_payments table...'); + + update_option('webhook_debug', $_GET); + break; + default: + $this->console_log('Order ' . $orderid . ' already paid or cancelled...'); + break; + } + } else { + $this->console_log('Invalid parameters...'); + } + } else { + $this->console_log('Database error...'); + } + } + + public function thankyou_page () { + if ( $description = $this->get_description() ) { + echo wpautop( wptexturize( $description ) ); + } + } + + public function console_log($data) { + + $file = plugin_dir_path( __DIR__ ) . '/zgopmtgwy/assets/console.log'; + file_put_contents($file, $data . chr(0x0D) . chr(0x0A), FILE_TEXT | FILE_APPEND | LOCK_EX ); + + } + + public function base64url_encode($data) { + + $edata = str_replace('=','',strtr(base64_encode($data), '+/', '-_')); + // $this->console_log('data -> ' . $data); + // $this->console_log('edata -> ' . $edata); + return $edata; + } + + } + + add_filter( 'woocommerce_payment_gateways', + 'add_custom_gateway_class' ); + function add_custom_gateway_class( $methods ) { + if ( ! in_array('WC_ZGopmt_Gateway', $methods) ) { + $methods[] = 'WC_ZGopmt_Gateway'; + } + return $methods; + } + + +}