cashier-paddle icon indicating copy to clipboard operation
cashier-paddle copied to clipboard

Activate subscription is not working.

Open livan2r opened this issue 1 year ago • 8 comments

Cashier Paddle Version

2.4.2

Laravel Version

10.48.10

PHP Version

8.2.12

Database Driver & Version

No response

Description

$subscription->activate(); to force a trial to end immediately and activate the subscription is failing to me on https://sandbox-api.paddle.com the API response returns the error message Paddle API error 'Invalid request' occurred.

I was digging a little bit and it looks like the issue is related to the content type that the Paddle API is expecting from this endpoint. For example, by calling the asForm method before making the request in Cashier:api() the response is successful.

Steps To Reproduce

On a trial subscription call $subscription->activate();

livan2r avatar May 08 '24 22:05 livan2r

That would seem weird to me as it's just a POST request: https://developer.paddle.com/api-reference/subscriptions/activate-subscription. Is there any other info about the failing request? Any other info in the message body from the return response or in the headers?

driesvints avatar May 10 '24 14:05 driesvints

Hi, @driesvints. Yeah, it looks weird to me too because it's a very simple endpoint. I'm sharing with you the response that I'm getting with the current Cashier::api method (asJson, default content-type), but if I send the request asForm the response is successful, maybe something changed on Padde's sandbox API for this endpoint.

\Illuminate\Http\Client\Response::__set_state(array(
   'response' => 
  \GuzzleHttp\Psr7\Response::__set_state(array(
     'reasonPhrase' => 'Bad Request',
     'statusCode' => 400,
     'headers' => 
    array (
      'Date' => 
      array (
        0 => 'Fri, 10 May 2024 16:39:00 GMT',
      ),
      'Content-Type' => 
      array (
        0 => 'application/json',
      ),
      'Content-Length' => 
      array (
        0 => '273',
      ),
      'Connection' => 
      array (
        0 => 'keep-alive',
      ),
      'Cache-Control' => 
      array (
        0 => 'no-store, max-age=0',
      ),
      'content-security-policy' => 
      array (
        0 => 'default-src \'none\'; frame-ancestors \'none\'; base-uri \'none\'',
      ),
      'cross-origin-embedder-policy' => 
      array (
        0 => 'require-corp',
      ),
      'cross-origin-opener-policy' => 
      array (
        0 => 'same-origin',
      ),
      'cross-origin-resource-policy' => 
      array (
        0 => 'same-site',
      ),
      'permissions-policy' => 
      array (
        0 => 'accelerometer=(),ambient-light-sensor=(),autoplay=(),battery=(),camera=(),display-capture=(),document-domain=(),encrypted-media=(),fullscreen=(),gamepad=(),geolocation=(),gyroscope=(),layout-animations=(self),legacy-image-formats=(self),magnetometer=(),microphone=(),midi=(),oversized-images=(self),payment=(),picture-in-picture=(),publickey-credentials-get=(),screen-wake-lock=(),speaker-selection=(),sync-xhr=(self),unoptimized-images=(self),unsized-media=(self),usb=(),web-share=(),xr-spatial-tracking=()',
      ),
      'pragma' => 
      array (
        0 => 'no-cache',
      ),
      'referrer-policy' => 
      array (
        0 => 'no-referrer',
      ),
      'request-id' => 
      array (
        0 => 'b3e38702-d804-4f30-a163-3b6feca5c4d0',
      ),
      'strict-transport-security' => 
      array (
        0 => 'max-age=31536000; includeSubDomains; preload',
      ),
      'x-content-type-options' => 
      array (
        0 => 'nosniff',
      ),
      'x-frame-options' => 
      array (
        0 => 'deny',
      ),
      'x-permitted-cross-domain-policies' => 
      array (
        0 => 'none',
      ),
      'x-robots-tag' => 
      array (
        0 => 'noindex, nofollow',
      ),
      'CF-Cache-Status' => 
      array (
        0 => 'DYNAMIC',
      ),
      'Server' => 
      array (
        0 => 'cloudflare',
      ),
      'CF-RAY' => 
      array (
        0 => '881b5ce58bf2a66f-MIA',
      ),
    ),
     'headerNames' => 
    array (
      'date' => 'Date',
      'content-type' => 'Content-Type',
      'content-length' => 'Content-Length',
      'connection' => 'Connection',
      'cache-control' => 'Cache-Control',
      'content-security-policy' => 'content-security-policy',
      'cross-origin-embedder-policy' => 'cross-origin-embedder-policy',
      'cross-origin-opener-policy' => 'cross-origin-opener-policy',
      'cross-origin-resource-policy' => 'cross-origin-resource-policy',
      'permissions-policy' => 'permissions-policy',
      'pragma' => 'pragma',
      'referrer-policy' => 'referrer-policy',
      'request-id' => 'request-id',
      'strict-transport-security' => 'strict-transport-security',
      'x-content-type-options' => 'x-content-type-options',
      'x-frame-options' => 'x-frame-options',
      'x-permitted-cross-domain-policies' => 'x-permitted-cross-domain-policies',
      'x-robots-tag' => 'x-robots-tag',
      'cf-cache-status' => 'CF-Cache-Status',
      'server' => 'Server',
      'cf-ray' => 'CF-RAY',
    ),
     'protocol' => '1.1',
     'stream' => 
    \GuzzleHttp\Psr7\Stream::__set_state(array(
       'stream' => NULL,
       'size' => NULL,
       'seekable' => true,
       'readable' => true,
       'writable' => true,
       'uri' => 'php://temp',
       'customMetadata' => 
      array (
      ),
    )),
  )),
   'decoded' => 
  array (
    'error' => 
    array (
      'type' => 'request_error',
      'code' => 'bad_request',
      'detail' => 'Invalid request',
      'documentation_url' => 'https://developer.paddle.com/v1/errors/shared/bad_request',
      'errors' => 
      array (
        0 => 
        array (
          'field' => '',
          'message' => 'invalid input',
        ),
      ),
    ),
    'meta' => 
    array (
      'request_id' => 'b3e38702-d804-4f30-a163-3b6feca5c4d0',
    ),
  ),
   'cookies' => 
  \GuzzleHttp\Cookie\CookieJar::__set_state(array(
     'cookies' => 
    array (
    ),
     'strictMode' => false,
  )),
   'transferStats' => 
  \GuzzleHttp\TransferStats::__set_state(array(
     'request' => 
    \GuzzleHttp\Psr7\Request::__set_state(array(
       'method' => 'POST',
       'requestTarget' => NULL,
       'uri' => 
      \GuzzleHttp\Psr7\Uri::__set_state(array(
         'scheme' => 'https',
         'userInfo' => '',
         'host' => 'sandbox-api.paddle.com',
         'port' => NULL,
         'path' => '/subscriptions/sub_01hxhnxneeggtwvqthyrv6s2c9/activate',
         'query' => '',
         'fragment' => '',
         'composedComponents' => 'https://sandbox-api.paddle.com/subscriptions/sub_01hxhnxneeggtwvqthyrv6s2c9/activate',
      )),
       'headers' => 
      array (
        'Content-Length' => 
        array (
          0 => '2',
        ),
        'Content-Type' => 
        array (
          0 => 'application/json',
        ),
        'Host' => 
        array (
          0 => 'sandbox-api.paddle.com',
        ),
        'Authorization' => 
        array (
          0 => 'Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
        ),
        'User-Agent' => 
        array (
          0 => 'Laravel\\Paddle/2.4.2',
        ),
        'Paddle-Version' => 
        array (
          0 => '1',
        ),
      ),
       'headerNames' => 
      array (
        'content-length' => 'Content-Length',
        'content-type' => 'Content-Type',
        'host' => 'Host',
        'authorization' => 'Authorization',
        'user-agent' => 'User-Agent',
        'paddle-version' => 'Paddle-Version',
      ),
       'protocol' => '1.1',
       'stream' => 
      \GuzzleHttp\Psr7\Stream::__set_state(array(
         'stream' => NULL,
         'size' => 2,
         'seekable' => true,
         'readable' => true,
         'writable' => true,
         'uri' => 'php://temp',
         'customMetadata' => 
        array (
        ),
      )),
    )),
     'response' => 
    \GuzzleHttp\Psr7\Response::__set_state(array(
       'reasonPhrase' => 'Bad Request',
       'statusCode' => 400,
       'headers' => 
      array (
        'Date' => 
        array (
          0 => 'Fri, 10 May 2024 16:39:00 GMT',
        ),
        'Content-Type' => 
        array (
          0 => 'application/json',
        ),
        'Content-Length' => 
        array (
          0 => '273',
        ),
        'Connection' => 
        array (
          0 => 'keep-alive',
        ),
        'Cache-Control' => 
        array (
          0 => 'no-store, max-age=0',
        ),
        'content-security-policy' => 
        array (
          0 => 'default-src \'none\'; frame-ancestors \'none\'; base-uri \'none\'',
        ),
        'cross-origin-embedder-policy' => 
        array (
          0 => 'require-corp',
        ),
        'cross-origin-opener-policy' => 
        array (
          0 => 'same-origin',
        ),
        'cross-origin-resource-policy' => 
        array (
          0 => 'same-site',
        ),
        'permissions-policy' => 
        array (
          0 => 'accelerometer=(),ambient-light-sensor=(),autoplay=(),battery=(),camera=(),display-capture=(),document-domain=(),encrypted-media=(),fullscreen=(),gamepad=(),geolocation=(),gyroscope=(),layout-animations=(self),legacy-image-formats=(self),magnetometer=(),microphone=(),midi=(),oversized-images=(self),payment=(),picture-in-picture=(),publickey-credentials-get=(),screen-wake-lock=(),speaker-selection=(),sync-xhr=(self),unoptimized-images=(self),unsized-media=(self),usb=(),web-share=(),xr-spatial-tracking=()',
        ),
        'pragma' => 
        array (
          0 => 'no-cache',
        ),
        'referrer-policy' => 
        array (
          0 => 'no-referrer',
        ),
        'request-id' => 
        array (
          0 => 'b3e38702-d804-4f30-a163-3b6feca5c4d0',
        ),
        'strict-transport-security' => 
        array (
          0 => 'max-age=31536000; includeSubDomains; preload',
        ),
        'x-content-type-options' => 
        array (
          0 => 'nosniff',
        ),
        'x-frame-options' => 
        array (
          0 => 'deny',
        ),
        'x-permitted-cross-domain-policies' => 
        array (
          0 => 'none',
        ),
        'x-robots-tag' => 
        array (
          0 => 'noindex, nofollow',
        ),
        'CF-Cache-Status' => 
        array (
          0 => 'DYNAMIC',
        ),
        'Server' => 
        array (
          0 => 'cloudflare',
        ),
        'CF-RAY' => 
        array (
          0 => '881b5ce58bf2a66f-MIA',
        ),
      ),
       'headerNames' => 
      array (
        'date' => 'Date',
        'content-type' => 'Content-Type',
        'content-length' => 'Content-Length',
        'connection' => 'Connection',
        'cache-control' => 'Cache-Control',
        'content-security-policy' => 'content-security-policy',
        'cross-origin-embedder-policy' => 'cross-origin-embedder-policy',
        'cross-origin-opener-policy' => 'cross-origin-opener-policy',
        'cross-origin-resource-policy' => 'cross-origin-resource-policy',
        'permissions-policy' => 'permissions-policy',
        'pragma' => 'pragma',
        'referrer-policy' => 'referrer-policy',
        'request-id' => 'request-id',
        'strict-transport-security' => 'strict-transport-security',
        'x-content-type-options' => 'x-content-type-options',
        'x-frame-options' => 'x-frame-options',
        'x-permitted-cross-domain-policies' => 'x-permitted-cross-domain-policies',
        'x-robots-tag' => 'x-robots-tag',
        'cf-cache-status' => 'CF-Cache-Status',
        'server' => 'Server',
        'cf-ray' => 'CF-RAY',
      ),
       'protocol' => '1.1',
       'stream' => 
      \GuzzleHttp\Psr7\Stream::__set_state(array(
         'stream' => NULL,
         'size' => NULL,
         'seekable' => true,
         'readable' => true,
         'writable' => true,
         'uri' => 'php://temp',
         'customMetadata' => 
        array (
        ),
      )),
    )),
     'transferTime' => 0.187911,
     'handlerStats' => 
    array (
      'url' => 'https://sandbox-api.paddle.com/subscriptions/sub_01hxhnxneeggtwvqthyrv6s2c9/activate',
      'content_type' => 'application/json',
      'http_code' => 400,
      'header_size' => 1296,
      'request_size' => 282,
      'filetime' => -1,
      'ssl_verify_result' => 0,
      'redirect_count' => 0,
      'total_time' => 0.187911,
      'namelookup_time' => 0.001599,
      'connect_time' => 0.026742,
      'pretransfer_time' => 0.06666,
      'size_upload' => 2.0,
      'size_download' => 273.0,
      'speed_download' => 1459.0,
      'speed_upload' => 10.0,
      'download_content_length' => 273.0,
      'upload_content_length' => 2.0,
      'starttransfer_time' => 0.187571,
      'redirect_time' => 0.0,
      'redirect_url' => '',
      'primary_ip' => '2606:4700:3108::ac42:2bc4',
      'certinfo' => 
      array (
      ),
      'primary_port' => 443,
      'local_ip' => '2600:1700:63d3:d860:c2c:44ff:feca:4d5e',
      'local_port' => 35938,
      'http_version' => 2,
      'protocol' => 2,
      'ssl_verifyresult' => 0,
      'scheme' => 'HTTPS',
      'appconnect_time_us' => 66585,
      'connect_time_us' => 26742,
      'namelookup_time_us' => 1599,
      'pretransfer_time_us' => 66660,
      'redirect_time_us' => 0,
      'starttransfer_time_us' => 187571,
      'total_time_us' => 187911,
      'effective_method' => 'POST',
      'appconnect_time' => 0.066585,
    ),
     'handlerErrorData' => 0,
  )),
))

livan2r avatar May 10 '24 16:05 livan2r

@livan2r I would take up contact with Paddle because this would clearly indicate something wrong on their end if it's not a JSON response.

driesvints avatar May 13 '24 14:05 driesvints

@livan2r I'm contacting Paddle about this directly and working with them on this. They mentioned your API key is exposed above so you will want to rotate it.

driesvints avatar May 13 '24 15:05 driesvints

Sure, no problem @driesvints. It's just my sandbox key but I will rotate it. Thanks for the heads up and the quick issue follow-up.

livan2r avatar May 13 '24 15:05 livan2r

@livan2r I think I managed to fix it with https://github.com/laravel/cashier-paddle/pull/260. Could you perhaps try out that change to see if things work for you again?

driesvints avatar May 17 '24 14:05 driesvints

Hi, @driesvints unfortunately with this fix still it's not working for me, is it working for you? It works to me by passing null instead of {} on line 128, I don't know whether there is a reason not to pass null.

livan2r avatar May 19 '24 01:05 livan2r

@livan2r pushed a new commit based on your feedback. Can you try again?

driesvints avatar May 21 '24 08:05 driesvints

Oh Yeah! That one is working for me too. Thanks.

livan2r avatar May 22 '24 12:05 livan2r

Cool. Thanks!

driesvints avatar May 22 '24 13:05 driesvints