📦 NEW: Billing features

This commit is contained in:
Austin Ginder 2021-01-01 19:57:01 -05:00
parent 4dea0b356b
commit ab8e127841
8 changed files with 1486 additions and 77 deletions

View file

@ -101,9 +101,10 @@ class Account {
return [];
}
$user_id = get_current_user_id();
$account = $this->account();
$record = [
"timeline" => $this->process_logs(),
"account" => $this->account(),
"account" => $account,
"invites" => $this->invites(),
"users" => $this->users(),
"domains" => $this->domains(),
@ -112,7 +113,7 @@ class Account {
"owner" => false,
];

if ( $user_id == $record["account"]["billing_user_id"] ) {
if ( $user_id == $account["plan"]->billing_user_id ) {
$record["owner"] = true;
}
@ -127,12 +128,12 @@ class Account {
$plan->addons = empty( $plan->addons ) ? [] : $plan->addons;
$plan->limits = empty( $plan->limits ) ? (object) [ "storage" => 0, "visits" => 0, "sites" => 0 ] : $plan->limits;
$plan->interval = empty( $plan->interval ) ? "12" : $plan->interval;
$plan->billing_user_id = empty( $plan->billing_user_id ) ? 0 : (int) $plan->billing_user_id;
if ( ! is_array( $defaults->users ) ) {
$defaults->users = [];
}
return [
"account_id" => $this->account_id,
"billing_user_id" => (int) $account->billing_user_id,
"name" => html_entity_decode( $account->name ),
"plan" => $plan,
"metrics" => json_decode( $account->metrics ),
@ -360,7 +361,7 @@ class Account {
$result = (object) [
'account_id' => $account->account_id,
'renewal' => $plan->next_renewal,
'plan' => (int) $account->billing_user_id,
'plan' => (int) $plan->billing_user_id,
];
}
$response[] = $result;
@ -370,34 +371,98 @@ class Account {
}

public function generate_order() {
$configurations = ( new Configurations )->get();
$account = ( new Accounts )->get( $this->account_id );
$customer = new WC_Customer( $account->billing_user_id );
$address = $customer->get_billing_address();
$order = wc_create_order( [ 'customer_id' => $account->billing_user_id ] );
$plan = json_decode( $account->plan );
$customer = new \WC_Customer( $plan->billing_user_id );
$address = $customer->get_billing();
$order = wc_create_order( [ 'customer_id' => $plan->billing_user_id ] );

$site_names = array_column( self::sites(), "name" );
sort( $site_names );
$site_names = implode( ", ", $site_names );

if ( ! empty( $address ) ) {
$order->set_address( $address, 'billing' );
$order->set_address( $address, 'shipping' );
$order->calculate_totals();
}

// Add addon product
$line_item_id = $order->add_product( get_product( '11062' ), 1 );
$line_item_id = $order->add_product( get_product( $configurations->woocommerce->hosting_plan ), 1 );

// Assign price
$order->get_items()[ $line_item_id ]->set_total( '99' );
$order->get_items()[ $line_item_id ]->set_subtotal( $plan->price );
$order->get_items()[ $line_item_id ]->set_total( $plan->price );
$order->get_items()[ $line_item_id ]->add_meta_data( "Details", $plan->name . "\n\n" . $site_names );
$order->get_items()[ $line_item_id ]->save_meta_data();
$order->get_items()[ $line_item_id ]->save();

// Assign meta field
$order->get_items()[ $line_item_id ]->get_meta( "Details" );
if ( $plan->addons && count( $plan->addons ) > 0 ) {
foreach ( $plan->addons as $addon ) {
$line_item_id = $order->add_product( get_product( $configurations->woocommerce->addons ), $addon->quantity );
$order->get_items()[ $line_item_id ]->set_subtotal( $addon->price * $addon->quantity );
$order->get_items()[ $line_item_id ]->set_total( $addon->price * $addon->quantity );
$order->get_items()[ $line_item_id ]->add_meta_data( "Details", $addon->name );
$order->get_items()[ $line_item_id ]->save_meta_data();
$order->get_items()[ $line_item_id ]->save();
}
}

if ( $plan->usage->sites > $plan->limits->sites ) {
$price = $configurations->usage_pricing->sites->cost;
if ( $plan->interval != $configurations->usage_pricing->sites->interval ) {
$price = $configurations->usage_pricing->sites->cost / ($configurations->usage_pricing->sites->interval / $plan->interval );
}
$quantity = $plan->usage->sites - $plan->limits->sites;
$total = $price * $quantity;
$line_item_id = $order->add_product( get_product( $configurations->woocommerce->usage ), $quantity );
$order->get_items()[ $line_item_id ]->set_subtotal( $total );
$order->get_items()[ $line_item_id ]->set_total( $total );
$order->get_items()[ $line_item_id ]->add_meta_data( "Details", "Extra Sites" );
$order->get_items()[ $line_item_id ]->save_meta_data();
$order->get_items()[ $line_item_id ]->save();
}

if ( $plan->usage->storage > ( $plan->limits->storage * 1024 * 1024 * 1024 ) ) {
$price = $configurations->usage_pricing->storage->cost;
if ( $plan->interval != $configurations->usage_pricing->storage->interval ) {
$price = $configurations->usage_pricing->storage->cost / ( $configurations->usage_pricing->storage->interval / $plan->interval );
}
$extra_storage = ( $plan->usage->storage / 1024 / 1024 / 1024 ) - $plan->limits->storage;
$quantity = ceil ( $extra_storage / $configurations->usage_pricing->storage->quantity );
$total = $price * $quantity;
$line_item_id = $order->add_product( get_product( $configurations->woocommerce->usage ), $quantity );
$order->get_items()[ $line_item_id ]->set_subtotal( $total );
$order->get_items()[ $line_item_id ]->set_total( $total );
$order->get_items()[ $line_item_id ]->add_meta_data( "Details", "Extra Storage" );
$order->get_items()[ $line_item_id ]->save_meta_data();
$order->get_items()[ $line_item_id ]->save();
}

if ( $plan->usage->visits > $plan->limits->visits ) {
$price = $configurations->usage_pricing->traffic->cost;
if ( $plan->interval != $configurations->usage_pricing->traffic->interval ) {
$price = $configurations->usage_pricing->traffic->cost / ( $configurations->usage_pricing->traffic->interval / $plan->interval );
}
$quantity = ceil ( ( $plan->usage->visits - $plan->limits->visits ) / $configurations->usage_pricing->traffic->quantity );
$total = $price * $quantity;
$line_item_id = $order->add_product( get_product( $configurations->woocommerce->usage ), $quantity );
$order->get_items()[ $line_item_id ]->set_subtotal( $total );
$order->get_items()[ $line_item_id ]->set_total( $total );
$order->get_items()[ $line_item_id ]->add_meta_data( "Details", "Extra Visits" );
$order->get_items()[ $line_item_id ]->save_meta_data();
$order->get_items()[ $line_item_id ]->save();
}

// Set payment method
// TODO fetch customer selected payment method
$order->set_payment_method( $payment_gateways['stripe'] );

$order->calculate_totals();

if ( $plan->auto_pay == "true" ) {
$payment_id = ( new \WC_Payment_Tokens )->get_customer_default_token( $plan->billing_user_id )->get_id();
( new User( $plan->billing_user_id, true ) )->pay_invoice( $order->get_id(), $payment_id );
return;
}

// here we are adding some system notes to the order
// $order->update_status( "processing", 'Imported Order From Funnel', TRUE );
WC()->mailer()->customer_invoice( $order );
$order->add_order_note( __( 'Order details manually sent to customer.', 'woocommerce' ), false, true );
do_action( 'woocommerce_after_resend_order_email', $order, 'customer_invoice' );
}

public function delete() {

View file

@ -57,4 +57,61 @@ class Accounts extends DB {
return $accounts;
}

public function update_plan( $new_plan, $account_id ) {
$account = self::get( $account_id );
$plan = json_decode( $account->plan );
$total = $plan->price;
if ( count( $plan->addons ) > 0 ) {
foreach( $plan->addons as $addon ) {
$total = $total + $addon->price;
}
}
// Calculate credit or charge for paid plans when interval changes.
if ( $plan->status == "active" && $plan->interval != $new_plan["interval"] ) {
$now = new \DateTime();
$next_renewal = new \DateTime( $plan->next_renewal );
$remaining_time = $now->diff( $next_renewal );
$remaining_days = $remaining_time->format('%a');
$per_month_total = $total / $plan->interval;
$remaining_credit = ( $remaining_days / 30 ) * $per_month_total;
if ( $remaining_credit > 0 ) {
$plan->credit = $plan->credit + $remaining_credit;
}
if ( $remaining_credit < 0 ) {
$plan->charge = $plan->charge + $remaining_credit;
}
}
if ( $plan->status == "" ) {
$plan->status == "pending";
}
$plan->name = $new_plan["name"];
$plan->price = $new_plan["price"];
$plan->addons = $new_plan["addons"];
$plan->limits = $new_plan["limits"];
$plan->auto_pay = $new_plan["auto_pay"];
$plan->interval = $new_plan["interval"];
$plan->next_renewal = $new_plan["next_renewal"];
$plan->billing_user_id = $new_plan["billing_user_id"];

self::update( [ "plan" => json_encode( $plan ) ], [ "account_id" => $account_id ] );
}

public function process_renewals() {

$accounts = self::with_renewals();
$now = strtotime( "now" );
foreach ( $accounts as $account ) {
$plan = json_decode( $account->plan );
$next_renewal = strtotime ( $plan->next_renewal );
if ( ! empty( $next_renewal ) && $next_renewal < $now ) {
echo "Processing renewal for {$account->name} as it's past {$plan->next_renewal}\n";
( new Account( $account->account_id, true ) )->generate_order();
$plan->next_renewal = date("Y-m-d H:i:s", strtotime( "+{$plan->interval} month", $next_renewal ) );
echo "Next renewal in {$plan->interval} months will be {$plan->next_renewal}\n";
self::update( [ "plan" => json_encode( $plan ) ], [ "account_id" => $account->account_id ] );
}
}
}

}

View file

@ -194,6 +194,28 @@ class DB {
return $results;
}

static function renewals( $user_id ) {
global $wpdb;
$table = self::_table();
$sql = "SELECT *
FROM {$table}
WHERE {$table}.plan like '%,\"billing_user_id\":\"$user_id\"%'
order by {$table}.`name` ASC";
$results = $wpdb->get_results( $sql );
return $results;
}

static function with_renewals() {
global $wpdb;
$table = self::_table();
$sql = "SELECT *
FROM {$table}
WHERE {$table}.plan like '%\"next_renewal\":\"%'
order by {$table}.`name` ASC";
$results = $wpdb->get_results( $sql );
return $results;
}

static function fetch_domains( $conditions = [] ) {
global $wpdb;
$table = self::_table();

View file

@ -25,6 +25,50 @@ class User {
return $accounts;
}

public function set_as_primary( $token ) {
\WC_Payment_Tokens::set_users_default( $this->user_id, intval( $token ) );
$billing = self::billing();
foreach ( $billing->subscriptions as $item ) {
$subscription = (object) $item;
if ( $subscription->type == "woocommerce" ) {
self::update_payment_method( $subscription->account_id, intval( $token ) );
}
}
}

public function add_payment_method( $source_id ) {
$customer = new \WC_Stripe_Customer( $this->user_id );
$response = $customer->add_source( $source_id );
return $response;
}

public function delete_payment_method( $token_id ) {
$token = \WC_Payment_Tokens::get( $token_id );
if ( is_null( $token ) || $this->user_id !== $token->get_user_id() ) {
return "Error";
}
$was_default = $token->is_default();
\WC_Payment_Tokens::delete( $token_id );

if ( $was_default ) {
$payment_tokens = \WC_Payment_Tokens::get_customer_tokens( $this->user_id );

// Set default if another payment token found.
if ( count( $payment_tokens ) > 0 ) {
$other_token_id = array_keys( $payment_tokens )[0];
self::set_as_primary( $other_token_id );
$billing = self::billing();
foreach ( $billing->subscriptions as $item ) {
$subscription = (object) $item;
if ( $subscription->type == "woocommerce" ) {
self::update_payment_method( $subscription->account_id, intval( $other_token_id ) );
}
}
}
}
}

public function verify_accounts( $account_ids = [] ) {
if ( self::is_admin() ) {
return true;
@ -54,6 +98,207 @@ class User {
return false;
}

public function billing() {

$customer = new \WC_Customer( $this->user_id );
$address = $customer->get_billing();
$invoices = wc_get_orders( [ 'customer' => $this->user_id ] );
foreach ( $invoices as $key => $invoice ) {
$order = wc_get_order( $invoice );
$item_count = $order->get_item_count();
$invoices[$key] = [
"order_id" => $order->id,
"date" => wc_format_datetime( $order->get_date_created() ),
"status" => wc_get_order_status_name( $order->get_status() ),
"total" => $order->get_total(),
];
}
// Fetch CaptainCore subscriptions
$subscriptions = ( new Accounts )->renewals( $this->user_id );
foreach ( $subscriptions as $key => $subscription ) {
$plan = json_decode( $subscription->plan );
$plan->addons = ( empty( $plan->addons ) ) ? [] : $plan->addons;
$subscriptions[ $key ]->plan = $plan;
}
// Fetch WooCommerce subscriptions
$current_subscriptions = wcs_get_users_subscriptions( $this->user_id );
foreach ( $current_subscriptions as $key => $subscription ) {
$interval = $subscription->get_billing_period();
$line_items = $subscription->get_data()["line_items"];
$line_item = array_shift ( array_values ( $line_items ) );
$details = $line_item->get_meta_data();
foreach ( $details as $detail ) {
$item = $detail->get_data();
if ( isset( $item["key"]) && $item["key"] == "Details" ) {
$name = $item["value"];
}
}

if ( $interval == "month" ) {
$interval_count = "1";
} else {
$interval_count = "12";
}
$subscriptions[] = [
"account_id" => $subscription->id,
"name" => $name,
"type" => "woocommerce",
"plan" => (object) [
"name" => $line_item->get_name(),
"next_renewal" => empty( $subscription->get_date( "next_payment" ) ) ? "" : $subscription->get_date( "next_payment" ),
"price" => $subscription->get_total(),
"usage" => (object) [],
"limits" => (object) [],
"interval" => $interval_count,
"addons" => [],
],
"payment_method" => $subscription->get_payment_method_to_display( 'customer' ),
"status" => wcs_get_subscription_status_name( $subscription->get_status() ),
];
}
$payment_methods = [];
$payment_tokens = \WC_Payment_Tokens::get_customer_tokens( $this->user_id );
foreach ( $payment_tokens as $payment_token ) {
$type = strtolower( $payment_token->get_type() );
$card_type = $payment_token->get_card_type();
$payment_methods[] = [
'method' => [
'brand' => ( ! empty( $card_type ) ? ucfirst( $card_type ) : esc_html__( 'Credit card', 'woocommerce' ) ),
'gateway' => $payment_token->get_gateway_id(),
'last4' => $payment_token->get_last4(),
],
'expires' => $payment_token->get_expiry_month() . '/' . substr( $payment_token->get_expiry_year(), -2 ),
'is_default' => $payment_token->is_default(),
'token' => $payment_token->get_id(),
];
}

$billing = (object) [
"address" => $address,
"subscriptions" => $subscriptions,
"invoices" => $invoices,
"payment_methods" => $payment_methods,
];

return $billing;
}

public function update_payment_method( $invoice_id, $payment_id ) {

try {

$wc_token = \WC_Payment_Tokens::get( $payment_id );
$source_id = $wc_token->get_token();
$customer = new \WC_Stripe_Customer( $this->user_id );
$customer_id = $customer->get_id();
$source_object = \WC_Stripe_API::retrieve( 'sources/' . $source_id );

$prepared_source = (object) [
'token_id' => $payment_id,
'customer' => $customer_id,
'source' => $source_id,
'source_object' => $source_object,
];

$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
$payment_method = isset( $available_gateways[ 'stripe' ] ) ? $available_gateways[ 'stripe' ] : false;
$order = wc_get_order( $invoice_id );
$payment_method->save_source_to_order( $order, $prepared_source );
return array(
'result' => 'success',
);

} catch ( \WC_Stripe_Exception $e ) {
return array(
'result' => 'fail',
'message' => $e->getMessage(),
);
}
}

public function pay_invoice( $invoice_id, $payment_id ) {

try {

$wc_token = \WC_Payment_Tokens::get( $payment_id );
$source_id = $wc_token->get_token();
$customer = new \WC_Stripe_Customer( $this->user_id );
$customer_id = $customer->get_id();
$source_object = \WC_Stripe_API::retrieve( 'sources/' . $source_id );

$prepared_source = (object) [
'token_id' => $payment_id,
'customer' => $customer_id,
'source' => $source_id,
'source_object' => $source_object,
];

$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
$payment_method = isset( $available_gateways[ 'stripe' ] ) ? $available_gateways[ 'stripe' ] : false;
$order = wc_get_order( $invoice_id );
$order->set_payment_method( 'stripe' );
$payment_method->save_source_to_order( $order, $prepared_source );
$intent = $payment_method->create_intent( $order, $prepared_source );
// Confirm the intent after locking the order to make sure webhooks will not interfere.
if ( empty( $intent->error ) ) {
$payment_method->lock_order_payment( $order, $intent );
$intent = $payment_method->confirm_intent( $intent, $order, $prepared_source );
}

if ( ! empty( $intent->error ) ) {
$payment_method->maybe_remove_non_existent_customer( $intent->error, $order );

// We want to retry.
if ( $payment_method->is_retryable_error( $intent->error ) ) {
return $payment_method->retry_after_error( $intent, $order, $retry, $force_save_source, $previous_error, $use_order_source );
}

$payment_method->unlock_order_payment( $order );
$payment_method->throw_localized_message( $intent, $order );
}

if ( ! empty( $intent ) ) {
// Use the last charge within the intent to proceed.
$response = end( $intent->charges->data );
}

// Process valid response.
$payment_method->process_response( $response, $order );

// Remove cart.
if ( isset( WC()->cart ) ) {
WC()->cart->empty_cart();
}

// Unlock the order.
$payment_method->unlock_order_payment( $order );
$order->update_status( 'completed' );

// Return thank you page redirect.
return array(
'result' => 'success',
'redirect' => $payment_method->get_return_url( $order ),
);

} catch ( \WC_Stripe_Exception $e ) {
wc_add_notice( $e->getLocalizedMessage(), 'error' );
\WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );

do_action( 'wc_gateway_stripe_process_payment_error', $e, $order );

/* translators: error message */
$order->update_status( 'failed' );

return array(
'result' => 'fail',
'redirect' => '',
);
}

}

public function roles() {
return $this->roles;
}
@ -266,4 +511,8 @@ class User {
delete_user_meta( $this->user_id, 'requested_sites' );
}

public function user_id() {
return $this->user_id;
}

}

View file

@ -3549,12 +3549,30 @@ function captaincore_local_action_callback() {
"total" => $order->get_formatted_line_subtotal( $item ),
];
}

$payment_gateways = WC()->payment_gateways->payment_gateways();
$payment_method = $order->get_payment_method();
$payment_method_string = sprintf(
__( 'Payment via %s', 'woocommerce' ),
esc_html( isset( $payment_gateways[ $payment_method ] ) ? $payment_gateways[ $payment_method ]->get_title() : "Check" )
);

if ( $order->get_date_paid() ) {
$paid_on = sprintf(
__( 'Paid on %1$s @ %2$s', 'woocommerce' ),
wc_format_datetime( $order->get_date_paid() ),
wc_format_datetime( $order->get_date_paid(), get_option( 'time_format' ) )
);
}

$response = [
"order_id" => $order_data->id,
"created_at" => $order_data->date_created->getTimestamp(),
"status" => $order_data->status,
"line_items" => $order_line_items,
"total" => $order_data->total,
"payment_method" => $payment_method_string,
"paid_on" => $paid_on,
"total" => number_format( (float) $order_data->total, 2, '.', '' ),
];
echo json_encode( $response );
}
@ -3707,8 +3725,70 @@ function captaincore_account_action_callback() {
$cmd = $_POST['command'];
$everyone_commands = [
'requestSite',
'payInvoice',
'setAsPrimary',
'addPaymentMethod',
'deletePaymentMethod',
'deleteRequestSite',
'cancelPlan',
'updateBilling',
];

if ( $cmd == 'updateBilling' ) {
$request = (object) $_POST['value'];
$customer = new WC_Customer( $user->user_id() );
$customer->set_billing_address_1( $request->address_1 );
$customer->set_billing_address_2( $request->address_2 );
$customer->set_billing_city( $request->city );
$customer->set_billing_company( $request->company );
$customer->set_billing_country( $request->country );
$customer->set_billing_email( $request->email );
$customer->set_billing_first_name( $request->first_name );
$customer->set_billing_last_name( $request->last_name );
$customer->set_billing_phone( $request->phone );
$customer->set_billing_postcode( $request->postcode );
$customer->set_billing_state( $request->state );
$customer->save();
};

if ( $cmd == 'cancelPlan' ) {

$current_subscription = (object) $_POST['value'];
$current_user = $user->fetch();
$billing = $user->billing();
if ( $current_subscription->account_id == "" || $current_subscription->name == "" ) {
wp_die();
}
foreach ( $billing->subscriptions as $subscription ) {
if ( $subscription->account_id == $current_subscription->account_id && $subscription->name == $current_subscription->name ) {
// Build email
$to = get_option( 'admin_email' );
$subject = "Request cancel plan '{$current_subscription->name}'";
$body = "Request cancel plan '{$current_subscription->name}' #{$current_subscription->account_id} from {$current_user['name']}, <a href='mailto:{$current_user['email']}'>{$current_user['email']}</a>.";
$headers = [ 'Content-Type: text/html; charset=UTF-8' ];

// Send email
wp_mail( $to, $subject, $body, $headers );
}
}

}

if ( $cmd == 'requestPlanChanges' ) {
$current_user = $user->fetch();
$subscription = (object) $_POST['value'];
// Build email
$to = get_option( 'admin_email' );
$subject = "Request plan change from {$current_user['name']} <{$current_user['email']}>";
$body = "Change subscription '{$subscription->name}' to {$subscription->plan['name']} and {$subscription->plan['interval']} interval.";
$headers = [ 'Content-Type: text/html; charset=UTF-8' ];

// Send email
wp_mail( $to, $subject, $body, $headers );
}

$account_id = intval( $_POST['account_id'] );

// Only proceed if have permission to particular site id.
@ -3718,6 +3798,37 @@ function captaincore_account_action_callback() {
return;
}

if ( $cmd == 'payInvoice' ) {
// Pay with new credit card
if ( isset( $_POST['source_id'] ) ) {
$response = $user->add_payment_method( $_POST['source_id'] );
$payment_tokens = WC_Payment_Tokens::get_customer_tokens( $user->user_id() );
foreach ( $payment_tokens as $payment_token ) {
if( $payment_token->get_token() == $_POST['source_id'] ) {
$user->pay_invoice( $_POST['value'], $payment_token->get_id() );
$user->set_as_primary( $payment_token->get_id() );
}
}
wp_die();
}
// Pay with existing credit card
$user->pay_invoice( $_POST['value'], $_POST['payment_id'] );
$user->set_as_primary( $_POST['payment_id'] );
};

if ( $cmd == 'setAsPrimary' ) {
$user->set_as_primary( $_POST['value'] );
};

if ( $cmd == 'addPaymentMethod' ) {
$response = $user->add_payment_method( $_POST['value'] );
echo json_encode( $response );
};

if ( $cmd == 'deletePaymentMethod' ) {
$user->delete_payment_method( $_POST['value'] );
};

if ( $cmd == 'requestSite' ) {
$user->request_site( $_POST['value'] );
echo json_encode( $user->fetch_requested_sites() );
@ -4371,14 +4482,7 @@ function captaincore_ajax_action_callback() {
}

if ( $cmd == 'updatePlan' ) {
$account = ( new CaptainCore\Accounts )->get( $post_id );
$plan = json_decode( $account->plan );
$plan->name = $value["plan"]["name"];
$plan->price = $value["plan"]["price"];
$plan->addons = $value["plan"]["addons"];
$plan->limits = $value["plan"]["limits"];
$plan->interval = $value["plan"]["interval"];
( new CaptainCore\Accounts )->update( [ "plan" => json_encode( $plan ) ], [ "account_id" => $account->account_id ] );
( new CaptainCore\Accounts )->update_plan( $value["plan"], $post_id );
}

if ( $cmd == 'updateSettings' ) {
@ -5542,7 +5646,6 @@ function captaincore_get_checkout_payment_url( $payment_url ) {
// Replace with
// https://captcore-sitename.com/checkout-express/1918/?pay_for_order=true&key=wc_order_576c79296c346&subscription_renewal=true
$home_url = esc_url( home_url( '/' ) );

$new_payment_url = str_replace( $home_url . 'checkout/order-pay/', $home_url . 'checkout-express/', $payment_url );

return $new_payment_url;
@ -5978,6 +6081,9 @@ function load_captaincore_template( $original_template ) {
add_filter('redirect_canonical', 'disable_404_redirection_for_captaincore');
function disable_404_redirection_for_captaincore($redirect_url) {
global $wp;
if ( strpos( $wp->request, "checkout-express/" ) !== false ) {
return false;
}
if ( strpos( $wp->request, "account/" ) !== false ) {
return false;
}

View file

@ -1827,6 +1827,10 @@ div.update_logs table tr td:nth-child(1) {

/* WooCommerce billing adjustments */

.theme--light.v-data-table.invoice>.v-data-table__wrapper>table>tbody>tr:hover:not(.v-data-table__expanded__content):not(.v-data-table__empty-wrapper) {
background: transparent;
}

.woocommerce-order-details .shop_table.shop_table_responsive.my_account_orders.woocommerce-orders-table.woocommerce-MyAccount-subscriptions.woocommerce-orders-table--subscriptions,
.woocommerce-order-details header,
.woocommerce-order-details .order-again {

File diff suppressed because it is too large Load diff

View file

@ -13,9 +13,6 @@ $order_key = get_field( '_order_key', $order_id );
// Loads order
$order = new WC_Order( $order_id );

// Fetch payment url
$payment_url = $order->get_checkout_payment_url();

// Fetch user
$user = get_user_by( 'id', $customer_id );

@ -26,7 +23,7 @@ if ( $user and $order_key == $key ) {
wp_set_auth_cookie( $user->ID );

// Redirect to payment url
wp_redirect( $payment_url );
wp_redirect( "/account/billing/" . $order_id );

} else {