PAYATHON 2026

GravityView 如何显示另一表单的 payment status

支付老李

结论

不要使用 gform_entry_id_pre_save_lead。这个钩子用于在提交表单时指定或替换即将保存的 Entry ID,无法让 GravityView 在渲染 Form A 时读取 Form B 的条目。使用不当还可能覆盖已有条目。

可以按下面的方式处理:

  1. 根据当前登录用户的 ID 查询 Form B;
  2. 检查该用户是否有支付成功的 Entry;
  3. 将查询结果封装成 shortcode;
  4. 在 GravityView 的 Custom Content 字段中调用这个 shortcode。

实现代码

将以下代码添加到子主题的 functions.php 或自定义功能插件中,并把 $payment_form_id 改为 Form B 的实际表单 ID。

<?php

add_shortcode( 'form_b_payment_status', 'my_form_b_payment_status_shortcode' );

function my_form_b_payment_status_shortcode( $atts ) {
	$atts = shortcode_atts(
		array(
			'form_id'     => 2,
			'paid_text'   => '已付款',
			'unpaid_text' => '未付款',
		),
		$atts,
		'form_b_payment_status'
	);

	if ( ! is_user_logged_in() || ! class_exists( 'GFAPI' ) ) {
		return esc_html( $atts['unpaid_text'] );
	}

	$user_id         = get_current_user_id();
	$payment_form_id = absint( $atts['form_id'] );

	if ( ! $payment_form_id ) {
		return esc_html( $atts['unpaid_text'] );
	}

	/*
	 * 同一个页面中的 GravityView 可能渲染多行。
	 * 使用静态缓存,避免每一行都重复查询 Form B。
	 */
	static $payment_cache = array();

	$cache_key = $payment_form_id . ':' . $user_id;

	if ( isset( $payment_cache[ $cache_key ] ) ) {
		return $payment_cache[ $cache_key ];
	}

	$search_criteria = array(
		'status'        => 'active',
		'field_filters' => array(
			'mode' => 'all',
			array(
				'key'   => 'created_by',
				'value' => $user_id,
			),
			array(
				'key'   => 'payment_status',
				'value' => 'Paid',
			),
		),
	);

	$sorting = array(
		'key'       => 'date_created',
		'direction' => 'DESC',
		'is_numeric' => false,
	);

	$paging = array(
		'offset'    => 0,
		'page_size' => 1,
	);

	$total_count = 0;

	$entries = GFAPI::get_entries(
		$payment_form_id,
		$search_criteria,
		$sorting,
		$paging,
		$total_count
	);

	$is_paid = ! is_wp_error( $entries ) && ! empty( $entries );

	$payment_cache[ $cache_key ] = esc_html(
		$is_paid ? $atts['paid_text'] : $atts['unpaid_text']
	);

	return $payment_cache[ $cache_key ];
}

然后在 GravityView 的 Custom Content 字段中填写:

[form_b_payment_status form_id="2"]

显示文字也可以自定义:

[form_b_payment_status form_id="2" paid_text="付款已完成" unpaid_text="尚未付款"]

为什么不能直接使用 {payment_status}

当前 View 的数据源是 Form A,所以 Custom Content 中的 Gravity Forms merge tag 默认以当前 Form A Entry 为上下文。

{payment_status} 表示当前 Entry 的支付状态。它不会自动切换到 Form B,也不会查找当前用户在 Form B 中的 Entry,更无法判断多条 Form B Entry 中哪一条代表有效付款。

因此,需要先确定 Form A 和 Form B 之间的关联条件。这里使用 Gravity Forms Entry 的 created_by 属性,也就是当前登录用户的 WordPress 用户 ID。

支付状态需要确认

示例把以下条件视为支付成功:

'payment_status' => 'Paid'

Paid 是 Gravity Forms 支付 Entry 中常见的成功状态,但实际值可能受到支付插件、支付流程和历史数据的影响。使用前应先检查 Form B 中的实际 Entry 数据。

如果实际的成功状态不是 Paid,请将代码中的值改为对应状态。不要根据前端显示的文字来猜测,因为数据库中的 payment_status 通常使用英文状态值。

如果需要显示 Form B 的原始状态

如果要显示最近一条 Form B Entry 的实际 payment_status,而不是简单显示“已付款”或“未付款”,可以只按 created_by 查询,然后读取:

$payment_status = rgar( $entries[0], 'payment_status' );

这种做法还需要明确一条业务规则:如果最近一次支付失败,是否要覆盖用户此前成功付款的记录。若要判断“用户是否曾经完成付款”,直接查询 payment_status = Paid 通常更符合要求。

注意事项

  • 用户必须登录。匿名提交的 Entry 通常没有可靠的 created_by,此时应通过订单号、邮箱或自定义关联字段连接两个表单。
  • 邮箱不适合作为唯一关联键,因为用户可能修改邮箱,也可能出现大小写或格式差异。
  • 支付状态可能由支付网关的 webhook 异步更新,因此提交 Form B 后,页面不一定会立即显示为已付款。
  • 如果 View 要显示每一行所属用户的付款状态,而不是当前登录用户的付款状态,就不能使用 get_current_user_id()。此时应从当前 Form A Entry 中读取对应的用户 ID,再查询 Form B。
  • 只有需要保存付款时的历史快照,或者需要按付款状态排序、筛选时,才建议把状态同步到 Form A。如果只是展示状态,动态查询 Form B 可以避免两份数据不一致。

备注:内容仅供参考。