paypal/paypal-checkout-sdk
Deprecated PayPal PHP SDK for REST APIs v2 (Checkout Orders and Payments). Provides model objects and HTTP call blueprints for server-side integrations. PHP 5.6+ and TLS 1.2 required. PayPal recommends migrating to the new Server SDK.
Installation:
composer require paypal/paypal-checkout-sdk
Ensure your composer.json includes "paypal/paypal-checkout-sdk": "^1.0" (or latest compatible version).
Environment Configuration:
Client ID and Client Secret.use PayPalCheckoutSdk\Core\SandboxEnvironment; // or LiveEnvironment
$environment = new SandboxEnvironment('YOUR_CLIENT_ID', 'YOUR_CLIENT_SECRET');
$client = new PayPalHttpClient($environment);
First Use Case: Create an Order
use PayPalCheckoutSdk\Orders\OrdersCreateRequest;
$request = new OrdersCreateRequest();
$request->body = [
"intent" => "CAPTURE",
"purchase_units" => [[
"amount" => ["currency_code" => "USD", "value" => "10.00"]
]],
"application_context" => [
"return_url" => route('paypal.return'),
"cancel_url" => route('paypal.cancel')
]
];
$response = $client->execute($request);
$orderId = $response->result->id;
Order Creation & Capture
OrdersCreateRequest to generate a PayPal approval link.OrdersCaptureRequest($orderId).OrdersRefundRequest for partial/full refunds.Webhook Handling
PAYMENT.CAPTURE.COMPLETED).PayPalHttpClient:
use PayPalCheckoutSdk\Webhooks\Events\CheckoutEvent;
use PayPalCheckoutSdk\Webhooks\VerifyWebhookSignature;
$signature = VerifyWebhookSignature::verify(
$webhookBody,
$webhookHeader['PAYPAL-WEBHOOK-SIGNATURE'],
$webhookHeader['PAYPAL-WEBHOOK-ID'],
$clientId
);
Error Handling
HttpException for API errors:
try {
$response = $client->execute($request);
} catch (HttpException $ex) {
Log::error("PayPal Error: " . $ex->getMessage(), ['status' => $ex->statusCode]);
return redirect()->route('payment.failed');
}
Laravel Service Provider: Bind the client to the container for dependency injection:
$this->app->singleton(PayPalHttpClient::class, function ($app) {
return new PayPalHttpClient(new LiveEnvironment(
config('services.paypal.client_id'),
config('services.paypal.secret')
));
});
Request Validation:
Use Laravel’s FormRequest to validate order data before SDK calls:
public function rules() {
return [
'price' => 'required|numeric|min:0.01',
'currency' => 'required|in:USD,EUR,GBP',
];
}
Testing:
Use the Sandbox environment for unit/integration tests. Mock PayPalHttpClient:
$mockClient = Mockery::mock(PayPalHttpClient::class);
$mockClient->shouldReceive('execute')
->andReturn(new OrdersCreateResponse(new OrdersData()));
Deprecation Warning:
PayPalHttpClient with Environment (Sandbox/Live), while this SDK uses PayPalHttpClient with SandboxEnvironment.TLS 1.2 Requirement:
; php.ini
openssl.cafile=/path/to/cacert.pem
Order Lifecycle:
OrdersCaptureRequest. Uncaptured orders expire after 3 days.Webhook Verification:
VerifyWebhookSignature to prevent replay attacks.Enable Logging: Configure the HTTP client to log requests/responses:
$client = new PayPalHttpClient($environment, [
'logger' => new PayPalHttpLogger(
new FileHandler('/path/to/paypal.log'),
PayPalHttpLogger::DEBUG
)
]);
Common Errors:
intent, currency_code).Client ID/Secret and environment (Sandbox/Live).Custom Headers: Add headers to requests:
$request->headers = ["X-Custom-Header" => "value"];
Retry Logic: Implement exponential backoff for transient failures:
use PayPalCheckoutSdk\Core\PayPalHttpClient;
use GuzzleHttp\Exception\RequestException;
try {
$response = $client->execute($request);
} catch (RequestException $e) {
if ($e->hasResponse() && $e->getResponse()->getStatusCode() === 429) {
sleep(2); // Retry after 2 seconds
return $client->execute($request);
}
throw $e;
}
Localization:
Support multiple currencies/languages by dynamically setting purchase_units.amount.currency_code and application_context.locale.
Environment Variables:
Avoid hardcoding credentials. Use Laravel’s .env:
PAYPAL_CLIENT_ID=your_id
PAYPAL_SECRET=your_secret
Access via config('services.paypal').
Sandbox vs. Live:
https://api.sandbox.paypal.com.https://api.paypal.com. Always test in Sandbox first.Idempotency:
Use the idempotency-key header to prevent duplicate transactions:
$request->headers = ["Idempotency-Key" => Str::uuid()->toString()];
How can I help you explore Laravel packages today?