LLMS_Payment_Gateway

LifterLMS Payment Gateways abstract class


Source Source

File: includes/abstracts/abstract.llms.payment.gateway.php

	/**
	 * Optional gateway description for the admin panel
	 *
	 * @var string
	 */
	public $admin_description = '';

	/**
	 * Fields the gateway uses on the admin panel when displaying/editing an order
	 *
	 * @var array
	 */
	public $admin_order_fields = array(
		'customer'     => false,
		'subscription' => false,
		'source'       => false,
	);

	/**
	 * Optional gateway title for the admin panel
	 *
	 * @var string
	 */
	public $admin_title = '';

	/**
	 * Optional gateway description for the frontend
	 *
	 * @var string
	 */
	public $description = '';

	/**
	 * Order to display the gateway in on the frontend
	 *
	 * @var integer
	 */
	public $display_order = 1;

	/**
	 * Is the gateway enabled for payment processing?
	 *
	 * @var string
	 */
	public $enabled = 'no';

	/**
	 * Optional icon displayed on the frontend
	 *
	 * @var string
	 */
	public $icon = '';

	/**
	 * ID of the Payment Gateway, used internally
	 *
	 * @var string
	 */
	public $id;

	/**
	 * Logging status
	 *
	 * @var string
	 */
	public $logging_enabled = '';

	/**
	 * Option name prefix.
	 *
	 * @var string
	 */
	protected $option_prefix = 'llms_gateway_';

	/**
	 * Array of supported gateway features
	 *
	 * @var array
	 */
	public $supports = array(
		'checkout_fields'    => false,
		'cc_save'            => false,
		'refunds'            => false,
		'single_payments'    => false,
		'recurring_payments' => false,
		'recurring_retry'    => false,
		'test_mode'          => false,
	);

	/**
	 * Description of the gateway's test mode (if supported)
	 *
	 * @var string
	 */
	public $test_mode_description = '';

	/**
	 * Is test mode enabled?
	 *
	 * Can be modified by user on settings page if gateway supports "test_mode".
	 *
	 * @var string
	 */
	public $test_mode_enabled = 'no';

	/**
	 * Title of the gateway's test mode (if supported)
	 *
	 * @var string
	 */
	public $test_mode_title = '';

	/**
	 * Gateway title for the frontend
	 *
	 * @var string
	 */
	public $title = '';

	/**
	 * Option's data version
	 *
	 * @var integer
	 */
	protected $version = 2;

	/**
	 * This should be called by the gateway after verifying the transaction was completed successfully
	 *
	 * @since 3.0.0
	 * @since 3.30.0 Added access plan and query string checkout redirect settings.
	 * @since 3.34.3 Use `llms_redirect_and_exit()` instead of `wp_redirect()` and `exit()`.
	 * @since 3.37.18 Allow redirection to external domains by disabling "safe" redirects.
	 *
	 * @param LLMS_Order $order      Instance of an LLMS_Order object.
	 * @param null       $deprecated Deprecated.
	 * @return void
	 */
	public function complete_transaction( $order, $deprecated = null ) {

		$this->log( $this->get_admin_title() . ' `complete_transaction()` started', $order );

		$redirect = $this->get_complete_transaction_redirect_url( $order );

		$this->log( $this->get_admin_title() . ' `complete_transaction()` finished', $redirect, $order );

		// Ensure notification processors get dispatched since shutdown wont be called.
		do_action( 'llms_dispatch_notification_processors' );

		// Execute a redirect.
		llms_redirect_and_exit(
			$redirect,
			array(
				'safe' => false,
			)
		);

	}

	/**
	 * Confirm a Payment
	 *
	 * Called by {@see LLMS_Controller_Orders::confirm_pending_order} on confirm form submission.
	 *
	 * Some validation is performed before passing to this function, as it's not required
	 * gateways will likely doing further validations as are needed.
	 *
	 * Not required if a confirmation isn't required by the gateway.
	 *
	 * @since 3.0.0
	 *
	 * @param LLMS_Order $order Instance of the order being processed.
	 * @return void
	 */
	public function confirm_pending_order( $order ) {}

	/**
	 * Get admin description for the gateway
	 *
	 * @since 3.0.0
	 *
	 * @return string
	 */
	public function get_admin_description() {

		/**
		 * Filters a payment gateway's admin description.
		 *
		 * @since 3.0.0
		 *
		 * @param string $admin_description The admin description.
		 * @param string $gateway_id        The payment gateway ID.
		 */
		return apply_filters( 'llms_get_gateway_admin_description', $this->admin_description, $this->id );

	}

	/**
	 * Get the admin title for the gateway
	 *
	 * @since 3.0.0
	 *
	 * @return string
	 */
	public function get_admin_title() {

		/**
		 * Filters a payment gateway's admin title.
		 *
		 * @since 3.0.0
		 *
		 * @param string $admin_title The admin title.
		 * @param string $gateway_id  The payment gateway ID.
		 */
		return apply_filters( 'llms_get_gateway_admin_title', $this->admin_title, $this->id );

	}

	/**
	 * Get data about the fields displayed on the admin panel when viewing an order
	 *
	 * @since 3.10.0
	 *
	 * @return array[]
	 */
	public function get_admin_order_fields() {

		$fields = array(
			'customer'     => array(
				'label'   => __( 'Customer ID', 'lifterlms' ),
				'enabled' => $this->admin_order_fields['customer'],
				'name'    => 'gateway_customer_id',
			),
			'source'       => array(
				'label'   => __( 'Source ID', 'lifterlms' ),
				'enabled' => $this->admin_order_fields['source'],
				'name'    => 'gateway_source_id',
			),
			'subscription' => array(
				'label'   => __( 'Subscription ID', 'lifterlms' ),
				'enabled' => $this->admin_order_fields['subscription'],
				'name'    => 'gateway_subscription_id',
			),
		);

		/**
		 * Filters a payment gateway's admin title.
		 *
		 * @since 3.10.0
		 *
		 * @param array[] $fields     Array of admin order fields.
		 * @param string  $gateway_id The payment gateway ID.
		 */
		return apply_filters( 'llms_get_gateway_admin_order_fields', $fields, $this->id );
	}

	/**
	 * Get default gateway admin settings fields
	 *
	 * @since 3.0.0
	 * @since 3.29.0 Unknown.
	 *
	 * @return array[]
	 */
	public function get_admin_settings_fields() {

		$fields = array();

		$fields[] = array(
			'type'  => 'custom-html',
			'value' => '
				<h1>' . $this->get_admin_title() . '</h1>
				<p>' . $this->get_admin_description() . '</p>
			',
		);

		$fields[] = array(
			'autoload'     => true,
			'id'           => $this->get_option_name( 'enabled' ),
			'desc'         => sprintf( _x( 'Enable %s', 'Payment gateway title', 'lifterlms' ), $this->get_admin_title() ),
			'desc_tooltip' => __( 'Checking this box will allow users to use this payment gateway.', 'lifterlms' ),
			'default'      => $this->get_enabled(),
			'title'        => __( 'Enable / Disable', 'lifterlms' ),
			'type'         => 'checkbox',
		);

		$fields[] = array(
			'id'      => $this->get_option_name( 'title' ),
			'desc'    => '<br>' . __( 'The title the user sees during checkout.', 'lifterlms' ),
			'default' => $this->get_title(),
			'title'   => __( 'Title', 'lifterlms' ),
			'type'    => 'text',
		);

		$fields[] = array(
			'id'      => $this->get_option_name( 'description' ),
			'desc'    => '<br>' . __( 'The description the user sees during checkout.', 'lifterlms' ),
			'default' => $this->get_description(),
			'title'   => __( 'Description', 'lifterlms' ),
			'type'    => 'text',
		);

		if ( $this->supports( 'test_mode' ) ) {

			$fields[] = array(
				'id'           => $this->get_option_name( 'test_mode_enabled' ),
				'desc'         => sprintf( _x( 'Enable %s', 'Payment gateway test mode title', 'lifterlms' ), $this->get_test_mode_title() ),
				'desc_tooltip' => $this->get_test_mode_description(),
				'default'      => $this->get_test_mode_enabled(),
				'title'        => $this->get_test_mode_title(),
				'type'         => 'checkbox',
			);

		}

		$fields[] = array(
			'id'           => $this->get_option_name( 'logging_enabled' ),
			'desc'         => __( 'Enable debug logging', 'lifterlms' ),
			'desc_tooltip' => sprintf( __( 'When enabled, debugging information will be logged to "%s"', 'lifterlms' ), llms_get_log_path( $this->get_id() ) ),
			'title'        => __( 'Debug Log', 'lifterlms' ),
			'type'         => 'checkbox',
		);

		/**
		 * Filters the gateway's settings fields displayed on the admin panel
		 *
		 * @since 3.0.0
		 *
		 * @param array[] $fields     Array of settings fields.
		 * @param string  $gateway_id The payment gateway ID.
		 */
		return apply_filters( 'llms_get_gateway_settings_fields', $fields, $this->id );

	}

	/**
	 * Get API mode
	 *
	 * If test is not supported will return "live".
	 *
	 * @since 3.0.0
	 *
	 * @return string
	 */
	public function get_api_mode() {
		if ( $this->supports( 'test_mode' ) && $this->is_test_mode_enabled() ) {
			return 'test';
		}
		return 'live';
	}

	/**
	 * Calculates the url to redirect to on transaction completion
	 *
	 * @since 3.30.0
	 *
	 * @param LLMS_Order $order The order object.
	 * @return string
	 */
	protected function get_complete_transaction_redirect_url( $order ) {

		// Get the redirect parameter.
		$redirect = urldecode( llms_filter_input( INPUT_GET, 'redirect', FILTER_VALIDATE_URL ) );

		// Redirect to the product's permalink, if no parameter was set.
		$redirect = ! empty( $redirect ) ? $redirect : get_permalink( $order->get( 'product_id' ) );

		// Fallback to the account page if we don't have a url for some reason.
		$redirect = ! empty( $redirect ) ? $redirect : get_permalink( llms_get_page_id( 'myaccount' ) );

		// Add order key to the url.
		$redirect = add_query_arg(
			array(
				'order-complete' => $order->get( 'order_key' ),
			),
			esc_url( $redirect )
		);

		// Redirection url on free checkout form.
		$quick_enroll_form = llms_filter_input( INPUT_POST, 'form' );

		$free_checkout_redirect = llms_filter_input( INPUT_POST, 'free_checkout_redirect' );

		if ( get_current_user_id() && ( 'free_enroll' === $quick_enroll_form ) && ! empty( $free_checkout_redirect ) ) {
			$redirect = urldecode( $free_checkout_redirect );
		}

		/**
		 * Filters the redirect on order completion.
		 *
		 * @since 3.8.0
		 *
		 * @param string     $redirect The URL to redirect user to.
		 * @param LLMS_Order $order    The order object.
		 */
		return esc_url( apply_filters( 'lifterlms_completed_transaction_redirect', $redirect, $order ) );

	}

	/**
	 * Gateways can override this to return a URL to a customer permalink on the gateway's website
	 *
	 * If this is not defined, it will just return the supplied ID.
	 *
	 * @since 3.0.0
	 *
	 * @param string $customer_id Gateway's customer ID.
	 * @param string $api_mode    Link to either the live or test site for the gateway, where applicable.
	 * @return string
	 */
	public function get_customer_url( $customer_id, $api_mode = 'live' ) {
		return $customer_id;
	}

	/**
	 * Get the frontend description setting
	 *
	 * @since 3.0.0
	 *
	 * @return string
	 */
	public function get_description() {
		return $this->get_option( 'description' );
	}

	/**
	 * Get the display order setting
	 *
	 * @since 3.0.0
	 *
	 * @return int
	 */
	public function get_display_order() {
		return absint( $this->get_option( 'display_order' ) );
	}

	/**
	 * Get the value of the enabled setting
	 *
	 * @since 3.0.0
	 *
	 * @return string
	 */
	public function get_enabled() {
		return $this->get_option( 'enabled' );
	}

	/**
	 * Get fields displayed on the checkout form
	 *
	 * Gateways should define this function if the gateway supports fields.
	 *
	 * @since 3.0.0
	 *
	 * @return string
	 */
	public function get_fields() {
		/**
		 * Filters the HTML of the gateway's checkout fields
		 *
		 * @since 3.0.0
		 *
		 * @param string $fields     Fields HTML string.
		 * @param string $gateway_id The payment gateway's ID.
		 */
		return apply_filters( 'llms_get_gateway_fields', '', $this->id );
	}

	/**
	 * Get the icon displayed on the checkout form
	 *
	 * @since 3.0.0
	 *
	 * @return string
	 */
	public function get_icon() {
		/**
		 * Filters the HTML of the gateway's checkout icon
		 *
		 * @since 3.0.0
		 *
		 * @param string $icon       Icon HTML string.
		 * @param string $gateway_id The payment gateway's ID.
		 */
		return apply_filters( 'llms_get_gateway_icon', $this->icon, $this->id );
	}

	/**
	 * Get the gateway's ID
	 *
	 * @since 3.0.0
	 *
	 * @return string
	 */
	public function get_id() {
		return $this->id;
	}

	/**
	 * Retrieve an HTML link to a customer, subscription, or source URL
	 *
	 * If no URL provided returns the item value as string.
	 *
	 * @since 3.10.0
	 *
	 * @param string $item_key   The key of the item to retrieve a URL for.
	 * @param string $item_value The value of the item to retrieve.
	 * @param string $api_mode   The current api mode to retrieve the URL for.
	 * @return string
	 */
	public function get_item_link( $item_key, $item_value, $api_mode = 'live' ) {

		switch ( $item_key ) {

			case 'customer':
				$url = $this->get_customer_url( $item_value, $api_mode );
				break;

			case 'subscription':
				$url = $this->get_subscription_url( $item_value, $api_mode );
				break;

			case 'source':
				$url = $this->get_source_url( $item_value, $api_mode );
				break;

			default:
				$url = $item_value;

		}

		if ( false === filter_var( $url, FILTER_VALIDATE_URL ) ) {
			return $item_value;
		}

		return sprintf( '<a href="%1$s" target="_blank">%2$s</a>', $url, $item_value );

	}

	/**
	 * Get the value of the logging setting
	 *
	 * @since 3.0.0
	 *
	 * @return string
	 */
	public function get_logging_enabled() {
		return $this->get_option( 'logging_enabled' );
	}

	/**
	 * Gateways can override this to return a URL to a source permalink on the gateway's website
	 *
	 * If this is not defined, it will just return the supplied ID.
	 *
	 * @since 3.0.0
	 *
	 * @param string $source_id Gateway's source ID.
	 * @param string $api_mode  Link to either the live or test site for the gateway, where applicable.
	 * @return string
	 */
	public function get_source_url( $source_id, $api_mode = 'live' ) {
		return $source_id;
	}

	/**
	 * Gateways can override this to return a URL to a subscription permalink on the gateway's website
	 *
	 * If this is not defined, it will just return the supplied ID.
	 *
	 * @since 3.0.0
	 *
	 * @param string $subscription_id Gateway's subscription ID.
	 * @param string $api_mode        Link to either the live or test site for the gateway, where applicable.
	 * @return string
	 */
	public function get_subscription_url( $subscription_id, $api_mode = 'live' ) {
		return $subscription_id;
	}

	/**
	 * Get an array of features the gateway supports
	 *
	 * @since 3.0.0
	 *
	 * @return array
	 */
	public function get_supported_features() {
		/**
		 * Filters the gateway's supported features array
		 *
		 * @since 3.0.0
		 *
		 * @param array  $supports   Array of feature support.
		 * @param string $gateway_id The payment gateway's ID.
		 */
		return apply_filters( 'llms_get_gateway_supported_features', $this->supports, $this->id );
	}

	/**
	 * Get the description of test mode displayed on the admin panel
	 *
	 * @since 3.0.0
	 *
	 * @return string
	 */
	public function get_test_mode_description() {
		return $this->test_mode_description;
	}

	/**
	 * Get value of the test mode enabled setting
	 *
	 * @since 3.0.0
	 *
	 * @return string
	 */
	public function get_test_mode_enabled() {
		return $this->get_option( 'test_mode_enabled' );
	}

	/**
	 * Get the title of test mode displayed on the admin panel
	 *
	 * @since 3.0.0
	 *
	 * @return string
	 */
	public function get_test_mode_title() {
		return $this->test_mode_title;
	}

	/**
	 * Get gateway title setting
	 *
	 * @since 3.0.0
	 *
	 * @return string
	 */
	public function get_title() {
		return $this->get_option( 'title' );
	}

	/**
	 * Gateways can override this to return a URL to a transaction permalink on the gateway's website
	 *
	 * If this is not defined, it will just return the supplied ID.
	 *
	 * @since 3.0.0
	 *
	 * @param string $transaction_id Gateway's transaction ID.
	 * @param string $api_mode       Link to either the live or test site for the gateway, where applicable.
	 *
	 * @return string
	 */
	public function get_transaction_url( $transaction_id, $api_mode = 'live' ) {
		return $transaction_id;
	}

	/**
	 * Called when the Update Payment Method form is submitted from a single order view on the student dashboard
	 *
	 * Gateways should do whatever the gateway needs to do to validate the new payment method and save it to the order
	 * so that future payments on the order will use this new source.
	 *
	 * This should be an abstract function but experience has taught me that no one will upgrade follow our instructions
	 * and they'll end up with 500 errors and debug mode disabled and send me giant frustrated question marks.
	 *
	 * @since 3.10.0
	 *
	 * @param LLMS_Order $order     Order object.
	 * @param array      $form_data Additional data passed from the submitted form (EG $_POST).
	 *
	 * @return null
	 */
	public function handle_payment_source_switch( $order, $form_data = array() ) {
		return llms_add_notice(
			sprintf(
				// Translatos: %s = the title of the payment gateway.
				esc_html__( 'The selected payment Gateway "%s" does not support payment method switching.', 'lifterlms' ),
				$this->get_title()
			),
			'error'
		);
	}

	/**
	 * Handle a Pending Order
	 *
	 * Called by LLMS_Controller_Orders->create_pending_order() on checkout form submission.
	 *
	 * All data will be validated before it's passed to this function.
	 *
	 * @since 3.0.0
	 *
	 * @param LLMS_Order        $order  The order being processed.
	 * @param LLMS_Access_Plan  $plan   Access plan the order is built from.
	 * @param LLMS_Student      $person The purchasing customer.
	 * @param LLMS_Coupon|false $coupon Coupon used during order processing or `false` if none supplied.
	 * @return void
	 */
	abstract public function handle_pending_order( $order, $plan, $person, $coupon = false );

	/**
	 * Called by scheduled actions to charge an order for a scheduled recurring transaction
	 *
	 * This function must be defined by gateways which support recurring transactions.
	 *
	 * @since 3.0.0
	 *
	 * @param LLMS_Order $order The order being processed.
	 * @return mixed
	 */
	public function handle_recurring_transaction( $order ) {}

	/**
	 * Determine if the gateway is the default gateway
	 *
	 * This will be the FIRST gateway in the gateways that are enabled.
	 *
	 * @since 3.0.0
	 * @since 5.3.0 Use `llms()` in favor of deprecated `LLMS()`.
	 *
	 * @return boolean
	 */
	public function is_default_gateway() {
		return ( $this->get_id() === llms()->payment_gateways()->get_default_gateway() );
	}

	/**
	 * Determine if the gateway is enabled according to admin settings checkbox
	 *
	 * @since 3.0.0
	 *
	 * @return boolean
	 */
	public function is_enabled() {
		return ( 'yes' === $this->get_enabled() ) ? true : false;
	}

	/**
	 * Determine if test mode is enabled
	 *
	 * Returns false if gateway doesn't support test mode.
	 *
	 * @since 3.0.0
	 *
	 * @return boolean
	 */
	public function is_test_mode_enabled() {
		return ( 'yes' === $this->get_test_mode_enabled() ) ? true : false;
	}

	/**
	 * Log messages if logging is enabled
	 *
	 * @since 3.0.0
	 *
	 * @return void
	 */
	public function log() {
		if ( 'yes' === $this->get_logging_enabled() ) {
			foreach ( func_get_args() as $data ) {
				llms_log( $data, $this->get_id() );
			}
		}


Top ↑

Methods Methods

  • complete_transaction — This should be called by the gateway after verifying the transaction was completed successfully
  • confirm_pending_order — Confirm a Payment Called by LLMS_Controller_Orders->confirm_pending_order() on confirm form submission Some validation is performed before passing to this function, as it's not required gateways will likely doing further validations as are needed
  • get_admin_description — Get admin description for the gateway
  • get_admin_order_fields — Get data about the fields displayed on the admin panel when viewing an order processed via this gateway
  • get_admin_settings_fields — Get default gateway admin settings fields
  • get_admin_title — Get the admin title for the gateway
  • get_api_mode — Get API mode if test is not supported will return "live"
  • get_complete_transaction_redirect_url — Calculates the url to redirect to on transaction completion
  • get_customer_url — Gateways can override this to return a URL to a customer permalink on the gateway's website If this is not defined, it will just return the supplied ID
  • get_description — Get the frontend description setting
  • get_display_order — Get the display order setting
  • get_enabled — Get the value of the enabled setting
  • get_fields — Get fields displayed on the checkout form Gateways should define this function if the gateway supports fields
  • get_icon — Get the icon displayed on the checkout form
  • get_id — Get the gateway's ID
  • get_item_link — Retrieve an HTML link to a customer, subscription, or source URL If no URL provided returns the item value as string
  • get_logging_enabled — Get the value of the logging setting
  • get_option — Get the value of an option from the database & fallback to default value if none found Optionally attempts to retrieve a secure key first, if secure key is provided.
  • get_option_name — Retrieve an option name specific to the gateway Used to retrieve options from the wp_options table where applicable
  • get_source_url — Gateways can override this to return a URL to a source permalink on the gateway's website If this is not defined, it will just return the supplied ID
  • get_subscription_url — Gateways can override this to return a URL to a subscription permalink on the gateway's website If this is not defined, it will just return the supplied ID
  • get_supported_features — Get an array of features the gateway supports
  • get_test_mode_description — Get the description of test mode displayed on the admin panel
  • get_test_mode_enabled — Get value of the test mode enabled setting
  • get_test_mode_title — Get the title of test mode displayed on the admin panel
  • get_title — Get gateway title setting
  • get_transaction_url — Gateways can override this to return a URL to a transaction permalink on the gateway's website If this is not defined, it will just return the supplied ID
  • handle_payment_source_switch — Called when the Update Payment Method form is submitted from a single order view on the student dashboard
  • handle_pending_order — Handle a Pending Order Called by LLMS_Controller_Orders->create_pending_order() on checkout form submission All data will be validated before it's passed to this function
  • handle_recurring_transaction — Called by scheduled actions to charge an order for a scheduled recurring transaction This function must be defined by gateways which support recurring transactions
  • is_default_gateway — Determine if the gateway is the default gateway This will be the FIRST gateway in the gateways that are enabled
  • is_enabled — Determine if the gateway is enabled according to admin settings checkbox
  • is_test_mode_enabled — Determine if test mode is enabled Returns false if gateway doesn't support test mode
  • log — Log messages if logging is enabled
  • process_refund — Called when refunding via a Gateway This function must be defined by gateways which support refunds This function is called by LLMS_Transaction->process_refund()
  • supports — Determine if a feature is supported by the gateway Looks at the $this->supports and ensures the submitted feature exists and is true

Top ↑

Changelog Changelog

Changelog
Version Description
4.0.0 Removed deprecated completed transaction message parameter output.
3.37.18 Allow redirection to external domains by disabling "safe" redirects.
3.34.3 During order completion, use llms_redirect_and_exit() instead of wp_redirect() and exit().
3.30.0 Added access plan and query string checkout redirect settings.
3.0.0 Introduced.

Top ↑

User Contributed Notes User Contributed Notes

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