1. Go to this page and download the library: Download uengage.io/php-platform-sdk library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
uengage.io / php-platform-sdk example snippets
use Uengage\PlatformSdk\Client;
$platform = Client::create([
'serviceId' => 'edge-zones-admin',
'serviceSecret' => getenv('EDGE_ZONES_ADMIN_SECRET'),
]);
// Zones - the new spatial primitive
$zone = $platform->zones->create([
'geometry' => [
'type' => 'Polygon',
'coordinates' => [[
[77.5, 12.9], [77.6, 12.9], [77.6, 13.0], [77.5, 13.0], [77.5, 12.9],
]],
],
'tags' => ['type' => 'delivery-area', 'city' => 'BLR'],
]);
$matches = $platform->zones->containing([
'point' => ['lat' => 12.97, 'lng' => 77.59],
'tags' => ['type' => 'delivery-area'],
]);
// Business read
$record = $platform->business->get(42, ['profile']);
// Groups: profile, branding, locale (public); compliance, address, contact, hours, slots,
// order_types, delivery, charges, attributes, app_config, payment_gateway, bank (need grants).
// Audit (buffered; flushed at shutdown or on demand)
$platform->audit->record([
'event_type' => 'business.profile_updated',
'tenant' => ['id' => '42', 'parent_id' => null],
'actor' => ['type' => 'service', 'id' => 'edge-zones-admin'],
'resource' => ['type' => 'business', 'id' => '42'],
'changes' => ['name' => ['before' => 'Old', 'after' => 'New']],
]);
$platform->audit->flush(); // optional; shutdown hook will best-effort flush
// Wallet — getWallet(...) returns a handle bound to one business.
// Needs wallet.balance:read (reads) / wallet.transactions:read|write (writes).
// Service ids: use Uengage\PlatformSdk\Wallet\Services (RECHARGE, SMS_CAMPAIGN,
// WHATSAPP_CAMPAIGN, FLASH_DELIVERY, EMAIL, PRISM_AI, WHATSAPP_ALERT, SMS_ALERT).
$wallet = $platform->wallet->getWallet(['id' => 'business:8841']);
$balance = $wallet->getBalance(); // ['balance'=>float, 'balanceMinor'=>int, 'currency'=>[...], 'source'=>..]
$currency = $wallet->getCurrency(); // ['code'=>'INR', 'symbol'=>'₹']
// getBalance() answers with what the business can still SPEND. For a
// merchant on the credit line that is their available credit, and
// 'source' says so ('wallet_balance' | 'credit_line') — so a caller that
// only pre-checks a balance before allowing a charge needs no change.
// On a dashboard, START HERE — wallet balance or credit line?
$o = $wallet->getOverview(); // ['mode' => 'prepaid'|'credit', 'balance' => [...], 'creditLine' => [...]]
// See "Wallet + credit line" below for the rest of the surface.
$txn = $wallet->credit([ // or ->debit([...])
'referenceId' => 'order-12345', // idempotency key
'amountMinor' => 1180, // ₹11.80, in integer minor units of the wallet currency
'service' => Services::RECHARGE, // legacy service_id; see Wallet\Services
'description' => 'wallet top-up',
'tags' => ['source' => 'edge'],
// 'reversalOf' => '<debit id>', // on credit → a refund capped by that debit
// 'isRefund' => true, // on credit → refund:1, uncapped, no link
// 'paymentId' => '', // on credit; '' is stored verbatim
// 'allowNegative' => true, // on debit → permit overdraw
// 'rto' => false, // on debit
// Legacy-ledger passthroughs, written as TOP-LEVEL ledger fields:
// 'taskId' => 'TASK-9912', // → task_id + transaction_order_id
// 'units' => 1, 'serviceBaseCost' => 38.5, // serviceBaseCost is MAJOR units
// 'updatedBy' => 'PetPooja', // → updated_by; `actor` still records the client
// 'occurredAt' => '2026-07-01 10:15:00', // IST; dates the CHARGE, not the write
// // (backfills/replays) — ≤90 days back, never future
// 'wallet' => ['parentBusinessId' => '100', 'childBusinessId' => '500'],
// // names the wallet outright, bypassing routing;
// // parentBusinessId is asserted, not filtered on
// // (409 wallet_identity_mismatch if it disagrees)
]);
$page = $wallet->listTransactions(['type' => 'debit', 'limit' => 20]); // keyset-paginated
$one = $wallet->getTransaction($txn['id']);
$messageId = $platform->alerts->raise([
'type' => 'wallet.low_balance', // category is derived, never sent
'title' => 'Wallet balance low',
'description' => 'Balance fell below the configured threshold.',
'tenant' => ['parentId' => 7175, 'businessId' => 38112], // int or string
'notify' => false, // optional, default false
'context' => ['balanceMinor' => 12050, 'currency' => 'INR'], // optional, flat
]);
$page = $platform->alerts->list([
'businessId' => 38112, // at least one of businessId, parentId, type, category, status, userId, notify => true
'status' => 'open', // open | resolved | muted
'limit' => 25, // 1-100
]);
foreach ($page['items'] as $alert) { /* ... */ }
$next = $page['nextCursor']; // pass back as 'cursor'; null on the last page
// Every alert of one identity, newest lastSeenAt first: current and resolved ones.
$history = $platform->alerts->list(['businessId' => 38112, 'type' => 'wallet.low_balance']);
// Alerts whose latest message had notify on (false = no filter).
$bell = $platform->alerts->list(['notify' => true, 'status' => 'open']);
// Only alerts this dashboard user can see (their id is in the alert's userIds).
// Counts as a filter on its own and combines with the others. Trusted like
// `actor`: your backend decides which user it is acting for.
$mine = $platform->alerts->list(['userId' => $dashboardUser->id, 'status' => 'open']);
$alert = $platform->alerts->get($alertId);
$platform->alerts->setStatus($alertId, [
'status' => 'resolved', // open | resolved | muted
'comment' => 'Wallet topped up', //
try {
$platform->alerts->setStatus($alertId, ['status' => 'open', 'actor' => $user]);
} catch (\Uengage\PlatformSdk\Alerts\AlertsApiException $e) {
if ($e->getErrorCode() === \Uengage\PlatformSdk\Alerts\AlertsClient::ERROR_NEWER_ALERT_OPEN) {
$current = $e->getNewerAlertId(); // act on this one instead
}
}
// 1. Which slots does this screen have? Once per screen, cacheable.
$placements = $platform->upsell->placements([
'channel' => 'whitelabel_web',
'parentId' => 5, // the brand
'businessId' => 6, // the outlet being ordered from
]);
// 2. What goes in one? Re-ask whenever the cart changes.
$result = $platform->upsell->suggest([
'channel' => 'whitelabel_web',
'placement' => 'cart_recommendation',
'tenant' => ['parentId' => 5, 'businessId' => 6],
'context' => [
'cart' => [
'subtotal' => 500,
'items' => [
[
'itemId' => 101,
'qty' => 1,
'unitPrice' => 400,
'itemSlug' => 'margherita',
'sectionName' => 'Pizzas', // drives category no-repeat
'veg' => 1, // drives the dietary rule
],
],
],
'fulfilmentMode' => 'delivery',
'sessionId' => session_id(),
],
]);
if ($result['items'] === []) {
return ''; // a normal answer — render nothing at all
}
// 3. Report what happened. Fails open — no try/catch needed: a timeout,
// an expired token or a 500 is logged and returns ['accepted' => 0].
$platform->upsell->reportEvents([
'channel' => 'whitelabel_web',
'placement' => 'cart_recommendation',
'tenant' => ['parentId' => 5, 'businessId' => 6],
'sessionId' => session_id(),
'configVersion' => $result['meta']['configVersion'],
'events' => [
['type' => 'shown', 'itemId' => 48346322, 'reasonCode' => 'popular_now'],
['type' => 'added', 'itemId' => 48346322],
],
]);
$o = $wallet->getOverview();
if ($o['mode'] === 'credit') {
$o['creditLine']['limit']['amountMinor']; // net of GST
$o['creditLine']['band']; // normal|warning|critical|blocked
} else {
$o['balance']['balanceMinor']; // prepaid: the wallet balance
}
$line = $wallet->getCreditLine(); // 404 credit_line_not_found if prepaid
$line['consumed']; // net, UNPAID — spans months
$line['available']; // limit − consumed
$line['estimatedInvoice']['total']; // exact, from recorded GST — not consumed × 1.18
$wallet->setCreditLimit([ // wallet.credit:write
'referenceId' => 'admin:limit:1200:2026-09-02', // idempotency key
'limitMinor' => 10000000, // ₹1,00,000, NET of GST; 0 blocks
'onBehalfOf' => 'user:4471', // ditEvents(); // limit changes + settlements
$wallet->listCreditEvents(['limit' => 200]); // the service defaults to 50
$platform->wallet->getCreditUtilisation(['band' => 'warning']); // cross-merchant
} catch (WalletApiException $e) {
if ($e->errorCode() === 'credit_limit_reached') {
$f = $e->creditFigures();
if ($f['availableMinor'] > 0) {
// Limit NOT used up — this ONE charge is larger than what is
// left. A smaller order would go through; do not send them to
// their account manager.
}
// Otherwise the ceiling is reached — possibly from unpaid
// invoices rather than this month's spend.
}
}