Получил код ответа Http 400 при доступе https://api.sandbox.paypal.com/v1/notifications/verify-webhook-signature

#laravel #paypal #paypal-sandbox #paypal-rest-sdk #paypal-subscriptions

#laravel #paypal #paypal-песочница #paypal-rest-sdk #paypal-подписки

Вопрос:

Я искал это в течение нескольких часов, я надеюсь, что кто-то здесь может помочь. Я создал сайт на основе подписки на Laravel и подписки PayPal, используя PayPal PHP SDK. Все работает отлично, за исключением одного: я создал webhook, когда пользователь отменяет платеж со своей стороны. Я получаю эту ошибку:

 Got Http response code 400 when accessing https://api.sandbox.paypal.com/v1/notifications/verify-webhook-signature.{"name":"VALIDATION_ERROR","message":"Invalid data provided","debug_id":"7225cebfec35a","information_link":"https://developer.paypal.com/docs/api/webhooks/#errors","details":[{"field":"webhook_id","location":"body","issue":"Required field cannot be blank"}],"links":[]}  
  

Вот мой код:

 public function webhook()
{
    

    /**
    * Receive the entire body that you received from PayPal webhook.
    */
    $bodyReceived = file_get_contents('php://input'); 

    // Receive HTTP headers that you received from PayPal webhook.
    $headers = getallheaders(); 

    /**
    * Uppercase all the headers for consistency
    */
    $headers = array_change_key_case($headers, CASE_UPPER); 

    $signatureVerification = new PayPalApiVerifyWebhookSignature(); 
    $signatureVerification->setWebhookId(env('PAYPAL_WEBHOOK_ID')); 
    $signatureVerification->setAuthAlgo($headers['PAYPAL-AUTH-ALGO']); 
    $signatureVerification->setTransmissionId($headers['PAYPAL-TRANSMISSION-ID']); 
    $signatureVerification->setCertUrl($headers['PAYPAL-CERT-URL']); 
    $signatureVerification->setTransmissionSig($headers['PAYPAL-TRANSMISSION-SIG']); 
    $signatureVerification->setTransmissionTime($headers['PAYPAL-TRANSMISSION-TIME']); 

    $webhookEvent = new PayPalApiWebhookEvent(); 
    $webhookEvent->fromJson($bodyReceived); 
    $signatureVerification->setWebhookEvent($webhookEvent); 
    $request = clone $signatureVerification; 

    try {
        $output = $signatureVerification->post($this->apiContext);
        
    } catch(Exception $ex) {
        //This is where it fails
        print_r($ex->getMessage());
        exit(1);
    }

    $verificationStatus = $output->getVerificationStatus();
    $responseArray = json_decode($request->toJSON(), true);

    $event = $responseArray['webhook_event']['event_type'];

    if ($verificationStatus == 'SUCCESS')
    { 

        switch($event)
        {
            case 'BILLING.SUBSCRIPTION.CANCELLED':
            case 'BILLING.SUBSCRIPTION.SUSPENDED':
            case 'BILLING.SUBSCRIPTION.EXPIRED':
            case 'BILLING_AGREEMENTS.AGREEMENT.CANCELLED':

            // $user = User::where('payer_id',$responseArray['webhook_event']['resource']['payer']['payer_info']['payer_id'])->first();
            $this->updateStatus($responseArray['webhook_event']['resource']['payer']['payer_info']['payer_id'], 0,1);
            
            break;
        }
    }
    echo $verificationStatus;
    
    exit(0);
}
  

И вот $this->apiContext :

 trait PayPalApiCredentialsTrait {

private $apiContext;

public function setCredentials()
{
    $this->apiContext = new PayPalRestApiContext(
        new PayPalAuthOAuthTokenCredential(
            env('PAYPAL_CLIENT_ID'),     // ClientID
            env('PAYPAL_CLIENT_SECRET')      // ClientSecret
        )
    );

    $this->apiContext->setConfig(
        array(
            'mode' => env("PAYPAL_MODE"),
            'log.LogEnabled' => true,
            'log.FileName' => '../PayPal.log',
            'log.LogLevel' => 'INFO', // PLEASE USE `INFO` LEVEL FOR LOGGING IN LIVE ENVIRONMENTS
        )
    );
}
  

}

Это ошибка, которую я получаю из paypal.log:

         [01-09-2020 15:54:18] PayPalCorePayPalHttpConnection : INFO: POST https://api.sandbox.paypal.com/v1/oauth2/token
    [01-09-2020 15:54:18] PayPalCorePayPalHttpConnection : INFO: Response Status  : 200
    [01-09-2020 15:54:18] PayPalCorePayPalHttpConnection : INFO: POST https://api.sandbox.paypal.com/v1/notifications/verify-webhook-signature
    [01-09-2020 15:54:19] PayPalCorePayPalHttpConnection : INFO: Response Status  : 400
[01-09-2020 15:54:19] PayPalCorePayPalHttpConnection : ERROR: Got Http response code 400 when accessing https://api.sandbox.paypal.com/v1/notifications/verify-webhook-signature. {"name":"VALIDATION_ERROR","message":"Invalid data provided","debug_id":"26b12ee43cddd","information_link":"https://developer.paypal.com/docs/api/webhooks/#errors","details":[{"field":"webhook_id","location":"body","issue":"Required field cannot be blank"}],"links":[]}
  

Я должен упомянуть, что все остальное работает нормально.
Создание планов, соглашений, отмена обоих, отображение активных планов и многое другое…
Все работает гладко.
Это единственное, что я, похоже, не могу исправить.
Если бы кто-нибудь мог разобраться в этом для меня, я был бы очень признателен.
Спасибо!

Комментарии:

1. я использовал paypal-sdk-api, иногда служба PayPal недоступна. вроде как проверьте paypal.log на предмет ответа

2. Спасибо за ответ. Я отредактировал и добавил точный вывод paypal.log. Похоже, это не так, иначе он сказал бы так, нет? Поскольку в нем указано «VALIDATION_ERROR», кажется, что данные для входа неверны, но они не могут быть, поскольку они работают везде.

3. я раньше не делал веб-ссылки, но я обнаружил, что эта функция setRequestBody() отсутствует, возможно, это проблема

4. Не сработало. Уведомления о песочнице PayPal находятся на обслуживании: paypal-status.com/product/sandbox Может ли это быть проблемой, а не моим кодом?

5. может быть, да, может быть, точно нет idk, я когда-нибудь говорил вам, что служба недоступна xD

Ответ №1:

PayPal-PHP-SDK устарел и больше не поддерживается; его не следует использовать для новых интеграций. Его реализация тарифных планов и подписок устарела и несовместима с текущей версией API подписок.

Вместо него следует использовать прямую интеграцию HTTPS (без SDK) для подписок и для проверки веб-ссылок.

(Для варианта использования одноразового платежа есть новая проверка версии v2-PHP-SDKhttps://developer.paypal.com/docs/api/rest-sdks / )

Комментарии:

1. Я понимаю. Однако весь код уже написан, и в настоящее время его нельзя изменить. Нет причин, по которым это не должно работать, если работает все остальное… Уведомления о песочнице PayPal находятся на обслуживании: paypal-status.com/product/sandbox Может ли это быть проблемой, а не моим кодом? Есть идеи?