Buy
Buy

We already know that our Stripe account has two environments, and each has its own two keys. This means that when we deploy, we'll need to update our code to use these Live keys, instead of the ones from the Test environment.

Well... that's going to be a bummer: the public key is hard-coded right in the middle of my template:

... lines 1 - 3
{% block body %}
<div class="nav-space-checkout">
<div class="container">
<div class="row">
... lines 8 - 34
<div class="col-xs-12 col-sm-6">
<form action="" method="POST">
<script
... line 38
data-key="pk_test_HxZzNHy8LImKK9LDtgMDRBwd"
... lines 40 - 45
</script>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

And the private one is stuck in the center of a controller:

... lines 1 - 10
class OrderController extends BaseController
{
... lines 13 - 30
public function checkoutAction(Request $request)
{
... lines 33 - 34
if ($request->isMethod('POST')) {
... lines 36 - 37
\Stripe\Stripe::setApiKey("XXX_PRIVATEKEY_XXX");
... lines 39 - 49
}
... lines 51 - 56
}
}

If you love editing random files whenever you deploy, then this is perfect! Have fun!

But for the rest of us, we need to move these keys to a central configuration file so they're easy to update on deploy. We also need to make sure that we don't commit this private key to our Git repository... ya know... because it's private - even though I keep showing you mine.

Quick! To a Configuration File!

How you do this next step will vary for different frameworks, but is philosophically always the same. In Symfony, we're going to move our keys to a special parameters.yml file, because our project is setup to not commit this to Git.

Add a stripe_secret_key config and set its value to the key from the controller:

... lines 1 - 3
parameters:
... lines 5 - 19
stripe_secret_key: XXX_PRIVATEKEY_XXX
... lines 21 - 22

Then add stripe_public_key and set that to the one from the template:

... lines 1 - 3
parameters:
... lines 5 - 20
stripe_public_key: YYY_PUBLISHABLE_KEY_YYY

In Symfony, we also maintain this other file - parameters.yml.dist - as a template for the original, uncommitted file. This one is committed to the repository. Add the keys here too, but give them fake values.

Using the Parameters

Now that these are isolated in parameters.yml, we can take them out of our code. In the controller, add $this->getParameter('stripe_secret_key'):

... lines 1 - 11
class OrderController extends BaseController
{
... lines 14 - 31
public function checkoutAction(Request $request)
{
... lines 34 - 35
if ($request->isMethod('POST')) {
... lines 37 - 38
\Stripe\Stripe::setApiKey($this->getParameter('stripe_secret_key'));
... lines 40 - 70
}
... lines 72 - 78
}
}

Next, pass a new stripe_public_key variable to the template set to $this->getParameter('stripe_public_key'):

... lines 1 - 11
class OrderController extends BaseController
{
... lines 14 - 31
public function checkoutAction(Request $request)
{
... lines 34 - 72
return $this->render('order/checkout.html.twig', array(
... lines 74 - 75
'stripe_public_key' => $this->getParameter('stripe_public_key')
));
}
}

Finally, in the template - render that new variable:

... lines 1 - 3
{% block body %}
<div class="nav-space-checkout">
<div class="container">
<div class="row">
... lines 8 - 34
<div class="col-xs-12 col-sm-6">
<form action="" method="POST">
<script
... line 38
data-key="{{ stripe_public_key }}"
... lines 40 - 45
</script>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

Make sure we didn't break anything by finding a product and adding it to the cart. The fact that this "Pay with Card" shows up means things are probably OK.

This was a small step, but don't mess it up! If that secret key becomes not so secret, sheep-zombies will attack.

Leave a comment!

  • 2019-05-06 Camille Seuvin

    Thank you Vladimir Sadicov ! It Works !!

  • 2019-05-06 Vladimir Sadicov

    Hey Camille Seuvin

    I'm not sure, because I don't know how your getParameter() works, But in your case, I prefer to use service definition for passing this parameter. For example
    in config/services.yaml under services: section define


    <your_namespase>\StripeClient:
    $secretKey: '%stripe_private_key%'


    and change your StripeClient constructor to


    public function __construct(EntityManagerInterface $em, string $secretKey)
    {
    // your code here
    }

    Hope this will help

    Cheers!!

  • 2019-05-04 Camille Seuvin

    Hello,
    I have a problem with my constructer (in StripeClient.php class)

    public function __construct(EntityManagerInterface $em)
    {
    $secretKey = $this->getParameter('stripe_private_key');
    \Stripe\Stripe::setApiKey($secretKey);

    $this->em = $em;
    }

    $secretKey return null

    I store it here services.yaml
    parameters:
    locale: 'fr'
    stripe_public_key: '%env(STRIPE_PUBLIC_KEY)%'
    stripe_private_key: '%env(STRIPE_SECRET_KEY)%'

    and in my .env.local
    ###STRIPE KEYS###
    STRIPE_PUBLIC_KEY=pk_test_EaLhidden
    STRIPE_SECRET_KEY=sk_test_Aghidden

    Can you help me please ?

    Thanks

  • 2019-04-26 Camille Seuvin

    Thank you for your help Vladimir Sadicov and Peter

  • 2019-04-25 Peter Tsiampas

    Yeah, after I posted I realised that framework was the wrong place to put it, I used it because it has a direct example of getting environment variables. :)

  • 2019-04-24 Vladimir Sadicov

    Hey Peter Tsiampas

    Thanks for good example, just instead of framework.yml it's better to use config/services.yaml

    Cheers!

  • 2019-04-24 Peter Tsiampas

    I was thinking the same thing, its pretty simple.

    In the .env.local, I just add two environment variables:

    STRIPE_SECRET_KEY=YourCrazyArsedTokenFromStriped_shhhSecret
    STRIPE_PUBLIC_KEY=YourCrazyArsedTokenFromStriped_pffttelleveryone

    Then in the framework.yml file you just pull them out. :)


    stripe_public_key: '%env(STRIPE_PUBLIC_KEY)%'
    stripe_private_key: '%env(STRIPE_SECRET_KEY)%'

    Now you can just grab them like any other variable from the config files.

  • 2019-04-23 Vladimir Sadicov

    hey Camille Seuvin

    It depends on what you need to store. For sensitive data(secret keys etc.) you should use .env.local or other env-related files like .env.*.local for other data config/services.yaml or .env, .env.*

    Cheers!

  • 2019-04-21 Camille Seuvin

    Hello, what is the right file in Symfony4 for fit with the parameters.yml in video (1:08) ?
    Thank you !