@RequestMapping(value = "/summary/createUpdatePaymentDetails.json", method = RequestMethod.POST)
  @RequireHardLogIn
  public String createUpdatePaymentDetails(
      final Model model, @Valid final PaymentDetailsForm form, final BindingResult bindingResult) {
    paymentDetailsValidator.validate(form, bindingResult);

    final boolean editMode = StringUtils.isNotBlank(form.getPaymentId());

    if (bindingResult.hasErrors()) {
      model.addAttribute("edit", Boolean.valueOf(editMode));

      return ControllerConstants.Views.Fragments.SingleStepCheckout.PaymentDetailsFormPopup;
    }

    final CCPaymentInfoData paymentInfoData = new CCPaymentInfoData();
    paymentInfoData.setId(form.getPaymentId());
    paymentInfoData.setCardType(form.getCardTypeCode());
    paymentInfoData.setAccountHolderName(form.getNameOnCard());
    paymentInfoData.setCardNumber(form.getCardNumber());
    paymentInfoData.setStartMonth(form.getStartMonth());
    paymentInfoData.setStartYear(form.getStartYear());
    paymentInfoData.setExpiryMonth(form.getExpiryMonth());
    paymentInfoData.setExpiryYear(form.getExpiryYear());
    paymentInfoData.setSaved(Boolean.TRUE.equals(form.getSaveInAccount()));
    paymentInfoData.setIssueNumber(form.getIssueNumber());

    final AddressData addressData;
    if (!editMode && Boolean.FALSE.equals(form.getNewBillingAddress())) {
      addressData = getCheckoutCart().getDeliveryAddress();
      if (addressData == null) {
        GlobalMessages.addErrorMessage(
            model, "checkout.paymentMethod.createSubscription.billingAddress.noneSelected");

        model.addAttribute("edit", Boolean.valueOf(editMode));
        return ControllerConstants.Views.Fragments.SingleStepCheckout.PaymentDetailsFormPopup;
      }

      addressData.setBillingAddress(true); // mark this as billing address
    } else {
      final AddressForm addressForm = form.getBillingAddress();

      addressData = new AddressData();
      if (addressForm != null) {
        addressData.setId(addressForm.getAddressId());
        addressData.setTitleCode(addressForm.getTitleCode());
        addressData.setFirstName(addressForm.getFirstName());
        addressData.setLastName(addressForm.getLastName());
        addressData.setLine1(addressForm.getLine1());
        addressData.setLine2(addressForm.getLine2());
        addressData.setTown(addressForm.getTownCity());
        addressData.setPostalCode(addressForm.getPostcode());
        addressData.setCountry(getI18NFacade().getCountryForIsocode(addressForm.getCountryIso()));
        addressData.setShippingAddress(Boolean.TRUE.equals(addressForm.getShippingAddress()));
        addressData.setBillingAddress(Boolean.TRUE.equals(addressForm.getBillingAddress()));
      }
    }

    paymentInfoData.setBillingAddress(addressData);

    final CCPaymentInfoData newPaymentSubscription =
        getCheckoutFacade().createPaymentSubscription(paymentInfoData);
    if (newPaymentSubscription != null
        && StringUtils.isNotBlank(newPaymentSubscription.getSubscriptionId())) {
      if (Boolean.TRUE.equals(form.getSaveInAccount())
          && getUserFacade().getCCPaymentInfos(true).size() <= 1) {
        getUserFacade().setDefaultPaymentInfo(newPaymentSubscription);
      }
      getCheckoutFacade().setPaymentDetails(newPaymentSubscription.getId());
    } else {
      GlobalMessages.addErrorMessage(model, "checkout.paymentMethod.createSubscription.failed");

      model.addAttribute("edit", Boolean.valueOf(editMode));
      return ControllerConstants.Views.Fragments.SingleStepCheckout.PaymentDetailsFormPopup;
    }

    model.addAttribute("createUpdateStatus", "Success");
    model.addAttribute("paymentId", newPaymentSubscription.getId());

    return REDIRECT_PREFIX
        + "/checkout/single/summary/getPaymentDetailsForm.json?paymentId="
        + paymentInfoData.getId()
        + "&createUpdateStatus=Success";
  }