Skip to content

Commit

Permalink
feat: changes for 2.0.2 (read the changelog)
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcuzz committed Oct 24, 2024
1 parent 6ed7a7f commit 86aba24
Show file tree
Hide file tree
Showing 34 changed files with 1,307 additions and 744 deletions.
8 changes: 8 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ Alternatively you could look into using WooCommerce "Early renewals": [https://d

== Changelog ==

= 2.0.2 =
* Fixed: Resubscribing to expired subscriptions is now possible when Checkout is enabled.
* Fixed: You are now informed that a Merchant Serial Number is required in order to enable Checkout.
* Fixed: Your applied coupons are now given the proper respect when Checkout is enabled.
* Fixed: The price is now set correctly when one off products are in a recurring cart when Checkout is enabled.
* Added: We now cancel initial orders after two hours to avoid checking them in cron forever.
* Added: You can now enable or disable deletion of changed or abandoned Checkout orders in the settings.

= 2.0.1 =
* Fixed: A conflict with some themes, like Salient, where this plugin would cause certain blocks to not load.
* Fixed: Products with a trial period and a sign up fee were not correctly dealt with when using the new Checkout.
Expand Down
2 changes: 1 addition & 1 deletion assets/build/checkout.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-element', 'wp-i18n'), 'version' => '6eaa0ac8875182e46d91');
<?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-element', 'wp-i18n'), 'version' => 'a65bf7a53eb74b650f0b');
2 changes: 1 addition & 1 deletion assets/build/checkout.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion assets/build/checkout.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 12 additions & 5 deletions includes/admin/vipps-recurring-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
'title_checkout' => [
'type' => 'title',
// translators: %s "use at your own risk" title
'title' => sprintf("<span style='color: #ff9800;' title='%s'>[BETA]</span>", __('Use at your own risk', 'vipps-recurring-payments-gateway-for-woocommerce')) . " " . __( 'Checkout settings', 'vipps-recurring-payments-gateway-for-woocommerce' ),
'title' => sprintf( "<span style='color: #ff9800;' title='%s'>[BETA]</span>", __( 'Use at your own risk', 'vipps-recurring-payments-gateway-for-woocommerce' ) ) . " " . __( 'Checkout settings', 'vipps-recurring-payments-gateway-for-woocommerce' ),
'description' => __( 'Vipps MobilePay Checkout replaces the normal WooCommerce checkout with an easier and more seamless checkout that allows you to pay with Vipps MobilePay (and soon also a credit card). Your customers will be able to provide their billing/shipping details directly from the Vipps MobilePay app. <br><br><strong>Important!</strong> Checkout for recurring payments <strong>only supports static shipping</strong> at the moment.', 'vipps-recurring-payments-gateway-for-woocommerce' ),
],
'checkout_enabled' => [
Expand All @@ -52,13 +52,20 @@
'type' => 'checkbox',
'default' => 'no',
],
'order_prefix' => [
'order_prefix' => [
'type' => 'text',
'title' => __('OrderId prefix', 'vipps-recurring-payments-gateway-for-woocommerce'),
'label' => __('OrderId prefix', 'vipps-recurring-payments-gateway-for-woocommerce'),
'description' => __('An alphanumeric text string to use as a prefix on checkout orders from your shop, to avoid duplicate order ids.','vipps-recurring-payments-gateway-for-woocommerce'),
'title' => __( 'OrderId prefix', 'vipps-recurring-payments-gateway-for-woocommerce' ),
'label' => __( 'OrderId prefix', 'vipps-recurring-payments-gateway-for-woocommerce' ),
'description' => __( 'An alphanumeric text string to use as a prefix on checkout orders from your shop, to avoid duplicate order ids.', 'vipps-recurring-payments-gateway-for-woocommerce' ),
'default' => ''
],
'checkout_cleanup_abandoned_orders' => [
'title' => __( 'Cleanup changed/abandoned orders', 'vipps-recurring-payments-gateway-for-woocommerce' ),
'label' => __( 'Cleanup changed/abandoned orders', 'vipps-recurring-payments-gateway-for-woocommerce' ),
'description' => __( 'Automatically clean up Checkout orders where the order was abandoned, or the specification changed (runs every hour).', 'vipps-recurring-payments-gateway-for-woocommerce' ),
'type' => 'checkbox',
'default' => 'no',
],
'title_api' => [
'type' => 'title',
'title' => __( 'API settings', 'vipps-recurring-payments-gateway-for-woocommerce' ),
Expand Down
75 changes: 68 additions & 7 deletions includes/wc-gateway-vipps-recurring.php
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,13 @@ public function check_charge_status( $order_id, $skip_lock = false ): string {

$agreement = $this->get_agreement_from_order( $order );
if ( ! $agreement ) {
// If there is no agreement we can't complete Checkout orders. Let Checkout deal with this through an action.
$order_initial = WC_Vipps_Recurring_Helper::get_meta( $order, WC_Vipps_Recurring_Helper::META_ORDER_INITIAL );

if ( $order_initial && $order->get_payment_method() === $this->id ) {
do_action( 'wc_vipps_recurring_check_charge_status_no_agreement', $order );
}

return 'INVALID';
}

Expand Down Expand Up @@ -527,6 +534,7 @@ public function check_charge_status( $order_id, $skip_lock = false ): string {
}

$charge = $this->get_latest_charge_from_order( $order );

if ( ! $charge ) {
// we're being rate limited
return 'SUCCESS';
Expand Down Expand Up @@ -1377,8 +1385,14 @@ public function create_vipps_agreement_from_order( $order, $subscription = null,
// If we have more products in our cart we know that the agreement total should just be the sum of the subscription total.
// We then create an initialCharge for the full initial sum, including the rest of the cart.
// We can safely ignore all of the above code regarding $agreement_total because this will never happen for a subscription switch.
$recurring_item_total = $subscription_item->get_total() + $order->get_shipping_total();

if ( $has_more_products ) {
$agreement_total = $subscription_item->get_total() + $order->get_shipping_total();
$agreement_total = $recurring_item_total;
}

if ( WC()->cart->has_discount() ) {
$agreement_total = (float) $parent_product->get_price( 'code' ) + $order->get_shipping_total();
}

$has_trial = WC_Subscriptions_Product::get_trial_length( $product ) !== 0;
Expand Down Expand Up @@ -1448,7 +1462,7 @@ public function create_vipps_agreement_from_order( $order, $subscription = null,
}

if ( $has_campaign ) {
$campaign_price = $has_free_campaign ? $sign_up_fee : $order->get_total();
$campaign_price = $has_free_campaign ? $sign_up_fee : $recurring_item_total;

$campaign_type = WC_Vipps_Agreement_Campaign::TYPE_PRICE_CAMPAIGN;
$campaign_period = null;
Expand All @@ -1460,10 +1474,10 @@ public function create_vipps_agreement_from_order( $order, $subscription = null,
->set_count( WC_Subscriptions_Product::get_trial_length( $product ) )
->set_unit( strtoupper( WC_Subscriptions_Product::get_trial_period( $product ) ) );
} else {
$next_payment = new DateTime( '@' . $subscription->get_time( 'next_payment' ) );
$end_date = new DateTime( '@' . $subscription->get_time( 'end' ) );
$next_payment = WC_Subscriptions_Product::get_first_renewal_payment_date( $product );
$end_date = WC_Subscriptions_Product::get_expiration_date( $product );

$campaign_end_date = $subscription->get_time( 'end' ) === 0 ? $next_payment : $end_date;
$campaign_end_date = $end_date === 0 ? $next_payment : $end_date;
}

$agreement = $agreement->set_campaign(
Expand Down Expand Up @@ -1872,6 +1886,20 @@ public function process_admin_options(): bool {
}

$checkout_enabled = $this->get_option( 'checkout_enabled' ) === "yes";
$test_mode = $this->get_option( 'test_mode' ) === "yes" || WC_VIPPS_RECURRING_TEST_MODE;

// Validate that we have an MSN set, as it is required in Checkout.
$merchant_serial_number = $test_mode ? $this->get_option( 'test_merchant_serial_number' ) : $this->get_option( 'merchant_serial_number' );
if ( empty( $merchant_serial_number ) ) {
$this->admin_notify( __( 'You need to provide a Merchant Serial Number before you can enable Checkout.', 'vipps-recurring-payments-gateway-for-woocommerce' ), "error" );

// Disable checkout if we do not have an MSN value.
$this->update_option( 'checkout_enabled', 'no' );
update_option( WC_Vipps_Recurring_Helper::OPTION_CHECKOUT_ENABLED, false, true );

return $saved;
}

update_option( WC_Vipps_Recurring_Helper::OPTION_CHECKOUT_ENABLED, $checkout_enabled, true );

if ( $checkout_enabled ) {
Expand Down Expand Up @@ -2500,6 +2528,11 @@ public function checkout_is_available() {
* @throws Exception
*/
public function create_partial_order( $checkout = false ): int {
$order_id = apply_filters( 'woocommerce_create_order', null );
if ( $order_id ) {
return $order_id;
}

// This is necessary for some plugins, like YITH Dynamic Pricing, that adds filters to get_price depending on whether is_checkout is true.
// so basically, since we are impersonating WC_Checkout here, we should define this constant too
wc_maybe_define_constant( 'WOOCOMMERCE_CHECKOUT', true );
Expand All @@ -2512,11 +2545,37 @@ public function create_partial_order( $checkout = false ): int {
WC()->cart->calculate_totals();
do_action( 'wc_vipps_recurring_before_create_express_checkout_order', WC()->cart );

$order_id = absint( WC()->session->get( 'order_awaiting_payment' ) );
$cart_hash = WC()->cart->get_cart_hash();
$order = $order_id ? wc_get_order( $order_id ) : null;

/**
* If there is an order pending payment, we can resume it here so
* long as it has not changed. If the order has changed, i.e.
* different items or cost, create a new order. We use a hash to
* detect changes which is based on cart items + order total.
*/
if ( $order && $order->has_cart_hash( $cart_hash ) && $order->has_status( array( 'pending', 'failed' ) ) ) {
/**
* Indicates that we are resuming checkout for an existing order (which is pending payment, and which
* has not changed since it was added to the current shopping session).
*
* @param int $order_id The ID of the order being resumed.
*
* @since 3.0.0 or earlier
*
*/
do_action( 'woocommerce_resume_order', $order_id );

// Remove all items - we will re-add them later.
$order->remove_order_items();
} else {
$order = new WC_Order();
}

// We store this in the order, so we don't have to access the cart when initiating payment. This allows us to restart orders etc.
$needs_shipping = WC()->cart->needs_shipping();

$order = new WC_Order();
$order->set_status( 'pending' );
$order->set_payment_method( $this );

try {
Expand All @@ -2529,6 +2588,8 @@ public function create_partial_order( $checkout = false ): int {

// We use 'checkout' as the created_via key as per requests, but allow merchants to use their own.
$created_via = apply_filters( 'wc_vipps_recurring_express_checkout_created_via', 'checkout', $order, $checkout );

$order->set_cart_hash( $cart_hash );
$order->set_created_via( $created_via );

$order->update_meta_data( WC_Vipps_Recurring_Helper::META_ORDER_IS_EXPRESS, 1 );
Expand Down
Loading

0 comments on commit 86aba24

Please sign in to comment.