Weave Code
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

Coinbase Bundle Laravel Package

borsaco/coinbase-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require borsaco/coinbase-bundle
    

    Ensure Borsaco\CoinbaseBundle\CoinbaseBundle is enabled in config/bundles.php.

  2. Configuration: Create config/packages/coinbase.yaml with your API credentials:

    coinbase_commerce:
      api:
        key: "%env(COINBASE_API_KEY)%"
        version: "2018-03-22"
      webhook:
        secret: "%env(COINBASE_WEBHOOK_SECRET)%"
    

    Store secrets in .env (never commit .env to version control).

  3. First Use Case: Inject CoinbaseHandler into a controller to create a charge:

    use Borsaco\CoinbaseBundle\Handler\CoinbaseHandler;
    
    #[Route('/charge', name: 'create_charge')]
    public function createCharge(CoinbaseHandler $handler): JsonResponse
    {
        $charge = $handler->createCharge([
            'name' => 'Product Purchase',
            'description' => 'Payment for product XYZ',
            'local_price' => ['amount' => 10.99, 'currency' => 'USD'],
            'metadata' => ['user_id' => 123],
        ]);
        return $this->json($charge);
    }
    

Implementation Patterns

Common Workflows

  1. Charge Creation: Use CoinbaseHandler::createCharge() with an array or Charge object. Always include:

    • name (string)
    • description (string)
    • local_price (array with amount and currency)
    • Optional: metadata (for tracking), pricing_type (fixed or dynamic).

    Example with dynamic pricing:

    $charge = $handler->createCharge([
        'name' => 'Subscription',
        'description' => 'Monthly plan',
        'pricing_type' => 'dynamic',
        'pricing_data' => [
            'price_per_unit' => ['amount' => 9.99, 'currency' => 'USD'],
            'unit' => 'month',
        ],
    ]);
    
  2. Webhook Handling: Validate and process Coinbase webhooks in a dedicated controller:

    #[Route('/webhook', name: 'coinbase_webhook', methods: ['POST'])]
    public function handleWebhook(Request $request, CoinbaseHandler $handler): Response
    {
        $payload = json_decode($request->getContent(), true);
        $secret = $request->headers->get('X-CC-Webhook-Signature');
        if ($handler->validateWebhook($payload, $secret)) {
            // Process event (e.g., charge:confirmed)
            $this->processEvent($payload['type'], $payload['data']);
        }
        return new Response('OK', 200);
    }
    
  3. Retrieving Charges: Fetch charges by ID or filter by metadata:

    // Get a single charge
    $charge = $handler->getCharge('charge_id_here');
    
    // List charges with metadata filter
    $charges = $handler->listCharges(['metadata.user_id' => 123]);
    
  4. Refunds: Refund a charge partially or fully:

    $refund = $handler->createRefund('charge_id_here', [
        'amount' => 5.00, // Partial refund
        'reason' => 'Customer requested partial refund',
    ]);
    

Integration Tips

  • Symfony Forms: Bind Coinbase charges to forms for user-friendly input:
    $builder->add('charge_name', TextType::class);
    $builder->add('charge_description', TextareaType::class);
    $builder->add('charge_amount', MoneyType::class, [
        'currency' => 'USD',
        'scale' => 2,
    ]);
    
  • Event Listeners: Subscribe to Coinbase events (e.g., charge:confirmed) using Symfony’s event dispatcher.
  • Testing: Mock CoinbaseHandler in tests:
    $handler = $this->createMock(CoinbaseHandler::class);
    $handler->method('createCharge')->willReturn(['id' => 'test_charge']);
    

Gotchas and Tips

Pitfalls

  1. API Key Exposure:

    • Never hardcode API keys in coinbase.yaml. Use %env() or Symfony’s parameter bag.
    • Restrict the Coinbase API key to only the required permissions (e.g., Commerce.Charges:Read, Commerce.Charges:Create).
  2. Webhook Validation:

    • Always validate webhook signatures using CoinbaseHandler::validateWebhook(). Skipping this risks processing fake events.
    • Coinbase sends webhooks asynchronously. Design your system to handle retries for failed processing.
  3. Idempotency:

    • Use the idempotency_key parameter in createCharge() to avoid duplicate charges if the same request is retried.
    • Example:
      $charge = $handler->createCharge($data, 'unique_key_123');
      
  4. Currency and Amount Precision:

    • Coinbase requires amounts to be sent as strings or numbers with exactly 2 decimal places (e.g., 10.99, not 10 or 10.990).
    • Use number_format() or Symfony’s Money component to ensure consistency.
  5. Rate Limits:

    • Coinbase enforces rate limits (e.g., 100 requests/minute). Cache responses for frequently accessed data (e.g., charge lists).
    • Implement exponential backoff for retries.
  6. Deprecated API Version:

    • The bundle defaults to 2018-03-22, which may not support all latest features. Check Coinbase’s API docs for updates.

Debugging

  • Enable Debug Mode: Set COINBASE_DEBUG=true in .env to log raw API responses. The bundle will output requests/responses to var/log/dev.log.

  • Common Errors:

    Error Solution
    Invalid API key Verify coinbase.yaml and ensure the key has Commerce permissions.
    Webhook signature mismatch Regenerate the webhook secret in Coinbase Dashboard and update config.
    Amount must be positive Ensure local_price.amount is > 0.
    Charge not found Double-check the charge ID and ensure it exists in Coinbase Dashboard.

Extension Points

  1. Custom Charge Objects: Extend Borsaco\CoinbaseBundle\Model\Charge to add domain-specific fields:

    class CustomCharge extends Charge
    {
        private $userId;
    
        public function setUserId(int $userId): self
        {
            $this->userId = $userId;
            $this->setMetadata(['user_id' => $userId]);
            return $this;
        }
    }
    

    Then pass the object to createCharge().

  2. Event Dispatcher: Integrate with Symfony’s event system to trigger custom logic on Coinbase events:

    // In services.yaml
    Borsaco\CoinbaseBundle\EventListener\CoinbaseWebhookListener:
        tags:
            - { name: kernel.event_listener, event: coinbase.webhook, method: onWebhook }
    
  3. Async Processing: Use Symfony Messenger to process webhooks asynchronously:

    $message = new CoinbaseWebhookMessage($payload);
    $this->messageBus->dispatch($message);
    
  4. Testing Helper: Create a test double for CoinbaseHandler to simulate API responses:

    class CoinbaseHandlerStub extends CoinbaseHandler
    {
        public function __construct()
        {
            $this->client = $this->createMock(\GuzzleHttp\Client::class);
        }
    
        public function createCharge(array $data, ?string $idempotencyKey = null)
        {
            return ['id' => 'test_charge_' . uniqid()];
        }
    }
    
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui