Stripe Payment Gateway

Configuration

First, you'll need to add Stripe to your simple-commerce.php config file. You will also need to pass in a key and secret file.

You can obtain your API keys from the Stripe Dashboard.

1'gateways' => [
2 \DoubleThreeDigital\SimpleCommerce\Gateways\Builtin\StripeGateway::class => [
3 'key' => env('STRIPE_KEY'),
4 'secret' => env('STRIPE_SECRET'),
5 ],
6],

It's best practice to use .env file for any API keys you need, rather than referencing them directly in your config file. Review Statamic Docs.

Payment Form

Stripe recommend using their Elements library to capture credit card information as it means your customers' card information never touches your server, which is good for a whole load of reasons.

The payment form should be included inside your {{ sc:checkout }} form, and any Stripe Elements magic should also be wrapped in the {{ sc:gateways }} tag to ensure you can make full use of your gateway's configuration values.

A rough example of a Stripe Elements implementation is provided below.

1<div>
2 <label for="card-element">Card Details</label>
3 <div id="card-element"></div>
4</div>
5 
6<input id="stripePaymentMethod" type="hidden" name="payment_method">
7<input type="hidden" name="gateway" value="DoubleThreeDigital\SimpleCommerce\Gateways\Builtin\StripeGateway">
8 
9<script src="https://js.stripe.com/v3/"></script>
10<script>
11 var stripe = Stripe('{{ gateway-config:key }}')
12 var elements = stripe.elements()
13 
14 const card = elements.create('card')
15 card.mount('#card-element')
16 
17 card.addEventListener('change', ({error}) => {
18 // Deal with errors
19 })
20 
21 function confirmPayment() {
22 stripe.confirmCardPayment('{{ client_secret }}', {
23 payment_method: { card: card },
24 }).then(function (result) {
25 if (result.paymentIntent.status === 'succeeded') {
26 document.getElementById('stripePaymentMethod').value = result.paymentIntent.payment_method
27 document.getElementById('checkout-form').submit()
28 } else if (result.error) {
29 // Deal with errors
30 }
31 })
32 }
33 
34 document.getElementById('checkout-form').addEventListener('submit', (e) => {
35 e.preventDefault()
36 confirmPayment()
37 })
38</script>

Bearing in mind, you will need to use that inside of a {{ sc:gateways }} tag in order to use any values from your gateway config.

Payment Intent

During the 'prepare' stage, Simple Commerce creates a Stripe Payment Intent. The Payment Intent generates a 'client secret' which is later given to Stripe Elements to render the payment fields.

Simple Commerce will automatically set the amount, currency, description and order ID (as metadata) on the Payment Intent. However, there can be times where you may need to add to the array that's sent.

You may do this easily by providing a closure in the Stripe gateway config:

1'gateways' => [
2 \DoubleThreeDigital\SimpleCommerce\Gateways\Builtin\StripeGateway::class => [
3 'key' => env('STRIPE_KEY'),
4 'secret' => env('STRIPE_SECRET'),
5 'payment_intent_data' => function ($order) {
6 return [
7 'metadata' => [
8 'product_ids' => $order->lineItems()->pluck('product')->join(', '),
9 ],
10 ];
11 },
12 ],
13],

The closure should accept an $order parameter and should then return an array which will be merged with the defaults.

It's worth nothing that Laravel doesn't support using closures in config files alongside config caching.