Webhooks

Webhooks allow you to receive real-time notifications when payment events occur. Both Maya and Magpie send 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
  • Payment expires
  • Payment is cancelled

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 dedicated webhook endpoints for each payment gateway:

  • Name
    Maya Webhook
    Description

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

  • Name
    Magpie Webhook
    Description

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


Maya Webhooks

Webhook Events

Maya sends the following events:

  • Name
    PAYMENT_SUCCESS
    Description

    Payment completed successfully

  • Name
    PAYMENT_FAILED
    Description

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

  • Name
    PAYMENT_EXPIRED
    Description

    Checkout session expired before payment

  • Name
    PAYMENT_CANCELLED
    Description

    User cancelled payment

Payload Structure

{
  "id": "maya_ch_abc123xyz",
  "status": "PAYMENT_SUCCESS",
  "requestReferenceNumber": "550e8400-e29b-41d4-a716-446655440000",
  "amount": {
    "value": 1000.00,
    "currency": "PHP"
  },
  "paymentMethod": "card",
  "createdAt": "2024-02-06T10:30:00Z",
  "completedAt": "2024-02-06T10:30:15Z"
}

Example: Payment Success

Maya Webhook - Payment Success

{
  "id": "maya_ch_abc123xyz",
  "status": "PAYMENT_SUCCESS",
  "requestReferenceNumber": "550e8400-e29b-41d4-a716-446655440000",
  "amount": {
    "value": 1040.00,
    "currency": "PHP"
  },
  "paymentMethod": "card",
  "customer": {
    "email": "donor@example.com"
  },
  "createdAt": "2024-02-06T10:30:00Z",
  "completedAt": "2024-02-06T10:30:15Z"
}

What happens:

  1. Maya sends webhook to your endpoint
  2. Batchmates verifies signature
  3. Donation status updated to completed
  4. Campaign raised_amount and available_amount incremented
  5. User receives success notification

Example: Payment Failed

Maya Webhook - Payment Failed

{
  "id": "maya_ch_def456abc",
  "status": "PAYMENT_FAILED",
  "requestReferenceNumber": "650e8400-e29b-41d4-a716-446655440001",
  "amount": {
    "value": 1040.00,
    "currency": "PHP"
  },
  "failureReason": "Insufficient funds",
  "createdAt": "2024-02-06T10:35:00Z"
}

What happens:

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

Magpie Webhooks

Webhook Events

Magpie sends the following events:

  • Name
    checkout.session.completed
    Description

    Checkout session completed successfully

  • Name
    checkout.session.expired
    Description

    Checkout session expired without payment

  • Name
    charge.succeeded
    Description

    Charge succeeded (payment captured)

  • Name
    charge.failed
    Description

    Charge failed

Payload Structure

{
  "type": "checkout.session.completed",
  "data": {
    "id": "ch_abc123xyz",
    "amount": 104000,
    "currency": "php",
    "status": "paid",
    "payment_method_types": ["card", "gcash"],
    "metadata": {
      "reference_number": "550e8400-e29b-41d4-a716-446655440000",
      "donation_id": 45,
      "campaign_id": 5
    },
    "created_at": 1707217800,
    "completed_at": 1707217815
  }
}

Example: Checkout Completed

Magpie Webhook - Checkout Completed

{
  "type": "checkout.session.completed",
  "data": {
    "id": "ch_abc123xyz",
    "amount": 104000,
    "currency": "php",
    "status": "paid",
    "payment_method_types": ["card"],
    "customer_email": "donor@example.com",
    "metadata": {
      "reference_number": "550e8400-e29b-41d4-a716-446655440000",
      "donation_id": 45,
      "campaign_id": 5
    },
    "created_at": 1707217800,
    "completed_at": 1707217815
  }
}

What happens:

  1. Magpie sends webhook to your endpoint
  2. Signature verified via Magpie-Signature header
  3. Donation status updated to completed
  4. Campaign raised_amount and available_amount incremented
  5. User receives confirmation notification

Example: Charge Failed

Magpie Webhook - Charge Failed

{
  "type": "charge.failed",
  "data": {
    "id": "ch_def456abc",
    "amount": 104000,
    "currency": "php",
    "status": "failed",
    "failure_message": "Card was declined",
    "failure_code": "card_declined",
    "metadata": {
      "reference_number": "650e8400-e29b-41d4-a716-446655440001",
      "donation_id": 46,
      "campaign_id": 5
    },
    "created_at": 1707218000
  }
}

Webhook Security

Signature Verification

Both payment gateways sign webhook requests to ensure they're authentic.

Maya Signature Verification

Maya uses HMAC-SHA256 signature in the Maya-Signature header:

$payload = $request->getContent();
$signature = $request->header('Maya-Signature');
$secret = config('services.maya.secret_key');

$expectedSignature = hash_hmac('sha256', $payload, $secret);

if (!hash_equals($expectedSignature, $signature)) {
    // Invalid signature - reject webhook
    abort(401, 'Invalid signature');
}

Magpie Signature Verification

Magpie uses HMAC-SHA256 signature in the Magpie-Signature header:

$payload = $request->getContent();
$signature = $request->header('Magpie-Signature');
$secret = config('services.magpie.secret_key');

$expectedSignature = hash_hmac('sha256', $payload, $secret);

if (!hash_equals($expectedSignature, $signature)) {
    // Invalid signature - reject webhook
    abort(401, 'Invalid signature');
}

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 payment gateway settings
# https://abc123.ngrok.io/api/v1/payments/maya/webhook

2. RequestBin for Quick Testing

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

Manual Webhook Testing

Test Maya Webhook

curl -X POST https://batchmates-v2.revlv.com/api/v1/payments/maya/webhook \
  -H "Content-Type: application/json" \
  -H "Maya-Signature: {computed_signature}" \
  -d '{
    "id": "maya_test_123",
    "status": "PAYMENT_SUCCESS",
    "requestReferenceNumber": "550e8400-e29b-41d4-a716-446655440000",
    "amount": {
      "value": 1040.00,
      "currency": "PHP"
    }
  }'

Test Magpie Webhook

curl -X POST https://batchmates-v2.revlv.com/api/v1/payments/magpie/webhook \
  -H "Content-Type: application/json" \
  -H "Magpie-Signature: {computed_signature}" \
  -d '{
    "type": "checkout.session.completed",
    "data": {
      "id": "ch_test_123",
      "amount": 104000,
      "status": "paid",
      "metadata": {
        "reference_number": "550e8400-e29b-41d4-a716-446655440000",
        "donation_id": 45
      }
    }
  }'

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: PAYMENT_SUCCESS
    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

Maya Events

EventDescriptionAction
PAYMENT_SUCCESSPayment completedMark donation completed
PAYMENT_FAILEDPayment failedMark donation failed
PAYMENT_EXPIREDSession expiredMark donation expired
PAYMENT_CANCELLEDUser cancelledMark donation failed

Magpie Events

EventDescriptionAction
checkout.session.completedSession completedMark donation completed, increment campaign raised_amount and available_amount
checkout.session.expiredSession expiredMark donation expired
charge.succeededCharge capturedMark donation completed, increment campaign raised_amount and available_amount
charge.failedCharge 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

Signature Verification Failed

Check:

  1. Using correct secret key
  2. Using raw request body (not parsed JSON)
  3. Signature header name matches gateway (Maya-Signature vs Magpie-Signature)
  4. Hash algorithm is HMAC-SHA256

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/maya/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?