2

I’m new to Craft Commerce and am really having trouble getting started with subscriptions.

I used the example from the docs and nothing happened. When reloading the cp though, it kept telling me "Unable to start the subscription. Please check your payment details." I learned from the docs that "Subscribing a user to a plan requires that the user have a stored payment source." So I added the getPaymentFormHtml bit. Without any success. Not to mention error messages of any kind.

This is my template so far:

<ul>
{% for item in craft.session.getFlashes() %}
    <li>{{item}}</li>
{% endfor %}
</ul>

{% set plans = craft.commerce.getPlans().getAllPlans() %}

<form method="POST">
    <input type="hidden" name="action" value="commerce/subscriptions/subscribe">

    {{ csrfInput() }}

    <div>
        {% for plan in plans %}
            <input type="hidden" name="planUid" value="{{ plan.uid|hash }}"/>

            {# Display only if the user does not have a payment soure saved #}
            {{ plan.getGateway().getPaymentFormHtml({})|raw }}

        {% endfor %}
    </div>

    <button type="submit">{{ "Subscribe"|t('commerce') }}</button>
</form>

I’ve set up a subscription in the cp, added store information and tried a valid testing card from the stripe docs. But even then it keeps giving me the above flash notice.

Could anybody shed some light here? Am I missing anything obvious?

2

So I had trouble with the demo's also. But if you head into the Craft Demo Store Templates you will find the following demo page you can use. Here's what I used to get it working.

{% set plans = craft.commerce.getPlans().getAllPlans() %}

{% if currentUser and plans|length%}
    {% for plan in plans %}
        <div class="md:flex service">
            <div class="md:w-1/4">
                <h2 class="mt-8">{{ plan.name }}</h2>
                {% set information = plan.getInformation() %}
            </div>
            <div class="md:w-3/4 md:mt-8 md:pt-4">
                {% set subscriptions = plan.getActiveUserSubscriptions(currentUser.id) %}
                {% if subscriptions|length == 0 %}
                    <p><strong>You have no subscriptions to this plan.</strong></p>
                {% endif %}
                {% if subscriptions|length > 1 %}
                    <p><strong>You have multiple subscriptions to this plan.</strong></p>
                {% endif %}
                {% for subscription in subscriptions %}
                    {% if subscription.isCanceled %}
                        Your subscription was canceled on {{ subscription.dateCanceled|date('Y-m-d') }} and will expire on {{ subscription.nextPaymentDate|date('Y-m-d') }}
                    {% else %}
                        You are subscribed and your next payment is due on {{ subscription.nextPaymentDate|date('Y-m-d') }}
                    {% endif %}
                    <br /><br />

                    <a href="{{ url('/shop/services/subscription', {subscription: subscription.id}) }}">Manage subscription</a><br /><br />
                {% endfor %}
            </div>
        </div>
        {% if loop.last %}
            <hr />
        {% endif %}
    {% endfor %}
    <div class="md:flex">
        <div class="md:w-1/4">
            <h2>Available plans</h2>
        </div>
        <div class="md:w-3/4 md:pt-4">
            {% for plan in plans %}
                <form method="POST">
                    <input type="hidden" name="action" value="commerce/subscriptions/subscribe">
                    <input type="hidden" name="planUid" value="{{ plan.uid|hash }}">
                    {{ redirectInput('shop/services') }}
                    {{ csrfInput() }}

                    <h4>{{ plan.name }}</h4>

                    <select name="trialDays" data-plan="{{ plan.id }}">
                        {% for i in [0, 3, 7, 14] %}
                            {% if i == 0 %}
                                <option value="{{ (plan.uid~':0')|hash}}">No trial period.</option>
                            {% else %}
                                <option value="{{ (plan.uid~':'~i)|hash  }}">Trial for {{ i }} days</option>
                            {% endif %}
                        {% endfor %}
                    </select>

                    {% set paymentSources = craft.commerce.getPaymentSources().getAllGatewayPaymentSourcesByUserId(plan.gateway.id, currentUser.id ?? null) %}

                    {% if not paymentSources|length %}
                        <div class="paymentForm">
                            {{ plan.gateway.getPaymentFormHtml({})|raw }}
                        </div>
                    {% endif %}

                    <button type="submit">{{ "Subscribe"|t }}</button>
                </form>
            {% endfor %}
        </div>
    </div>
{% endif %}
  • 1
    Does the subscribing to a plan without a predefined payment source work for you with this example? Because for me it has the same issues that I mentioned in my question (no errors when entering wrong credentials etc.). Because if it worked for you, maybe there is something else wrong with my installation. – medoingthings May 16 '19 at 7:32
  • I would get started with the default dummy gateway first, get your subscriptions working. Once you've nailed that, try Stripe. I didn't get it working with Stripe but it should be fairly simple if it's working with the dummy gateway - make sure your webhook and everything is set up correctly. If all else fails - contact Andris through Discord, the docs for subscribing are fairly loose and need to be a bit more comprehensive. – JMKelley May 16 '19 at 11:21
  • 1
    That was actually very helpful advice. I tried the dummy gateway and it worked flawlessly. Which meant that there must be something else wrong. Turns out: I only tested with the card details. But the Stripe backend requires address and etc. So when I add those details in the Stripe backend and then retry with the subscription form, it works. I’ll check what else there is to do and post the working example here. Thanks for the nudge into the right direction @JMKelley! – medoingthings May 21 '19 at 12:31
2

I was barking up the wrong tree for the whole time. The template code was fine. It turned out that jQuery was missing. I’ve had a console error telling me ReferenceError: Can't find variable: $ in paymentForm.js:6. The injected code doesn’t seem to make sure jQuery is available.

I’ve made sure jQuery was available and from then on it worked like a charm.

When the payment form looks like this, something is wrong: Form looks like this? It might be jQuery missing

When it looks like this, the injected JavaScript works properly:

This is what the form is supposed to look like

Oh man, I just wasted so much time...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.