Stripe sends events to POST /wp-json/formforge/v1/stripe/webhook.
Signature Verification
php
$payload = file_get_contents( 'php://input' );
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'] ?? '';
// Parse: t=1705762522,v1=abc123def456...
$parts = [];
foreach ( explode( ',', $sig_header ) as $item ) {
list( $key, $value ) = explode( '=', $item, 2 );
$parts[ $key ] = $value;
}
// Reject events older than 5 minutes
if ( abs( time() - (int) $parts['t'] ) > 300 ) {
return new WP_REST_Response( [ 'error' => 'Timestamp too old' ], 400 );
}
// HMAC verification
$signed_payload = $parts['t'] . '.' . $payload;
$expected = hash_hmac( 'sha256', $signed_payload, $webhook_secret );
if ( ! hash_equals( $expected, $parts['v1'] ) ) {
return new WP_REST_Response( [ 'error' => 'Signature mismatch' ], 400 );
}Handled Events
| Event | Action |
|---|---|
payment_intent.succeeded | Marks payment_status as succeeded and adds _payment data |
payment_intent.payment_failed | Marks payment_status as failed |
charge.refunded | Reads data.object.payment_intent and marks payment_status as refunded |
Webhook Setup in Stripe Dashboard
- Go to Stripe Dashboard > Developers > Webhooks
- Click “Add endpoint”
- Enter URL:
https://example.com/wp-json/formforge/v1/stripe/webhook - Select events:
payment_intent.succeeded,payment_intent.payment_failed,charge.refunded - Copy the signing secret (
whsec_...) to Form Forge settings
—