Skip to content

Commit

Permalink
Merge pull request #371 from krokedil/develop
Browse files Browse the repository at this point in the history
Version 3.3.0
  • Loading branch information
MichaelBengtsson committed Jan 15, 2024
2 parents 9e1ccec + f9beb88 commit 325928f
Show file tree
Hide file tree
Showing 18 changed files with 1,148 additions and 342 deletions.
644 changes: 378 additions & 266 deletions assets/js/klarna-payments.js

Large diffs are not rendered by default.

66 changes: 65 additions & 1 deletion classes/class-kp-api.php
Expand Up @@ -166,6 +166,71 @@ public function cancel_recurring_order( $country, $recurring_token ) {
return self::check_for_api_error( $response );
}

/**
* Get the Klarna order from the order management API.
*
* @param string $country The Klarna country to use.
* @param string $klarna_order_id The Klarna order id.
*
* @return array|WP_Error The response from Klarna.
*/
public function get_klarna_om_order( $country, $klarna_order_id ) {
$request = new KP_Get_Order(
array(
'country' => $country,
'klarna_order_id' => $klarna_order_id,
)
);
$response = $request->request();

return self::check_for_api_error( $response );
}

/**
* Upsell the klarna order.
*
* @param string $country The Klarna country to use.
* @param string $klarna_order_id The Klarna order id.
* @param int $order_id The WooCommerce order id.
*
* @return array|WP_Error The response from Klarna.
*/
public function upsell_klarna_order( $country, $klarna_order_id, $order_id ) {
$request = new KP_Upsell_Order(
array(
'country' => $country,
'klarna_order_id' => $klarna_order_id,
'order_id' => $order_id,
)
);
$response = $request->request();

return self::check_for_api_error( $response );
}

/**
* Return the session from Klarna Payments.
*
* @param string $session_id The Klarna session id.
* @param string $country The Klarna country to use.
* @return array|WP_Error The response from Klarna.
*/
public function get_session( $session_id, $country = null ) {
if ( ! $country ) {
$country = kp_get_klarna_country();
}

$request = new KP_Get_Session(
array(
'session_id' => $session_id,
'country' => $country,
)
);
$response = $request->request();

return self::check_for_api_error( $response );
}

/**
* Checks for WP Errors and returns either the response or a WP Error..
*
Expand All @@ -182,5 +247,4 @@ private static function check_for_api_error( $response ) {
}
return $response;
}

}
2 changes: 1 addition & 1 deletion classes/class-kp-assets.php
Expand Up @@ -41,7 +41,7 @@ public function enqueue_checkout_script() {
}

$settings = get_option( 'woocommerce_klarna_payments_settings', array() );
if ( 'yes' !== $settings['enabled'] ?? 'no' ) {
if ( 'yes' !== ( $settings['enabled'] ?? 'no' ) ) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion classes/class-kp-banners.php
Expand Up @@ -21,7 +21,6 @@ public function __construct() {
add_action( 'in_admin_header', array( $this, 'klarna_banner' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'load_admin_css' ) );
add_action( 'wp_ajax_hide_klarna_kp_banner', array( $this, 'hide_klarna_kp_banner' ) );
add_action( 'wp_ajax_nopriv_hide_klarna_kp_banner', array( $this, 'hide_klarna_kp_banner' ) );
}

/**
Expand Down Expand Up @@ -196,6 +195,7 @@ public static function settings_sidebar( $parent_options ) {
* Hide Klarna banner in admin pages for.
*/
public function hide_klarna_kp_banner() {
check_ajax_referer( 'hide-klarna-banner', '_wpnonce' );
$permanent = ( array_key_exists( 'permanent', $_POST ) && 'true' === $_POST['permanent'] ); //phpcs:ignore WordPress.Security.NonceVerification.Missing -- It is my understanding that WP checks the nonce before triggering the action?
if ( $permanent ) {
set_transient( 'klarna_kp_hide_banner', '1' );
Expand Down
2 changes: 1 addition & 1 deletion classes/class-kp-checkout.php
Expand Up @@ -57,4 +57,4 @@ public function html_client_token( $session_token = false ) {
<input type="hidden" id="kp_client_token" value="<?php echo esc_html( $session_token ); ?>" >
<?php
}
} new KP_Checkout();
}
149 changes: 149 additions & 0 deletions classes/class-kp-klarna-express-checkout.php
@@ -0,0 +1,149 @@
<?php
/**
* Handle the integration with Klarna Express Checkout.
*
* @package WC_Klarna_Payments/Classes
*/

defined( 'ABSPATH' ) || exit;

use Krokedil\KlarnaExpressCheckout\KlarnaExpressCheckout;

/**
* Class KP_Klarna_Express_Checkout
*/
class KP_Klarna_Express_Checkout {
/**
* The Klarna Express Checkout class.
*
* @var KlarnaExpressCheckout
*/
private $klarna_express_checkout;

/**
* Class constructor.
*
* @return void
*/
public function __construct() {
$this->klarna_express_checkout = new KlarnaExpressCheckout();

$this->klarna_express_checkout->ajax()->set_get_payload( array( $this, 'get_payload' ) );
$this->klarna_express_checkout->ajax()->set_finalize_callback( array( $this, 'finalize_callback' ) );
}

/**
* Get order data for the cart.
*
* @return KP_Order_Data
*/
public function get_order_data_helper() {
$settings = get_option( 'woocommerce_klarna_payments_settings', array() );
$customer_type = $settings['customer_type'] ?? 'b2c';
$order_data_helper = new KP_Order_Data( $customer_type ); // Should always use the cart.

return $order_data_helper;
}

/**
* Get the payload for the Klarna Express Checkout.
*
* @return array
*/
public function get_payload() {
$order_data_helper = $this->get_order_data_helper();

$payload = array(
'purchase_country' => kp_get_klarna_country(),
'purchase_currency' => get_woocommerce_currency(),
'locale' => kp_get_locale(),
'order_amount' => $order_data_helper->order_data->get_total(),
'order_tax_amount' => $order_data_helper->order_data->get_total_tax(),
'order_lines' => $order_data_helper->get_klarna_order_lines_array(),
);

return $payload;
}

/**
* Finalize order callback handler.
*
* @param string $auth_token The auth token from Klarna.
* @param string $order_id The order ID.
* @param string $order_key The order key.
*
* @throws Exception If the order is invalid.
* @return array
*/
public function finalize_callback( $auth_token, $order_id, $order_key ) {
// Get the order from the order ID.
$order = wc_get_order( $order_id );

// Verify the order.
if ( ! $order ) {
throw new Exception( __( 'Invalid order.', 'klarna-payments-for-woocommerce' ) ); // phpcs:ignore
}

// Verify the order key.
if ( $order->get_order_key() !== $order_key ) {
throw new Exception( __( 'Invalid order key.', 'klarna-payments-for-woocommerce' ) ); // phpcs:ignore
}

add_filter( 'http_headers_useragent', array( $this, 'add_to_useragent' ) );

// Make a place order call to Klarna.
$place_order_response = KP_WC()->api->place_order( kp_get_klarna_country(), $auth_token, $order_id );

// Verify the response.
if ( is_wp_error( $place_order_response ) ) {
throw new Exception( $place_order_response->get_error_message() ); // phpcs:ignore
}

$fraud_status = $place_order_response['fraud_status'];
switch ( $fraud_status ) {
case 'ACCEPTED':
kp_process_accepted( $order, $place_order_response );
kp_unset_session_values();
return array(
'result' => 'success',
'redirect' => $place_order_response['redirect_url'],
);
case 'PENDING':
kp_process_pending( $order, $place_order_response );
kp_unset_session_values();
return array(
'result' => 'success',
'redirect' => $place_order_response['redirect_url'],
);
case 'REJECTED':
kp_process_rejected( $order, $place_order_response );
kp_unset_session_values();
return array(
'result' => 'error',
'redirect' => $order->get_cancel_order_url_raw(),
);
default:
kp_unset_session_values();
return array(
'result' => 'error',
'redirect' => $order->get_cancel_order_url_raw(),
);
}
}

/**
* Add to user agent.
*
* @param string $user_agent The user agent.
*
* @return string
*/
public function add_to_useragent( $user_agent ) {
// Only if the useragent contains KP.
if ( strpos( $user_agent, 'KP' ) !== false ) {
$user_agent .= ' KEC: ' . KlarnaExpressCheckout::VERSION;
}

return $user_agent;
}
}

0 comments on commit 325928f

Please sign in to comment.