Action: a donation completed
Fires once when a donation is confirmed paid (one-time, recurring first payment, or a renewal).
add_action( 'donor_merchant_donation_completed', function ( $donation ) {
// $donation->amount, ->total, ->currency, ->frequency,
// ->campaign_id, ->designation, ->donor_id, ->meta (JSON), ...
} );
Filters
| Filter | What it changes |
|---|---|
donor_merchant_receipt_email | The donor receipt before sending — ( array $email, $donation, $donor ) with subject, body, headers. |
donor_merchant_monthly_report_email | The monthly summary email — ( array $email, array $stats ). |
donor_merchant_estimated_fee | The fee-recovery estimate — ( float $fee, float $amount ). |
donor_merchant_rate_limit | Max donation attempts per IP per hour — ( int $limit ). |
donor_merchant_suppress_receipt | Return true to skip a donor receipt — ( bool, $donation ). |
donor_merchant_suppress_admin_notification | Return true to skip the admin notice — ( bool, $donation ). |
// Example: tweak the receipt subject.
add_filter( 'donor_merchant_receipt_email', function ( $email, $donation, $donor ) {
$email['subject'] = 'We received your gift, ' . $donor->first_name . '!';
return $email;
}, 10, 3 );
Outgoing webhooks
Add one or more URLs under Settings → Integrations and Donor Merchant POSTs a JSON payload to each on every completed donation — perfect for Zapier, Make, or your own endpoint.
{
"event": "donation.completed",
"donation": {
"id": 123, "amount": 50, "fee_amount": 0, "total": 50,
"currency": "USD", "frequency": "monthly", "status": "completed",
"payment_method": "stripe", "transaction_id": "pi_...",
"campaign": "Spring Appeal", "designation": "Scholarship Fund",
"tribute_type": "", "tribute_name": "",
"created_at": "2026-06-14 10:00:00",
"custom_fields": [ { "label": "How did you hear?", "value": "Friend" } ]
},
"donor": { "first_name": "Sam", "last_name": "Rivera", "email": "sam@example.org", "phone": "" },
"organization": "Hope Community Center",
"site": "https://example.org"
}
Verifying the signature
Each request includes an X-Donor-Merchant-Signature header — an HMAC-SHA256 of the raw body using your outgoing webhook secret. Verify it like so:
$payload = file_get_contents( 'php://input' );
$signature = $_SERVER['HTTP_X_DONOR_MERCHANT_SIGNATURE'] ?? '';
$expected = hash_hmac( 'sha256', $payload, $your_secret );
if ( hash_equals( $expected, $signature ) ) {
// Trusted.
}
Shortcodes & REST
Render anywhere with [donor_merchant], [donor_merchant campaign="N"], [donor_merchant_progress campaign="N"], and [donor_merchant_portal]. The donation, verification, and webhook endpoints live under the REST namespace donor-merchant/v1.