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

Payment Bundle Laravel Package

c975l/payment-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle

    composer require c975L/payment-bundle
    

    Ensure you’re using v3.x for Symfony 4.x+ or v2.x for Symfony 3.x.

  2. Enable the Bundle Add to config/bundles.php:

    return [
        // ...
        C975L\PaymentBundle\PaymentBundle::class => ['all' => true],
    ];
    
  3. Configure Stripe Add Stripe credentials to .env:

    STRIPE_SECRET_KEY=your_secret_key
    STRIPE_PUBLISHABLE_KEY=your_publishable_key
    
  4. Basic Form Integration Use the provided form type in a controller:

    use C975L\PaymentBundle\Form\PaymentType;
    
    public function paymentAction(Request $request) {
        $form = $this->createForm(PaymentType::class, null, [
            'amount' => 10.00, // Fixed amount
            'currency' => 'usd',
            'description' => 'Product Purchase',
            'order_id' => 'ORDER-' . uniqid(),
        ]);
        // ...
    }
    
  5. Render the Form In your template (payment.html.twig):

    {{ form_start(form) }}
        {{ form_widget(form) }}
        <button type="submit">Pay Now</button>
    {{ form_end(form) }}
    
  6. Handle the Payment Submit the form to a route (e.g., /payment/process) and process the Stripe response:

    public function processPayment(Request $request) {
        $form = $this->createForm(PaymentType::class, $paymentData);
        $form->handleRequest($request);
    
        if ($form->isSubmitted() && $form->isValid()) {
            $payment = $this->get('c975l_payment.payment_handler')->process($form->getData());
            // Redirect to success page or show flash message
        }
    }
    

Implementation Patterns

Workflow: Standard Payment Flow

  1. Form Creation Use PaymentType for dynamic or fixed amounts:

    $form = $this->createForm(PaymentType::class, null, [
        'amount' => $variableAmount, // Can be dynamic (e.g., from a product)
        'currency' => 'eur',
        'success_url' => $this->generateUrl('payment_success'),
        'cancel_url' => $this->generateUrl('payment_cancel'),
    ]);
    
  2. Dynamic Amounts (Donations/Consultations) Enable the "free amount" option in the form configuration:

    $form = $this->createForm(PaymentType::class, null, [
        'free_amount' => true, // Allows user to input custom amount
        'min_amount' => 5.00,  // Optional: Set a minimum
        'max_amount' => 100.00,
    ]);
    
  3. Predefined Payment Buttons Generate buttons/links for common payments in a template:

    {% for button in buttons %}
        {{ path('payment_button', {
            'amount': button.amount,
            'description': button.description
        })|raw }}
    {% endfor %}
    

    Define routes in routes.yaml:

    payment_button:
        path: /payment/button/{amount}/{description}
        controller: App\Controller\PaymentController::buttonAction
    
  4. Controller for Predefined Buttons

    public function buttonAction($amount, $description) {
        $form = $this->createForm(PaymentType::class, null, [
            'amount' => $amount,
            'description' => $description,
            'order_id' => 'BUTTON-' . uniqid(),
        ]);
        // Render form or redirect to Stripe Checkout
    }
    
  5. Webhook Handling Configure Stripe webhooks to update your database:

    public function handleWebhook(Request $request) {
        $payload = $request->getContent();
        $sigHeader = $request->headers->get('stripe-signature');
        $event = \Stripe\Webhook::constructEvent($payload, $sigHeader, 'your_webhook_secret');
    
        switch ($event->type) {
            case 'payment_intent.succeeded':
                $paymentIntent = $event->data->object;
                $this->get('c975l_payment.payment_handler')->updateTransaction($paymentIntent);
                break;
            // Handle other event types
        }
    }
    
  6. Email Notifications Configure email templates in c975LEmailBundle and enable in config/packages/c975l_payment.yaml:

    c975l_payment:
        email:
            enabled: true
            send_to_user: true
            send_to_site: true
            template_user: 'payment_confirmation'
            template_site: 'payment_receipt'
    
  7. Database Integration The bundle auto-creates a payment_transactions table. Customize the entity if needed by extending:

    use C975L\PaymentBundle\Entity\PaymentTransaction;
    
    class CustomPaymentTransaction extends PaymentTransaction {
        // Add custom fields/methods
    }
    

    Update config/packages/c975l_payment.yaml:

    c975l_payment:
        entity:
            class: App\Entity\CustomPaymentTransaction
    

Gotchas and Tips

Pitfalls

  1. Stripe Keys

    • Gotcha: Forgetting to set STRIPE_SECRET_KEY and STRIPE_PUBLISHABLE_KEY in .env will cause silent failures.
    • Fix: Validate keys in a config validator or use stripe\Stripe::setApiKey() in a service constructor.
  2. SSL Requirement

    • Gotcha: Stripe blocks requests without SSL in production. Local development may work, but production will fail.
    • Fix: Use https:// in production and configure your dev environment with a local SSL certificate (e.g., using Laravel Valet or mkcert).
  3. Webhook Verification

    • Gotcha: Webhook events may fail silently if the stripe-signature header is missing or invalid.
    • Fix: Log webhook payloads and signatures for debugging:
      file_put_contents('stripe_webhook.log', print_r([
          'payload' => $payload,
          'signature' => $sigHeader,
      ], true), FILE_APPEND);
      
  4. Database Migrations

    • Gotcha: The bundle auto-creates the payment_transactions table, but custom fields may require manual migrations.
    • Fix: Extend the entity and run:
      php bin/console doctrine:migrations:diff
      php bin/console doctrine:migrations:migrate
      
  5. Email Bundle Dependency

    • Gotcha: Emails rely on c975LEmailBundle, which may not be installed or configured.
    • Fix: Install the bundle and configure it:
      composer require c975L/email-bundle
      
      Update config/packages/c975l_email.yaml with your email settings.
  6. Flash Messages

    • Gotcha: Flash messages may not appear if the session is not started or the bundle is not properly registered.
    • Fix: Ensure the bundle is enabled in bundles.php and the session component is configured in config/packages/framework.yaml.
  7. Currency and Amount Validation

    • Gotcha: Stripe requires amounts in the smallest currency unit (e.g., cents for USD). Incorrect formatting (e.g., 10.00 instead of 1000) will cause failures.
    • Fix: Validate amounts in the form type or controller:
      $amount = $form->get('amount')->getData() * 100; // Convert to cents
      

Debugging Tips

  1. Stripe API Errors

    • Enable Stripe debug mode in .env:
      STRIPE_DEBUG=true
      
    • Check logs for detailed error messages.
  2. Form Validation

    • Dump form errors in the controller:
      if ($form->isSubmitted() && !$form->isValid()) {
          dump($form->getErrors(true)); // Show all errors
      }
      
  3. Database Queries

    • Use Doctrine debug mode to inspect queries:
      $this->get('doctrine')->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger());
      
  4. Webhook Testing

    • Use Stripe’s webhook test tool to simulate events locally.
    • Test locally with ngrok to expose your webhook endpoint:
      ngrok http 8000
      
      Configure the web
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky