Buy

So you want to handle payment on the web? You brave, foolish soul :).

Nah, it's fine - these days, handling credit card payments is a blast. Especially with Stripe - an awesome service we've used on KnpU for years.

But let's be real: you're dealing with people's money, so don't muck it up! If you screw up or do something insecure, there could be real consequences. You will at least have an angry customer. So I guess this tutorial is all about accepting money and having happy customers.

So let's build a real-life, robust payment system so that when things go wrong - because they will - we fail gracefully, avoid surprises and make happy customers.

Code Along with Me. Do it!

As always, I beg you, I implore you, to code along with me! To do that, download the course code on this page, unzip it, and move into the start/ directory. That will give you the same code I have here.

This is a Symfony project, but we'll avoid going too deep into that stuff because I want to focus on Stripe. Inside, open the README.md file and follow the setup details to get the project running. The last step is to open your favorite console app, move into the directory, and run:

php bin/console server:run

to start up the built-in web server.

Our Great Idea: Sheep Shear Club

But before you start collecting any money, you need to come up with that next, huge idea. And here at KnpUniversity, we're convinced we've uncovered the next tech unicorn.

Ready to find out what it is? Open your browser, and go to:

http://localhost:8000

That's right: welcome to The Sheep Shear Club, your one-stop shop for artisanal shearing accessories for the most dapper sheep. Purchase cutting-edge individual products - like one of our After-Shear scents - or have products delivered directly to your farm with a monthly subscription.

Gosh, it's shear luck that we got to this idea first. Once we finish coding the checkout, our competition will be feeling sheepish.

But the site is pretty simple: we have a login page - the password is breakingbaad. After you login, you can add items to your cart and they'll show up on the checkout page. But notice, there is no checkout form yet. That's our job.

Getting to Know your Stripe Dashboard

The first step towards that is to sign up with a fancy new account on Stripe. Once you're in, you'll see this: your new e-commerce best friend: the Stripe dashboard.

There is a lot here, but right now I want you to notice that there are two environments: "test" and "live". These are like two totally separate databases full of orders, customers and more, and you can just switch between them to see your data.

Also, once you login, when you read the Stripe documentation, it will actually pre-fill your account's API keys into code examples.

Let's use those docs to put in our checkout form!

Leave a comment!

  • 2018-04-02 Iulian Beleiu

    Hey,

    The problem was at composer install, I don't know exactly why this issue occur:
    "The archive may contain identical file names with different capitalization (which fails on case insensitive filesystems)"
    Looks like UnZip fails to unzip packages. Very strange.

    Anyway the fix was to move the project in a new folder different location and run composer install again and everything works fine.

    Cheers!

  • 2018-03-29 weaverryan

    Hey Beleiu!

    Ah man, sorry about this! I just downloaded the start code and it works for me. But, let's debug!

    First, I can tell you that this class comes from a library called "ocramius/proxy-manager", and you should see this downloaded when you run composer install. The mystery is... why is this class missing? First, to make sure there weren't any download issues, try removing the vendor directory entirely and running composer install again. Also, what version of PHP are you using? That shouldn't make a difference, but that library can be weird sometimes with PHP versions.

    Let me know, and hopefully we can fix it :).

    Cheers!

  • 2018-03-29 Beleiu Iulian

    Hi,
    I have some issues when I run composer install:

    [RuntimeException]
    An error occurred when executing the ""cache:clear --no-warmup"" command:

    Fatal error: Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "LazyLoadin
    gMethodInterceptor" from namespace "ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator".
    Did you forget a "use" statement for "ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator\LazyLoadin
    gMethodInterceptor"? in C:\Users\beleiui\Documents\Symfony tutorial\Stripe\Stripe Killer Payment Processing Profit
    Tutorial\practice\start\vendor\ocramius\proxy-manager\src\ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerat
    or.php on line 122

    Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "LazyLoadingMethodInterceptor" fr
    om namespace "ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator".
    Did you forget a "use" statement for "ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator\LazyLoadin
    gMethodInterceptor"? in C:\Users\beleiui\Documents\Symfony tutorial\Stripe\Stripe Killer Payment Processing Profit
    Tutorial\practice\start\vendor\ocramius\proxy-manager\src\ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerat
    or.php on line 122

    Call Stack:
    1.9888 20509544 1. Symfony\Component\Debug\ErrorHandler->handleException() C:\Users\beleiui\Documents\Symfo
    ny tutorial\Stripe\Stripe Killer Payment Processing Profit Tutorial\practice\start\vendor\symfony\symfony\src\Symfo
    ny\Component\Debug\ErrorHandler.php:0

    PHP Fatal error: Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "LazyL
    oadingMethodInterceptor" from namespace "ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator".
    Did you forget a "use" statement for "ProxyManager\ProxyGenerator\LazyLoadingValueHolder\MethodGenerator\LazyLoadin
    gMethodInterceptor"? in C:\Users\beleiui\Documents\Symfony tutorial\Stripe\Stripe Killer Payment Processing Profit
    Tutorial\practice\start\vendor\ocramius\proxy-manager\src\ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerat
    or.php:122
    Stack trace:
    #0 [internal function]: ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator->ProxyManager\ProxyGenerator\{c
    losure}(Object(ReflectionMethod))
    #1 C:\Users\beleiui\Documents\Symfony tutorial\Stripe\Stripe Killer Payment Processing Profit Tutorial\practice\sta
    rt\vendor\ocramius\proxy-manager\src\ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator.php(95): array_map
    (Object(Closure), Array)
    #2 C:\Users\beleiui\Documents\Symfony tutori in C:\Users\beleiui\Documents\Symfony tutorial\Stripe\Stripe Killer Pa
    yment Processing Profit Tutorial\practice\start\vendor\ocramius\proxy-manager\src\ProxyManager\ProxyGenerator\LazyL
    oadingValueHolderGenerator.php on line 122

    Does someone have any idea what is going on?
    Thank you.

  • 2018-03-27 Victor Bocharsky

    Great! Glad it helped. And good luck with this complex course! Well, e-commerce always complex ;)

    Cheers!

  • 2018-03-26 Rodolfo Velasco

    I was able to solve the problem by copying the file you are refering to into my migrations folder. Now I'm checking the SheepShear Club website. Hope to be finishing this course soon. Thanks!!!

  • 2018-03-23 Victor Bocharsky

    Hey Rodolfo,

    Not on the moment you asked, but now it's fixed. I added a new migration to fix "salt not null" problem and other inconsistency of mapping with DB schema, see https://github.com/knpunive... . Now fixtures should be loaded without errors, so no more "salt not null" error.

    Cheers!

  • 2018-03-23 Rodolfo Velasco

    Hey, have you fixed the migration error? I'm getting the salt error. Please guide on what could solve the problem.

  • 2018-03-21 weaverryan

    Hey Paolo Mazzanti!

    Woohoo! And thanks to you for reporting it - this is *not* how we want the tutorial code to work :).

    Cheers!

  • 2018-03-21 Paolo Mazzanti

    Hello Ryan,
    thanks a lot for your reply and your help.
    What you wrote me about the twig version let me realize that, when I downloaded the course code again, I still got the old one, not the new one.
    Now I could make a test running composer install with the the new code files and it works like a charm, so the Twig/Symfony problem is definitively solved.

    I tested the database installation anyway and, as expected, I got the salt column error.
    Now I know the reason why.

    As I wrote in my previous post, I could follow the next lessons coding. Thanks to the finish folder files I could execute the correct migration on chapter 5.
    I really appreciate your support. Cheers!

  • 2018-03-21 weaverryan

    Hey Paolo Mazzanti!

    Hmm, I do *not* get the Twig issue with the newly downloaded start code (because inside the composer.json file, you should now see twig/twig set to ^1.24.1 to avoid using Twig 2. But, as long as you got it working, it's great!

    About the database issue, you're right! We have a bug in our migration. The salt column is not required in the code, but the migration makes it required. We'll fix that up - it was due to an upgrade of FOSUserBundle in the tutorial.

    Cheers!

  • 2018-03-20 Paolo Mazzanti

    Hello Ryan,
    thank you very much for your reply.
    I downloaded again the course code as you indicated.
    Unfortunately I experienced the same problems.

    To solve the Twig/Symfony one I ran 'composer update'.
    At the end I could follow the course lessons coding anyway.

  • 2018-03-19 weaverryan

    Hey Paolo!

    Ah man, lame! Sorry about the issues. Let's get things figured out! And actually, this looks like *our* error! For the first, we upgraded some minor dependencies on this project, but it caused an odd conflict between the version of Twig & Symfony. I've just updated that - re-download the course code, and it should be all better. Sorry about that - but thanks for reporting it!

    About the second issue, I can't repeat it: the fixtures load just fine for me. The salt column IS null, but the mapping allows for this and that's intended. So, it may have been due to the first issue - you may have possibly updated some libraries in an attempt to fix our mistake :). Try the fresh start code again, and let me know if you have any issues.

    Cheers!

  • 2018-03-19 Paolo Mazzanti

    Hello,
    I experienced several errors during the initial set up of the project.

    When I executed composer install I had the following error messages:

    [Twig_Error_Runtime]
    The "core" extension is not enabled.

    Script Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache handling the post-install-cmd event terminated with an exception

    [RuntimeException]
    An error occurred when executing the "'cache:clear --no-warmup'" command:

    [Twig_Error_Runtime]
    The "core" extension is not enabled.
    .

    I executed 'composer info twig/twig' as suggested in one conversation
    name : twig/twig
    descrip. : Twig, the flexible, fast, and secure template language for PHP
    keywords : templating
    versions : * v2.3.2
    type : library
    license : BSD 3-Clause "New" or "Revised" License (BSD-3-Clause) (OSI approved) https://spdx.org/licenses/B...
    source : [git] https://github.com/twigphp/... 85e8372c451510165c04bf781295f9d922fa524b
    dist : [zip] https://api.github.com/repo... 85e8372c451510165c04bf781295f9d922fa524b
    names : twig/twig

    autoload
    psr-0
    Twig_ => lib/

    requires
    php ^7.0
    symfony/polyfill-mbstring ~1.0

    requires (dev)
    psr/container ^1.0
    symfony/debug ~2.7
    symfony/phpunit-bridge ~3.3@dev

    ------------------------------------------------------------------------------------------

    When I executed php bin/console h:d:f:l

    I've got the following error messages:

    [Doctrine\DBAL\Exception\NotNullConstraintViolationException]
    An exception occurred while executing 'INSERT INTO fos_user (username, username_canonical, email, email_canonical, enabled, salt, password, last_login, confirmation_token, password_re
    quested_at, roles) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)' with params ["sleek_sheep1", "sleek_sheep1", "sleek_sheep1@example.com", "sleek_sheep1@example.com", 1, null, "$2y$13$G2Jk
    UMLRipnqD6V08sPCkO9TRd\/\/Bdz3MR9YMogEcwBtelm6cC.fG", null, null, null, "a:0:{}"]:
    SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'salt' cannot be null

    [Doctrine\DBAL\Driver\PDOException]
    SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'salt' cannot be null

    [PDOException]
    SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'salt' cannot be null

    I'm sure enough the parameters.yml settings are correct because I used the sames in many other Symfony 3 courses of yours.

    I thank you in advance for your help. Paolo

  • 2017-10-18 Diego Aguiar

    Hey RAJAONA Ywoumé

    If you want to install a specific version, there are many options, but the easiest one (at least to me) is like this:

     composer require vendor/package:version

    You can find more info here: https://getcomposer.org/doc...

    Have a nice day

  • 2017-10-18 RAJAONA Ywoumé

    hi, my twig is versions : * v2.4.4 .... idont know how to fix it to 2.0 do i put in the composer of symfony ? where i do composer require twig/twig i have the same probleme... i've change in vender/symfony and do composer install but there is a same pbm, i've doing composer update but the same pbm... idont know how to do

  • 2017-10-18 Victor Bocharsky

    Hey RAJAONA Ywoumé ,

    What Twig version do you use? You can check it with "$ composer info twig/twig". You can try to upgrade dependencies, most probably it'll fix the problem. Have you tried it?

    Cheers!

  • 2017-10-18 RAJAONA Ywoumé

    Do have resolve your pbm ?

  • 2017-10-18 RAJAONA Ywoumé

    Twig_Error_Runtime in ExtensionSet.php line 82:
    The "core" extension is not enabled.

    in the project i dont know ho to enable it

  • 2017-09-19 Diego Aguiar

    Hey Nina

    Can you tell me which version of Symfony / Twig you are installing? I believe this is a version problem between Symfony and Twig

    Cheers!

  • 2017-09-19 Nina

    Hello
    I have error
    Some parameters are missing. Please provide them.
    database_host (127.0.0.1):
    database_port (null):
    database_name (stripe):
    database_user (root):
    database_password (null):
    mailer_transport (smtp):
    mailer_host (127.0.0.1):
    mailer_user (null):
    mailer_password (null):
    secret (ThisTokenIsNotSoSecretChangeIt):
    > Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::buildBootstrap
    > Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache

    [Twig_Error_Runtime]
    The "core" extension is not enabled.

    Script Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache handling the post-install-cmd event terminated with an exception

    [RuntimeException]
    An error occurred when executing the ""cache:clear --no-warmup"" command:

    [Twig_Error_Runtime]
    The "core" extension is not enabled.

    .
    can you help me fix this, please?

  • 2017-06-02 Diego Aguiar

    I'm happy to help you, also, we have fixed our problem in our base code, if for any reason you have to download it again, you won't face this problem :)

    Que tengas un buen día!

  • 2017-05-31 Céline Ollagnier

    Good to "see" you gain Diego Aguiar
    I need to learn Symfony + Stripe so... Thanks for the congif it's working :)
    ¡ Gracias todavía por tu ayuda Diego! Merci encore pour ton aide Diego !

  • 2017-05-31 Diego Aguiar

    Hey Céline Ollagnier, it's good to see you again! :)

    Look's like FOSUserBundle has made some changes since this tutorial was released, but it's easy to fix :)
    Just add this to your config.yml:


    # config.yml
    fos_user:
    ...
    from_email:
    address: '%mailer_sender_address%' # whatever email you want to use for this tutorial
    sender_name: '%mailer_sender_name%'

    Cheers!

  • 2017-05-31 Céline Ollagnier

    Hi KNP' teachs!

    I've done the installation as said and can see the site mehhh. Composer told me that the lock file is outdated so I need updates after. Why not? But at the end of the update I've got...

    [Symfony\Component\Config\Definition\Exception\InvalidConfigurationException]
    The child node "from_email" at path "fos_user" must be configured.

    And I can't access the site, my sheeps are in the wildddddd.
    So... can I work without the updates for the course? If I start again with the "old" files it will work but if you've got an answer with the updated one I'm also OK with it.

    Thanks!

  • 2017-05-17 Victor Bocharsky

    Hey Danny,

    Yeah, non-standard MySQL port is another common mistake. Glad you got it working!

    Cheers!

  • 2017-05-15 Danny Avery

    Hey Victor,

    I'm under a different account now. Ok, everything is working fine now. I replaced database_host: "localhost" with "127.0.0.1" and added my MAMP MySQL database_port: "8889". Thanks for the help!

    Danny

  • 2017-05-15 Victor Bocharsky

    Hey Danny,

    Do you have installed MySQL? Are that DB credentials in parameters.yml valid for your MySQL, i.e. your db user is root and its password is root too? Also, try to replace "localhost" with IP "127.0.0.1" in database_host parameter. Let me know if you still have this error.

    Cheers!

  • 2017-05-15 Victor Bocharsky

    Hey Danny,

    "Could not open input file: composer.phar" error means that you don't have downloaded composer.phar file in the directory where you run this command. If you already have Composer installed globally - it makes sense. So you can replace all the commands in our screencasts which starts with "php composer.phar ..." with simple "composer ...", so you just need to run "composer install" in this case.

    Cheers!

  • 2017-05-12 DannyandAndrea Avery

    I'm also getting the following errors in the terminal:

    [Doctrine\DBAL\Exception\ConnectionException]
    An exception occured in driver: SQLSTATE[HY000] [2002] No such file or directory

    [Doctrine\DBAL\Driver\PDOException]
    SQLSTATE[HY000] [2002] No such file or directory

    [PDOException]
    SQLSTATE[HY000] [2002] No such file or directory

  • 2017-05-12 DannyandAndrea Avery

    When I run "php composer.phar install" I get the following error "Could not open input file: composer.phar". However, if I run "composer" I have it installed globally. So, I ran "composer install" in the directory. Not sure how to move forward. I have the following in my "parameters.yml":

    parameters:
    database_host: localhost
    database_port: null
    database_name: knpu_stripe
    database_user: root
    database_password: root
    mailer_transport: smtp
    mailer_host: 127.0.0.1
    mailer_user: null
    mailer_password: null
    secret: ThisTokenIsNotSoSecretChangeIt

    Thanks!

  • 2017-03-22 Victor Bocharsky

    Actually, yes, exactly like a PHP native. But with Symfony you probably want to declare this cart as a service to use everywhere in your code base - it allows you always use a single instance of your cart and inject its service into other services. And you have to use Symfony's built-in `session` service to work with sessions inside your shopping cart service, i.e. you have to inject '@session' in it. I mean don't use low-level $_SESSION.

  • 2017-03-22 Henri Tompodung

    Thank you Victor Bocharsky ... So just like a PHP native?

  • 2017-03-15 Victor Bocharsky

    Hey Henri,

    Well, it's simple Symfony service, which works with session, i.e. you hold order items in session. For that you probably want to create a model for order items, which will hold information about products which user want to add to the cart. You don't have to store this order items in the DB yet, just hold them in session. You also need a controller with simple CRUD operations to be able to add/edit/delete orders in your shopping card. So when a user do checkout - you will convert stored order items into real products user want to buy and add them to an order entity which in turn should be persisted in DB. Also, you have to assign the current user to this order entity to know who was made this order.

    Probably you can take a look at Open Source SyliusOrderBundle which is a part of popular E-Commerce platform.

    Cheers!

  • 2017-03-14 Henri Tompodung

    Hi Ryan..
    Don't you mind if you explain step by step how to create a shopping cart in Symfony?