c975l / payment-bundle
Defines form, transactions, database store, etc. for payments using Stripe
Fund package maintenance!
Patreon
Open Collective
buymeacoff.ee/laurentmarquet
Installs: 302
Dependents: 3
Suggesters: 0
Security: 0
Stars: 1
Watchers: 2
Forks: 1
Open Issues: 0
Type:symfony-bundle
Requires
Requires (Dev)
- dev-master
- dev-main
- v5.0.5
- v5.0.4
- v5.0.3
- v5.0.2
- v5.0.1
- v5.0
- 4.x-dev
- v4.0
- 3.x-dev
- v3.5
- v3.4
- v3.3.1
- v3.3
- v3.2.1
- v3.2
- v3.1.1
- v3.1
- v3.0.1
- v3.0
- 2.x-dev
- v2.1.1.2
- v2.1.1.1
- v2.1.1
- v2.1
- v2.0.6
- v2.0.5
- v2.0.4
- v2.0.3
- v2.0.2.1
- v2.0.2
- v2.0.1
- v2.0
- 1.x-dev
- v1.16.2
- v1.16.1
- v1.16
- v1.15.2
- v1.15.1.1
- v1.15.1
- v1.15
- v1.14.1
- v1.14
- v1.13.1.1
- v1.13.1
- v1.13
- v1.12
- v1.11.5
- v1.11.4
- v1.11.3
- v1.11.2
- v1.11.1
- v1.11
- v1.10.1
- v1.10
- v1.9.1
- v1.9
- v1.8.2
- v1.8.1
- v1.8
- v1.7
- v1.6
- v1.5.2
- v1.5.1.1
- v1.5.1
- v1.5
- v1.4.2
- v1.4.1
- v1.4
- v1.3.2
- v1.3.1
- v1.3
- v1.2.1
- v1.2
- v1.1
- v1.0
- dev-dev
This package is auto-updated.
Last update: 2024-11-05 16:00:03 UTC
README
PaymentBundle does the following:
- Defines form to request payment,
- Stores the transaction in a database table with a unique order id,
- Allows the possibility to add buttons/links for pre-defined payment,
- Allows to define a free amount form for payment (Donation, Consultation, etc.),
- Sends an email, to the user, of the transaction via c975LEmailBundle as
c975LEmailBundle
provides the possibility to save emails in a database, there is an option to NOT do so via this Bundle, - Sends an email, to the site, containing same information as above + fee and estimated income,
- Creates flash to inform user,
- Display information about payment after transaction.
This Bundle relies on the use of Stripe and its PHP Library. So you MUST have a Stripe account. It is also recomended to use this with a SSL certificat to reassure the user.
PaymentBundle dedicated web page.
PaymentBundle API documentation.
Bundle installation
Step 1: Download the Bundle
v3.x works with Symfony 4.x. Use v2.x for Symfony 3.x Use Composer to install the library
composer require c975L/payment-bundle
Step 2: Configure the Bundle
Check dependencies for their configuration:
c975LPaymentBundle uses c975L/ConfigBundle to manage configuration parameters. Use the Route "/payment/config" with the proper user role to modify them.
Step 3: Enable the Routes
Then, enable the routes by adding them to the /config/routes.yaml
file of your project:
c975_l_payment: resource: "@c975LPaymentBundle/Controller/" type: annotation prefix: / #Multilingual website use the following #prefix: /{_locale} #defaults: { _locale: '%locale%' } #requirements: # _locale: en|fr|es
Step 4: Create MySql table
You can use php bin/console make:migration
to create the migration file as documented in Symfony's Doctrine docs OR use /Resources/sql/payment.sql
to create the tables stripe_payment
. The DROP TABLE
is commented to avoid dropping by mistake.
Step 5: copy images to web folder
Install images by running
php bin/console assets:install --symlink
It will copy content of folder Resources/public/images/
to your web folder. They are used to be displayed on the payment form.
You can also have a look at official badges from Stripe.
How to use
The process is the following:
- User selects a product,
- User clicks to pay,
- Payment is created in DB,
- User is redirected to Payment form,
- User pays,
- User is redirected to returnRoute,
- Actions are executed to deliver product (if payment successful or sends an error),
- User is redirected to final confirmation or delivery product page.
To achieve this, you have to define 2 Controller Routes and 2 Services methods (+ Interface) (while you can do all of this in Controller, Best Practices recommend to keep Controller methods skinny).
Here are the examples for those files:
//YourProductServiceInterface file namespace App\Service; use c975L\PaymentBundle\Entity\Payment; interface YourProductServiceInterface { public function validate(Payment $payment); }
//Your ProductService file namespace App\Service; use Doctrine\ORM\EntityManagerInterface; use App\Service\YourProductServiceInterface; class YourProductService implements YourProductServiceInterface { private $em; public function __construct(EntityManagerInterface $em) { $this->em = $em; } public function validate(Payment $payment) { /** * For example if `$payment->getAction()` contains the result of "json_encode(array('addCredits' => 10));" */ $action = (array) json_decode($payment->getAction()); if (array_key_exists('addCredits', $action)) { //Gets the user $user = $this->em->getRepository('c975LUserBundle:User') ->findOneById($payment->getUserId()); //Adds credits to user $user->setCredits($user->getCredits() + $action['addCredits']); $this->em->persist($user); //Set payment as finished $payment->setFinished(true); $this->em->persist($payment); $this->em->flush(); return true; } return false; } }
//YourPaymentServiceInterface file namespace App\Service; interface YourPaymentServiceInterface { public function payment($yourNeededData); }
//Your PaymentService file namespace App\Service; use App\Service\YourPaymentServiceInterface; use c975L\PaymentBundle\Service\PaymentServiceInterface; class YourPaymentService implements YourPaymentServiceInterface { public function payment(PaymentServiceInterface $paymentService, $yourNeededData) { /** * Except amount and currency all the fields are nullable * You may use the data define in `$yourNeededData` */ $paymentData = array( 'amount' => YOUR_AMOUNT, //Must be an integer in cents 'currency' => YOUR_CURRENCY, //Coded on 3 letters or use "$paymentService->getParameter('c975LPayment.defaultCurrency')" to get your default currency 'action' => YOUR_ACTION, //Store the action to achieve after the payment. Mainly used by `returnRoute`. As a string, you can store plain text, json, etc. 'description' => YOUR_DESCRIPTION, 'userId' => USER_ID, 'userIp' => $request->getClientIp(), 'live' => false|true, //If your product is live or not, different from live config value 'returnRoute' => 'THE_NAME_OF_YOUR_RETURN_ROUTE', //This Route is defined in your Controller 'vat' => 'YOUR_VAT_RATE', //Rate value without % i.e. 5.5 for 5.5%, or 20 for 20% ); $paymentService->create($paymentData); } }
//Your Controller file use Symfony\Component\Routing\Annotation\Route; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use c975L\PaymentBundle\Entity\Payment; use c975L\PaymentBundle\Service\PaymentServiceInterface; use App\Service\YourPaymentServiceInterface; class PaymentController extends AbstractController { /** * Route used to proceed to payment * @return Response * * @Route("proceed-to-payment", * name="proceed_to_payment") */ public function proceedToPayment(YourPaymentServiceInterface $yourPaymentService) { //Creates the Payment $yourPaymentService->payment(); //Redirects to the payment form return $this->redirectToRoute('payment_form'); } /** * Return Route used after payment * @return Redirect * @throws NotFoundHttpException * * @Route("/payment-done/{orderId}", * name="payment_done", * methods={"HEAD", "GET"}) */ public function paymentDone(YourProductServiceInterface $yourProductService, PaymentServiceInterface $paymentService, Payment $payment) { //Validates the Payment $validation = $yourProductService->validate($payment); //Redirects or renders if ($validation) { return $this->redirectToRoute('YOUR_ROUTE'); } //Payment has been done but product was not validated $paymentService->error($payment); return $this->redirectToRoute('payment_display', array('orderId' => $payment->getOrderId())); } }
Use the testing cards to test before going to production.
Merchant's data
You need to override the template fragments/merchantData.html.twig
in your /templates/bundles/c975LPaymentBundle/fragments/merchantData.html.twig
and indicate there all your official data, such as address, VAT number, etc.
This template will be included in the email sent to the user after its payment.
Mention payment system
You can mention the payment system used (i.e. in the footer) by simply include an html fragment with the following code {% include '@c975LPayment/fragments/paymentSystem.html.twig' %}
. This will include Stripe logo and accepted cards.
Use payment buttons/links
You can add any payment button/link, wherever you want, by using the Twig extensions with the following code:
{{ payment_button('YOUR_TEXT_TO_DISPLAY', AMOUNT, 'CURRENCY', 'YOUR_OPTIONAL_STYLES') }} {{ payment_link('YOUR_TEXT_TO_DISPLAY', AMOUNT, 'CURRENCY') }}
AMOUNT
is the real amount (i.e. 12.92), NOT the amount in cents.
Or you can use it empty, this will lead user fo fill a form to proceed to payment
{{ payment_button() }} {{ payment_link() }}
If this project help you to reduce time to develop, you can sponsor me via the "Sponsor" button at the top :)