I'm working with a one-page checkout process, where cart contents, account info, billing, payment, and coupon information are all under Checkout. Coupons are handled by commerce_coupon.

This has worked fine, but now I want to allow free orders using 100% discount coupons, and I'm having trouble getting the right payment method selected when the coupon is applied.

To handle order totals being <= 0 because of coupons applied, I've added additional conditions to two payment methods as follows:

Stripe - commerce-order:commerce-order-total > 0.00

No Payment - commerce-order:commerce-order-total <= 0.00

Here's what happens:

When the order arrives at checkout. Stripe is selected as the payment method. When the 100% coupon is applied, the order total drops to zero as expected (through an AJAX refresh), but stripe stays selected as the payment method and the no payment option is not visible. If I reload the page manually, Stripe goes away and the No payment option is selected.

What I want:

Ideally, when a user applies a 100% coupon to the order at checkout, Stripe would disappear from available payment methods and "No payment required" would be automatically selected. Even better would be to also remove the billing information if the order total is <= 0, since there is no reason to collect it.

How can I achieve this?

I'm happy to work directly in code if that's a better approach.

  • All I can understand is it's happening because you have payment method at same page & coupons are applied by ajax. If same ajax work for payment section as well, I think it will be resolved.
    – RajeevK
    Jan 31, 2014 at 7:44

3 Answers 3


Looking at your conditions, both of them match at $0.00. You'd at least need to switch Stripe to > 0 for it to work. However, simply adding a coupon on the checkout form doesn't trigger a refresh of the entire page. By that time, the form has already been built with the payment methods shown, and the only AJAX functionality on the pane is to switch out what payment details form elements may be visible.

You're either going to need review / payment on its own step (not a bad idea since you're using coupons anyways) or else write your own code to Ajax refresh the payment options as other elements on the form are updated.

  • 1
    Thankfully, my impossible conditions were just a late-night typo :) Stripe was > 0. Fixed now.
    – Dave Bruns
    Jan 31, 2014 at 14:15
  • Thanks. I'm not opposed to a review step with payment, but I'm feeling a little obsessed about the one page checkout at the the moment. Do you know of any code examples for the AJAX refresh idea? I will look at commerce_coupon first.
    – Dave Bruns
    Jan 31, 2014 at 14:20
  • I would also like some example how to manually refresh the payment methods on 100% coupon Dec 11, 2014 at 20:38

A solution to this occurred to me. I just experimented with a setup and it appears to work.

Use the Commerce Checkout Pages module: https://www.drupal.org/project/dc_co_pages

Add an extra page to the checkout sequence and move the Payment piece out of Review page to the new page you create that comes after Review. This gives us the page refresh we need.

It adds an extra page/step to the checkout process but it solves the problem.



The solution I ended up at, which keeps the whole thing on one page was to edit the $form_state before it gets to the submit handler of the checkout pane.

I did this in the submit handler of a custom pane that was earlier in the form.

 * Custom pane: submit callback.
function custom_pane_checkout_form_submit($form, &$form_state, $checkout_pane, $order) {

  // This fixes our one page AJAX issue for full price loyalty discount
  if ($order->commerce_order_total[LANGUAGE_NONE][0]['amount'] == 0) {

There's probably a more elegant way to update what's in the $form_state but this works.

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.