Student pricing, inside your own checkout.
Two lines of HTML. We verify the student, issue a code that belongs to them alone, and fill your discount field with it. There is nothing to build and nothing to store.
<script src="https://theunideals.com/sdk/v1.js" data-key="pk_live_YOURKEY" defer></script>
<div data-tud-widget data-tud-input="#discount-code"></div>
Swap pk_live_YOURKEY for the key we issue you, and #discount-code for the selector of your own discount input.
Try it yourself.
The button below is the real widget, loaded from the real script, wired to a demo shop. Claim a code and watch it land in the discount box.
- Cotton hoodie, size M
- Rs 4,500
- Delivery
- Rs 250
- Total
- Rs 4,750
What your page sees
Every claim fires a tud:code event on the widget element, whether or not you pointed us at an input. This panel is listening to it.
Waiting for tud:code
Nothing here is charged, stored or sent anywhere. The demo shop is ours.
The whole surface.
Four things exist. That is the entire API.
| Name | What it does |
|---|---|
data-tud-widget |
Marks an element as a mount point. We render the button inside it. Put as many on a page as you like. |
data-tud-input |
A CSS selector for your discount input, on the same element as data-tud-widget. When a code arrives we set the value, then fire input and change so React, Vue, Shopify and jQuery listeners all pick it up. Optional. |
tud:code |
A bubbling CustomEvent dispatched on the widget element, with detail: { code, offerId }. Fires on every claim, with or without data-tud-input. |
data-tud-custom |
Bring your own button. We render nothing; the element marked data-tud-trigger inside the widget opens the claim window, so the button inherits your design completely. |
data-tud-apply="shopify" |
Shopify stores only: when the code arrives we route it through your store's discount link, so it attaches to the checkout with no typing. An element with class tud-applied inside the widget is revealed on the way back. |
window.TheUniDeals |
Set to { version: '1', reportOrder } once the script has loaded. Use it to check the widget is present. |
TheUniDeals.reportOrder(opts) |
Called on your thank-you page with { orderId, subtotal, currency, code } to report a completed order. code is optional and defaults to the last code the widget delivered, but that default only works when the call runs on the same page the widget ran on; pass code explicitly on a separate thank-you page. Called from the browser, the order is recorded but never billed: report it again from your own server, signed with your partner secret, to count it toward commission. Returns a promise that resolves { ok: true } or rejects with the API's error. |
Doing your own thing with the code
document.addEventListener('tud:code', function (event) {
var code = event.detail.code;
var offerId = event.detail.offerId;
applyDiscount(code); // your own cart call
});
On Shopify, in your own code
The app's theme block is the no-code way in. If you would rather place it yourself, in a custom liquid section or an older theme, paste this anywhere in your templates. The button uses your theme's own button class, the discount applies at checkout automatically, and the small applied message takes the button's place afterwards.
<div data-tud-widget data-tud-custom data-tud-apply="shopify">
<button type="button" class="button" data-tud-trigger>Get the student price</button>
<p class="tud-applied" hidden>Student discount applied at checkout</p>
</div>
<script src="https://theunideals.com/sdk/v1.js" data-key="pk_live_YOURKEY" defer></script>
The event bubbles, so you can listen on the widget, on a container, or on the document.
Report the order
Commission is only ever computed from what is reported back to us. An order nobody reports is never charged. Pass the code explicitly: checkout usually redirects to a separate thank-you page, and by then the widget's in-page memory of the code is gone, so render the order's own applied discount code into the page yourself, on the server, and hand it to the call:
TheUniDeals.reportOrder({
orderId: '1001',
subtotal: 4500,
currency: 'PKR',
code: 'SAVE20-AB12' // printed into the page by your server, from the order's own applied discount code
})
.then(function () { /* reported */ })
.catch(function (err) { /* log it; do not block checkout on it */ });
subtotal is before tax and delivery. The code must have been revealed to a student in the last 30 days. Omitting code falls back to the last code the widget delivered, and that fallback only works when reportOrder runs on the same page the widget delivered it on; a navigation to a separate thank-you page has no such value, so pass code there.
That browser call is recorded, not billed. Your public key sits in your page source in plain sight, so anyone could open dev tools and call reportOrder themselves; a browser call alone cannot prove an order is real, so we log it but never charge for it. To be billed, report the same order again from your own server, signed with your partner secret.
Find your secret in the partner portal, on the Widget tab. Compute an HMAC-SHA256 of the exact JSON body you send, using the secret as the key, and send the hex digest as an X-TUD-Signature header, shaped sha256=<hex>. Post it to https://api.theunideals.com/v1/partners/{key}/orders, the same address the browser call uses. In Node:
var crypto = require('crypto');
var https = require('https');
var key = 'pk_live_YOURKEY';
var secret = process.env.TUD_PARTNER_SECRET; // from the partner portal, Widget tab
var body = JSON.stringify({
order_id: '1001',
code: 'SAVE20-AB12',
subtotal: 4500,
currency: 'PKR'
});
var signature = crypto.createHmac('sha256', secret).update(body).digest('hex');
var req = https.request('https://api.theunideals.com/v1/partners/' + key + '/orders', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(body),
'X-TUD-Signature': 'sha256=' + signature
}
}, function (res) {
var chunks = '';
res.on('data', function (c) { chunks += c; });
res.on('end', function () { console.log(chunks); });
});
req.write(body);
req.end();
Or in PHP:
<?php
$key = 'pk_live_YOURKEY';
$secret = getenv('TUD_PARTNER_SECRET'); // from the partner portal, Widget tab
$body = json_encode(array(
'order_id' => '1001',
'code' => 'SAVE20-AB12',
'subtotal' => 4500,
'currency' => 'PKR'
));
$signature = hash_hmac('sha256', $body, $secret);
$ch = curl_init('https://api.theunideals.com/v1/partners/' . $key . '/orders');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'X-TUD-Signature: sha256=' . $signature
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
Signed or not, the response is the same shape. An unsigned report comes back { ok: true, verified: false }: recorded, but not billed. A signed one comes back { ok: true, verified: true } and counts toward commission. If you run on WooCommerce or Shopify, you do not need any of this: the plugin and the app sign every order for you.
Why a public key is safe.
Your key sits in your page source, in plain sight. It identifies you. It authorizes nothing.
- Codes only go where you said. You register the exact origins that may receive a code. Our claim window checks that list on our server, on our domain, before it hands anything back. A copy of your key pasted on another site claims nothing.
- Every code has a name on it. A student signs in and passes verification before any code is issued, and every reveal is logged against that account with your shop recorded beside it. If a code turns up on a deals forum, we know whose it was.
- Codes do not multiply. A pooled code binds to the first student who reveals it and never moves. Repeat reveals return that same code, and each account is capped at three reveals per offer and fifteen a day across everything on The Uni Deals.
-
Your page stays yours.
The script sets no cookies, writes nothing to storage, and loads no fonts or stylesheets. It makes no network call of its own beyond the
reportOrdercall you choose to make on your thank-you page, which carries no cookies either. Sign-in happens on theunideals.com, in a window we serve.
Tell us where the widget goes.
Email us your shop name, the offer you want to run, and the exact origins the button will live on, like https://shop.yourbrand.pk. We issue the key and you are live the same day.