Adding Try-On to a Custom PHP Store
By the ZeDaq.ai team · · 4 min read
On this page
You can add virtual try-on to a custom PHP store in two ways: paste the ZeDaq.ai script-tag widget into your product template, or call the REST API from a PHP endpoint and build your own button. The widget is faster, and the API gives you full control of the interface.
This guide focuses on how try-on fits into a PHP store's structure. For the full overview, read the virtual try-on API guide for developers. For a line-by-line curl example, see calling the try-on API from PHP.
Which route should you pick?
Use this table to decide.
| Widget | REST API | |
|---|---|---|
| Effort | One tag in the template | A PHP endpoint plus front-end code |
| Interface | Provided: "Try it on" and "Find my size" | Yours to design |
| Key location | Browser, locked to your domain | Server only |
| Best for | Fast launch | Custom flows |
If your store has a shared product template, start with the widget. Move to the API only if you need something it does not do.
How do you add the widget route?
Paste this into your product template, for example the footer part of product.php:
<script src="https://www.zedaq.ai/widget/zedaq.js"
data-key="YOUR_WIDGET_KEY"
data-garment-type="upper_body"
defer></script>
Create the key in Dashboard → API keys and lock it to your store's domain. Unlocked keys are refused, because the key is visible in your page source. The widget docs list the options.
In PHP, set the garment type from your own data so each product gets the right value:
<?php
$type = $product['garment_type']; // upper_body, lower_body or dresses
echo '<script src="https://www.zedaq.ai/widget/zedaq.js"'
. ' data-key="' . htmlspecialchars(WIDGET_KEY) . '"'
. ' data-garment-type="' . htmlspecialchars($type) . '" defer></script>';
That one change gives every product page a button, and the shopper's photo goes through ZeDaq.ai, not through your server.
How do you add the API route?
With the API, your server calls ZeDaq.ai, and the browser calls your server. Never put the server key in front-end code.
The flow has four parts:
- A button on the product page that opens a file picker.
- An endpoint such as
/tryon.phpthat receives the photo and a product id. - A product lookup that finds the product image and garment type from your own database.
- The API call to
POST /api/v1/tryonwith thex-api-keyheader.
The request body is JSON with person_image_base64, product_image_base64 and an optional garment_type. A 200 response returns image_base64, and a 202 means you poll the poll_url. See the API reference for details.
What does the endpoint look like?
Here is a short outline. Use the helper from the worked example linked above to make the curl call.
<?php
$id = (int) ($_POST['product_id'] ?? 0);
$row = find_product($id); // your own lookup
if (!$row || empty($_FILES['photo'])) { http_response_code(400); exit; }
[$status, $data] = zedaq_request('POST', '/api/v1/tryon', [
'person_image_base64' => base64_encode(file_get_contents($_FILES['photo']['tmp_name'])),
'product_image_base64' => base64_encode(file_get_contents($row['image_path'])),
'garment_type' => $row['garment_type'],
]);
http_response_code($status);
echo json_encode($data);
Take the product image and garment type from your database, not from the request. Otherwise a visitor could send any image through your key.
How do you protect the endpoint?
A public endpoint that spends renders needs some guards:
- Validate the upload. Accept only JPEG or PNG files and set a size limit.
- Add a CSRF token or other request check from your framework.
- Limit requests per session or address.
- Keep the key out of logs and templates.
- Show calm error messages. Map API error codes to friendly text.
The API's usage counts against your plan, and Free includes 3 try-ons a month. See pricing for paid plans, which start with Micro at $14 a month and include a 3-day free trial with no card required.
How do you add sizing as well?
The widget already adds "Find my size". To use your own size labels, enter your size guide in Dashboard → Size charts, one chart per garment type.
If you use the API, the scan and size-chart endpoints are described in the reference. Compare this PHP route with the way other stacks do it in try-on for WooCommerce, Magento and custom stores and the Django version.
If your front end is a JavaScript app, read about adding try-on to a React storefront, which pairs well with a PHP back end.
Get a key and try it on your own product pages
FAQs
Do I need Composer packages?
No. Curl and standard PHP functions are enough for the API route, and the widget needs no PHP code at all.
Where should the API key live?
Keep the server key in an environment variable or a config file outside your web root. Only a domain-locked key belongs in a page.
Does the widget work on a custom site?
Yes. It is built for WooCommerce, Wix, Squarespace, BigCommerce and custom sites, as long as the key is locked to your domain.
What if the render takes a while?
The API may return 202. Poll the given URL about every 2 seconds, and set a maximum number of tries.
Try ZeDaq.ai free
Virtual try-on and Find my size for your store, plus client, order and invoicing tools for tailors, in one subscription.


