Skip to content

Commit

Permalink
feat: work on a new virtual action system for ajax payment redirection
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcuzz committed Mar 15, 2024
1 parent 1dadd17 commit 777158a
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 136 deletions.
3 changes: 0 additions & 3 deletions assets/css/vipps-recurring.css

This file was deleted.

6 changes: 0 additions & 6 deletions includes/admin/vipps-recurring-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,6 @@
'default' => '',
'desc_tip' => true,
],
'special_actions_page_id' => [
'type' => 'page_dropdown',
'title' => __( 'Special actions page', 'vipps-recurring-payments-gateway-for-woocommerce' ),
'description' => __( 'The page to use for special pages, like a cancelled purchase.', 'vipps-recurring-payments-gateway-for-woocommerce' ),
'show_option_none' => __( 'Create a new page', 'vipps-recurring-payments-gateway-for-woocommerce' )
],
'default_reserved_charge_status' => [
'type' => 'select',
'title' => __( 'Default status to give orders with a reserved charge', 'vipps-recurring-payments-gateway-for-woocommerce' ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

defined( 'ABSPATH' ) || exit;

get_header();

?>

<div id="vipps-mobilepay-recurring-app"></div>

<?php

get_footer();

?>
78 changes: 1 addition & 77 deletions includes/wc-gateway-vipps-recurring.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,6 @@ class WC_Gateway_Vipps_Recurring extends WC_Payment_Gateway {
*/
public string $api_url;

/**
* The page to redirect to for cancelled orders
*/
public int $special_actions_page_id;

/**
* The default status to give pending renewals
*/
Expand Down Expand Up @@ -152,7 +147,6 @@ public function __construct() {
$this->secret_key = $this->get_option( 'secret_key' );
$this->client_id = $this->get_option( 'client_id' );
$this->subscription_key = $this->get_option( 'subscription_key' );
$this->special_actions_page_id = (int) $this->get_option( 'special_actions_page_id' );
$this->default_renewal_status = $this->get_option( 'default_renewal_status' );
$this->default_reserved_charge_status = $this->get_option( 'default_reserved_charge_status' );
$this->transition_renewals_to_completed = $this->get_option( 'transition_renewals_to_completed' );
Expand Down Expand Up @@ -344,77 +338,6 @@ public function process_redirect_payment( $order_id ): void {
$status = $this->check_charge_status( $order_id );

WC_Vipps_Recurring_Logger::log( sprintf( "[%s] process_redirect_payment: charge status is: %s", $order_id, $status ) );

$this->maybe_redirect_to_cancelled_order_page( $status );
}

/**
* @param $status
*/
public function maybe_redirect_to_cancelled_order_page( $status ): void {
if ( $status !== 'CANCELLED' ) {
return;
}

// redirect to check out, or cancelled page?
$page = $this->ensure_special_actions_page();
wp_redirect( $page->guid . '?vipps_recurring_page=cancelled_payment' );

exit;
}

/**
* @return array|WC_Vipps_Recurring_Exception|WP_Post|null
*/
public function ensure_special_actions_page() {
if ( $this->special_actions_page_id ) {
$page = get_post( $this->special_actions_page_id );

if ( $page ) {
return $page;
}

$this->update_option( 'special_actions_page_id', 0 );
}

// Determine what author to use by the currently logged-in user
$author = null;
if ( current_user_can( 'manage_options' ) ) {
$author = wp_get_current_user();
}

// If author is null it means it was not installed through the UI, wp-cli maybe
// Set author to random administrator
if ( ! $author ) {
$all_admins = get_users( [
'role' => 'administrator'
] );

if ( $all_admins ) {
$all_admins = array_reverse( $all_admins );
$author = $all_admins[0];
}
}

$author_id = $author->ID ?? 0;

$page_data = [
'post_title' => __( 'Vipps/MobilePay Recurring Payments specials', 'vipps-recurring-payments-gateway-for-woocommerce' ),
'post_status' => 'publish',
'post_author' => $author_id,
'post_type' => 'page',
'post_content' => ''
];

$post_id = wp_insert_post( $page_data );

if ( is_wp_error( $post_id ) ) {
return new WC_Vipps_Recurring_Exception( __( 'Could not create or find the "Vipps/MobilePay Recurring Payments specials" page', 'vipps-recurring-payments-gateway-for-woocommerce' ) . ": " . $post_id->get_error_message() );
}

$this->update_option( 'special_actions_page_id', $post_id );

return get_post( $post_id );
}

/**
Expand Down Expand Up @@ -1528,6 +1451,7 @@ public function process_payment( $order_id, bool $retry = true, bool $previous_e
$agreement_url = get_home_url();
}

// todo: point to our new page for payment redirection
$redirect_url = $this->get_return_url( $order );

// total no longer returns the order amount when gateway is being changed
Expand Down
67 changes: 67 additions & 0 deletions includes/wc-vipps-recurring-rest-api.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

defined( 'ABSPATH' ) || exit;

class WC_Vipps_Recurring_Rest_Api {
private string $api_namespace = 'vipps-mobilepay-recurring/v1';

private static ?WC_Vipps_Recurring_Rest_Api $instance = null;

private ?WC_Gateway_Vipps_Recurring $gateway = null;

/**
* Returns the *Singleton* instance of this class.
*
* @return WC_Vipps_Recurring_Rest_Api
*/
public static function get_instance(): WC_Vipps_Recurring_Rest_Api {
if ( null === self::$instance ) {
self::$instance = new self();
}

return self::$instance;
}

public function __construct() {
$this->gateway = WC_Gateway_Vipps_Recurring::get_instance();

add_action( 'rest_api_init', [ $this, 'init' ] );
}

public function init() {
register_rest_route( $this->api_namespace, '/orders/status/(?P<order_id>[0-9]+)', [
'methods' => 'GET',
'callback' => [ $this, 'order_status' ],
'permission_callback' => function () {
return current_user_can( '__return_true' );
}
] );
}

/**
* @throws WC_Vipps_Recurring_Exception
* @throws WC_Vipps_Recurring_Temporary_Exception
* @throws WC_Vipps_Recurring_Config_Exception
*/
public function order_status( WP_REST_Request $request ) {
$order_id = $request->get_param( 'order_id' );
$order_key = $request->get_param( 'key' );

$order = wc_get_order( $order_id );
if ( ! $order || $order_key !== $order->get_order_key() ) {
return new WP_Error(
'not_found',
'Order not found.',
[ 'status' => 404 ]
);
}

$this->gateway->check_charge_status( $order_id );
$order = wc_get_order( $order_id );

return [
'status' => $order->get_status(),
'redirect_url' => $order->get_checkout_order_received_url()
];
}
}
3 changes: 2 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import "./main.scss";
import createApp from "./lib/create-app";
import PaymentRedirectPage from "./pages/PaymentRedirectPage";

if (document.getElementById("vipps-mobilepay-recurring-app")) {
createApp(document.querySelector("#vipps-mobilepay-recurring-app"), <div />);
createApp(document.querySelector("#vipps-mobilepay-recurring-app"), <PaymentRedirectPage/>);
}
4 changes: 4 additions & 0 deletions src/main.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.vipps-recurring-icon {
width: 70px;
}

.payment-transport-page {
//
}
7 changes: 7 additions & 0 deletions src/pages/PaymentRedirectPage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function PaymentRedirectPage() {
return (
<div>
Checking your payment. Please wait.
</div>
)
}
3 changes: 0 additions & 3 deletions src/pages/PaymentTransportPage.jsx

This file was deleted.

96 changes: 50 additions & 46 deletions woo-vipps-recurring.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ class WC_Vipps_Recurring {

public array $ajax_config = [];

public array $special_pages = [];

/**
* Returns the *Singleton* instance of this class.
*
Expand Down Expand Up @@ -160,19 +158,13 @@ public function init() {
require_once __DIR__ . '/includes/wc-vipps-recurring-logger.php';
require_once __DIR__ . '/includes/wc-gateway-vipps-recurring.php';
require_once __DIR__ . '/includes/wc-vipps-recurring-admin-notices.php';
require_once __DIR__ . '/includes/wc-vipps-recurring-rest-api.php';

self::load_plugin_textdomain( 'vipps-recurring-payments-gateway-for-woocommerce', false, plugin_basename( __DIR__ ) . '/languages' );

$this->notices = WC_Vipps_Recurring_Admin_Notices::get_instance( __FILE__ );
$this->gateway = WC_Gateway_Vipps_Recurring::get_instance();

$this->special_pages = [
'cancelled_payment' => [
'title' => __( 'Cancelled payment', 'vipps-recurring-payments-gateway-for-woocommerce' ),
// translators: %s: brand (Vipps or MobilePay)
'content' => sprintf( __( 'It looks like you cancelled your order in %s. If this was a mistake you can try again by checking out again :)', 'vipps-recurring-payments-gateway-for-woocommerce' ), $this->gateway->title )
]
];
WC_Vipps_Recurring_Rest_Api::get_instance();

add_action( 'wp_enqueue_scripts', [ $this, 'wp_enqueue_scripts' ] );

Expand Down Expand Up @@ -242,11 +234,12 @@ public function init() {
'order_handle_vipps_recurring_action'
] );

// Add a filter to control the content on our special action pages
add_filter( 'the_content', [ $this, 'special_action_page_content' ] );
add_filter( 'the_title', [ $this, 'special_action_page_title' ], 10, 2 );

add_action( 'woocommerce_api_wc_gateway_vipps_recurring', [ $this, 'handle_webhook_callback' ] );

// Custom actions
add_filter( 'generate_rewrite_rules', [ $this, 'custom_action_endpoints' ] );
add_filter( 'query_vars', [ $this, 'custom_action_query_vars' ] );
add_filter( 'template_include', [ $this, 'custom_action_page_template' ] );
}

/**
Expand Down Expand Up @@ -540,6 +533,32 @@ public function admin_menu_page_html() {
include __DIR__ . '/includes/pages/admin/vipps-recurring-admin-menu-page.php';
}

public function custom_action_endpoints( $rewrites ) {
$rewrites->rules = array_merge(
[ 'vipps-mobilepay-recurring-payment/?$' => 'index.php?vipps_recurring_action=payment-redirect' ],
$rewrites->rules
);

return $rewrites;
}

public function custom_action_query_vars( $query_vars ) {
$query_vars[] = 'vipps_recurring_action';

return $query_vars;
}

public function custom_action_page_template( $original_template ) {
$custom_action = get_query_var( 'vipps_recurring_action' );

if ( ! empty ( $custom_action ) ) {
include WC_VIPPS_RECURRING_PLUGIN_PATH . '/includes/pages/payment-redirect-page.php';
die;
}

return $original_template;
}

/**
* Force check status of all pending charges
*/
Expand Down Expand Up @@ -778,7 +797,6 @@ public function plugin_action_links( $links ): array {
* @version 3.1.0
*/
public function install() {
$this->gateway->ensure_special_actions_page();
$this->upgrade();
}

Expand All @@ -803,8 +821,23 @@ public function add_gateways( $methods ): array {
* Enqueue our CSS and other assets.
*/
public function wp_enqueue_scripts() {
wp_enqueue_style( 'woo-vipps-recurring', plugins_url( 'assets/css/vipps-recurring.css', __FILE__ ), [],
filemtime( __DIR__ . '/assets/css/vipps-recurring.css' ) );
wp_enqueue_style(
'woo-vipps-recurring',
WC_VIPPS_RECURRING_PLUGIN_URL . '/assets/build/index.css', [],
filemtime( WC_VIPPS_RECURRING_PLUGIN_PATH . '/assets/build/index.css' )
);

$asset = require WC_VIPPS_RECURRING_PLUGIN_PATH . '/assets/build/index.asset.php';

wp_enqueue_script(
'woo-vipps-recurring',
WC_VIPPS_RECURRING_PLUGIN_URL . '/assets/build/index.js',
$asset['dependencies'],
filemtime( WC_VIPPS_RECURRING_PLUGIN_PATH . '/assets/build/index.js' ),
true
);

wp_set_script_translations( 'woo-vipps-recurring', 'mediebank', WC_VIPPS_RECURRING_PLUGIN_PATH . '/languages' );
}

/**
Expand Down Expand Up @@ -854,35 +887,6 @@ public static function load_plugin_textdomain( $domain, $deprecated = false, $pl
return load_textdomain( $domain, $path . '/' . $mo_file, $locale );
}

public function get_special_page_text( string $value, string $part ): string {
$action = $_GET['vipps_recurring_page'] ?? '';
if ( ! isset( $this->special_pages[ $action ] ) ) {
return $value;
}

return $this->special_pages[ $action ][ $part ];
}

public function special_action_page_title( $title, $post_id ): string {
// If this is not our special actions page, do not override anything
if ( $post_id !== (int) $this->gateway->get_option( 'special_actions_page_id' ) ) {
return $title;
}

return $this->get_special_page_text( $title, 'title' );
}

public function special_action_page_content( $content ): string {
global $post;

// If this is not our special actions page, do not override anything
if ( $post->ID !== (int) $this->gateway->get_option( 'special_actions_page_id' ) ) {
return $content;
}

return $this->get_special_page_text( $content, 'content' );
}

public function handle_webhook_callback() {
wc_nocache_headers();
status_header( 202, "Accepted" );
Expand Down

0 comments on commit 777158a

Please sign in to comment.