11( function ( ) {
22 const { registerPaymentMethod } = wc . wcBlocksRegistry ;
33 const { __ } = wp . i18n ;
4- const { useEffect } = wp . element ;
4+ const { useEffect, useRef } = wp . element ;
5+ const { useSelect } = wp . data ;
56 const bizumData = wc . wcSettings . getSetting ( 'monei_bizum_data' ) ;
67
78 const MoneiBizumContent = ( props ) => {
89 const { responseTypes } = props . emitResponse ;
910 const { onPaymentSetup, onCheckoutSuccess } = props . eventRegistration ;
1011 const { activePaymentMethod } = props ;
11- let requestToken = null ;
12+
13+ // Use useRef to persist values across re-renders
14+ const requestTokenRef = useRef ( null ) ;
15+ const currentBizumInstanceRef = useRef ( null ) ;
16+ const lastAmountRef = useRef ( null ) ;
17+ const isInitializedRef = useRef ( false ) ;
18+
19+ // Subscribe to cart totals
20+ const cartTotals = useSelect ( ( select ) => {
21+ return select ( 'wc/store/cart' ) . getCartTotals ( ) ;
22+ } , [ ] ) ;
23+
1224 useEffect ( ( ) => {
1325 const placeOrderButton = document . querySelector (
1426 '.wc-block-components-button.wp-element-button.wc-block-components-checkout-place-order-button.wc-block-components-checkout-place-order-button'
2941 }
3042 } ;
3143 } , [ activePaymentMethod ] ) ;
44+
3245 useEffect ( ( ) => {
3346 // We assume the MONEI SDK is already loaded via wp_enqueue_script on the backend.
34- if ( typeof monei !== 'undefined' && monei . Bizum ) {
47+ if ( typeof monei !== 'undefined' && monei . Bizum && ! isInitializedRef . current ) {
3548 initMoneiCard ( ) ;
36- } else {
49+ isInitializedRef . current = true ;
50+ } else if ( ! monei || ! monei . Bizum ) {
3751 console . error ( 'MONEI SDK is not available' ) ;
3852 }
39- } , [ ] ) ; // Empty dependency array ensures this runs only once when the component mounts.
53+ } , [ ] ) ; // Only initialize once on mount
54+
55+ useEffect ( ( ) => {
56+ // Only update amount if instance exists and cart totals changed
57+ if ( isInitializedRef . current && currentBizumInstanceRef . current && cartTotals ) {
58+ updateBizumAmount ( ) ;
59+ }
60+ } , [ cartTotals ] ) ; // Update amount when cart totals change
61+
4062 /**
41- * Initialize MONEI card input and handle token creation .
63+ * Initialize MONEI Bizum instance once .
4264 */
4365 const initMoneiCard = ( ) => {
44- const bizum = monei . Bizum ( {
66+ const currentTotal = cartTotals ?. total_price ?
67+ parseInt ( cartTotals . total_price ) :
68+ parseInt ( bizumData . total * 100 ) ;
69+
70+ lastAmountRef . current = currentTotal ;
71+
72+ const container = document . getElementById ( 'bizum-container' ) ;
73+ if ( ! container ) {
74+ console . error ( 'Bizum container not found' ) ;
75+ return ;
76+ }
77+
78+ // Clear container
79+ container . innerHTML = '' ;
80+
81+ currentBizumInstanceRef . current = monei . Bizum ( {
4582 accountId : bizumData . accountId ,
4683 sessionId : bizumData . sessionId ,
4784 language : bizumData . language ,
48- amount : parseInt ( bizumData . total * 100 ) ,
85+ amount : currentTotal ,
4986 currency : bizumData . currency ,
5087 onSubmit ( result ) {
5188 if ( result . token ) {
52- requestToken = result . token ;
89+ requestTokenRef . current = result . token ;
5390 const placeOrderButton = document . querySelector (
5491 '.wc-block-components-button.wp-element-button.wc-block-components-checkout-place-order-button.wc-block-components-checkout-place-order-button'
5592 ) ;
64101 }
65102 } ,
66103 onError ( error ) {
67- console . error ( error ) ;
104+ console . error ( 'Bizum error:' , error ) ;
68105 } ,
69106 } ) ;
70107
71- const container = document . getElementById ( 'bizum-container' ) ;
72- bizum . render ( container ) ;
108+ currentBizumInstanceRef . current . render ( container ) ;
109+ } ;
110+
111+ /**
112+ * Update the amount in the existing Bizum instance.
113+ */
114+ const updateBizumAmount = ( ) => {
115+ const currentTotal = cartTotals ?. total_price ?
116+ parseInt ( cartTotals . total_price ) :
117+ parseInt ( bizumData . total * 100 ) ;
118+
119+ // Only update if amount actually changed
120+ if ( currentTotal === lastAmountRef . current ) {
121+ return ;
122+ }
123+
124+ lastAmountRef . current = currentTotal ;
125+
126+ if ( currentBizumInstanceRef . current ) {
127+ const preservedToken = requestTokenRef . current ;
128+
129+ if ( typeof currentBizumInstanceRef . current . destroy === 'function' ) {
130+ currentBizumInstanceRef . current . destroy ( ) ;
131+ }
132+
133+ // Clear container
134+ const container = document . getElementById ( 'bizum-container' ) ;
135+ if ( container ) {
136+ container . innerHTML = '' ;
137+ }
138+
139+ // Recreate with new amount
140+ currentBizumInstanceRef . current = monei . Bizum ( {
141+ accountId : bizumData . accountId ,
142+ sessionId : bizumData . sessionId ,
143+ language : bizumData . language ,
144+ amount : currentTotal ,
145+ currency : bizumData . currency ,
146+ onSubmit ( result ) {
147+ if ( result . token ) {
148+ requestTokenRef . current = result . token ;
149+ const placeOrderButton = document . querySelector (
150+ '.wc-block-components-button.wp-element-button.wc-block-components-checkout-place-order-button.wc-block-components-checkout-place-order-button'
151+ ) ;
152+ if ( placeOrderButton ) {
153+ placeOrderButton . style . color = '' ;
154+ placeOrderButton . style . backgroundColor = '' ;
155+ placeOrderButton . disabled = false ;
156+ placeOrderButton . click ( ) ;
157+ } else {
158+ console . error ( 'Place Order button not found.' ) ;
159+ }
160+ }
161+ } ,
162+ onError ( error ) {
163+ console . error ( 'Bizum error:' , error ) ;
164+ } ,
165+ } ) ;
166+
167+ currentBizumInstanceRef . current . render ( container ) ;
168+ }
73169 } ;
74170
75171 // Hook into the payment setup
76172 useEffect ( ( ) => {
77173 const unsubscribePaymentSetup = onPaymentSetup ( ( ) => {
78174 // If no token was created, fail
79- if ( ! requestToken ) {
175+ if ( ! requestTokenRef . current ) {
80176 return {
81177 type : 'error' ,
82178 message : __ (
89185 type : responseTypes . SUCCESS ,
90186 meta : {
91187 paymentMethodData : {
92- monei_payment_request_token : requestToken ,
188+ monei_payment_request_token : requestTokenRef . current ,
93189 monei_is_block_checkout : 'yes' ,
94190 } ,
95191 } ,
100196 unsubscribePaymentSetup ( ) ;
101197 } ;
102198 } , [ onPaymentSetup ] ) ;
199+
103200 useEffect ( ( ) => {
104201 const unsubscribeSuccess = onCheckoutSuccess (
105202 ( { processingResponse } ) => {
108205 const paymentId = paymentDetails . paymentId ;
109206 const tokenValue = paymentDetails . token ;
110207 monei . confirmPayment ( {
111- paymentId,
112- paymentToken : tokenValue } )
208+ paymentId,
209+ paymentToken : tokenValue } )
113210 . then ( ( result ) => {
114211 if (
115212 result . nextAction &&
146243 unsubscribeSuccess ( ) ;
147244 } ;
148245 } , [ onCheckoutSuccess ] ) ;
246+
247+ // Cleanup on unmount
248+ useEffect ( ( ) => {
249+ return ( ) => {
250+ if ( currentBizumInstanceRef . current ) {
251+ if ( typeof currentBizumInstanceRef . current . destroy === 'function' ) {
252+ currentBizumInstanceRef . current . destroy ( ) ;
253+ }
254+ currentBizumInstanceRef . current = null ;
255+ }
256+ } ;
257+ } , [ ] ) ;
258+
149259 return (
150260 < fieldset className = "monei-fieldset monei-payment-request-fieldset" >
151261 < div
164274 </ fieldset >
165275 ) ;
166276 } ;
277+
167278 const bizumLabel = ( ) => {
168279 return (
169280 < div className = "monei-label-container" >
170- < span className = "monei-text" >
171- { __ ( bizumData . title , 'monei' ) }
172- </ span >
281+ < span className = "monei-text" >
282+ { __ ( bizumData . title , 'monei' ) }
283+ </ span >
173284 { bizumData ?. logo && (
174285 < div className = "monei-logo" >
175286 < img src = { bizumData . logo } alt = "" />
191302 supports : bizumData . supports ,
192303 } ;
193304 registerPaymentMethod ( MoneiBizumPaymentMethod ) ;
194- } ) ( ) ;
305+ } ) ( ) ;
0 commit comments