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.
Enable the Bundle
Add to config/bundles.php:
return [
// ...
C975L\PaymentBundle\PaymentBundle::class => ['all' => true],
];
Configure Stripe
Add Stripe credentials to .env:
STRIPE_SECRET_KEY=your_secret_key
STRIPE_PUBLISHABLE_KEY=your_publishable_key
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(),
]);
// ...
}
Render the Form
In your template (payment.html.twig):
{{ form_start(form) }}
{{ form_widget(form) }}
<button type="submit">Pay Now</button>
{{ form_end(form) }}
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
}
}
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'),
]);
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,
]);
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
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
}
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
}
}
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'
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
Stripe Keys
STRIPE_SECRET_KEY and STRIPE_PUBLISHABLE_KEY in .env will cause silent failures.stripe\Stripe::setApiKey() in a service constructor.SSL Requirement
https:// in production and configure your dev environment with a local SSL certificate (e.g., using Laravel Valet or mkcert).Webhook Verification
stripe-signature header is missing or invalid.file_put_contents('stripe_webhook.log', print_r([
'payload' => $payload,
'signature' => $sigHeader,
], true), FILE_APPEND);
Database Migrations
payment_transactions table, but custom fields may require manual migrations.php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
Email Bundle Dependency
c975LEmailBundle, which may not be installed or configured.composer require c975L/email-bundle
Update config/packages/c975l_email.yaml with your email settings.Flash Messages
bundles.php and the session component is configured in config/packages/framework.yaml.Currency and Amount Validation
10.00 instead of 1000) will cause failures.$amount = $form->get('amount')->getData() * 100; // Convert to cents
Stripe API Errors
.env:
STRIPE_DEBUG=true
Form Validation
if ($form->isSubmitted() && !$form->isValid()) {
dump($form->getErrors(true)); // Show all errors
}
Database Queries
$this->get('doctrine')->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger());
Webhook Testing
ngrok to expose your webhook endpoint:
ngrok http 8000
Configure the webHow can I help you explore Laravel packages today?