Captcha Challenge 404 On Custom Forms

Cavera
Shopify Partner
24 0 7

I have created a custom theme and am trying to integrate Shopify Forms but am running into an issue. When CAPTCHA is enabled, and it kicks in on a form submission, the user is redirected to a "challenge" page that displays the CAPTCHA image matching test. When you complete that challenge and click submit, you are back to the /challenge URL that shows a 404 error since that page doesn't exist. I've created the form as per Shopify's docs but not sure what I'm missing.

 

I've tested the same site with Dawn and it works fine from what I can see so it's an issue with theme but damned if I can see anything different between how Dawn's doing it and me. Below is my custom form for reference.

 

Any help anyone can give would be much appretiated.

 

 

 

{% form 'contact' -%}
	<div class="form_msg_container">
		{% if form.posted_successfully? -%}
			<div class="alert success_msg">Testing</div>
		{% else -%}
			<div class="alert error_msg">{{ form.errors | default_errors }}</div>
		{% endif -%}
	</div>
	<div class="form_container">
		<div class="input_email">
			<label for="email">Email Address</label>
			<input id="email" type="email" name="contact[email]" value="{% if form.email %}{{ form.email }}{% elsif customer %}{{ customer.email }}{% endif %}" autocomplete="email" spellcheck="false" autocapitalize="off" aria-required="true" required />
			{%- if form.errors contains 'email' -%}
				<div class="field_error">{{ form.errors.messages['email'] }}</div>
			{%- endif -%}
		</div>
		<div class="input_message">
			<label for="message">Message</label>
			<textarea id="message" name="contact[body]"></textarea>
		</div>
		<div class="input_password">
			<label for="password">Password</label>
			<input id="password" type="password" name="contact[password]" />
		</div>
		<div class="form_submit">
			<button type="submit" class="btn ">Submit</button>
		</div>
	</div>
{% endform %}

 

 

 

 

 

Replies 10 (10)

Cavera
Shopify Partner
24 0 7

Oh, and another follow up. The FORM object doesn't appear to be returning correctly when the form submits.  I am checking for posted_successfully? among other form attributes and I'm not getting anything. What am I missing?

m8hue
Shopify Partner
5 0 1

Just here to say me to, and all of the sudden hitting all of the same problems when trying to edit the literal dawn form require the name field in addition to the email field. 

 

If you had any luck figuring it out, please share. 

Cavera
Shopify Partner
24 0 7

No, still no progress on this one. I did reach out to Shopify support and like usual, was zero help and advised me to post to the community forum to see if they could offer a solution. Maybe more people that commenting on this thread will inspire someone from Shopify to chime in? Maybe?

savita_nagdev
Shopify Partner
20 0 1

@Cavera  @m8hue ,

Did anyone from you guys get a solution for 404? As I am also facing the same issue I have implemented reCaptcha v2 in the contact form and when I submit that it redirects me to 404.

Cavera
Shopify Partner
24 0 7

No solution on my end, no. Hopefully, the more people chime in on this thread, the more likely it will be that Shopify responds.... maybe. If I hear back or come up with a solution, I'll be sure to post in this thread.

atafone
Visitor
1 0 0

I have a custom form for registration and have experienced the same issue with getting redirected back to the /challenge page, which shows a 404 view. Can't replicate it as it doesn't seem to happen every time.

 

Would love to know if anyone has come up with an answer or solution to this problem.

WyldCode
Shopify Partner
10 0 0

I posted a response above with some code

WyldCode
Shopify Partner
10 0 0

Hi everyone. I have a simple and proper solution to this problem. No need to add spam to your inbox by disabling recaptcha through Shopify support.

 

First let's bread down what the issue is.
Shopify has hooks that automatically add the recaptcha validation token to the form right before it submits. In order to mimic/replicate the functionality of a standard submit, you have to just add the recaptcha token to the form submission request. I'm going to use jQuery code here to make the code mode readable.

The first step

Unbind Shopify's submit hook on the form. You can either do it by using "off()":

$('#FORM_ID').off('submit');

 

Or you can create a non-submit button and run your custom form validation/etc on button click.

Second step
Attach your own submit callback.

$('#FORM_ID').on('submit', submitHandleCallback);


Third step
Call the RecaptchaV3 JS API yourself.

const submitHandleCallback = (e) => {
    e.preventDefault();

    // Here we fetch your site key.
    const siteKey = window.Shopify.recaptchaV3.siteKey;
    
    // Probably a good idea to do some form input validation here

    // Now get the recaptcha validation token
    grecaptcha.ready(function() {
        // do request for recaptcha token
        grecaptcha.execute(siteKey, {action:'validate_captcha'}).then(function(token) {
            // Serialize the form and add the token to the payload
           let payload = $('#FORM_ID').serializeObject();
           payload['g-recaptcha-response'] = token;
           
           // Now we have to payload, let's submit it.  But first we get the submit location
           const action = $('#FORM_ID').attr('action');
           $.ajax('POST', payload, function(){
               // Success action here
           },
           function(){
               // Error action here
           }
        });
    });
}

 

The issue is that you don't get some kind of JSON or serialized payload. You get either an error header or a success header.

You can either parse out the result, or you can rely on the success/error responses.

m8hue
Shopify Partner
5 0 1
@WyldCode This solution looks great.

It'll take me a bit before I can jump back and check the forms on a dev site on my side, but I really appreciate the solution.
WyldCode
Shopify Partner
10 0 0

Just to be clear, this section is pseudocode. 

let payload = $('#FORM_ID').serializeObject();

 

You have to do 

const data_array = $('#FORM_ID').serializeArray();

Loop through the array and create an object for payload (it's easy). Then send the payload