All Projects → craftcms → commerce-stripe

craftcms / commerce-stripe

Licence: MIT license
Stripe payment gateway for Craft Commerce

Programming Languages

PHP
23972 projects - #3 most used programming language
javascript
184084 projects - #8 most used programming language
Twig
543 projects

Projects that are alternatives of or similar to commerce-stripe

DigitalProducts
Sell digital products with Craft Commerce
Stars: ✭ 48 (+128.57%)
Mutual labels:  craftcms, craft-plugin, craft-commerce
Craft Embedded Assets
Manage YouTube videos, Instagram photos, Twitter posts and more as first class assets in Craft CMS
Stars: ✭ 165 (+685.71%)
Mutual labels:  craftcms, craft-plugin
Linkit
Multi-purpose link plugin for Craft CMS
Stars: ✭ 155 (+638.1%)
Mutual labels:  craftcms, craft-plugin
Craft Imageoptimize
Automatically create & optimize responsive image transforms, using either native Craft transforms or a service like Imgix, with zero template changes.
Stars: ✭ 227 (+980.95%)
Mutual labels:  craftcms, craft-plugin
Craft Seomatic
SEOmatic facilitates modern SEO best practices & implementation for Craft CMS 3. It is a turnkey SEO system that is comprehensive, powerful, and flexible.
Stars: ✭ 135 (+542.86%)
Mutual labels:  craftcms, craft-plugin
Simplemap
A beautifully simple map field type for Craft CMS.
Stars: ✭ 136 (+547.62%)
Mutual labels:  craftcms, craft-plugin
Seo
SEO utilities including a unique field type, sitemap & redirect manager
Stars: ✭ 210 (+900%)
Mutual labels:  craftcms, craft-plugin
Plugins
The master list of Craft 3-compatible plugins
Stars: ✭ 111 (+428.57%)
Mutual labels:  craftcms, craft-plugin
smartdown.craft-plugin
Bringing the unbridled joy of Markdown Extra and Smartypants to your Craft websites.
Stars: ✭ 26 (+23.81%)
Mutual labels:  craftcms, craft-plugin
craft3-sitecopy
With this plugin you can copy the content of an entry to another site.
Stars: ✭ 22 (+4.76%)
Mutual labels:  craftcms, craft-plugin
buffer
DEPRECATED Send social updates to Twitter, Facebook, etc. through Buffer.com via Twig templates, URLs, and plugins.
Stars: ✭ 43 (+104.76%)
Mutual labels:  craftcms, craft-plugin
craft3-forms
This craft CMS 3 form plugin makes it easy to create and use custom forms with the features the Yii 2 Framework offers. On top of this, the plugin provides even more functionalities for easy implementation of forms in twig templates.
Stars: ✭ 20 (-4.76%)
Mutual labels:  craftcms, craft-plugin
Craft Fieldlabels
Override Craft CMS field labels and instructions in the field layout designer
Stars: ✭ 128 (+509.52%)
Mutual labels:  craftcms, craft-plugin
Commerce
Fully integrated ecommerce for Craft CMS
Stars: ✭ 144 (+585.71%)
Mutual labels:  craftcms, craft-plugin
Minify
DEPRECATED A simple plugin that allows you to minify blocks of HTML, CSS, and JS inline in Craft CMS templates
Stars: ✭ 111 (+428.57%)
Mutual labels:  craftcms, craft-plugin
Retour
DEPRECATED Retour allows you to intelligently redirect legacy URLs, so that you don't lose SEO value when rebuilding & restructuring a website.
Stars: ✭ 172 (+719.05%)
Mutual labels:  craftcms, craft-plugin
AssetSubfolderAccess
Limits user groups to only access certain asset subfolders
Stars: ✭ 18 (-14.29%)
Mutual labels:  craftcms, craft-plugin
Craft Quick Field
Create fields on the fly while designing field layouts
Stars: ✭ 104 (+395.24%)
Mutual labels:  craftcms, craft-plugin
Craft Asset Rev
A Craft CMS plugin to help with cache busting
Stars: ✭ 109 (+419.05%)
Mutual labels:  craftcms, craft-plugin
Spoon
Spoon plugin for Craft CMS - Enhance your Matrix fields with groups, tabs and more!
Stars: ✭ 82 (+290.48%)
Mutual labels:  craftcms, craft-plugin

Stripe for Craft Commerce icon

Stripe for Craft Commerce

This plugin provides a Stripe integration for Craft Commerce supporting Payment Intents and traditional charges.

Requirements

  • Craft CMS 4.0 or later
  • Craft Commerce 4.0 or later
  • Stripe API version '2019-03-14'

Installation

You can install this plugin from the Plugin Store or using Composer.

From the Plugin Store

Go to the Plugin Store in your project’s control panel, search for “Stripe for Craft Commerce”, and choose Install in the plugin’s modal window.

With Composer

Open your terminal and run the following commands:

# go to the project directory
cd /path/to/my-project.test

# tell Composer to load the plugin
composer require craftcms/commerce-stripe

# tell Craft to install the plugin
php craft install/plugin commerce-stripe

Changes in 2.0

We deprecated the original “Stripe” gateway as “Stripe Charge” and added a new “Stripe Payment Intents” gateway which uses Stripe’s Payment Intents API and 3D Secure 2, which is easier to implement than the old 3D Secure standard and delivers a better customer experience.

Stripe began declining all EU charges using its old charge API on September 14, 2019, so we highly recommend switching to the newer “Stripe Payment Intents” gateway. (Learn more by reading Stripe’s Strong Customer Authentication guide.)

Setup

To add the Stripe payment gateway in the Craft control panel, navigate to CommerceSettingsGateways, create a new gateway, and set the gateway type to “Stripe Payment Intents”.

⚠️ The deprecated “Stripe Charge” gateway is still available. See Changes in 2.0.

In order for the gateway to work properly, the following settings are required:

  • Publishable API Key
  • Secret API Key

You can find these in your Stripe dashboard under DevelopersAPI keys.

Payment Process and Security

This plugin relies on stored payment methods and doesn’t allow directly-submitted credit card details. To check out, a customer must submit a paymentMethodId parameter to the Commerce commerce/payments/pay form action.

A new payment method can be created prior to checkout using Stripe’s front-end JavaScript API.

Check out Stripe’s Create Payment Method documentation to learn how to save a payment method or follow the example below.

Webhooks

You’ll need to update configuration with this plugin and the Stripe dashboard in order to utilize webhooks.

Configuring Stripe

Set up a webhook endpoint in your Stripe dashboard API settings. The URL for this endpoint can be found in your Commerce Stripe gateway settings.

We recommend emitting all possible events, but the required events are:

For 3D Secure Payments (if using Stripe Charge gateway)

  • source.cancelled
  • source.chargeable
  • source.failed

For refunds:

  • charge.refund.updated

For Subscriptions

  • invoice.payment_succeeded
  • customer.subscription.deleted

We strongly recommended enabling the following events to ensure your Commerce subscriptions stay in sync with your Stripe dashboard:

  • plan.deleted
  • plan.updated
  • invoice.created
  • customer.subscription.updated
  • invoice.payment_failed

Configuring the Gateway

When you've set up the endpoint, you can view the signing secret in its settings. Enter this value in your Stripe gateway settings in the Webhook Signing Secret field. To use webhooks, the Webhook Signing Secret setting is required.

Configuration Settings

chargeInvoicesImmediately

For subscriptions with automatic payments, Stripe creates an invoice 1-2 hours before attempting to charge it. By setting this to true in your commerce-stripe.php config file, you can force Stripe to charge this invoice immediately.

This setting affects all Stripe gateways on your Commerce installation.

Subscriptions

Creating a Subscription Plan

  1. Every subscription plan must first be created in the Stripe dashboard.
  2. In the Craft control panel, navigate to CommerceSettingsSubscription plans and create a new subscription plan.

Subscribe Options

trialDays

When subscribing, you can pass a trialDays parameter. The first full billing cycle will start once the number of trial days lapse. Default value is 0.

Cancel Options

cancelImmediately

If this parameter is set to true, the subscription is canceled immediately. Otherwise, it is marked to cancel at the end of the current billing cycle. Defaults to false.

Plan-Switching Options

prorate

If this parameter is set to true, the subscription switch will be prorated. Defaults to false.

billImmediately

If this parameter is set to true, the subscription switch is billed immediately. Otherwise, the cost (or credit, if prorate is set to true and switching to a cheaper plan) is applied to the next invoice.

⚠️ If the billing periods differ, the plan switch will be billed immediately and this parameter will be ignored.

Events

The plugin provides several events you can use to modify the behavior of your integration.

Payment Request Events

buildGatewayRequest

Plugins get a chance to provide additional metadata to any request that is made to Stripe in the context of paying for an order. This includes capturing and refunding transactions.

There are some restrictions:

  • Changes to the Transaction model available as the transaction property will be ignored;
  • Changes to the order_id, order_number, transaction_id, client_ip, and transaction_reference metadata keys will be ignored;
  • Changes to the amount, currency and description request keys will be ignored;
use craft\commerce\models\Transaction;
use craft\commerce\stripe\events\BuildGatewayRequestEvent;
use craft\commerce\stripe\base\Gateway as StripeGateway;
use yii\base\Event;

Event::on(
    StripeGateway::class,
    StripeGateway::EVENT_BUILD_GATEWAY_REQUEST,
    function(BuildGatewayRequestEvent $e) {
        /** @var Transaction $transaction */
        $transaction = $e->transaction;
        
        if ($transaction->type === 'refund') {
            $e->request['someKey'] = 'some value';
        }
    }
);

receiveWebhook

Plugins get a chance to do something whenever a webhook is received. This event will be fired regardless of whether or not the gateway has done something with the webhook.

use craft\commerce\stripe\events\ReceiveWebhookEvent;
use craft\commerce\stripe\base\Gateway as StripeGateway;
use yii\base\Event;

Event::on(
    StripeGateway::class,
    StripeGateway::EVENT_RECEIVE_WEBHOOK,
    function(ReceiveWebhookEvent $e) {
        if ($e->webhookData['type'] == 'charge.dispute.created') {
            if ($e->webhookData['data']['object']['amount'] > 1000000) {
                // Be concerned that a USD 10,000 charge is being disputed.
            }
        }
    }
);

Subscription Events

createInvoice

Plugins get a chance to do something when an invoice is created on the Stripe gateway.

use craft\commerce\stripe\events\CreateInvoiceEvent;
use craft\commerce\stripe\base\SubscriptionGateway as StripeGateway;
use yii\base\Event;

Event::on(
    StripeGateway::class, 
    StripeGateway::EVENT_CREATE_INVOICE,
    function(CreateInvoiceEvent $e) {
        if ($e->invoiceData['billing'] === 'send_invoice') {
            // Forward this invoice to the accounting department.
        }
    }
);

beforeSubscribe

Plugins get a chance to tweak subscription parameters when subscribing.

use craft\commerce\stripe\events\SubscriptionRequestEvent;
use craft\commerce\stripe\base\SubscriptionGateway as StripeGateway;
use yii\base\Event;

Event::on(
    StripeGateway::class,
    StripeGateway::EVENT_BEFORE_SUBSCRIBE,
    function(SubscriptionRequestEvent $e) {
        $e->parameters['someKey'] = 'some value';
        unset($e->parameters['unneededKey']);
    }
);

Deprecated Events

The following event is deprecated because it’s associated with the deprecated Stripe Charge gateway.

receive3dsPayment

Plugins get a chance to do something whenever a successful 3D Secure payment is received.

use craft\commerce\Plugin as Commerce;
use craft\commerce\stripe\events\Receive3dsPaymentEvent;
use craft\commerce\stripe\gateways\PaymentIntents as StripeGateway;
use yii\base\Event;

Event::on(
    StripeGateway::class,
    StripeGateway::EVENT_RECEIVE_3DS_PAYMENT,
    function(Receive3dsPaymentEvent $e) {
        $order = $e->transaction->getOrder();
        $paidStatus = Commerce::getInstance()->getOrderStatuses()->getOrderStatusByHandle('paid');
        if ($order && $paidStatus && $order->orderStatusId !== $paidStatus->id && $order->getIsPaid()) {
            $order->orderStatusId = $paidStatus->id;
            Craft::$app->getElements()->saveElement($order);
        }
    }
);

Creating a Stripe Payment Form for the Payment Intents Gateway

You can output a standard form quickly using order.gateway.getPaymentFormHtml() or gateway.getPaymentFormHtml(), but you can take a little more time to follow these steps and have more control over the resulting template.

1. Include Stripe’s JavaScript on your payment page.

<script src="https://js.stripe.com/v3/"></script>

💡 See the Stripe JS documentation for more on using the Stripe JavaScript libraries and Stripe Elements front end tools we’re using below.

2. Create the HTML wrapper for Stripe’s inputs.

We only need a few specific IDs in our markup, and Stripe’s JavaScript will take care of the rest by inserting and managing form inputs.

Replace the YOUR_GATEWAY_ID below with your Stripe Payment Intents gateway ID. (You can omit the gatewayId input if the gateway is already saved to the cart.)

<form method="post" action="" id="payment-form">
    {{ actionInput('commerce/payments/pay') }}
    {{ redirectInput(siteUrl('shop/customer/order', { number: cart.number, success: 'true' })) }}
    {{ hiddenInput('cancelUrl', siteUrl('shop/checkout/payment')|hash) }}
    {{ hiddenInput('gatewayId', 'YOUR_GATEWAY_ID') }}
    {{ csrfInput() }}

    {% namespace cart.gateway.handle|commercePaymentFormNamespace %}        
        <div class="form-row">
            <label for="card-element">
                Credit or debit card input fields
            </label>
            <div id="card-element">
                {# Stripe’s JavaScript will insert Stripe Elements here #}
            </div>
            {# Used to display form errors #}
            <div id="card-errors" role="alert"></div>
        </div>
    {% endnamespace %}

    <button id="submit-button" type="submit">Submit Payment</button>
</form>

3. Instantiate the Stripe JS library with your gateway’s publishableKey.

Create the stripe object in your page’s JavaScript:

var stripe = Stripe('{{ parseEnv(cart.gateway.publishableKey) }}');

This expects the Stripe gateway to be set on the order. If you’re setting it on the order during the payment submission, you would need to get a reference to the gateway first:

{% set gateway = craft.commerce.gateways.getGatewayById('YOUR_GATEWAY_ID') %}

Then you could instantiate the stripe object using gateway.publishableKey:

var stripe = Stripe('{{ parseEnv(gateway.publishableKey) }}');

Once you have a stripe object, you need to create an instance of Stripe Elements:

// Create an instance of Elements
var elements = stripe.elements();

4. Create a styled card instance.

Set some style attributes for the card element we’ll create:

var style = {
  base: {
    color: '#32325d',
    fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
    fontSmoothing: 'antialiased',
    fontSize: '16px',
    '::placeholder': {
      color: '#aab7c4'
    }
  },
  invalid: {
    color: '#fa755a',
    iconColor: '#fa755a'
  }
};

Create the cart instance using those styles:

// Create an instance of the card Element
var card = elements.create('card', { style: style });

Mount that card into our markup’s <div id="card-element"> we created earlier:

card.mount('#card-element');

To handle real-time validation errors from the card Element, we’ll add error messages to our markup’s <div id="card-errors" role="alert"></div>:

card.on('change', function(event) {
    var displayError = document.getElementById('card-errors');
    if (event.error) {
        displayError.textContent = event.error.message;
    } else {
        displayError.textContent = '';
    }
});

Finally, add a form listener that uses the submitted card details to create a payment method and pass in optional billing details:

var form = document.getElementById('payment-form');

form.addEventListener('submit', function(event) {
    event.preventDefault();

    var paymentData = {
        billing_details: {
            email: "{{ cart.email }}",
        }
    };

    stripe.createPaymentMethod('card', card, paymentData).then(function(result) {
        if (result.error) {
            // Show the user any errors
            var errorElement = document.getElementById('card-errors');
            errorElement.textContent = result.error.message;
        } else {
            // Insert the token ID into the form so it gets submitted to the server
            var form = document.getElementById('payment-form');
            var hiddenInput = document.createElement('input');
            hiddenInput.setAttribute('type', 'hidden');
            hiddenInput.setAttribute('name', 'paymentMethodId'); // Craft Commerce only needs this
            hiddenInput.setAttribute('value', result.paymentMethod.id);
            form.appendChild(hiddenInput);

            form.submit();
        }
    });
});
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].