Webhooks

Webhooks allow you to receive real-time notifications when payment events occur. PayMongo sends webhook events to inform you about donation status changes.


Overview

Instead of polling the API to check donation status, configure webhooks to receive automatic notifications when:

  • Payment is completed
  • Payment fails

Benefits

  • Name
    Real-time Updates
    Description

    Get instant notifications without polling

  • Name
    Reduced API Calls
    Description

    No need to constantly check donation status

  • Name
    Reliable
    Description

    Payment gateways retry failed webhook deliveries

  • Name
    Automatic
    Description

    Updates happen in the background without user action


Webhook Endpoints

Batchmates provides a dedicated webhook endpoint for the payment gateway:

  • Name
    PayMongo Webhook
    Description

    POST https://batchmates-v2.revlv.com/api/v1/payments/paymongo/webhook


PayMongo Webhooks

Webhook Events

PayMongo sends the following events:

  • Name
    checkout_session.payment.paid
    Description

    Hosted checkout payment completed successfully (primary completion signal)

  • Name
    payment.paid
    Description

    Payment completed; marks the donation completed if resolvable, otherwise logged and skipped

  • Name
    payment.failed
    Description

    Payment failed (insufficient funds, declined card, etc.)

Payload Structure

{
  "data": {
    "id": "evt_abc123",
    "attributes": {
      "type": "checkout_session.payment.paid",
      "data": {
        "id": "cs_abc123",
        "attributes": {
          "reference_number": "550e8400-e29b-41d4-a716-446655440000",
          "metadata": { "donation_reference": "550e8400-e29b-41d4-a716-446655440000" },
          "payments": [{ "attributes": { "status": "paid", "source": { "type": "gcash" } } }]
        }
      }
    }
  }
}

Example: Payment Success

PayMongo Webhook - Payment Success

{
  "data": {
    "id": "evt_abc123xyz",
    "attributes": {
      "type": "checkout_session.payment.paid",
      "data": {
        "id": "cs_abc123xyz",
        "attributes": {
          "reference_number": "550e8400-e29b-41d4-a716-446655440000",
          "payments": [{ "attributes": { "status": "paid", "amount": 103730, "source": { "type": "gcash" } } }]
        }
      }
    }
  }
}

What happens:

  1. PayMongo sends webhook to your endpoint
  2. Batchmates verifies the Paymongo-Signature header
  3. Donation status updated to completed
  4. Campaign raised_amount and available_amount incremented
  5. User receives success notification

Example: Payment Failed

PayMongo Webhook - Payment Failed

{
  "data": {
    "id": "evt_def456abc",
    "attributes": {
      "type": "payment.failed",
      "data": {
        "id": "pi_def456abc",
        "attributes": {
          "reference_number": "650e8400-e29b-41d4-a716-446655440001",
          "last_payment_error": { "failed_message": "Insufficient funds" }
        }
      }
    }
  }
}

What happens:

  1. PayMongo sends webhook
  2. Donation status updated to failed
  3. User can retry payment from their donation history

Webhook Security

PayMongo's webhook endpoint is protected by HMAC signature verification — every request is signed and the signature is checked before the handler runs.

Paymongo-Signature: t=,te=,li=

Which signature is checked depends on PAYMONGO_LIVEMODE (te when false, li when true). Requests older than 5 minutes are rejected as replays.


Testing Webhooks

Using Webhook Testing Tools

1. ngrok for Local Development

# Install ngrok
brew install ngrok  # macOS
# or download from ngrok.com

# Start your local server
php artisan serve

# Expose port 8000
ngrok http 8000

# Use the ngrok URL in your PayMongo dashboard webhook config
# https://abc123.ngrok.io/api/v1/payments/paymongo/webhook

2. RequestBin for Quick Testing

# Create a RequestBin at requestbin.com
# Use the bin URL to inspect webhook payloads

Manual Webhook Testing

Test PayMongo Webhook

curl -X POST https://batchmates-v2.revlv.com/api/v1/payments/paymongo/webhook \
  -H "Content-Type: application/json" \
  -H "Paymongo-Signature: t={timestamp},te={computed_signature}" \
  -d '{
    "data": {
      "id": "evt_test_123",
      "attributes": {
        "type": "checkout_session.payment.paid",
        "data": { "id": "cs_test_123", "attributes": { "reference_number": "550e8400-e29b-41d4-a716-446655440000" } }
      }
    }
  }'

Webhook Flow Diagram

Complete Payment Flow

sequenceDiagram
    participant User
    participant App
    participant API
    participant Gateway

    User->>App: Click "Donate"
    App->>API: POST /donations
    API->>Gateway: Create checkout
    Gateway-->>API: Checkout URL
    API-->>App: Redirect URL
    App->>Gateway: Redirect to payment
    User->>Gateway: Enter payment details
    Gateway->>Gateway: Process payment
    Gateway->>API: Webhook: checkout_session.payment.paid
    API->>API: Update donation status
    API->>API: Update campaign balances
    API->>User: Send notification
    Gateway->>User: Redirect to success page
    User->>App: View success page

Webhook Event Reference

PayMongo Events

EventDescriptionAction
checkout_session.payment.paidPayment completedMark donation completed
payment.paidPayment completed (saved-card / intent charges)Mark donation completed if resolvable
payment.failedPayment failedMark donation failed

Troubleshooting

Webhook Not Received

Check:

  1. Webhook URL configured correctly in gateway dashboard
  2. Server is publicly accessible (not behind firewall)
  3. HTTPS enabled (required by most gateways)
  4. No rate limiting blocking webhook requests

Webhook Rejected

Check:

  1. Paymongo-Signature header present and not malformed
  2. The correct signing secret is configured for the mode (te/li) currently in use
  3. Request is not older than 5 minutes (replay protection)
  4. No proxy is rewriting the request body — signature verification hashes the raw body

Donation Not Updating

Check:

  1. Webhook handler returns 200 OK
  2. Reference number matches donation record
  3. Idempotency checks not blocking legitimate updates
  4. Database transaction not rolled back due to error

Testing Webhooks

# Check if webhook endpoint is accessible
curl -I https://batchmates-v2.revlv.com/api/v1/payments/paymongo/webhook

# Should return 405 Method Not Allowed (POST required)
# If timeout or connection error, check firewall/DNS

Need Help?

If webhooks aren't working as expected:

  1. Check webhook logs in payment gateway dashboard
  2. Verify webhook URL configuration
  3. Test with manual webhook calls
  4. Review signature verification implementation
  5. Contact support with webhook payload and error logs

Was this page helpful?