braintree/braintree_php
Official Braintree PHP SDK for integrating Braintree payments into PHP apps. Supports transactions, customer and payment method management, subscriptions, webhooks, and more, with configuration for sandbox/production and comprehensive API coverage.
Installation:
composer require braintree/braintree_php
Add the package to your composer.json and run composer install.
Configuration:
Create a .env entry for Braintree credentials:
BRAINTREE_ENVIRONMENT=sandbox # or production
BRAINTREE_MERCHANT_ID=your_merchant_id
BRAINTREE_PUBLIC_KEY=your_public_key
BRAINTREE_PRIVATE_KEY=your_private_key
Publish the config file (if using Laravel):
php artisan vendor:publish --provider="Braintree\Gateway\ServiceProvider"
First Use Case: Initialize the gateway in a service or controller:
use Braintree\Gateway;
$gateway = new Gateway([
'environment' => env('BRAINTREE_ENVIRONMENT'),
'merchantId' => env('BRAINTREE_MERCHANT_ID'),
'publicKey' => env('BRAINTREE_PUBLIC_KEY'),
'privateKey' => env('BRAINTREE_PRIVATE_KEY')
]);
Test with a simple client token generation:
$clientToken = $gateway->clientToken()->generate();
Use this token in your frontend (e.g., Drop-in UI) to collect payment details.
$clientToken = $gateway->clientToken()
->generate(['customerId' => $customerId]);
braintree.setup(clientToken, { id: 'dropin-container' }, responseHandler);
$result = $gateway->transaction()->sale([
'amount' => '10.00',
'paymentMethodNonce' => $request->input('payment_method_nonce'),
'options' => [
'submitForSettlement' => true,
],
]);
$paymentMethod = $gateway->paymentMethod()->create([
'paymentMethodNonce' => $nonceFromForm,
'options' => [
'makeDefault' => true,
],
]);
$transaction = $gateway->transaction()->sale([
'amount' => '20.00',
'paymentMethodToken' => $paymentMethod->token,
]);
$customer = $gateway->customer()->create([
'firstName' => 'John',
'lastName' => 'Doe',
'email' => 'john@example.com',
]);
$gateway->customer()->update($customer->id, [
'paymentMethodToken' => $paymentMethod->token,
]);
$subscription = $gateway->subscription()->create([
'planId' => 'monthly_plan_id',
'customerId' => $customer->id,
]);
$gateway->subscription()->cancel($subscription->id);
use Braintree\WebhookNotification;
$notification = new WebhookNotification($request->getContent());
$kind = $notification->kind;
if ($notification->isValid()) {
switch ($kind) {
case 'subscription_canceled':
// Handle cancellation
break;
case 'subscription_charged_successfully':
// Handle successful charge
break;
}
}
Laravel Service Provider: Bind the gateway to the container for easy dependency injection:
// In AppServiceProvider@boot()
$this->app->singleton(Gateway::class, function () {
return new Gateway([
'environment' => env('BRAINTREE_ENVIRONMENT'),
'merchantId' => env('BRAINTREE_MERCHANT_ID'),
'publicKey' => env('BRAINTREE_PUBLIC_KEY'),
'privateKey' => env('BRAINTREE_PRIVATE_KEY'),
]);
});
Now inject Gateway directly into controllers/services.
Request Validation:
Use Laravel's validation to ensure required fields (e.g., payment_method_nonce) are present:
$request->validate([
'payment_method_nonce' => 'required|string',
]);
Logging: Enable logging for debugging:
$gateway = new Gateway([...], [
'logger' => new Monolog\Logger('braintree'),
]);
Environment Mismatch:
BRAINTREE_ENVIRONMENT matches your dashboard settings (e.g., sandbox vs. production).Nonce Expiry:
Idempotency:
idempotencyKey for critical transactions (e.g., subscriptions) to avoid duplicate charges:
$gateway->transaction()->sale([
'amount' => '10.00',
'paymentMethodNonce' => $nonce,
'options' => [
'idempotencyKey' => Str::uuid()->toString(),
],
]);
Webhook Validation:
if (!$notification->isValid()) {
abort(403, 'Invalid webhook signature');
}
Currency and Amount:
"10.00", not 10.00 or 10).Customer Lookup:
customer->find() to avoid duplicate customers:
$customer = $gateway->customer()->find($customerId);
if (!$customer) {
$customer = $gateway->customer()->create([...]);
}
$gateway = new Gateway([...], [
'logger' => new \Braintree\Logger\FileLogger('/path/to/braintree.log'),
'debug' => true,
]);
Custom Fields: Add metadata to transactions/customers for tracking:
$gateway->transaction()->sale([
'amount' => '10.00',
'paymentMethodNonce' => $nonce,
'options' => [
'submitForSettlement' => true,
],
'customer' => [
'customFields' => [
'order_id' => $order->id,
'user_id' => auth()->id(),
],
],
]);
Advanced Fraud Tools: Enable Kount or 3D Secure via the dashboard and configure in the SDK:
$gateway->transaction()->sale([
'amount' => '10.00',
'paymentMethodNonce' => $nonce,
'options' => [
'threeDSecure' => [
'required' => true,
],
],
]);
Custom Error Handling: Catch specific exceptions for granular control:
try {
$result = $gateway->transaction()->sale([...]);
} catch (\Braintree\Exception\ValidationException $e) {
// Handle validation errors (e.g., invalid nonce)
} catch (\Braintree\Exception\GatewayException $e) {
// Handle gateway errors (e.g., network issues)
}
Plan Management: Dynamically create plans for subscriptions:
$plan = $gateway->subscription()->plan()->create([
'id' => 'custom_plan_' . Str::uuid(),
'name' => '
How can I help you explore Laravel packages today?