LLMS_Controller_Orders::recurring_charge( int $order_id )

Trigger a recurring payment.


Description Description

Called by action scheduler.


Top ↑

Parameters Parameters

$order_id

(int) (Required) WP Post ID of the order.


Top ↑

Return Return

(bool) false if the recurring charge cannot be processed, true when the charge is successfully handed off to the gateway.


Top ↑

Source Source

File: includes/controllers/class.llms.controller.orders.php

	public function recurring_charge( $order_id ) {

		// Make sure the order still exists.
		$order = llms_get_post( $order_id );
		if ( ! $order || ! is_a( $order, 'LLMS_Order' ) ) {

			/**
			 * Fired when a LifterLMS order's recurring charge errors because the order doesn't exist anymore
			 *
			 * @since Unknown
			 *
			 * @param int                    $order_id   WP Post ID of the order.
			 * @param LLMS_Controller_Orders $controller This controller's instance.
			 */
			do_action( 'llms_order_recurring_charge_order_error', $order_id, $this );
			llms_log( sprintf( 'Recurring charge for Order #%d could not be processed because the order no longer exists.', $order_id ), 'recurring-payments' );
			return false;

		}

		// Check the user still exists.
		$user_id = $order->get( 'user_id' );
		if ( ! get_user_by( 'id', $user_id ) ) {

			/**
			 * Fired when a LifterLMS order's recurring charge errors because the user who placed the order doesn't exist anymore
			 *
			 * @since Unknown
			 *
			 * @param int                    $order_id   WP Post ID of the order.
			 * @param int                    $user_id    WP User ID of the user who placed the order.
			 * @param LLMS_Controller_Orders $controller This controller's instance.
			 */
			do_action( 'llms_order_recurring_charge_user_error', $order_id, $user_id, $this );
			llms_log( sprintf( 'Recurring charge for Order #%1$d could not be processed because the user (#%2$d) no longer exists.', $order_id, $user_id ), 'recurring-payments' );

			// Translators: %d = The deleted user's ID.
			$order->add_note( sprintf( __( 'Recurring charge skipped. The user (#%d) no longer exists.', 'lifterlms' ), $user_id ) );
			return false;

		}

		// Ensure Gateway is still available.
		$gateway = $order->get_gateway();

		if ( is_wp_error( $gateway ) ) {
			/**
			 * Fired when a LifterLMS order's recurring charge errors because of a gateway error. E.g. it's not available anymore.
			 *
			 * @since Unknown
			 *
			 * @param int                    $order_id   WP Post ID of the order.
			 * @param WP_Error               $error      WP_Error instance.
			 * @param LLMS_Controller_Orders $controller This controller's instance.
			 */
			do_action( 'llms_order_recurring_charge_gateway_error', $order_id, $gateway, $this );

			llms_log(
				sprintf(
					'Recurring charge for Order #%1$d could not be processed because the "%2$s" gateway is no longer available. Gateway Error: %3$s',
					$order_id,
					$order->get( 'payment_gateway' ),
					$gateway->get_error_message()
				),
				'recurring-payments'
			);

			$order->add_note(
				sprintf(
					// Translators: %s = error message encountered while loading the gateway.
					__( 'Recurring charge was not processed due to an error encountered while loading the payment gateway: %s.', 'lifterlms' ),
					$gateway->get_error_message()
				)
			);
			return false;

		}

		// Gateway doesn't support recurring payments.
		if ( ! $gateway->supports( 'recurring_payments' ) ) {

			/**
			 * Fired when a LifterLMS order's recurring charge errors because the selected gateway doesn't support recurring payments.
			 *
			 * @since Unknown
			 *
			 * @param int                    $order_id   WP Post ID of the order.
			 * @param LLMS_Payment_Gateway   $gateway    LLMS_Payment_Gateway extending class instance.
			 * @param LLMS_Controller_Orders $controller This controller's instance.
			 */
			do_action( 'llms_order_recurring_charge_gateway_payments_disabled', $order_id, $gateway, $this );
			llms_log(
				sprintf(
					'Recurring charge for order #%d could not be processed because the gateway no longer supports recurring payments.',
					$order_id
				),
				'recurring-payments'
			);

			$order->add_note( __( 'Recurring charge skipped because recurring payments are disabled for the payment gateway.', 'lifterlms' ) );
			return false;

		}

		// Recurring payments disabled as a site feature when in staging mode.
		if ( ! LLMS_Site::get_feature( 'recurring_payments' ) ) {

			/**
			 * Fired when a LifterLMS order's recurring charge errors because the recurring payments site feature is disabled.
			 *
			 * @since Unknown
			 *
			 * @param int                    $order_id   WP Post ID of the order.
			 * @param LLMS_Payment_Gateway   $gateway    LLMS_Payment_Gateway extending class instance.
			 * @param LLMS_Controller_Orders $controller This controller's instance.
			 */
			do_action( 'llms_order_recurring_charge_skipped', $order_id, $gateway, $this );
			$order->add_note( __( 'Recurring charge skipped because recurring payments are disabled in staging mode.', 'lifterlms' ) );
			return false;

		}

		// Related product removed.
		if ( empty( $order->get_product() ) ) {

			/**
			 * Fired when a LifterLMS order's recurring charge errors because the purchased product (Course/Membership) doesn't exist anymore.
			 *
			 * @since Unknown
			 *
			 * @param int                    $order_id   WP Post ID of the order.
			 * @param LLMS_Controller_Orders $controller This controller's instance.
			 */
			do_action( 'llms_order_recurring_charge_aborted_product_deleted', $order_id, $this );
			llms_log(
				sprintf(
					'Recurring charge for order #%d could not be processed because the product #%d does not exist anymore.',
					$order_id,
					$order->get( 'product_id' )
				),
				'recurring-payments'
			);

			$order->add_note( __( 'Recurring charge aborted because the purchased product does not exist anymore.', 'lifterlms' ) );
			return false;

		}

		// Passed validation, hand off to the gateway.
		$gateway->handle_recurring_transaction( $order );
		return true;

	}


Top ↑

Changelog Changelog

Changelog
Version Description
5.4.0 Handle case when the order's related product has been removed.
5.2.0 Fixed buggy logging on gateway error because it doesn't support recurring payments.
3.36.1 Made sure to process only proper LLMS_Orders of existing users.
3.32.0 Record order notes and trigger actions during errors.
3.0.0 Introduced.

Top ↑

User Contributed Notes User Contributed Notes

You must log in before being able to contribute a note or feedback.