Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Braintree Bundle Laravel Package

shwrm/braintree-bundle

This package provides a Braintree integration for PHP applications, making it easier to configure credentials and access Braintree payment services. Use it to streamline payment processing setup and reduce boilerplate when working with Braintree.

View on GitHub
Deep Wiki
Context7

Getting Started

First, confirm what you are actually installing. shwrm/braintree-bundle is a Symfony 2 bundle (CometCult\BraintreeBundle\...), not a Laravel package. It ships no ServiceProvider, no facade, no config/braintree.php, and no auto-discovery. Dropping it into a Laravel app gives you a bundle class that Laravel's container never sees, and none of its Symfony DI wiring will execute. If your stack is Laravel (5.x through 12.x), stop here and treat this repo as a reading reference.

Where to look first in the repo:

  1. composer.json — read the require block before anything else. The pinned braintree/braintree_php constraint and symfony/* constraints tell you immediately whether Composer will even resolve on a modern app. If you see symfony/symfony ~2.x or PHP ^5.3|^7.0, that is your hard stop.
  2. The bundle's DI extension class (DependencyInjection/*Extension.php) and Resources/config/services.yml. This is the entire functional payload — a config array and one or two service definitions wrapping the Braintree gateway.
  3. The bundle registration class (CometCultBraintreeBundle). It is only meaningful inside AppKernel::registerBundles().
  4. Any README examples for credential config shape — useful as a checklist even if you rebuild them.

The path you should actually take for Laravel:

composer require braintree/braintree_php

The wrapper's whole value proposition — "centralized config and service wiring" — is ~20 lines of Laravel code. Going direct costs you nothing and buys you a maintained dependency instead of a stale one.

First use case (Laravel, direct SDK): bind the gateway as a singleton in a service provider, pull merchant ID / public / private key / environment from config/services.php (env-backed), and produce a client token for the frontend to initialize Braintree Drop-in or Hosted Fields. That single flow — client token → Drop-in UI → charge → refund — is the 2-day sandbox spike worth timeboxing before any broader commitment.

First use case (genuine legacy Symfony 2.8 app): read the bundle's config shape, register it in AppKernel, and use it only as documentation while planning your migration off Symfony 2.

Implementation Patterns

Pattern 1 — Direct SDK behind a service provider (recommended). Reproduce exactly what the bundle does, idiomatically:

// config/services.php
'braintree' => [
    'environment'   => env('BRAINTREE_ENVIRONMENT', 'sandbox'),
    'merchant_id'   => env('BRAINTREE_MERCHANT_ID'),
    'public_key'    => env('BRAINTREE_PUBLIC_KEY'),
    'private_key'   => env('BRAINTREE_PRIVATE_KEY'),
],

// app/Providers/BraintreeServiceProvider.php
public function register(): void
{
    $this->app->singleton(\Braintree\Gateway::class, fn ($app) => new \Braintree\Gateway([
        'environment' => config('services.braintree.environment'),
        'merchantId'  => config('services.braintree.merchant_id'),
        'publicKey'   => config('services.braintree.public_key'),
        'privateKey'  => config('services.braintree.private_key'),
    ]));
}

Add BraintreeServiceProvider::class to config/app.php providers (or rely on auto-discovery if you package it internally).

Pattern 2 — Wrap the vendor in a domain interface. The single most valuable pattern, and the one the bundle does not provide. Define a PaymentGateway interface (charge, vault, refund, clientToken, verifyWebhook) with a BraintreeGateway adapter that implements it. Controllers and jobs only depend on the interface. When you swap providers or upgrade the SDK's surface, only the adapter changes.

Pattern 3 — Client token → Drop-in UI → charge. Server issues a client token; the browser initializes Braintree's Drop-in; the payment method nonce comes back to your charge endpoint. Do not hand-roll card forms — Drop-in / Hosted Fields is what keeps your PCI scope at SAQ A/A-EP.

Pattern 4 — Signature-verified webhooks with idempotency. A controller that calls Webhook::parse() first (before any state change), plus a table keyed on Braintree's notification ID so replays are no-ops. This is table stakes and the bundle does not help you with it.

Pattern 5 — Idempotent charges and retries. Wrap charge calls in retry-with-backoff on transient network errors, and key on your own idempotency token so retries cannot double-charge. Do this in the adapter, not scattered through controllers.

Pattern 6 — Queue webhook handling. Accept the webhook synchronously (respond 200 fast), push processing to a queue, use a circuit breaker on upstream gateway timeouts.

If you're actually on Symfony 2.8: the bundle's idiom is config under comet_cult_braintree.* and an injected DI service for the Braintree\Gateway. Register via AppKernel::registerBundles(), inject the service into controllers/commands, and treat it as legacy code you maintain until migration.

Gotchas and Tips

  • It is not a Laravel package. No service provider, no facade, no auto-discovery. Any "make Symfony 2's container cooperate with Laravel's" shim costs more than writing the provider (~20 lines) and leaves dead Symfony 2 abstractions in the codebase. Do not pursue it.

  • Composer will block you up front. This bundle's era means Symfony 2 and PHP 5.x/7.0 constraints. Before any spike run composer why-not shwrm/braintree-bundle (or composer require --dry-run) on your target Laravel/PHP. It will almost certainly hard-conflict with Laravel 10/11/12 and PHP 8.2+. Know this before you schedule work.

  • Silent SDK drift is the nastiest failure. A pinned, stale braintree/braintree_php against a live API surface fails intermittently — auth errors, token-generation breakage, 3DS2 flow regressions — not with clean exceptions. Verify against the SDK's own changelog and Braintree's docs, never against bundle behavior.

  • Webhook signature verification is the highest-severity omission. A wrapper that documents credential config but not Webhook::parse() invites forged payment-state transitions. Never trust the payload before verification; always dedupe on notification ID.

  • SCA/3DS2 is not a "maybe later." EU/UK Strong Customer Authentication and 3DS2 have been mandatory since 2021. Confirm SCA handling and Drop-in UI compatibility against the vendor SDK, not the bundle's docs — a Symfony 2-era wrapper predates those flows.

  • Credential handling. Config shape in the bundle makes it tempting to put keys into committed YAML/PHP. Use env vars and a secrets store; never let BRAINTREE_PRIVATE_KEY into source.

  • Supply-chain reality. Zero stars, zero dependents, single maintainer. No community means no implicit test coverage, nobody to file issues to, bus factor of one on your revenue path. Forking means owning it permanently — for functionality the vendor SDK already provides.

  • Compliance evidence. Running an EOL framework and EOL SDK in a cardholder-data-adjacent path complicates PCI DSS evidence and SAQ responses. Document the choice; expect auditors to ask.

  • Escalation path is Braintree, not the bundle. Internal runbooks must be written against braintree/braintree_php and vendor support. That's another argument for skipping the wrapper entirely — your runbooks are useful either way, but SDK-based ones survive migration.

  • Ramp-up cost is best modeled as "read the Braintree PHP quickstart" (hours), not "onboard onto this bundle." Engineers would otherwise learn a dead Symfony 2 idiom that does not exist elsewhere in your estate. The SDK knowledge is durable across framework upgrades; the bundle knowledge is not.

  • Documented rejection is a valid deliverable. If this came in as a request, reject at intake with "Symfony 2 bundle vs. Laravel stack" as the stated reason and redirect to the direct-SDK adapter workstream. Estimated adapter effort: 2–4 engineer-days versus an open-ended, likely-failing adaptation effort. That delta is the recommendation.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package