2017 © Pedro Peláez
 

symfony-bundle payment-bundle

Defines form, transactions, database store, etc. for payments using Stripe

image

c975l/payment-bundle

Defines form, transactions, database store, etc. for payments using Stripe

  • Friday, July 27, 2018
  • by Laurent3170
  • Repository
  • 1 Watchers
  • 1 Stars
  • 117 Installations
  • PHP
  • 4 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 31 Versions
  • 13 % Grown

The README.md

PaymentBundle

PaymentBundle does the following:, (*1)

  • 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., (*2)

PaymentBundle dedicated web page., (*3)

PaymentBundle API documentation., (*4)

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, (*5)

    composer require c975L/payment-bundle

Step 2: Configure the Bundle

Check dependencies for their configuration:, (*6)

c975LPaymentBundle uses c975L/ConfigBundle to manage configuration parameters. Use the Route "/payment/config" with the proper user role to modify them., (*7)

Step 3: Enable the Routes

Then, enable the routes by adding them to the /config/routes.yaml file of your project:, (*8)

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., (*9)

Step 5: copy images to web folder

Install images by running, (*10)

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., (*11)

You can also have a look at official badges from Stripe., (*12)

How to use

The process is the following:, (*13)

  • 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)., (*14)

Here are the examples for those files:, (*15)

//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., (*16)

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., (*17)

This template will be included in the email sent to the user after its payment., (*18)

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., (*19)

You can add any payment button/link, wherever you want, by using the Twig extensions with the following code:, (*20)

{{ 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., (*21)

Or you can use it empty, this will lead user fo fill a form to proceed to payment, (*22)

{{ 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 :), (*23)

The Versions

27/07 2018

dev-master

9999999-dev https://github.com/975L/PaymentBundle

Defines form, transactions, database store, etc. for payments using Stripe

  Sources   Download

MIT

The Requires

 

The Development Requires

payment bundle symfony stripe

27/07 2018

v1.12

1.12.0.0 https://github.com/975L/PaymentBundle

Defines form, transactions, database store, etc. for payments using Stripe

  Sources   Download

MIT

The Requires

 

The Development Requires

payment bundle symfony stripe

21/02 2018
19/02 2018
18/02 2018
02/02 2018

v1.3.2

1.3.2.0 https://github.com/975L/PaymentBundle

Defines form, transactions, database store, etc. for payments using Stripe

  Sources   Download

MIT

The Requires

 

payment bundle symfony stripe

02/02 2018

v1.3.1

1.3.1.0 https://github.com/975L/PaymentBundle

Defines form, transactions, database store, etc. for payments using Stripe

  Sources   Download

MIT

The Requires

 

payment bundle symfony stripe

01/02 2018

v1.3

1.3.0.0 https://github.com/975L/PaymentBundle

Defines form, transactions, database store, etc. for payments using Stripe

  Sources   Download

MIT

The Requires

 

payment bundle symfony stripe

01/02 2018

v1.2.1

1.2.1.0 https://github.com/975L/PaymentBundle

Defines form, transactions, database store, etc. for payments using Stripe

  Sources   Download

MIT

The Requires

 

payment bundle symfony stripe

17/08 2017

v1.2

1.2.0.0 https://github.com/975L/PaymentBundle

Defines form, transactions, database store, etc. for payments using Stripe

  Sources   Download

MIT

The Requires

 

payment bundle symfony stripe

17/08 2017

v1.1

1.1.0.0 https://github.com/975L/PaymentBundle

Defines form, transactions, database store, etc. for payments using Stripe

  Sources   Download

MIT

The Requires

 

payment bundle symfony stripe

08/07 2017

v1.0

1.0.0.0 https://github.com/975L/PaymentBundle

Defines form, transactions, database store, etc. for payments using Stripe

  Sources   Download

MIT

The Requires

 

payment bundle symfony stripe