# give/4.18.0/src/Framework/PaymentGateways/Webhooks/EventHandlers/SubscriptionFirstDonationCompleted.php

GiveWP – Donation Plugin and Fundraising Platform, version 4.18.0. 113 lines.

- Page: https://pluginprobe.com/plugins/give/4.18.0/code/src/Framework/PaymentGateways/Webhooks/EventHandlers/SubscriptionFirstDonationCompleted.php
- Raw: https://pluginprobe.com/plugins/give/4.18.0/raw/src/Framework/PaymentGateways/Webhooks/EventHandlers/SubscriptionFirstDonationCompleted.php
- Modified: 2026-10-01T20:29:10+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/give/4.18.0/code/src/Framework/PaymentGateways/Webhooks/EventHandlers/SubscriptionFirstDonationCompleted.php#L10-L20`.

```php
<?php

namespace Give\Framework\PaymentGateways\Webhooks\EventHandlers;

use Exception;
use Give\Donations\Models\Donation;
use Give\Donations\Models\DonationNote;
use Give\Donations\ValueObjects\DonationStatus;
use Give\Framework\PaymentGateways\Log\PaymentGatewayLog;
use Give\Framework\PaymentGateways\Webhooks\EventHandlers\Actions\UpdateDonationStatus;
use Give\Framework\PaymentGateways\Webhooks\EventHandlers\Actions\UpdateSubscriptionStatus;
use Give\Subscriptions\ValueObjects\SubscriptionStatus;

/**
 * @since 3.6.0
 */
class SubscriptionFirstDonationCompleted
{
    /**
     * @since 4.18.0 Guard against a null initial donation and a missing subscription instead of fataling on them.
     * @since 4.16.0 Add $donationId to support gateways that only receive the transaction ID via webhook (e.g. PayFast).
     * @since 4.5.0 Add $setDonationComplete and $gatewaySubscriptionId parameters
     * @since 3.6.0
     */
    public function __invoke(
        string $gatewayTransactionId,
        string $message = '',
        bool $setSubscriptionActive = true,
        bool $setDonationComplete = true,
        string $gatewaySubscriptionId = '',
        int $donationId = 0
    )
    {
        if ($donationId > 0) {
            $donation = Donation::find($donationId);

            if ($donation && $donation->subscription) {
                $donation->gatewayTransactionId = $gatewayTransactionId;
                $donation->save();

                if ( ! empty($gatewaySubscriptionId) && empty($donation->subscription->gatewaySubscriptionId)) {
                    $donation->subscription->gatewaySubscriptionId = $gatewaySubscriptionId;
                    $donation->subscription->save();
                }
            }
        } else {
            $donation = give()->donations->getByGatewayTransactionId($gatewayTransactionId);

            if (! $donation && ! empty($gatewaySubscriptionId) && $subscription = give()->subscriptions->getByGatewaySubscriptionId($gatewaySubscriptionId)) {
                $donation = $subscription->initialDonation();

                if ($donation) {
                    $donation->gatewayTransactionId = $gatewayTransactionId;
                    $donation->save();
                }
            }
        }

        if ( ! $donation || ! $donation->subscription || ! $donation->type->isSubscription()) {
            PaymentGatewayLog::error(
                sprintf('The first donation was not updated for the gateway transaction ID %s because no valid subscription donation was found to update.',
                    $gatewayTransactionId),
                [
                    'Gateway Subscription ID' => $gatewaySubscriptionId,
                    'Gateway Transaction ID' => $gatewayTransactionId,
                    'Donation ID' => $donationId,
                    'Message' => $message,
                ]
            );

            return;
        }

        try {
            if ($setDonationComplete && ! $donation->status->isComplete()) {
                if (empty($message)) {
                    $message = __('Subscription First Donation Completed.', 'give');
                }

                (new UpdateDonationStatus())($donation, DonationStatus::COMPLETE(), $message);
            } else {
                if (empty($message)) {
                    $message = __('Subscription First Donation Updated.', 'give');
                }

                DonationNote::create([
                    'donationId' => $donation->id,
                    'content' => $message . ' ' . sprintf(__('%s transaction ID: %s', 'give'),
                            $donation->gateway()->getName(),
                            $donation->gatewayTransactionId
                        ),
                ]);
            }

            if ($setSubscriptionActive && ! $donation->subscription->status->isActive()) {
                (new UpdateSubscriptionStatus())($donation->subscription, SubscriptionStatus::ACTIVE(),
                    __('Subscription Active After The First Donation Got Completed.', 'give'));
            }
        } catch (Exception $e) {
            PaymentGatewayLog::error(
                sprintf('Subscription First Donation Failed! Error: %s',
                    $e->getCode() . ' - ' . $e->getMessage()),
                [
                    'Donation Id' => $donation->id,
                    'Gateway Transaction Id' => $gatewayTransactionId,
                    'Gateway Subscription Id' => $donation->subscriptionId,
                    'message' => $message,
                ]
            );
        }
    }
}

```
