Paddle with Passport giving: Authentication header included, but incorrectly formatted
jeanlinux opened this issue · comments
Cashier Paddle Version
2.4
Laravel Version
11.0.1
PHP Version
8.1
Database Driver & Version
No response
Description
I am trying to setup cashier-paddle on laravel for my API service with passport for authentication, I have an endpoint /subscriptions that is supposed to return all subscriptions for the currently logged in user or guest if not logged in. but to I was getting curl ssl certificate error when I connect from localhost so I updated src/Cashier.php line 124
/** @var \Illuminate\Http\Client\Response $response */
$response = Http::withToken($apiKey)
->withUserAgent('Laravel\Paddle/' . static::VERSION)
->withHeaders(['Paddle-Version' => 1])
->$method("{$host}/{$uri}", $payload);
to
/** @var \Illuminate\Http\Client\Response $response */
$response = Http::withToken($apiKey)
->withUserAgent('Laravel\Paddle/' . static::VERSION)
->withOptions(["verify" => false])
->withHeaders(['Paddle-Version' => 1])
->$method("{$host}/{$uri}", $payload);
When I make the request without bearer token (as guest) I get all the subscription plans for guests.
But now I am getting another error when I make a get request with Bearer Authentication header.
Paddle API error 'Authentication header included, but incorrectly formatted' occurred
Here is my subscriptions controller.
<?php
namespace App\Http\Controllers;
use App\Models\Plan;
use Exception;
use Illuminate\Http\JsonResponse;
use Log;
use PDOException;
class SubscriptionsController extends Controller
{
public function __construct()
{
}
public function index(): JsonResponse
{
try {
/**
* This part assumes that the current billable instance is the authorised user.
*/
if (!is_null(auth('api')->user())) {
$billable = auth('api')->user();
// Our list of available plans, note the name could be anything here for the plan model.
$plans = Plan::whereIsAvailable(true)
->get(['id', 'paddle_id', 'title', 'name', 'is_available']);
Log::info('Plans are : ' . count($plans));
$subscriptions = $plans->map(function ($plan) use ($billable) {
if ($currentSubscription = $billable->subscribed($plan->name)) {
/** For this example you can just giving them the option to cancel the plan*/
$payLink = $billable->subscription($plan->name)->cancelUrl();
} else {
$payLink = $billable->checkout($plan->name)
->returnTo('https://pb2f0ybgfb.sharedwithexpose.com/dashboard');
}
return [
'title' => $plan->title,
'name' => $plan->name,
'payLink' => $payLink,
'current' => $currentSubscription,
];
});
} else {
// Our list of available plans, note the name could be anything here for the plan model.
$plans = Plan::whereIsAvailable(true)
->get(['id', 'paddle_id', 'title', 'name', 'is_available']);
Log::info('guest Plans are : ' . count($plans));
$subscriptions = $plans->map(function ($plan) {
return [
'title' => $plan->title,
'name' => $plan->name,
];
});
}
return new JsonResponse([
'data' => $subscriptions,
], 200);
} catch (PDOException $e) {
Log::error($e->getMessage());
return new JsonResponse(['error' => 'failed to list subscriptions'], 400);
} catch (\Laravel\Paddle\Exceptions\PaddleException $e) {
Log::error($e->getMessage());
return new JsonResponse(['error' => 'could not list subscriptions'], 400);
} catch (Exception $e) {
Log::error($e->getMessage());
return new JsonResponse(['error' => 'could not list subscriptions'], 400);
}
}
public function billing(): JsonResponse
{
return new JsonResponse(['status' => 'billing goes here'], 200);
}
public function update_payment_method(): JsonResponse
{
$user = auth('api')->user();
return new JsonResponse($user->subscription()->redirectToUpdatePaymentMethod());
}
}
Here is my Plan model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Concerns\HasUuids;
class Plan extends Model
{
use SoftDeletes, HasUuids;
protected $fillable = [
'paddle_id',
'name',
'title',
'is_available',
];
protected $visible = [
'id',
'paddle_id',
'name',
'title',
'is_available',
];
public function users()
{
return $this->HasMany(User::class);
}
}
Steps To Reproduce
- Create plans on Paddle sandbox
- Seed database with your plans
- Install passport and configure
- Update laravel/cashier-paddle/src/Cashier.php to allow accessing paddle from localhost
- access subscription url without passport bearer token (You should see your subscriptions list)
- Now pass bearer token to the same route and see the result
Hi there,
Thanks for reporting but it looks like this is a question which can be asked on a support channel. Please only use this issue tracker for reporting bugs with the library itself. If you have a question on how to use functionality provided by this repo you can try one of the following channels:
However, this issue will not be locked and everyone is still free to discuss solutions to your problem!
Thanks.
Any suggestions, I am still struggling to get cashier-paddle and passport authentication to work, I need to get this behind me, I dont know why authorization header is being affected when I post authentication token to a route that will be calling cashier-paddle API.
The error "Authentication header included, but incorrectly formatted" may occur if you try php sdk with application SDK API key: https://vendors.paddle.com/sdk
Instead, you need to use authorization key: https://vendors.paddle.com/authentication