Skip to content
← Back to Functions
Code

Refund Eligibility Checker

Checks order status, payment status, age, and item rules before allowing refund.

Function signature

ogCheckRefundEligibility(order = array(), policy = array())

Categories

  • Ecommerce Workflows

Parameters

orderValidated order record used for refund eligibility checks.policyCaller-approved workflow policy for the ecommerce, admin, privacy, or export decision.

Return value

Public-safe status string returned by the function for explicit controller branching or logging.

  • success
  • message
  • data

Compatibility

Existing function name, slug, path, and call order preserved; advertised metadata corrected to the actual source behavior.

Minimum PHP version: 7.4

Security notes

Use caller-owned allowlists and context-specific escaping; validate admin actions, export fields, privacy plans, cache keys, templates, settings, routes, and ecommerce policies before production use.

Code

<?php

/*
 * Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
 * Free for personal and internal use. Paid project use requires visible credit
 * to Jeffery L. Paris. Corporate use requires a paid license fee unless a
 * separate written license states otherwise.
 */

/**
 * Checks whether an order appears eligible for a refund under supplied policy rules.
 *
 * This function only returns an eligibility decision. It does not call payment
 * processors, send money, mutate order state, or approve refunds by itself.
 *
 * @param array $order Order data with status, payment_status, total, and purchase time.
 * @param array $policy Refund policy settings.
 * @return array Eligibility decision and reason list.
 */
function ogCheckRefundEligibility($order = array(), $policy = array()) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

	if (!is_array($order)) {
		$result['message'] = 'Order must be an array.';
		return $result;
	}

	if (!is_array($policy)) {
		$policy = array();
	}

	$allowed_order_statuses = array('paid', 'fulfilled', 'completed');
	if (!empty($policy['allowed_order_statuses']) && is_array($policy['allowed_order_statuses'])) {
		$allowed_order_statuses = $policy['allowed_order_statuses'];
	}

	$allowed_payment_statuses = array('paid', 'captured', 'settled');
	if (!empty($policy['allowed_payment_statuses']) && is_array($policy['allowed_payment_statuses'])) {
		$allowed_payment_statuses = $policy['allowed_payment_statuses'];
	}

	$max_days = 30;
	if (!empty($policy['max_days'])) {
		$max_days = (int)$policy['max_days'];
	}
	if ($max_days < 1) {
		$max_days = 1;
	}

	$order_status = '';
	if (!empty($order['order_status'])) {
		$order_status = strtolower(trim((string)$order['order_status']));
	}

	$payment_status = '';
	if (!empty($order['payment_status'])) {
		$payment_status = strtolower(trim((string)$order['payment_status']));
	}

	$purchased_at = 0;
	if (!empty($order['purchased_at'])) {
		if (is_numeric($order['purchased_at'])) {
			$purchased_at = (int)$order['purchased_at'];
		} else {
			$purchased_at = strtotime((string)$order['purchased_at']);
		}
	}

	$total_minor_units = 0;
	if (!empty($order['total_minor_units'])) {
		$total_minor_units = (int)$order['total_minor_units'];
	}

	$reasons = array();
	if (!in_array($order_status, $allowed_order_statuses, true)) {
		$reasons[] = 'Order status is not refundable.';
	}
	if (!in_array($payment_status, $allowed_payment_statuses, true)) {
		$reasons[] = 'Payment status is not refundable.';
	}
	if ($purchased_at <= 0) {
		$reasons[] = 'Purchase date is missing or invalid.';
	} else {
		$age_seconds = time() - $purchased_at;
		$max_seconds = $max_days * 86400;
		if ($age_seconds > $max_seconds) {
			$reasons[] = 'Order is outside the refund window.';
		}
	}
	if ($total_minor_units <= 0) {
		$reasons[] = 'Refundable amount is empty.';
	}

	$result['success'] = true;
	if (empty($reasons)) {
		$result['message'] = 'Order appears refund eligible.';
	} else {
		$result['message'] = 'Order is not refund eligible.';
	}
	$result['data'] = array(
		'eligible' => empty($reasons),
		'reasons' => $reasons,
		'max_days' => $max_days,
		'total_minor_units' => $total_minor_units
	);

	return $result;
}