Repository navigation
v4.5.0 - Touchpoints 2.0: Server-Composed Touchpoint Serve API
PlaySuper Unity SDK v4.5.0
Touchpoints 2.0. A new, server-composed touchpoint API. Your game asks for the screen it is about to show, and PlaySuper answers with the frame artwork the studio chose in the console and one concrete offer already composed into it, priced for that player with the coin maths done. The game draws two images and opens a URL. Nothing to walk, nothing to interpret.
What's New
🎯 TouchpointV2Manager.Serve — one call per screen
using PlaySuperUnity;
var tp = await TouchpointV2Manager.Serve(TouchpointV2Manager.Screens.Home);
if (tp == null)
{
// The request itself failed (SDK not initialised, network, non-2xx). Already logged.
return;
}
if (!tp.HasTouchpoint)
{
// Nothing configured for this screen, or no catalogue item available right now.
// This is a normal state, not an error — draw nothing.
return;
}
// Frame + offer art
frameImage.LoadFromUrl(tp.FrameImageUrl); // tp.asset.imageUrl
offerImage.LoadFromUrl(tp.OfferImageUrl); // tp.item.imageUrl
// Copy
titleText.text = tp.item.title;
ctaButton.text = tp.item.cta.label; // e.g. "Claim now"
// Tap → store, landing on this exact offer with attribution intact
ctaButton.onClick.AddListener(() => TouchpointV2Manager.OpenCta(tp));Serve(screen, type, utmSource, utmMedium, utmCampaign) hits GET /v2/touchpoints/serve and returns a TouchpointV2Response. Only screen is required.
screen— useTouchpointV2Manager.Screens.Home.homeis the only live screen in this release; other slugs are rejected with a 400 that names the valid ones.type— optional filter fromTouchpointV2Manager.ItemType(Product,Coupon,GiftCard). Only needed when the studio has placed more than one kind of offer on the same screen; the API rejects an ambiguous call rather than picking for you.utmSource/utmMedium/utmCampaign— optional. Appended server-side to the CTA URL.
📦 A response you can render directly
| Field | What it is |
|---|---|
asset |
The frame. imageUrl, orientation (PORTRAIT / LANDSCAPE), source (PRESET / UPLOAD), optional width / height. |
item |
The offer inside the frame. type (PRODUCT / COUPON / GIFT_CARD), title, subtitle, brandName, imageUrl, pricing, coins, offerText, cta. |
item.pricing |
currency, mrp, price, priceAfterCoins, discountPct. All computed server-side for this player and this game's coin. discountPct is the pre-coin MRP → price badge; the coin saving is reported separately. |
item.coins |
coinsRequired, coinDiscount, plus coinId / coinName / coinImageUrl. Null when this game's coin cannot be spent on the item or the saving rounds to nothing. |
item.offerText |
Pre-formatted coupon line, e.g. "Flat 40% off up to ₹200". Display as given. |
item.cta |
label and an absolute store url with attribution already appended. |
placementId, servedAt |
The console placement this came from and when the server composed it. |
Convenience properties on the response: HasTouchpoint, FrameImageUrl, OfferImageUrl, IsPortrait.
🔗 TouchpointV2Manager.OpenCta — open the store at the offer
Hands the CTA's own URL to OpenStore, so the player lands on the item they tapped rather than the storefront. The URL already carries the campaign attribution the server appended, and OpenStore reads it back off. Build the URL yourself and that attribution is silently lost for every touchpoint you open.
👤 Player-aware pricing
When a player is signed in, the SDK sends their token with the request and the offer comes back priced for them. An anonymous call still returns a touchpoint, just without player-specific pricing. Either way, no arithmetic in the game.
Behaviour to Know
nullmeans the call failed.HasTouchpoint == falsedoes not. A screen the studio hasn't configured, or one with no catalogue item currently available, is a200with emptyassetanditem. CheckHasTouchpointbefore drawing; don't null-test the response for that.assetanditemarrive together or not at all. A frame with an empty centre is never served, soHasTouchpointis a single check.- Unknown screen → the 400 body is logged, not just the status code. It lists the screens that would have worked.
- Query parameters are escaped, so a UTM value carrying
&or a space cannot truncate the request. - Console setup is required. A touchpoint is only served once the studio has an active placement for that screen in the PlaySuper console. Until then
Servesucceeds andHasTouchpointisfalse.
Upgrade Notes
- Purely additive. No breaking API changes. Drop-in replacement for v4.4.x.
- No code changes required in your game unless you adopt Touchpoints 2.0.
- The v1
TouchpointManageris unchanged and still available. Touchpoints 2.0 is the recommended path for new integrations. - No manifest, Gradle, Info.plist or permissions changes.
- No store-side changes required.
- Android and iOS behaviour is otherwise unchanged.
- The PlaySuper docs and console integration step gate Touchpoints 2.0 on SDK 4.5.0 or later. Confirm
package.jsonreports4.5.0after updating.
Under the Hood (for developers)
- New file:
Runtime/TouchpointV2.cs. Everything in this release lives here: theTouchpointV2*response types (mirroring the server'sServeTouchpointResponseDtofield for field), the internal API wrapper, and the staticTouchpointV2Manager. - Endpoint:
GET {baseUrl}/v2/touchpoints/serve?screen=…[&type=…][&utm_source=…][&utm_medium=…][&utm_campaign=…]withAccept: application/json,x-api-key, andAuthorization: Bearerwhen a player token is present. - Transport:
UnityWebRequestawaited viaTask.Yield(); response parsed with Newtonsoft.Json. Nullable fields useNullValueHandling.Ignore. - Naming: the screen constants class is
Screens, notScreen, to avoid shadowingUnityEngine.Screenin any file withusing UnityEngine. - Version:
package.jsonbumped4.4.0 → 4.5.0.