1
1
( function ( ) {
2
2
const { registerPaymentMethod } = wc . wcBlocksRegistry ;
3
3
const { __ } = wp . i18n ;
4
- const { useEffect } = wp . element ;
4
+ const { useEffect, useRef } = wp . element ;
5
+ const { useSelect } = wp . data ;
5
6
const bizumData = wc . wcSettings . getSetting ( 'monei_bizum_data' ) ;
6
7
7
8
const MoneiBizumContent = ( props ) => {
8
9
const { responseTypes } = props . emitResponse ;
9
10
const { onPaymentSetup, onCheckoutSuccess } = props . eventRegistration ;
10
11
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
+
12
24
useEffect ( ( ) => {
13
25
const placeOrderButton = document . querySelector (
14
26
'.wc-block-components-button.wp-element-button.wc-block-components-checkout-place-order-button.wc-block-components-checkout-place-order-button'
29
41
}
30
42
} ;
31
43
} , [ activePaymentMethod ] ) ;
44
+
32
45
useEffect ( ( ) => {
33
46
// 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 ) {
35
48
initMoneiCard ( ) ;
36
- } else {
49
+ isInitializedRef . current = true ;
50
+ } else if ( ! monei || ! monei . Bizum ) {
37
51
console . error ( 'MONEI SDK is not available' ) ;
38
52
}
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
+
40
62
/**
41
- * Initialize MONEI card input and handle token creation .
63
+ * Initialize MONEI Bizum instance once .
42
64
*/
43
65
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 ( {
45
82
accountId : bizumData . accountId ,
46
83
sessionId : bizumData . sessionId ,
47
84
language : bizumData . language ,
48
- amount : parseInt ( bizumData . total * 100 ) ,
85
+ amount : currentTotal ,
49
86
currency : bizumData . currency ,
50
87
onSubmit ( result ) {
51
88
if ( result . token ) {
52
- requestToken = result . token ;
89
+ requestTokenRef . current = result . token ;
53
90
const placeOrderButton = document . querySelector (
54
91
'.wc-block-components-button.wp-element-button.wc-block-components-checkout-place-order-button.wc-block-components-checkout-place-order-button'
55
92
) ;
64
101
}
65
102
} ,
66
103
onError ( error ) {
67
- console . error ( error ) ;
104
+ console . error ( 'Bizum error:' , error ) ;
68
105
} ,
69
106
} ) ;
70
107
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
+ }
73
169
} ;
74
170
75
171
// Hook into the payment setup
76
172
useEffect ( ( ) => {
77
173
const unsubscribePaymentSetup = onPaymentSetup ( ( ) => {
78
174
// If no token was created, fail
79
- if ( ! requestToken ) {
175
+ if ( ! requestTokenRef . current ) {
80
176
return {
81
177
type : 'error' ,
82
178
message : __ (
89
185
type : responseTypes . SUCCESS ,
90
186
meta : {
91
187
paymentMethodData : {
92
- monei_payment_request_token : requestToken ,
188
+ monei_payment_request_token : requestTokenRef . current ,
93
189
monei_is_block_checkout : 'yes' ,
94
190
} ,
95
191
} ,
100
196
unsubscribePaymentSetup ( ) ;
101
197
} ;
102
198
} , [ onPaymentSetup ] ) ;
199
+
103
200
useEffect ( ( ) => {
104
201
const unsubscribeSuccess = onCheckoutSuccess (
105
202
( { processingResponse } ) => {
108
205
const paymentId = paymentDetails . paymentId ;
109
206
const tokenValue = paymentDetails . token ;
110
207
monei . confirmPayment ( {
111
- paymentId,
112
- paymentToken : tokenValue } )
208
+ paymentId,
209
+ paymentToken : tokenValue } )
113
210
. then ( ( result ) => {
114
211
if (
115
212
result . nextAction &&
146
243
unsubscribeSuccess ( ) ;
147
244
} ;
148
245
} , [ 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
+
149
259
return (
150
260
< fieldset className = "monei-fieldset monei-payment-request-fieldset" >
151
261
< div
164
274
</ fieldset >
165
275
) ;
166
276
} ;
277
+
167
278
const bizumLabel = ( ) => {
168
279
return (
169
280
< 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 >
173
284
{ bizumData ?. logo && (
174
285
< div className = "monei-logo" >
175
286
< img src = { bizumData . logo } alt = "" />
191
302
supports : bizumData . supports ,
192
303
} ;
193
304
registerPaymentMethod ( MoneiBizumPaymentMethod ) ;
194
- } ) ( ) ;
305
+ } ) ( ) ;
0 commit comments