Go Back to Parent Doc

Developer Reference

Tribuy is built to be extended, and the Pro add-on uses only these public hooks. Text domain: tribuy-group-buy-for-woocommerce. Namespace: Tribuy. Function, hook and option prefix: tribuy_. Meta prefix: _tribuy_. Constants: TRIBUY_*. Pro uses TribuyPro, tribuy_pro_, _tribuy_pro_ and TRIBUY_PRO_*.

Template overrides

All group buy markup loads through wc_get_template(). Copy any file from the plugin’s templates/ directory into yourtheme/woocommerce/, keeping the same relative path:

templates/single-product/group-buy.php
→ yourtheme/woocommerce/single-product/group-buy.php
FolderTemplates
single-product/group-buy.php (the campaign box), group-buy-share.php (share links), group-buy-participants.php (recently joined)
loop/group-buy-progress.php (compact progress in the shop and style="compact")
myaccount/group-buys.php (My Account → Group buys)
emails/ and emails/plain/tribuy-customer-joined.php, tribuy-customer-ending-soon.php, tribuy-customer-confirmed.php, tribuy-customer-failed.php, tribuy-campaign-started.php, tribuy-goal-reached.php, tribuy-campaign-ended.php

Pro’s email templates (tribuy-pro-campaign-update.php, tribuy-pro-supplier-order.php) override the same way. Each template carries a @version; WooCommerce → Status → Group buy flags theme overrides that are out of date.

Every template receives $campaign, the GroupBuyProduct. The email templates also receive $order, $email_heading, $additional_content, $sent_to_admin, $plain_text and $email; the failed email receives $result (refunded, cancelled or refund_pending) and the campaign ended email $participants. The account template receives $rows.

Data model

  • Product type: group_buy, class Tribuy\Products\GroupBuyProduct (extends WC_Product_Simple). Use its getters: get_group_price(), get_goal_qty(), get_max_qty(), get_min_per_customer(), get_max_per_customer(), get_committed_qty(), get_remaining_qty() (-1 means no limit), get_qty_to_goal(), get_progress_percent(), get_savings_percent(), get_campaign_status(), get_round(), is_running(), is_scheduled(), is_closed(), is_successful(), is_failed(), is_goal_reached(), get_customer_qty( $user_id, $email ), get_customer_limits( $user_id, $email ), can_participate( $user_id ).
  • Group price: stored as the WooCommerce sale price, so carts, filters, sorting and the Store API charge it natively.
  • Product meta: _tribuy_goal_qty, _tribuy_max_qty, _tribuy_min_per_customer, _tribuy_max_per_customer, _tribuy_start_date, _tribuy_end_date, _tribuy_status, _tribuy_round, _tribuy_committed_qty (a cache, rebuilt from the participants table and frozen at close), _tribuy_closed_date, _tribuy_ending_soon_sent.
  • Campaign states: scheduled → active → successful | failed. A closed campaign can start a new round with Campaign::start_new_round().
  • Participants table: {$wpdb->prefix}tribuy_participants, with the columns id, product_id, round, order_id, order_item_id (unique), user_id, email, qty, unit_price, status (awaiting, confirmed, refunded, refund_pending or cancelled), date_created and date_updated. Only awaiting and confirmed rows count towards the committed quantity.
  • Order status: wc-tribuy-awaiting (“Awaiting group”). It counts as paid, reduces stock, and keeps downloads locked.
  • Order data: order item meta _tribuy_round. Order meta _tribuy_joined_email_sent.
  • Dates: campaign dates are stored as site-local Y-m-d H:i:s strings. Convert them with tribuy_local_to_timestamp(), never with strtotime(), which reads them as UTC.
  • Scheduling: Action Scheduler, group tribuy-group-buy-for-woocommerce, with the actions tribuy_start_campaign, tribuy_end_campaign, tribuy_campaign_ending_soon, tribuy_process_orders (batches of 20) and the hourly tribuy_sweep_campaigns.
  • My Account endpoint: group-buys.

Helper functions

FunctionReturns
tribuy_get_campaign( $product )The GroupBuyProduct, or false if it isn’t a group buy.
tribuy_is_campaign( $product )Whether a product is a group buy.
tribuy_get_campaign_statuses(), tribuy_get_campaign_status_label( $status )Status labels.
tribuy_is_ending_soon( $campaign )Whether a running campaign is inside the “Ending soon” window.
tribuy_get_badges( $campaign ), tribuy_get_badges_html( $campaign )The campaign’s badges (goal-reached, ending-soon).
tribuy_get_share_links( $campaign )Share links keyed by network, each with label and url.
tribuy_get_public_name( $first, $last )“Jane D.”, for public display.
tribuy_local_to_timestamp( $date ), tribuy_format_date( $date )Date helpers.
tribuy_get_paid_order_statuses()Order statuses that make an order join a campaign.
tribuy_get_template( $name, $args ), tribuy_get_template_html( $name, $args )Load a plugin template.
tribuy_get_admin_url( $args )URL of WooCommerce → Group Buys, e.g. array( 'tab' => 'participants', 'product_id' => 123 ).
Tribuy\Campaign::recalculate( $campaign )Rebuild the committed quantity and transition the campaign if needed.
Tribuy\Campaign::close( $campaign, $outcome = '' )Close a campaign now; pass successful or failed to force the outcome.
Tribuy\Campaign::extend( $campaign, $seconds )Move the end date of a running campaign.
Tribuy\Campaign::start_new_round( $campaign, $start, $end )Start a new round of a closed campaign.
Tribuy\Participants::query( $args )Participant rows (product_id, round, status, user_id, email, per_page, page, count).
Tribuy\Participants::get_committed_qty( $product_id, $round ), get_revenue(), get_recipients()Campaign figures.
Tribuy\Frontend\Shortcodes::get_campaign_ids( $atts )Campaign IDs for a grid (status, limit, orderby, order).

Actions

ActionArgumentsFires
tribuy_loaded$pluginAfter the plugin instantiates its classes. Boot add-ons here.
tribuy_installed—After an install or upgrade routine.
tribuy_campaign_started$campaignWhen a campaign starts accepting orders (also at the start of a new round).
tribuy_goal_reached$campaignThe first time the committed quantity reaches the goal.
tribuy_campaign_succeeded / tribuy_campaign_failed$campaignWhen a campaign closes with that outcome.
tribuy_campaign_closed$campaignWhen a campaign closes, whatever its outcome.
tribuy_campaign_extended$campaign, $end_dateWhen the end date is moved.
tribuy_campaign_new_round$campaign, $previous_roundWhen a closed campaign starts a new round.
tribuy_campaign_ending_soon$product_idScheduled at the start of the “Ending soon” window.
tribuy_participant_added$participant_id, $campaign, $orderWhen an order line item joins a campaign.
tribuy_participant_status_changed$participant_id, $new_status, $old_statusWhen a participant’s status changes.
tribuy_order_confirmed$order_id, $product_idWhen an order’s group buy items are confirmed.
tribuy_order_failed$order_id, $product_id, $resultWhen an order’s group buy items are refunded or cancelled.
tribuy_product_data_panel$campaignAt the end of the admin Group buy tab. Add your own fields here.
tribuy_closed_campaign_notice$campaignInside the “This group buy has ended” notice.
tribuy_campaign_box_after_facts / tribuy_campaign_box_end$campaignInside the campaign box: after the facts, and at the end.
tribuy_email_campaign_details$campaign, $order, $plain_text, $emailBefore the order details of the joined and successful emails.
tribuy_participants_table_actions$campaign, $roundAbove a campaign’s participants list.
tribuy_admin_tab_{tab}$tabRender a custom tab on WooCommerce → Group Buys.
tribuy_campaign_action_{action}$campaignHandle a custom campaign action (see Admin\Actions::get_action_url()).

Filters

FilterArgumentsUse
tribuy_can_participatetrue, $campaign, $user_idReturn false or a message to stop a customer joining (roles, private campaigns…).
tribuy_validate_qty$error, $campaign, $quantity, $limitsReturn an error message to reject a quantity, or '' to accept it.
tribuy_customer_qty_limits$limits, $campaign, $user_id, $emailThe min/max a customer may still order (max of -1 means no limit).
tribuy_remaining_qty$remaining, $campaignUnits left (-1 for no limit).
tribuy_is_purchasable$purchasable, $campaignWhether the campaign accepts orders.
tribuy_cart_item_price$price, $campaign, $cart_itemChange the price charged in the cart.
tribuy_should_close_campaigntrue, $campaign, $reasonReturn false to keep a due campaign open ($reason: ended, cap or goal).
tribuy_campaign_outcome$outcome, $campaignOverride the outcome of a closing campaign (not applied to forced outcomes).
tribuy_refund_amount$amount, $order, $participants, $campaignThe amount refunded for a failed campaign.
tribuy_paid_order_statuses$statusesOrder statuses that make an order join a campaign.
tribuy_campaign_badges, tribuy_share_links$list, $campaignBadges and share links.
tribuy_campaigns_query_args$args, $attsThe WP_Query of the campaigns shortcode, block, dashboard and CLI.
tribuy_account_rows$rowsRows of My Account → Group buys.
tribuy_product_data_errors$errors, $productAdd validation errors for the Group buy tab.
tribuy_settings_fields$settingsAdd fields to WooCommerce → Settings → Group buy.
tribuy_email_classes$emailsRegister or replace emails.
tribuy_admin_tabs$tabsAdd tabs to WooCommerce → Group Buys.
tribuy_campaigns_table_columns, tribuy_campaigns_table_column, tribuy_campaigns_table_row_actions—Extend the campaigns table.
tribuy_participants_table_columns, tribuy_participants_table_column—Extend the participants table.
tribuy_campaign_statuses, tribuy_participant_statuses$statusesStatus labels.
tribuy_add_to_cart_url, tribuy_add_to_cart_text, tribuy_single_add_to_cart_text$value, $campaignButton URL and text.
tribuy_campaigns_per_sweep50Campaigns checked per hourly sweep.

Example: only let customers with a billing phone join

add_filter( 'tribuy_can_participate', function ( $allowed, $campaign, $user_id ) {
    if ( true !== $allowed || ! $user_id ) {
        return $allowed;
    }
    return get_user_meta( $user_id, 'billing_phone', true )
        ? true
        : __( 'Please add a phone number to your account before joining a group buy.', 'my-plugin' );
}, 10, 3 );

Example: notify a supplier when a campaign succeeds

add_action( 'tribuy_campaign_succeeded', function ( $campaign ) {
    wp_mail(
        'orders@supplier.example',
        sprintf( 'Confirmed: %s', $campaign->get_name() ),
        sprintf( 'Please prepare %d units.', $campaign->get_committed_qty() )
    );
} );

Example: give campaigns one extra day when they are almost there

add_filter( 'tribuy_should_close_campaign', function ( $close, $campaign, $reason ) {
    if ( 'ended' === $reason && $campaign->get_progress_percent() >= 90 && ! $campaign->get_meta( '_my_extended' ) ) {
        $campaign->update_meta_data( '_my_extended', 1 );
        $campaign->save_meta_data();
        Tribuy\Campaign::extend( $campaign, DAY_IN_SECONDS );
        return false;
    }
    return $close;
}, 10, 3 );

WP-CLI

wp tribuy list [--status=<status>] [--format=table|csv|json|ids]
wp tribuy recalc [<id>...] [--all]
wp tribuy resolve <id>... [--outcome=successful|failed] [--yes]
wp tribuy extend <id>... [--days=<days>]

Pro hooks

HookTypeArguments
tribuy_pro_loadedaction$plugin: Pro features booted (license valid).
tribuy_pro_tier_unlockedaction$campaign, $tier: a new price tier was reached.
tribuy_pro_milestone_reachedaction$campaign, $percent.
tribuy_pro_order_settledaction$order, $campaign, $amount, $method (refund, due, coupon or manual).
tribuy_pro_campaign_relaunchedaction$campaign.
tribuy_pro_campaign_auto_extendedaction$campaign, $days.
tribuy_pro_tiersfilter$tiers, $campaign: the tiers (qty, price), sorted by quantity.
tribuy_pro_settlement_amountfilter$amount, $order, $campaign, $final_price.
tribuy_pro_live_datafilter$data, $campaign: the live progress payload.
tribuy_pro_rest_prepare_campaignfilter$data, $campaign: extend REST campaign objects.

Helpers: tribuy_pro_get_tiers(), tribuy_pro_get_price_at( $campaign, $qty ), tribuy_pro_get_next_tier(), tribuy_pro_get_history(). Pro product meta: _tribuy_pro_tiers, _tribuy_pro_roles, _tribuy_pro_hide_price, _tribuy_pro_access, _tribuy_pro_password, _tribuy_pro_invite_token, _tribuy_pro_qty_step, _tribuy_pro_min_value, _tribuy_pro_supplier_email, _tribuy_pro_extend_threshold, _tribuy_pro_extend_days, _tribuy_pro_auto_relaunch, _tribuy_pro_relaunch_delay, _tribuy_pro_relaunch_limit, _tribuy_pro_history. Waitlist table: {$wpdb->prefix}tribuy_pro_waitlist. Background work runs on Action Scheduler in the tribuy-group-buy-for-woocommerce-pro group.

REST API (Pro)

Namespace group-buy/v1. Campaign reads are public for published campaigns (private campaigns are hidden from visitors). Participants and actions need the edit_product capability, so authenticate with a cookie + wp_rest nonce or an application password.

Method & routeParametersReturns
GET /wp-json/group-buy/v1/campaignsstatus (active default, scheduled, successful, failed, any, or several separated by commas), per_page (1–100, default 10), orderby (end_date, date, title, popularity)Array of campaigns.
GET /wp-json/group-buy/v1/campaigns/{id}—One campaign.
GET /wp-json/group-buy/v1/campaigns/{id}/participantsround (default current), per_page (1–500, default 50), pageParticipants: id, order_id, user_id, email, qty, unit_price, status, date. Total in the X-WP-Total header.
POST /wp-json/group-buy/v1/campaigns/{id}/endoutcome (optional: successful or failed)The closed campaign.
POST /wp-json/group-buy/v1/campaigns/{id}/extenddays (1–365, default 1)The campaign.
POST /wp-json/group-buy/v1/campaigns/{id}/recalculate—The campaign.

A campaign object includes id, name, permalink, status, round, goal, max, committed, progress, remaining, min_per_customer, max_per_customer, start_date, end_date, seconds_remaining, currency, regular_price, group_price, current_price, tiers and next_tier (qty, price, needed, or null).

curl -X POST https://example.com/wp-json/group-buy/v1/campaigns/123/extend \
  -u "username:application-password" \
  -d days=3
Shopping Cart
  • Your cart is empty.