skip to Main Content

I am using WordPress and I wanted to include to my server a stripe webhook endpoint.
I don’t know why but even if I hardcode error "400" to send to stripe it send "200"
and I don’t know why, it seems weird but StripeStripeClient(STRIPE_TEST_KEY); seems to send the response "200" because after this instruction nothing happens.

Here is my code:

require_once('wp-content/plugins/myplugin/stripe/init.php');
require_once( dirname( __FILE__ ) . '/wp-load.php' );


/*$stripe = new */
StripeStripeClient(STRIPE_TEST_KEY);
$response = ["user" => 6];
http_response_code(400);
header('Content-Type: application/json'); // Setting header
echo json_encode($response); // Sending response
exit();

// This is your Stripe CLI webhook secret for testing your endpoint locally.
$endpoint_secret = 'whsec_Qz...';

$payload = @file_get_contents('php://input');
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = null;

try {
  $event = StripeWebhook::constructEvent(
    $payload, $sig_header, $endpoint_secret
  );
} catch(UnexpectedValueException $e) {
  // Invalid payload
  http_response_code(400);
  exit(); 
} catch(StripeExceptionSignatureVerificationException $e) {
  // Invalid signature
  http_response_code(400);
  
}

http_response_code(200);

Typically this code should send to stripe the response ‘400’ but it does not and if the instruction

$response = ["user" => 6];
header('Content-Type: application/json'); // Setting header
echo json_encode($response); // Sending response
exit();

was put before:

StripeStripeClient(STRIPE_TEST_KEY);

it sends the response "400" to stripe.

I read the documentation but I found nothing about that.

3

Answers


  1. Chosen as BEST ANSWER

    I resolve my problem by declaring:

    new StripeStripeClient(STRIPE_TEST_KEY);
    

    rather than only:

    StripeStripeClient(STRIPE_TEST_KEY);
    

  2. You only specified 400 error code on your catch statement.

    this line below, does not set your response status code to anything and would presumably just send back a 200 status response.

    header('Content-Type: application/json'); // Setting header
    echo json_encode($response); // Sending response
    exit();
    

    I have this code below that captures webhook from stipe from a plugin I’ve created years ago which you can refer, if you want to send back an error response to stripe without actually catching and error, you need to define http_response_code(400); outside of try-catch block

    public function captureStipeWebhook() {
        $action = isset( $_REQUEST['stripe_bacs_webhook'] ) ? $_REQUEST['stripe_bacs_webhook'] : false;
        
        if ( !$action || !in_array( $action, ['live', 'test']))
            return;
    
        StripeStripe::setApiKey( $this->stripeSecretKey() );
        
        $payload = @file_get_contents('php://input');
        $sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
        $response = null;   
        
        try {
            $response = StripeWebhook::constructEvent(
                $payload, $sig_header, get_option( $this->stripeOptNameSecret() )
            );
            
            if ( 
                    $response->type === 'checkout.session.completed' 
                    && isset( $response->data->object->metadata->sb_sub )  
                    && $this->url() == $response->data->object->metadata->url  
                ) {
                $intent = StripeSetupIntent::retrieve( $response->data->object->setup_intent );
                $prices = explode(',', str_replace(' ', '', $response->data->object->metadata->selected_price) );
                $oneTimeCharges = $response->data->object->metadata->additional_items ? explode(',', str_replace(' ', '', $response->data->object->metadata->additional_items) ) : false;
                $items = [];
                $oneTimeItems = [];
                foreach ( $prices as $price ) {
                    if ( $price && $price !== '' ) {
                        $items[] = ['price' => $price];
                    }
                }
                foreach ( $oneTimeCharges as $otc ) {
                    if ( $otc && $otc !== '' && $otc !== 'false' ) {
                        $oneTimeItems[] = ['price' => $otc];
                    }
                }
                $subData = [
                    'customer' => $intent->customer,                
                    'default_payment_method' => $intent->payment_method,
                    'items' => [$items],                    
                ];
                if ( $oneTimeItems ) {
                    $subData['add_invoice_items'] = $oneTimeItems;
                }
                if ( isset( $response->data->object->metadata->selected_coupon ) ) {
                    $subData['coupon'] = $response->data->object->metadata->selected_coupon;
                }
                $subscription = StripeSubscription::create( $subData, [
                    'idempotency_key' => $response->data->object->metadata->iptc_key
                ]);
                //$this->log( 'webhook-event', json_encode( $subscription ) ) ;
                wp_send_json([$subData, $subscription]);
            } else {
                $responseMessage = [
                    'message' => 'Webhook Received!',
                    'type'  => 'No Sub'
                ];
            }     
        } catch(UnexpectedValueException $e) {
            // Invalid payload
            http_response_code(400);
            $this->log( 'webhook-error', json_encode( $e->getMessage() ) ) ;
            $responseMessage = $e->getMessage();
        } catch(StripeExceptionSignatureVerificationException $e) {
            // Invalid signature
            http_response_code(400);
            $this->log( 'webhook-error', json_encode( $e->getMessage() ) ) ;
            $responseMessage = $e->getMessage();
        }
        wp_send_json([$responseMessage]);
    }
    
    Login or Signup to reply.
  3. You dont have to set header('Content-Type: application/json'); for the endpoint if you are not sending data back to stripe.

    here is the code I currently have set up:

    $payload = file_get_contents('php://input');
    
    if(!$payload) {
        http_response_code(400);
        exit(); 
    }
    
    if( !isset($_SERVER["HTTP_STRIPE_SIGNATURE"])){
        http_response_code(401);
        exit(); 
    }
    
    $endpoint_secret = 'whsec_Qz...';
    $event = null;
    
    try {
        $event = StripeEvent::constructFrom(
            json_decode($payload, true)
        );
    } catch(UnexpectedValueException $e) {
        echo '⚠️  Webhook error while parsing basic request.';
        http_response_code(400);
        exit();
    }
    
    if ($endpoint_secret) {
        $sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
        try {
            $event = StripeWebhook::constructEvent(
                $payload, $sig_header, $endpoint_secret
            );
        } catch(StripeExceptionSignatureVerificationException $e) {
            echo '⚠️  Webhook error while validating signature.';
            http_response_code(400);
            exit();
        }
    }
    
    switch ($event->type) {
        case 'checkout.session.completed':
    
    //Do stuff
    break;
    default:
            exit();
    }
    
    http_response_code(200);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search