Template Guides

Redeeming Voucher Codes

When a customer is provided a gift voucher code, they'll obviously want to be able to use them on your store. The best way for them to enter this code is through a form at your cart.

Use the following template code and add it to your cart page (ideally near the coupon form if you're using that).

{% if cart.getFirstError('voucherCode') %}
    <span class="flash">{{ cart.getFirstError('voucherCode') }}</span>
{% endif %}

<form method="POST">
    <input type="hidden" name="action" value="gift-voucher/cart/add-code">
    {{ redirectInput('shop/cart') }}
    {{ csrfInput() }}

    <span class="{% if cart.getFirstError('voucherCode') %}has-error{% endif %}">
        <input type="text" name="voucherCode" width="11" class="{% if cart.getFirstError('voucherCode') %}has-error{% endif %}" placeholder="Voucher Code"/>
    </span>

    <input type="submit" class="button" value="Apply Voucher"/>
</form>

If successful in entering a valid gift voucher code, the users' cart will update, reflecting the discount added to their cart. From this point onwards, its treated as a discount adjuster (opens new window).

Submission Rate Limits

Code submissions are limited to approximately one request per second per IP address. The storefront and control-panel add-code actions share this allowance, including when the submitted value is a Commerce coupon. Removing a code does not consume the allowance.

If you submit codes with JavaScript, handle HTTP 429 by keeping the entered value and asking the customer to wait before trying again. The response includes Retry-After: 1; wait at least one second before another attempt. Customers sharing an IP address also share the allowance.

The limit uses Craft's resolved client IP, cache and mutex. Configure trusted proxy headers correctly so Craft receives the real client IP. Installations with multiple application servers need shared cache and mutex storage for a site-wide limit. If the allowance cannot be saved, submissions return HTTP 503 until cache storage is available.

Removing Vouchers

Gift Vouchers support for multiple vouchers needs a way to remove already entered voucher codes. In our cart template (shop/cart.html for example), we have the following code looping through the adjustment items for the order.

{% for code in craft.giftVoucher.getVoucherCodes() %}
    <form method="POST">
        <input type="hidden" name="action" value="gift-voucher/cart/remove-code">
        {{ redirectInput('shop/cart') }}
        {{ csrfInput() }}

        <input type="text" name="voucherCode" width="11" value="{{ code }}">

        <input type="submit" class="button" value="Remove Voucher">
    </form>
{% endfor %}

Combining Coupons and Vouchers

Because they're often considered similar in the eyes of customers, you can use the same field in your templates to handle either a gift voucher, or a coupon code. Just use the previous examples, and it'll automatically check if the provided text is a coupon code, and if so, try and apply it against the order.

However, you may want to provide some feedback on the discount (coupon) and the voucher. In order to do this, ensure you're checking for both voucherCode and couponCode errors.

{% if cart.getFirstError('voucherCode') %}
    <span class="flash">{{ cart.getFirstError('voucherCode') }}</span>
{% endif %}

{% if cart.getFirstError('couponCode') %}
    <span class="flash">{{ cart.getFirstError('couponCode') }}</span>
{% endif %}