Hi Jeff,
now couple of questions - the external page shall provide authentication / registration, right?
Are you using simple credentials authentication of full registration there?
Either or - you shall use RADIUS server / AAA policy for that also - either external or internal.
Captive portal, actually the AAA, rely on access-accept / reject to react as default option is "access-type radius".
When using external portals we do expect getting response similar to attached picture

Be careful to abide sequence of
f_user, f_pass, f_hs_server, f_curr_time and
f_Qv - hslogin.cgi is little touchy here
š
I would strongly recommend to get some captures from controller using these two commands in CLI:
-
remote-debug captive-portal hosts CP1 clients all max-events 5000 events all
-
remote-debug wireless hosts CP2 clients all max-events 5000 events all
Here
CP1 is device running captive portal service and
CP2 is AP where test client connects.
Try to connect and browse with unauthenticated client and I'll tell you more having these.
Also - server modes explained here

Regards,
Ondrej