PageSourceSearch

https://www.sicherheitsakademie.de/wp-content/plugins/klarna-payme…/assets/js/klarna-payments.js?ver=4.12.0

js sicherheitsakademie.de collected 2026-10-05 23:03:35 UTC 20,790 bytes, 625 lines download raw bytes

1/* global console, Klarna */
2jQuery( function ( $ ) {
3	"use strict"
4
5	var klarna_payments = {
6		authorization_response: {},
7		iframe_loaded: false,
8		show_form: false,
9		klarna_container_selector: "#klarna_container_2",
10		checkout_values: {},
11		addresses: {},
12		cart_total: klarna_payments_params.cart_total, // in minor units
13		submit_button_selectors: klarna_payments_params.submit_button_selectors.join( ", " ),
14		log: ( ...args ) => {
15			if ( klarna_payments_params.debug ) {
16				console.log( ...args )
17			}
18		},
19
20		check_changes: function () {
21			$(
22				".woocommerce-billing-fields input, .woocommerce-billing-fields select, .woocommerce-shipping-fields input, .woocommerce-shipping-fields select",
23			).each( function () {
24				var fieldName = $( this ).attr( "name" )
25				var fieldValue = $( this ).val()
26				if ( klarna_payments.checkout_values[ fieldName ] !== fieldValue ) {
27					klarna_payments.checkout_values[ fieldName ] = fieldValue
28					$( this ).trigger( "change" )
29				}
30			} )
31		},
32
33		debounce_changes: function ( func, wait, immediate ) {
34			var timeout
35			return function () {
36				var context = this,
37					args = arguments
38				var later = function () {
39					timeout = null
40					if ( ! immediate ) func.apply( context, args )
41				}
42				var callNow = immediate && ! timeout
43				clearTimeout( timeout )
44				timeout = setTimeout( later, wait )
45				if ( callNow ) func.apply( context, args )
46			}
47		},
48
49		start: function () {
50			// Store all billing and shipping values.
51			$( document ).ready( function () {
52				$( "#customer_details input, #customer_details select" ).each( function () {
53					var fieldName = $( this ).attr( "name" )
54					var fieldValue = $( this ).val()
55					klarna_payments.checkout_values[ fieldName ] = fieldValue
56				} )
57				if ( klarna_payments.isKlarnaPaymentsSelected() ) {
58					klarna_payments.initKlarnaCredit()
59					klarna_payments.load().then( klarna_payments.loadHandler )
60				}
61			} )
62
63			/**
64			 * When WooCommerce updates checkout
65			 * Happens on initial page load, country, state and postal code changes
66			 */
67			$( "body" ).on( "updated_checkout", function ( event, data ) {
68				// Unblock the payments element if blocked
69				var blocked_el = $( ".woocommerce-checkout-payment" )
70				var blocked_el_data = blocked_el.data()
71				if ( blocked_el.length && 1 === blocked_el_data[ "blockUI.isBlocked" ] ) {
72					blocked_el.unblock()
73				}
74
75				// Check if we need to hide the shipping fields
76				klarna_payments.maybeHideShippingAddress()
77
78				if (klarna_payments.isKlarnaPaymentsSelected()) {
79					data = data || { fragments: null }
80
81					klarna_payments.initKlarnaCredit()
82					klarna_payments.load( data.fragments ).then( klarna_payments.loadHandler )
83				}
84			} )
85
86			/**
87			 * Clear auth token if there's checkout error.
88			 */
89			$( document.body ).on( "checkout_error", function () {
90				$( 'input[name="klarna_payments_authorization_token"]' ).remove()
91			} )
92
93			/**
94			 * Phone field changes. Has to be 5 characters or longer for KP to work.
95			 */
96			$( "form.checkout" ).on(
97				"keyup",
98				"#billing_phone",
99				klarna_payments.debounce_changes( function () {
100					if ( klarna_payments.isKlarnaPaymentsSelected() ) {
101						//$('#place_order').attr('disabled', true);
102						if ( $( this ).val().length > 4 ) {
103							klarna_payments.initKlarnaCredit()
104							klarna_payments.load().then( klarna_payments.loadHandler )
105						}
106					}
107				}, 750 ),
108			)
109
110			/**
111			 * Email field changes, check if WooCommerce says field is valid.
112			 */
113			$( "form.checkout" ).on(
114				"keyup",
115				"#billing_email",
116				klarna_payments.debounce_changes( function () {
117					if ( klarna_payments.isKlarnaPaymentsSelected() ) {
118						//$('#place_order').attr('disabled', true);
119						if ( ! $( this ).parent().hasClass( "woocommerce-invalid" ) ) {
120							klarna_payments.initKlarnaCredit()
121							klarna_payments.load().then( klarna_payments.loadHandler )
122						}
123					}
124				}, 750 ),
125			)
126
127			/**
128			 * Billing company field changes.
129			 */
130			$( "form.checkout" ).on(
131				"keyup",
132				"#billing_company",
133				klarna_payments.debounce_changes( function () {
134					if ( klarna_payments.isKlarnaPaymentsSelected() ) {
135						klarna_payments.initKlarnaCredit()
136						klarna_payments.load().then( klarna_payments.loadHandler )
137					}
138				}, 750 ),
139			)
140
141			/**
142			 * When changing payment method.
143			 */
144			$( "body" ).on( "change", 'input[name="payment_method"]', function () {
145				// If Klarna Payments is selected and iframe is not loaded yet, disable the form. Also collapse any unselected Klarna Payments gateways.
146				if ( klarna_payments.isKlarnaPaymentsSelected() ) {
147					klarna_payments.initKlarnaCredit()
148					klarna_payments.load().then( klarna_payments.loadHandler )
149					klarna_payments.collapseGateways()
150				}
151
152				// Enable the form if any other payment method is selected.
153				if ( ! klarna_payments.isKlarnaPaymentsSelected() ) {
154					$( "#place_order" ).attr( "disabled", false )
155				}
156
157				// Check if we need to hide the shipping fields
158				klarna_payments.maybeHideShippingAddress()
159			} )
160		},
161
162		load: function ( fragments = null ) {
163			var $defer = $.Deferred()
164
165			// Dont run load during checkout completion.
166			if ( $( "form.checkout" ).hasClass( "processing" ) ) {
167				return $defer.reject()
168			}
169
170			var klarna_payments_container_selector_id = "#" + klarna_payments.getSelectorContainerID()
171			klarna_payments.log( klarna_payments_container_selector_id )
172
173			if ( klarna_payments_container_selector_id ) {
174				var klarnaLoadedInterval = setInterval( function () {
175					var Klarna = false
176
177					try {
178						Klarna = window.Klarna
179					} catch ( e ) {
180						klarna_payments.log( e )
181					}
182
183					if ( Klarna && Klarna.Payments ) {
184						clearInterval( klarnaLoadedInterval )
185						clearTimeout( klarnaLoadedTimeout )
186
187						var options = {
188							container: klarna_payments_container_selector_id,
189							// purchased_amount is used on the checkout page in any of Klarna payment methods that show a cost breakdown (the "Learn more" OSM widget).
190							purchase_amount: klarna_payments.cart_total,
191						}
192
193						// When the payment methods are combined into a single method, the category is omitted so the widget displays all payment options available in the Klarna session.
194						var payment_method_category = klarna_payments.getSelectedPaymentCategory()
195						if ( "klarna_payments" !== payment_method_category ) {
196							options.payment_method_category = payment_method_category
197						}
198
199						if ( fragments && fragments.kp_cart_total ) {
200							// Update the global instance. If we don't do this, the initial cart total will be used on further loads.
201							klarna_payments.cart_total = fragments.kp_cart_total
202							options.purchase_amount = klarna_payments.cart_total
203						}
204
205						if ( "US" === $( "#billing_country" ).val() ) {
206							var address = klarna_payments.get_address_from_checkout_form()
207
208							Klarna.Payments.load( options, address, function ( response ) {
209								$defer.resolve( response )
210							} )
211						} else {
212							Klarna.Payments.load( options, function ( response ) {
213								$defer.resolve( response )
214							} )
215						}
216					}
217				}, 100 )
218
219				var klarnaLoadedTimeout = setTimeout( function () {
220					clearInterval( klarnaLoadedInterval )
221					$defer.reject()
222				}, 3000 )
223
224				return $defer.promise()
225			}
226		},
227
228		loadHandler: function ( response ) {
229			klarna_payments.iframe_loaded = true
230
231			if ( response.show_form ) {
232				klarna_payments.show_form = true
233			}
234		},
235
236		isKlarnaPaymentsSelected: function () {
237			if ( $( 'input[name="payment_method"]:checked' ).length ) {
238				var selected_value = $( 'input[name="payment_method"]:checked' ).val()
239				return selected_value.indexOf( "klarna_payments" ) !== -1
240			}
241
242			return false
243		},
244
245		isTermsAccepted: function () {
246			if ( ! $( "#terms" ).length || $( "#terms" ).is( ":checked" ) ) {
247				return true
248			}
249
250			return false
251		},
252
253		setRadioButtonValues: function () {
254			$( 'input[name="payment_method"]' ).each( function () {
255				if ( $( this ).val().indexOf( "klarna_payments" ) !== -1 ) {
256					$( this ).val( "klarna_payments" )
257				}
258			} )
259		},
260
261		getSelectorContainerID: function () {
262			var containerID = $( 'input[name="payment_method"]:checked' ).attr( "id" ).replace( "payment_method_", "" )
263
264			return containerID + "_container"
265		},
266
267		getSelectedPaymentCategory: function () {
268			var selected_category = $( 'input[name="payment_method"]:checked' )
269				.attr( "id" )
270				.replace( "payment_method_", "" )
271			klarna_payments.log( selected_category )
272			return selected_category.replace( "klarna_payments_", "" )
273		},
274
275		authorize: function () {
276			var $defer = $.Deferred()
277			var address = klarna_payments.get_address()
278
279			klarna_payments.authorization_response = {}
280
281			// The category must match the load() call, so it is omitted here as well when the payment methods are combined into a single method.
282			var options = {}
283			var payment_method_category = klarna_payments.getSelectedPaymentCategory()
284			if ( "klarna_payments" !== payment_method_category ) {
285				options.payment_method_category = payment_method_category
286			}
287
288			try {
289				Klarna.Payments.authorize(
290					address,
291					options,
292					function ( response ) {
293						klarna_payments.authorization_response = response
294						$defer.resolve( response )
295					},
296				)
297			} catch ( e ) {
298				klarna_payments.logToFile( e )
299			}
300
301			return $defer.promise()
302		},
303
304		get_address: function () {
305			var address = {
306				billing_address: {
307					given_name: klarna_payments.addresses.billing.given_name,
308					family_name: klarna_payments.addresses.billing.family_name,
309					email: klarna_payments.addresses.billing.email,
310					phone: klarna_payments.addresses.billing.phone,
311					country: klarna_payments.addresses.billing.country,
312					region: klarna_payments.addresses.billing.region,
313					postal_code: klarna_payments.addresses.billing.postal_code,
314					city: klarna_payments.addresses.billing.city,
315					street_address: klarna_payments.addresses.billing.street_address,
316					street_address2: klarna_payments.addresses.billing.street_address2,
317					organization_name:
318						"b2b" === klarna_payments_params.customer_type
319							? klarna_payments.addresses.billing.organization_name
320							: "",
321				},
322				shipping_address: {},
323			}
324
325			address.shipping_address = $.extend( {}, address.billing_address )
326
327			if ( $( "#ship-to-different-address" ).find( "input" ).is( ":checked" ) ) {
328				address.shipping_address.given_name = klarna_payments.addresses.shipping.given_name
329				address.shipping_address.family_name = klarna_payments.addresses.shipping.family_name
330				address.shipping_address.country = klarna_payments.addresses.shipping.country
331				address.shipping_address.region = klarna_payments.addresses.shipping.regi
331on
332				address.shipping_address.postal_code = klarna_payments.addresses.shipping.postal_code
333				address.shipping_address.city = klarna_payments.addresses.shipping.city
334				address.shipping_address.street_address = klarna_payments.addresses.shipping.street_address
335				address.shipping_address.street_address2 = klarna_payments.addresses.shipping.street_address2
336			}
337
338			return address
339		},
340
341		get_address_from_checkout_form: function () {
342			var address = {
343				billing_address: {
344					given_name: klarna_payments.checkout_values.billing_first_name,
345					family_name: klarna_payments.checkout_values.billing_last_name,
346					email: klarna_payments.checkout_values.billing_email,
347					phone: klarna_payments.checkout_values.billing_phone,
348					country: klarna_payments.checkout_values.billing_country,
349					region: klarna_payments.checkout_values.billing_state,
350					postal_code: klarna_payments.checkout_values.billing_postcode,
351					city: klarna_payments.checkout_values.billing_city,
352					street_address: klarna_payments.checkout_values.billing_address_1,
353					street_address2: klarna_payments.checkout_values.billing_address_2,
354					organization_name:
355						"b2b" === klarna_payments_params.customer_type
356							? klarna_payments.checkout_values.billing_company
357							: "",
358				},
359				shipping_address: {},
360			}
361
362			address.shipping_address = $.extend( {}, address.billing_address )
363
364			if ( $( "#ship-to-different-address" ).find( "input" ).is( ":checked" ) ) {
365				address.shipping_address.given_name = klarna_payments.checkout_values.shipping_first_name
366				address.shipping_address.family_name = klarna_payments.checkout_values.shipping_last_name
367				address.shipping_address.country = klarna_payments.checkout_values.shipping_country
368				address.shipping_address.region = klarna_payments.checkout_values.shipping_state
369				address.shipping_address.postal_code = klarna_payments.checkout_values.shipping_postcode
370				address.shipping_address.city = klarna_payments.checkout_values.shipping_city
371				address.shipping_address.street_address = klarna_payments.checkout_values.shipping_address_1
372				address.shipping_address.street_address2 = klarna_payments.checkout_values.shipping_address_2
373			}
374
375			return address
376		},
377
378		collapseGateways: function () {
379			$( 'input[name="payment_method"]' ).each( function () {
380				if ( $( this ).is( ":checked" ) ) {
381					$( this ).siblings( "div.payment_box" ).show()
382				} else {
383					$( this ).siblings( "div.payment_box" ).hide()
384				}
385			} )
386		},
387
388		maybeHideShippingAddress: function () {
389			if ( false !== klarna_payments.isKlarnaPaymentsSelected() ) {
390				if ( "b2b" === klarna_payments_params.customer_type ) {
391					jQuery( "#customer_details .col-2" ).hide()
392				}
393			} else {
394				jQuery( "#customer_details .col-2" ).show()
395			}
396		},
397
398		initKlarnaCredit: function ( client_token ) {
399			var client_token = klarna_payments.getClientToken()
400			window.klarnaInitData = { client_token: client_token }
401			Klarna.Payments.init( klarnaInitData )
402		},
403
404		printErrorMessage: function ( message ) {
405			$( "#klarna-payments-error-notice" ).remove()
406			const is_pay_for_order = true == klarna_payments_params.pay_for_order
407			const $target = is_pay_for_order ? $( "div.woocommerce-notices-wrapper" ) : $( "form.checkout" )
408
409			$target.prepend(
410				'<div id="klarna-payments-error-notice" class="woocommerce-NoticeGroup"><ul class="woocommerce-error" role="alert"><li>' +
411					message +
412					"</li></ul></div>",
413			)
414			$.scroll_to_notices( $target )
415		},
416
417		authorizeKlarnaOrder: function ( order_id, order_key ) {
418			klarna_payments.authorize().done( function ( response ) {
419				if ( "authorization_token" in response ) {
420					$( "body" ).trigger( "kp_auth_success" )
421					$.ajax( klarna_payments_params.place_order_url, {
422						type: "POST",
423						dataType: "json",
424						async: true,
425						data: {
426							order_key: order_key,
427							order_id: order_id,
428							auth_token: klarna_payments.authorization_response.authorization_token,
429							nonce: klarna_payments_params.place_order_nonce,
430						},
431						success: function ( response ) {
432							// Log the success.
433							klarna_payments.log( "kp_place_order success" )
434							klarna_payments.log( response )
435						},
436						error: function ( response ) {
437							// Log the error.
438							klarna_payments.logToFile( response )
439						},
440						complete: function ( response ) {
441							if ( response.responseJSON.success === true ) {
442								window.location.href = response.responseJSON.data
443							} else {
444								$( "form.checkout" ).removeClass( "processing" ).unblock()
445								$( "form.checkout" )
446									.find( ".input-text, select, input:checkbox" )
447									.trigger( "validate" )
448									.blur()
449								$( "form.checkout" ).trigger( "update_checkout" )
450							}
451						},
452					} )
453				} else {
454					$( "body" ).trigger( "kp_auth_failed" )
455
456					// Re-enable the form.
457					$( "body" ).trigger( "updated_checkout" )
458					$( "form.checkout" ).removeClass( "processing" )
459					$( "form.checkout" ).unblock()
460
461					const reason = response.show_form ? "aborted by customer" : "rejected by 
461Klarna"
462					klarna_payments.logToFile(
463						`(Order ${ order_id }): No authorization_token in response. Reason: ${ reason }.`,
464					)
465					$( "form.woocommerce-checkout" ).removeClass( "processing" ).unblock()
466					$.ajax( klarna_payments_params.auth_failed_url, {
467						type: "POST",
468						dataType: "json",
469						async: true,
470						data: {
471							show_form: response.show_form,
472							order_key: order_key,
473							order_id: order_id,
474							nonce: klarna_payments_params.auth_failed_nonce,
475						},
476					} )
477				}
478			} )
479		},
480
481		klarnaPayForOrder: function ( event ) {
482			if ( klarna_payments.isKlarnaPaymentsSelected() ) {
483				event.preventDefault()
484
485				if ( ! klarna_payments.isTermsAccepted() ) {
486					klarna_payments.printErrorMessage( klarna_payments_params.i18n.terms_not_checked )
487					return
488				}
489
490				klarna_payments.addresses = klarna_payments_params.addresses
491				klarna_payments.authorizeKlarnaOrder(
492					klarna_payments_params.order_id,
493					klarna_payments_params.order_key,
494				)
495			}
496		},
497
498		getClientToken: function () {
499			if ( $( "#kp_client_token" ).length > 0 ) {
500				return $( "#kp_client_token" ).val()
501			} else {
502				return klarna_payments_params.client_token
503			}
504		},
505
506		orderSubmit: function ( event ) {
507			if ( klarna_payments.isKlarnaPaymentsSelected() ) {
508				event.preventDefault()
509
510				if ( $( "form.checkout" ).is( ".processing" ) ) {
511					return false
512				}
513
514				$( "form.checkout" ).addClass( "processing" )
515				$( "form.checkout" ).block( {
516					message: null,
517					overlayCSS: {
518						background: "#fff",
519						opacity: 0.6,
520					},
521				} )
522
523				$.ajax( {
524					type: "POST",
525					url: klarna_payments_params.submit_order,
526					data: $( "form.checkout" ).serialize(),
527					dataType: "json",
528					success: function ( data ) {
529						try {
530							if ( "success" === data.result ) {
531								klarna_payments.logToFile(
532									"Successfully placed order. Starting authorization with Klarna",
533								)
534								klarna_payments.addresses = data.addresses
535								klarna_payments.authorizeKlarnaOrder( data.order_id, data.order_key )
536							} else {
537								throw "Result failed"
538							}
539						} catch ( err ) {
540							if ( data.messages ) {
541								klarna_payments.logToFile( "Checkout error | " + data.messages )
542								klarna_payments.failOrder( "submission", data.messages )
543								// If requested, reload the page.
544							} else if ( true === data.reload ) {
545								window.location.reload()
546							} else {
547								klarna_payments.logToFile( "Checkout error | " + err )
548								klarna_payments.failOrder(
549									"submission",
550									'<div class="woocommerce-error">' + "Checkout error" + "</div>",
551								)
552							}
553						}
554					},
555					error: function ( data ) {
556						try {
557							klarna_payments.logToFile( "AJAX error | " + JSON.stringify( data ) )
558						} catch ( e ) {
559							klarna_payments.logToFile( "AJAX error | Failed to parse error message." )
560						}
561						klarna_payments.failOrder(
562							"ajax-error",
563							'<div class="woocommerce-error">Internal Server Error</div>',
564						)
565					},
566				} )
567			}
568		},
569
570		/**
571		 * Fails the order with Klarna on a checkout error and timeout.
572		 * @param {string} event
573		 */
574		failOrder: function ( event, error_message ) {
575			// Re-enable the form.
576			$( "body" ).trigger( "updated_checkout" )
577			$( "form.checkout" ).removeClass( "processing" )
578			$( "form.checkout" ).unblock()
579
580			// Print error messages, and trigger checkout_error, and scroll to notices.
581			$( ".woocommerce-NoticeGroup-checkout, .woocommerce-error, .woocommerce-message" ).remove()
582			$( "form.checkout" ).prepend(
583				'<div class="woocommerce-NoticeGroup woocommerce-NoticeGroup-checkout">' + error_message + "</div>",
584			) // eslint-disable-line max-len
585			$( "form.checkout" ).removeClass( "processing" ).unblock()
586			$( "form.checkout" ).find( ".input-text, select, input:checkbox" ).trigger( "validate" ).blur()
587			$( document.body ).trigger( "checkout_error", [ error_message ] )
588			$.scroll_to_notices( $( "form.checkout" ) )
589		},
590
591		/**
592		 * Logs the message to the klarna payments log in WooCommerce.
593		 * @param {string} message
594		 */
595		logToFile: function ( message ) {
596			klarna_payments.log( message )
597			$.ajax( {
598				url: klarna_payments_params.log_to_file_url,
599				type: "POST",
600				dataType: "json",
601				data: {
602					message: message,
603					nonce: klarna_payments_params.log_to_file_nonce,
604				},
605			} )
606		},
607	}
608	klarna_payments.start()
609	$( document ).ready( function () {
610		klarna_payments.setRadioButtonValues()
611	} )
612
613	$( document ).ajaxComplete( function () {
614		klarna_payments.setRadioButtonValues()
615	} )
616
617	$( document ).on( "click", klarna_payments.submit_button_selectors, function ( e ) {
618		// No strict comparison: wp_localize_script() converts booleans to strings "1", respectively, "0".
619		if ( true == klarna_payments_params.pay_for_order ) {
620			klarna_payments.klarnaPayForOrder( e )
621		} else {
622			klarna_payments.orderSubmit( e )
623		}
624	} )
625} )

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.