Jump to content

Remote Order Form using the API


Matt

Recommended Posts

  • WHMCS CEO

We've been receiving a few requests recently for help with using the API, and in particular the order function. So I've written up an example remote order form which uses the WHMCS API. It's a basic example allowing the ordering of a selection of 3 packages with monthly & annual cycle options.

 

The code below can be copied and pasted into a file and given any name. You will need to customise the packages and payment options it offers to suit your setup. Therefore knowledge of both HTML & PHP will be required to style & customise it for your needs.

 

<?php

$whmcsurl = "http://www.yourdomain.com/whmcsfolder/";
$apiusername = "adminuser"; # Admin username goes here
$apipassword = "password"; # Admin password goes here

if ($_POST["action"]=="submit") {

   # Get Values
   $domain = trim(htmlentities($_POST["domain"]));
   $domaintype = trim(htmlentities($_POST["domaintype"]));
   $pid = trim(htmlentities($_POST["pid"]));
   $billingcycle = trim(htmlentities($_POST["billingcycle"]));
   $firstname = trim(htmlentities($_POST["firstname"]));
   $lastname = trim(htmlentities($_POST["lastname"]));
   $companyname = trim(htmlentities($_POST["companyname"]));
   $email = trim(htmlentities($_POST["email"]));
   $address1 = trim(htmlentities($_POST["address1"]));
   $address2 = trim(htmlentities($_POST["address2"]));
   $city = trim(htmlentities($_POST["city"]));
   $state = trim(htmlentities($_POST["state"]));
   $postcode = trim(htmlentities($_POST["postcode"]));
   $country = trim(htmlentities($_POST["country"]));
   $phonenumber = trim(htmlentities($_POST["phonenumber"]));
   $password = trim(htmlentities($_POST["password"]));
   $password2 = trim(htmlentities($_POST["password2"]));
   $paymentmethod = trim(htmlentities($_POST["paymentmethod"]));
   $tosagreement = $_POST["tosagreement"];

   # Error Checking
   if (!$domain) {
       $errors[] = "You did not enter a domain name";
   }
   if (ereg('[^a-z0-9.-]', $domain)) {
       $errors[] = "The domain you entered is not valid";
   }
   if (($billingcycle!="monthly")AND($billingcycle!="annually")) {
       $billingcycle = "monthly";
   }
   if (!$firstname) {
       $errors[] = "You did not enter your first name";
   }
   if (!$lastname) {
       $errors[] = "You did not enter your last name";
   }
   if (!$email) {
       $errors[] = "You did not enter your email address";
   } elseif (!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,6})$", $email)) {
   	$errors[] = "The email address you entered is invalid";
   }
   if (!$address1) {
       $errors[] = "You did not enter the first line of your address";
   }
   if (!$city) {
       $errors[] = "You did not enter your city";
   }
   if (!$state) {
       $errors[] = "You did not enter your state";
   }
   if (!$postcode) {
       $errors[] = "You did not enter your postcode";
   }
   if (!$country) {
       $errors[] = "You did not enter your country";
   }
   if (!$phonenumber) {
       $errors[] = "You did not enter your phone number";
   }
   if (!$password) {
       $errors[] = "You must enter a password";
   } elseif ($password!=$password2) {
       $errors[] = "The password you entered did not match";
   }
   if (!$tosagreement) {
       $errors[] = "You must agree to the terms of service";
   }

   if (!$errors) {

       # Submit Order

       $apiurl = $whmcsurl."includes/api.php"; # URL to WHMCS API file

       $postfields = array();
       $postfields["username"] = $apiusername;
       $postfields["password"] = md5($apipassword);
       $postfields["action"] = "addclient";
       $postfields["firstname"] = $firstname;
       $postfields["lastname"] = $lastname;
       $postfields["companyname"] = $companyname;
       $postfields["email"] = $email;
       $postfields["address1"] = $address1;
       $postfields["address2"] = $address2;
       $postfields["city"] = $city;
       $postfields["state"] = $state;
       $postfields["postcode"] = $postcode;
       $postfields["country"] = $country;
       $postfields["phonenumber"] = $phonenumber;
       $postfields["password2"] = $password;

       $query_string = "";
       foreach ($postfields AS $k=>$v) {
           $query_string .= "$k=".urlencode($v)."&";
       }

       $ch = curl_init();
       curl_setopt($ch, CURLOPT_URL, $apiurl);
       curl_setopt($ch, CURLOPT_POST, 1);
       curl_setopt($ch, CURLOPT_TIMEOUT, 100);
       curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
       curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);
       $data = curl_exec($ch);
       curl_close($ch);

       $data = explode(";",$data);
       foreach ($data AS $temp) {
           $temp = explode("=",$temp);
           $results[$temp[0]] = $temp[1];
       }

       if ($results["result"]=="success") {
           $clientid = $results["clientid"];
       } else {
           die("An error occured. Please contact support. ({$results['message']})");
       }

       $postfields = array();
       $postfields["username"] = $apiusername;
       $postfields["password"] = md5($apipassword);
       $postfields["action"] = "addorder";
       $postfields["clientid"] = $clientid;
       $postfields["pid"] = $pid;
       $postfields["domain"] = $domain;
       if (($domaintype=="register")OR($domaintype=="transfer")) {
           $postfields["domaintype"] = $domaintype;
           $postfields["regperiod"] = 1;
       }
       $postfields["billingcycle"] = $billingcycle;
       $postfields["paymentmethod"] = $paymentmethod;

       $query_string = "";
       foreach ($postfields AS $k=>$v) {
           $query_string .= "$k=".urlencode($v)."&";
       }

       $ch = curl_init();
       curl_setopt($ch, CURLOPT_URL, $apiurl);
       curl_setopt($ch, CURLOPT_POST, 1);
       curl_setopt($ch, CURLOPT_TIMEOUT, 100);
       curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
       curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);
       $data = curl_exec($ch);
       curl_close($ch);

       $data = explode(";",$data);
       foreach ($data AS $temp) {
           $temp = explode("=",$temp);
           $results[$temp[0]] = $temp[1];
       }

       if ($results["result"]=="success") {
           $invoiceid = $results["invoiceid"];
           header("Location: ".$whmcsurl."dologin.php?username=$email&password=$password&goto=viewinvoice&id=$invoiceid");
           exit;
       } else {
           die("An error occured. Please contact support. ({$results['message']})");
       }

   }

}

?><html>
<head>
<title>Order Form</title>
</head>
<body>

<h1>Order Form</h1>

<?php
if ($errors) {
   echo "<p>The following errors occured.</p><ul>";
   foreach ($errors AS $error) {
       echo "<li>$error</li>";
   }
   echo "</ul>";
}
?>

<form method="post" action="<?php echo $_SERVER["PHP_SELF"] ?>">
<input type="hidden" name="action" value="submit" />

<table>
<tr><td width="150"><b>Domain Details</b></td></tr>
<tr><td>Domain Name</td><td>www. <input type="text" name="domain" size="40" value="<?php echo $domain ?>" /> (eg. mydomain.com)</td></tr>
<tr><td>Domain Type</td><td>
<input type="radio" name="domaintype" value="register"<?php if (($domaintype=="register")OR(!$domaintype)) { echo " checked"; } ?> /> I want to register this as a new domain<br />
<input type="radio" name="domaintype" value="transfer"<?php if ($domaintype=="transfer") { echo " checked"; } ?> /> I already own this domain and want to transfer it to you<br />
<input type="radio" name="domaintype" value="owndomain"<?php if ($domaintype=="owndomain") { echo " checked"; } ?> /> I own this domain and will change the nameservers at my existing registrar</td></tr>
<tr><td><br /></td></tr>
<tr><td><b>Hosting Details</b></td></tr>
<tr><td>Hosting Package</td><td>
<input type="radio" name="pid" value="1"<?php if (($pid=="1")OR(!$pid)) { echo " checked"; } ?> /> Starter Package
<input type="radio" name="pid" value="2"<?php if ($pid=="2") { echo " checked"; } ?> /> Standard Package
<input type="radio" name="pid" value="3"<?php if ($pid=="3") { echo " checked"; } ?> /> Advanced Package
</td></tr>
<tr><td>Billing Cycle</td><td><select name="billingcycle"><option value="monthly"<?php if ($billingcycle=="monthly") { echo " selected"; } ?>>Monthly</option><option value="annually"<?php if ($billingcycle=="annually") { echo " selected"; } ?>>Annually</option></select></td></tr>
<tr><td><br /></td></tr>
<tr><td><b>Your Details</b></td></tr>
<tr><td>First Name</td><td><input type="text" name="firstname" size="30" value="<?php echo $firstname ?>" /></td></tr>
<tr><td>Last Name</td><td><input type="text" name="lastname" size="30" value="<?php echo $lastname ?>" /></td></tr>
<tr><td>Company Name</td><td><input type="text" name="companyname" value="<?php echo $companyname ?>" size="30" /></td></tr>
<tr><td>Email Address</td><td><input type="text" name="email" value="<?php echo $email ?>" size="30" /></td></tr>
<tr><td>Address 1</td><td><input type="text" name="address1" value="<?php echo $address1 ?>" size="30" /></td></tr>
<tr><td>Address 2</td><td><input type="text" name="address2" value="<?php echo $address2 ?>" size="30" /></td></tr>
<tr><td>City</td><td><input type="text" name="city" size="30" value="<?php echo $city ?>" /></td></tr>
<tr><td>State</td><td><input type="text" name="state" size="30" value="<?php echo $state ?>" /></td></tr>
<tr><td>Postcode</td><td><input type="text" name="postcode" size="30" value="<?php echo $postcode ?>" /></td></tr>
<tr><td>Country</td><td><input type="text" name="country" size="30" value="<?php echo $country ?>" /></td></tr>
<tr><td>Phone Number</td><td><input type="text" name="phonenumber" size="30" value="<?php echo $phonenumber ?>" /></td></tr>
<tr><td>Payment Method</td><td>
<input type="radio" name="paymentmethod" value="paypal"<?php if (($paymentmethod=="paypal")OR(!$paymentmethod)) { echo " checked"; } ?> /> PayPal
<input type="radio" name="paymentmethod" value="authorize"<?php if ($paymentmethod=="authorize") { echo " checked"; } ?> /> Credit Card
</td></tr>
<tr><td>Password</td><td><input type="password" name="password" size="30" /></td></tr>
<tr><td>Confirm Password</td><td><input type="password" name="password2" size="30" /></td></tr>
</table>

<p align="center"><input type="checkbox" name="tosagreement" /> I have read and agree to the <a href="http://www.yourdomain.com/terms.html" target="_blank">Terms of Service</a></p>

<p align="center"><input type="submit" value="Submit Order" /></p>

</form>

</body>
</html>

Link to comment
Share on other sites

  • 1 month later...

When the form is submitted, I do get the notification of the new order but the page displays this error:

 

 

Warning: Cannot modify header information - headers already sent by (output started at /home/*****/public_html/remoteorder/test.php:1) in /home/*****/public_html/remoteorder/test.php on line 163

 

Please advise

Link to comment
Share on other sites

TommyK - all those things are possible - order description and customer login are built into the system, and it's assumed you understand how it works. Ajax domain lookup is possible, not sure whether anyone has made one publicly available yet.

 

mbadr - you've somehow managed to allow output before the cookies are set. This is usually caused by blank lines before the opening <?php tag. You need to make sure the <?php tag is right at the very very top of the file. The starting line number of 1 in your error message seems to confirm that. As Matt mentions, you do need some PHP knowledge to use this form, and there are people around available for hire who can do that.

Link to comment
Share on other sites

  • 3 weeks later...

This would be awesome if I didn't get a lot of errors when I load the page for the first time

 

Notice: Undefined index: action in /var/www/apiorderform/index.php on line 7

...

...

 

So I'm gonna have to break it down, tbh, its probably my PHP version, so I'll check it out and report back

Link to comment
Share on other sites

what do you mean by that? pass affiliate orders how?

 

As I understand it, there are basically two choices - you can take over the ordering process with the API completely, which should enable you to write your own interface however you like, and pass anything you like to anyone you like however you like on completion.

 

The other choice is to use WHMCS's inbuilt order processing cart/system and add functionality in one of the action hooks, which would allow you to pass an order anywhere also.

 

Both pretty flexible ...

Link to comment
Share on other sites

This would be awesome if I didn't get a lot of errors when I load the page for the first time

 

 

 

So I'm gonna have to break it down, tbh, its probably my PHP version, so I'll check it out and report back

 

That's because of:

if ($_POST["action"]=="submit") {

 

$_POST['action'] isn't defined if you call the script without any POST variables, so PHP throws a warning (unless you have error reporting turned to a lower level, or off).

Link to comment
Share on other sites

  • 1 month later...
  • 2 months later...
  • 5 months later...
  • 4 weeks later...
  • 2 weeks later...
  • 2 months later...
  • 2 weeks later...

I have successfully managed to use api to add a new customer and post the transaction and then we end up in the invoice view.

How could I take the new customer through to his selected payment gateway?

I am assuming it will be a goto setting in the final redirect url, but how do I find out what settings are available here?

Is there anywhere that i can find proper documentation on using the api. The documentation on the site is very basic and I find myself spending hours guessing at what would be easy to find if we only knew where to look.

 

Thanks in anticipation of help.

Link to comment
Share on other sites

How would one customize the group allocation of the client and also the admin notes:

 

Ive tried the following withou any luck:

 

$postfields["groupid"]= 2;

$postfields["notes"] = "Client Signed Up From X453";

 

unfortunly you can't set the groupid of a client with the api, the only fields you can use are there in the manual, if up need this i suggest you create you own function and update this field after the return of the native api!

Link to comment
Share on other sites

  • 2 weeks later...
  • 2 weeks later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated