I'm having a very hard time making a one-page checkout. What I actually want is: automatically add the item to the cart. The cart can only contain one item. On the product page (that automatically adds the item to the cart) I want name and address fields and that's it. A pay button below that redirects to the payment gateway. This is what I have now, but the page keeps redirecting to the same page instead of going to the payment gateway.

{% set cart = craft.commerce.getCarts().getCart(true)%}
{% do cart.setLineItems([]) %}
{% set lineItem = craft.commerce.lineitems.resolveLineItem(cart.id, product.defaultVariant.id, [], 1, '') %}
{% do cart.addLineItem(lineItem) %}
<form method="POST">
<input type="hidden" name="action" value="commerce/payments/pay"/>
{{ redirectInput('/shop/customer/order?number='~cart.number) }}
<input type="hidden" name="cancelUrl" value="{{ '/shop/checkout/payment'|hash }}"/>
<input type="hidden" name="orderEmail" value="[email protected]"/>
{{ csrfInput() }}

<input type="text" name="shippingAddress[firstName]" value="dsfdsfsd">
<input type="text" name="shippingAddress[lastName]" value="sdfsdfsfsdfs">
<input type="hidden" name="shippingAddress[countryId]" value="166">
<input type="text" id="shippingAddress-address1" name="shippingAddress[address1]" value="straatnaam nummer">
<input type="text" id="shippingAddress-city" name="shippingAddress[city]" value="Gemeente">
<input type="text" id="shippingAddress-zipCode"name="shippingAddress[zipCode]" value="2910">
<input type="text" id="shippingAddress-phone" name="shippingAddress[phone]" value="4545546544654465">
<input type="email" id="email" name="email" value="[email protected]">
<input type="hidden" name="shippingMethodHandle" value="freeShipping">
<input type="hidden" id="paymentMethod" name="paymentMethod" value="gateway:2">
<input type="submit" value="Pay">
  • 1
    You will probably have to submit parts of the checkout process via Ajax. We have a one page checkout but it relies on adding an item beforehand and adding and saving an address. From my experience, the cart item adding and the addresses are separate submits to commerce than the final payment and review submissions. Commented Dec 24, 2018 at 13:35

1 Answer 1


As Indigo mentions in the comment, the add to cart (items), update cart (with address details) and payment are different controller methods, you would need 3 different calls. The form as you have currently have it, wouldn't work.

Though for this to work on onepage checkout, you should not have any restrictions related to the payment method (the payment method is always available for any address, order value etc)

2 ways of achieving it.

  1. Custom route and controller method that incorporates all three different methods calling the related services where your form is submitted. This implementation might be problematic though if not thoroughly tested.

  2. Front end AJAX calls with promises/callbacks that first add to cart, then update addresses, and then submit the payment. Imho, this is preferred, as you have better control on errors of each call which you can display on the page (stopping the process) and the user does not get confused.

In your case, as you set the cart line items within the template, you can just process 2 calls (update cart with addresses and then payment).

Hope this helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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