From 0fb7847e09a7697a8d0a0a95932d853c7d3781e6 Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Mon, 19 Oct 2020 02:31:44 +1100 Subject: [PATCH] MDL-69166 core_payment: Use promises instead of callbacks --- payment/amd/build/gateways_modal.min.js | Bin 4411 -> 4425 bytes payment/amd/build/gateways_modal.min.js.map | Bin 12054 -> 11734 bytes payment/amd/src/gateways_modal.js | 45 ++--- .../paypal/amd/build/gateways_modal.min.js | Bin 4786 -> 4685 bytes .../amd/build/gateways_modal.min.js.map | Bin 10367 -> 10550 bytes .../paypal/amd/build/repository.min.js | Bin 417 -> 632 bytes .../paypal/amd/build/repository.min.js.map | Bin 2205 -> 3344 bytes .../gateway/paypal/amd/src/gateways_modal.js | 188 +++++++++--------- payment/gateway/paypal/amd/src/repository.js | 25 ++- 9 files changed, 133 insertions(+), 125 deletions(-) diff --git a/payment/amd/build/gateways_modal.min.js b/payment/amd/build/gateways_modal.min.js index d177a3d55edf9995339a09fb7fef23a009a08cc3..3cda81021801e245388b1e7da4e6be18af5e93c2 100644 GIT binary patch delta 192 zcmdn3bW&-7}HmC6?xt=q2W)7L{lyDd{9?PIlr*Vu$M4yqKe( zm0h#CEU`!-eX}*+e@2sZ+eE$M)Vvb71$v1|MWqEm%@9MCbkg+-it>|Fi;Fdqby9Rv Mb<#8^hY36d01bIUlmGw# delta 190 zcmX@9v|DMzRCX_&w9>rflFa-(jYQ4rvcw{VB-=#2;?m^g)Z${DWFR{i$Vg02)k(1} z%g;xt(yX4mkzJWFW%5;aWtrO4oZ{5#EWMP} zw8YY!61~Kn)S?m%B_*8{&DzOE97&t!aP+Zq>ZC(#%-C$m_n%QE17vY(UWs*vUO`bl g$bOAvofMr^oiw0A>*U1ZR0WgC{k&0=j|nsb0EAdU5&!@I diff --git a/payment/amd/build/gateways_modal.min.js.map b/payment/amd/build/gateways_modal.min.js.map index cc38c7626c3b7be1619a106149d88f479ea2e2ce..d215e534c80d2169adb995907cc16ad1ed445f9d 100644 GIT binary patch delta 745 zcmZ8fO>fgc5S0T>l?o&hS|NlWn+TLtU6LYD5vqWUosWi)j{+*CsQ@?G)=vBp>~*RN zRXuRyx>A1!k`EjZ`~$8W;KY%iz>Qg_NKJisnwg#VX5M;_U;pTSnvb3526M!8!Hza6*ip|iX zHNX>5O1wF$K@DgV2~TAMfTV074Ae5Mz);niv;h_-8Yb;%KudPE={gRm(3b#u16yE6 zR&5nY;6xJxwIfU8D0zaRrOJhEbq#TZigj>R@i%evvJ9aZ?d_H)9>nro<_by;t8zYA zRn*lau~NPtcIUcr#TK70b!LMmXb0+sxSq`4T9FE6otoISC5?bC0WYWx(OrSBj>RB( zH&uN_m+@qc2GZAh=ba|LC7&q|L^5?%SqYa?!wYw|9dhbhoK6e!=j3hX`}!Uu4B6(pjvg=xwyKg#s#A7`09O84GGn+Y_ zm_BjXn0a`j_YBrAka|=c1)LbnV`LEcoN$-e`j8RkTPBhWeKa~KoE^7G{>z{2yE@%* zc-C9=-cFlqx!l|}v240dA$o=RT#gd)JF^geByW}3!h{n3$&3?XKbMUA+(TR9*V2}F WOgG~bd*Ya?@kN||xEg-AEtG$8tk?Pg delta 941 zcmZuwOK;Oa5LSYKG~|$|fDn{qTY>UgVX5U&35v37I}f5fnwFPZQ8}rTritw;iCan( z^~9CSN}S*qAfzH6_y_z1{sUKf<-m+%x2j+z&+g3k&1-l3bK~QiF&r)d2;guAa8F8hH(?Fy3*`6F4JL{oQ{(W+>4 zm8s^mX{?>e?qzJ_ame3_Tx@Bc8R|5IsY0=NDER=;BDED@b$GoX-p3lZBz5Wo6u2%p zWA)JOs { - modal.hide(); - if (success) { - Notification.addNotification({ - message: message, - type: 'success', - }); - location.reload(); - } else { - Notification.alert('', message); - } - }, - ); + rootNode.dataset.description + ) + .then(message => { + modal.hide(); + Notification.addNotification({ + message: message, + type: 'success', + }); + location.reload(); + + // The following return statement is never reached. It is put here just to make eslint happy. + return message; + }) + .catch(message => Notification.alert('', message)); } else { // We cannot use await in the following line. // The reason is that we are preventing the default action of the save event being triggered, // therefore we cannot define the event handler function asynchronous. - getString('nogatewayselected', 'core_payment').then(message => addToast(message)); + getString('nogatewayselected', 'core_payment').then(message => addToast(message)).catch(); } e.preventDefault(); @@ -166,22 +166,13 @@ const updateCostRegion = async(root, defaultCost = '') => { * @param {string} paymentArea Name of the area in the component that the itemId belongs to * @param {number} itemId An internal identifier that is used by the component * @param {string} description Description of the payment - * @param {processPaymentCallback} callback The callback function to call when processing is finished - * @returns {Promise} + * @returns {Promise} */ -const processPayment = async(gateway, component, paymentArea, itemId, description, callback) => { +const processPayment = async(gateway, component, paymentArea, itemId, description) => { const paymentMethod = await import(`paygw_${gateway}/gateways_modal`); - paymentMethod.process(component, paymentArea, itemId, description, callback); + return paymentMethod.process(component, paymentArea, itemId, description); }; -/** - * The callback definition for processPayment. - * - * @callback processPaymentCallback - * @param {bool} success - * @param {string} message - */ - /** * Set up the payment actions. */ diff --git a/payment/gateway/paypal/amd/build/gateways_modal.min.js b/payment/gateway/paypal/amd/build/gateways_modal.min.js index 8faa42b473c7da25dd6d0fa2141520266c348e9f..21236a04fededd9ea0458c171c210fe70ec6bab0 100644 GIT binary patch delta 1020 zcmZ{jL2DC16vx?^9-?h*6-BT@6I5n!7}|PJ42!f?sNg|bZzag=%u9CD*`2aG+Yr;G zc=6zM(1V}Aiy-#sSJ0z3J$Ua&5bgAXS7SO#tO=vNW)b6nQ-ir_3PJOO=aL_%w?$rd73|L5qZgZOMk5;rzxeXy9 z$ALu9;jTy*0)HFRE>kA`U~93>6q==WOY$z*4Pz{!++Y+}&=I+|JdBirgpJeCp~SPy zre=V$Xe$Mqr^&*T)WlH+T9wCnj`stje)ju{Mo@9Gle4QrTqX!!$CF gaVmL;X}Q?hLHKK7q*eJ`Pgf_g4U^mM`Gvc`0j6(cV*mgE delta 898 zcmZ8g&ubGw6lP;YYTG2O;-v-CU}XlzrHzP?Woi9!Xu&G9B1jEkGBZgw*_}ydCrv}L z_yfFn9Zz083u6C)o;+3R&A-8a!ILjb8o|rFdAswz`QG=v`El#p`qvLmmbU4!edp|D zNXwo(2jvc`V~_a(V%XylIQ9etfxQNV2KJf|nvnG+Gl7!D!0u(rPTRi8Y{7b(K~Bg1 z&csgpqqIf*+rQgP5IgJs*$qX;Dzp`H(dGh}9S=MQs>|fn+ z?Dx4ltBf>AK-#2(M@Li_BO-|+UD6|(#P-kJ^D9yu8^7$?&-3_2dKg!s6B>(Rxf1!* zjfFIx^g|SpGWL`&4>zh_7s6)M>-k-m^|cm~4LvB3h0=JiVsn#ggtw{ zVCH({h=zSp(YCg@22#FVjOV*zIm(J(}Zqez&RN>MANE*&-pHCVeetT8R95j6vs#x(V}##Gb|g%Kq}bu+Gv zCb^Q(Y=sf1ieN{fssip95e2*w5T&`$uzN+_bi4aFNvas+c1=r2G?O9iq!n<1us5aJ zfdNTyl3*9S02GwAnhG@mm`I*ly18lZ&A+st@@saxa6Rw)fK{Kt*sa2f!|h?=$vVd) z?skEpG*1;502`?z@u(Gq9A-O7CbPusS)sHXG!TQ|ln)OKh=51T-dq|~05wSx5yoP~ zU7(25r$$*mTJj}ZT(Q9DXnBnqNEMwpE#C(l;Z8%HAT^sXiKtdM}fO0SJX=6 zE={g1(T%|XIi)8DbLgdQ(Dc}&fgXYcX-~bhXnQD{Qx9!Xpoba-0_0E>NM`0ODav(< z?BVTu^X7lPd6=)Vzr6MI&ma6XaWdF+yfJ;OY}d+mQTpD7TYyV#7p_%z-5|HQlHbP5 zT+wyBz|GTkr&4jeTn)EXCoudx?J7>yFFtZ`x9fU&e-}P#Tk5b&{*D*GzuKaQbAB~| z_E&!Hmh8&*YQ^@db}n#zPx_^D(FsV=^LhL%+?s#+G5}Qix?*lKP4eQqtC>8oxr$qB!y&>NEhw22;(N3`Yh+=o z{mcSi-b3cpQbtdS#SC7iO#O}!=M7?hY%qJxAPYs~F3E1wL0&T0w=^rZp{;8e&U8fL zo9v{bx`w_i#1d+k3&^%$;w~-N*V{1MK2qPfg=CX_ur^5bb=oF3$O*ARi(I0Wt;%Kn zrVwFt*?sa&B3CFI3oJ)orElYcYAjJOmR2#YO@rE<4rK%TS^Tp_E{ z!h;T^#C5LURgci(0B;^@f9b9`yq1ZVANP#) zaDSrXs7NH?pFOYLRP3$(k_GWPXHL#ib&C9Cmkhdi#Pyhw0`rJ$FOhq8|Jc35&ptmf zdk6~s$2+P)#q|pCPQL~}>(@_AY4dMtKUnuP{3=ecQ}JMIpgye#37R(I@wZBT-Y)7| z>(KFbLlBIoSJmOk)VFt&1o4CP;5wWe99mlU_7#TSdd_ac<9IkC zwIoN$YnmFF5-Jx7V|4)V{=|A0w=YG!5 zJ68^5v>7Yk>G12panPc#viRBPk>jn|PwK9 z;;B{szkljI{u4hrsl|>%XDk9DHVuW?Ii`K6b-+(!7VrNSTju}y;qj2a9oC0WH2J0-5YgUl1u{%HCL7)zIRzhTr%C0} zuq=3U6+Vj&90~>cngTS$Hn0HCwE<`wjn}D8Pa4#N2vIf~XeUN@L!(kB!fAD?^^Wde zz%jCtO%@5q+J+_KeuAKy=1zL4EDgV{qA)rdJ+kH%eLG);Pfrg_XYE?nE^3SRBYP!R zam#_Wg42d(dwGqSG+QH#`kn*7>y1Wu%1`CBP)rTgTFQjczP`Q&(6rS}M{69w?(etI zOKo~~-OC|vgZ=i?=CycZF4vn9jV`BvLIE|fe-ud^3EAQAkx}@?ST5CUK!3GS%SHhSK;0DPlkjzczfAPQzb6tT{o0G%#7JL*nfHx11+Gnw91Fv3D03zg hv&7U4>VI<-W~lkN!LKG0eJ{lXbi`*`5@N-#d<|JoC++|M delta 3413 zcmZ`*O-x+Z6&AH|@DFxk^E3Q-xL^zeJP%OEHpaopdv|^q#x{ll?ATcNF>_}an0asf z-s5L%QPMLy&lL z?>Xn5bH4AMd+&KR`@h>CeA|#UOQmHqyY}HXqx}`LS}{w~w(`Y7kJgi2cN}G9t2i{v z_PXVf%yvBp)m z-|9l}-?~p{^i^{!Sb;xf<*nE`%PcFLm`=gP9}H7Q$EKr9oE1G)<`}kTlHeA7 ziUyBY4VsMkldC*&C2KtXmSg;5#WZ_TPtQqcJkoWcWaMeprlH047iS(8ju^8b>w9} zqbu=u$VWP6z&{##VXa}Qaf2oPZe50N8!}gjk~QOQTFdBqhP`TK1BZ->l{QDSVAAk`*e?-n+y2al1xb+<5p!7%lM}Lm#xW%!>Z8NGH_Bw>q%`rh80#!pg4)dlsI)i75@|@36U(boU_7O!i7OC;V^zt($Z9g z<-yT;BsHbq(H**1^iBUHUGfbW)rx-^rHF(n#K0-0V?W|Zf6S?mkOS#S`0hlsY3m2! z^otN_{8c^W5`*s>KRQm}u~zVAxDB72Y^$4wFHUy1@NMQx$=wt|h)u)4Pxdq}(}IhX zGnNGOoVt)gY$)0fiZG#QoiWK#(pMy5!mHW(aqFj_p1OCqiQW#8ckHt0&)SX}HgW#+ z`I+%UI~CJ0%i>AJv9ro`W$?gli)=6wb1Q0ZLXQMJQNpuXC^qpO5y9f3RS-p2?IlO2om}+gQH{B|}Jr7&8d2Kh;fS9;0 zo-A5uh<{nzay@b1pOBzz=gg9}H{bsn2jT}}LYSLo(SyH-Lh!7$(0XmZv)Y3#Cg78f zme>nA{{_eO``t$AIlm@`hlRv}*erT0!d-W=EBN}VC}j%i&>Qf6s2e^DwVd4^K$rUi z?r#F%o1SRXi_ZO?0FIvP?j`PDZVDp%mun&dZ-!b<1Z_g3zklEw{HATO?PWru#=7Sr zcM%xr=!19KBkqhcv*=hV2UO*I(pxYW2|mex_|Qv#x^ z9fmqPA>FwQpLe#wpE{G!c6JUPoqZ4GP4H^?HT-=Qu7(Gp5WWCE>pB9z4#(lU@HC8f zokx8=taP15`HeS;Nkl4K*$s zXO2^0M~Sbemn!Rv|V~ zgyQ-WDW5t<`ufBONEKJ>|DrnEaE5^KI?0ShaHER%Vlwvw(mskc(TE3;pW3sZSa+7 zg@1}(crSA1;S1+Br|4Aj$t4(!Y4C=C7urjiFB0*9MowvTc{PvF5XMRX}%7 zbE=F3v!KWdPxGQRJm~wQ<*qPA4TpdCn3hmMuPau~4b$a@7%z;Hg6GZcJAN-J=4WpR zJ1>xkJ@Y9v_xooye<7_}kZlgf7gkMFyQhK#{cD7z{mYR4euJ&a@e)wJL^CFUB`mVaXmyL h(F+G9_Cvq{Uid{M8rt2~m-Y$%7#TVk&i9e={{tz$DWU)X diff --git a/payment/gateway/paypal/amd/build/repository.min.js b/payment/gateway/paypal/amd/build/repository.min.js index 83d0ead3479405d45efd13d69d981cad8ceb0235..72cdeb9286291eb2c0b08061dc4b67775c407696 100644 GIT binary patch delta 144 zcmZ3;{DWmeheU2-QFcgCVqS4#a!F=>o^yU~K~8E(s_n$KH{#Z1iA4%2wrQn#U^$IM zon)O9oz#ghjir-|QWHy3<4X`aFMMbrKA>RrdXxc*2Zc^8^qRHC+gv{ KD`j#Kqdoxei8m_% delta 13 VcmeytvXFT~$HYaiCVMjJ0{|@D1>*n! diff --git a/payment/gateway/paypal/amd/build/repository.min.js.map b/payment/gateway/paypal/amd/build/repository.min.js.map index 9f0f3835069f780ec4f12de224a549637f2a2c9c..792cd9b26fcb2823022f954cc6845bf407653c74 100644 GIT binary patch delta 520 zcmZ{hy-EW?5XU(|&sHmm7UN+dVezA}i1@KtjYJKJm?%m_Hg~I@-t8W98#M&+0c;{y zTUuF)&*203Bv!hcC{|AKV`t_+v%}2OSTEOmUL{`4@v4qorrg(|l1#-(B((5|r!Wv$ z4t`%@;GI}`l7#X+^$On2?&I6%42g?0EmE>YX{AaSHD=i^T5gejN?HB!W4ai!JsY`X zmP?k07bQ}mv|1yFlo!2>c&sl5A`Fy@9ArFj45u^gI1%g&^ z&7&~jS^$>;_&m{V6p-*vETo1rh0tG0HZ<~epK# { * @param {string} paymentArea The area of the component that the itemId belongs to * @param {number} itemId An internal identifier that is used by the component * @param {string} description Description of the payment - * @param {processCallback} callback The callback function to call when processing is finished - * @returns {Promise} + * @returns {Promise} */ -export const process = async(component, paymentArea, itemId, description, callback) => { - - const [ - modal, - paypalConfig, - ] = await Promise.all([ +export const process = (component, paymentArea, itemId, description) => { + return Promise.all([ showModalWithPlaceholder(), Repository.getConfigForJs(component, paymentArea, itemId), - ]); - const currency = paypalConfig.currency; - const amount = paypalConfig.cost; // Cost with surcharge. - - modal.getRoot().on(ModalEvents.hidden, () => { - // Destroy when hidden. - modal.destroy(); - }); - - const paypalScript = `https://www.paypal.com/sdk/js?client-id=${paypalConfig.clientid}¤cy=${currency}`; - - callExternalFunction(paypalScript, () => { - modal.setBody(''); // We have to clear the body. The render method in paypal.Buttons will render everything. - - paypal.Buttons({ // eslint-disable-line - // Set up the transaction. - createOrder: function(data, actions) { - return actions.order.create({ - purchase_units: [{ // eslint-disable-line - amount: { - currency_code: currency, // eslint-disable-line - value: amount + ]) + .then(([modal, paypalConfig]) => { + modal.getRoot().on(ModalEvents.hidden, () => { + // Destroy when hidden. + modal.destroy(); + }); + + return Promise.all([ + modal, + paypalConfig, + switchSdk(paypalConfig.clientid, paypalConfig.currency), + ]); + }) + .then(([modal, paypalConfig]) => { + // We have to clear the body. The render method in paypal.Buttons will render everything. + modal.setBody(''); + + return new Promise(resolve => { + window.paypal.Buttons({ + // Set up the transaction. + createOrder: function(data, actions) { + return actions.order.create({ + purchase_units: [{ // eslint-disable-line + amount: { + currency_code: paypalConfig.currency_code, // eslint-disable-line + value: paypalConfig.cost, + }, + description: Truncate.truncate(description, {length: 127, stripTags: true}), + }], + application_context: { // eslint-disable-line + shipping_preference: 'NO_SHIPPING', // eslint-disable-line + brand_name: Truncate.truncate(paypalConfig.brandname, {length: 127, stripTags: true}), // eslint-disable-line }, - description: Truncate.truncate(description, {length: 127, stripTags: true}), - }], - application_context: { // eslint-disable-line - shipping_preference: 'NO_SHIPPING', // eslint-disable-line - brand_name: Truncate.truncate(paypalConfig.brandname, {length: 127, stripTags: true}), // eslint-disable-line - }, - }); - }, - // Finalise the transaction. - onApprove: function(data) { - modal.getRoot().on(ModalEvents.outsideClick, (e) => { - // Prevent closing the modal when clicking outside of it. - e.preventDefault(); - }); - - modal.setBody(getString('authorising', 'paygw_paypal')); - - // Call server to validate and capture payment for order. - return Ajax.call([{ - methodname: 'paygw_paypal_create_transaction_complete', - args: { - component, - paymentarea: paymentArea, - itemid: itemId, - orderid: data.orderID, - }, - }])[0] - .then(function(res) { - modal.hide(); - return callback(res); - }); - } - }).render(modal.getBody()[0]); + }); + }, + // Finalise the transaction. + onApprove: function(data) { + modal.getRoot().on(ModalEvents.outsideClick, (e) => { + // Prevent closing the modal when clicking outside of it. + e.preventDefault(); + }); + + modal.setBody(getString('authorising', 'paygw_paypal')); + + Repository.markTransactionComplete(component, paymentArea, itemId, data.orderID) + .then(res => { + modal.hide(); + return res; + }) + .then(resolve); + } + }).render(modal.getBody()[0]); + }); + }) + .then(res => { + if (res.success) { + return Promise.resolve(res.message); + } + + return Promise.reject(res.message); }); }; /** - * The callback definition for process. + * Unloads the previously loaded PayPal JavaScript SDK, and loads a new one. * - * @callback processCallback - * @param {bool} success - * @param {string} message + * @param {string} clientId PayPal client ID + * @param {string} currency The currency + * @returns {Promise} */ +const switchSdk = (clientId, currency) => { + const sdkUrl = `https://www.paypal.com/sdk/js?client-id=${clientId}¤cy=${currency}`; -/** - * Calls a function from an external javascript file. - * - * @param {string} jsFile URL of the external JavaScript file - * @param {function} func The function to call - */ -const callExternalFunction = (jsFile, func) => { // Check to see if this file has already been loaded. If so just go straight to the func. - if (callExternalFunction.currentlyloaded == jsFile) { - func(); - return; + if (switchSdk.currentlyloaded === sdkUrl) { + return Promise.resolve(); } // PayPal can only work with one currency at the same time. We have to unload the previously loaded script // if it was loaded for a different currency. Weird way indeed, but the only way. // See: https://github.com/paypal/paypal-checkout-components/issues/1180 - if (callExternalFunction.currentlyloaded) { - const suspectedScript = document.querySelector(`script[src="${callExternalFunction.currentlyloaded}"]`); + if (switchSdk.currentlyloaded) { + const suspectedScript = document.querySelector(`script[src="${switchSdk.currentlyloaded}"]`); if (suspectedScript) { suspectedScript.parentNode.removeChild(suspectedScript); } @@ -152,29 +144,31 @@ const callExternalFunction = (jsFile, func) => { const script = document.createElement('script'); - if (script.readyState) { - script.onreadystatechange = function() { - if (this.readyState == 'complete' || this.readyState == 'loaded') { - this.onreadystatechange = null; - func(); - } - }; - } else { - script.onload = function() { - func(); - }; - } + return new Promise(resolve => { + if (script.readyState) { + script.onreadystatechange = function() { + if (this.readyState == 'complete' || this.readyState == 'loaded') { + this.onreadystatechange = null; + resolve(); + } + }; + } else { + script.onload = function() { + resolve(); + }; + } - script.setAttribute('src', jsFile); - document.head.appendChild(script); + script.setAttribute('src', sdkUrl); + document.head.appendChild(script); - callExternalFunction.currentlyloaded = jsFile; + switchSdk.currentlyloaded = sdkUrl; + }); }; /** - * Holds the full url of loaded external JavaScript file. + * Holds the full url of loaded PayPal JavaScript SDK. * * @static * @type {string} */ -callExternalFunction.currentlyloaded = ''; +switchSdk.currentlyloaded = ''; diff --git a/payment/gateway/paypal/amd/src/repository.js b/payment/gateway/paypal/amd/src/repository.js index 627753e6956..facec049fb0 100644 --- a/payment/gateway/paypal/amd/src/repository.js +++ b/payment/gateway/paypal/amd/src/repository.js @@ -30,7 +30,7 @@ import Ajax from 'core/ajax'; * @param {string} component Name of the component that the itemId belongs to * @param {string} paymentArea The area of the component that the itemId belongs to * @param {number} itemId An internal identifier that is used by the component - * @returns {Promise<{clientid: string, brandname: string}>} + * @returns {Promise<{clientid: string, brandname: string, cost: number, currency: string}>} */ export const getConfigForJs = (component, paymentArea, itemId) => { const request = { @@ -44,3 +44,26 @@ export const getConfigForJs = (component, paymentArea, itemId) => { return Ajax.call([request])[0]; }; + +/** + * Call server to validate and capture payment for order. + * + * @param {string} component Name of the component that the itemId belongs to + * @param {string} paymentArea The area of the component that the itemId belongs to + * @param {number} itemId An internal identifier that is used by the component + * @param {string} orderId The order id coming back from PayPal + * @returns {*} + */ +export const markTransactionComplete = (component, paymentArea, itemId, orderId) => { + const request = { + methodname: 'paygw_paypal_create_transaction_complete', + args: { + component, + paymentarea: paymentArea, + itemid: itemId, + orderid: orderId, + }, + }; + + return Ajax.call([request])[0]; +}; -- 2.43.0