Testing
Certify against UAT, then switch hosts. Request and response contracts are identical between environments — only the hosts and credentials differ.
Before you have credentials
Two things can be verified entirely offline:
Your signing implementation. Sign a BDATA string with your private key and verify it with your
own certificate. If that round trip passes but Cheggout still reports Signature Mismatch!, the
problem is in your application code rather than your keys. See
Key generation.
Your parsers. Feed your response handlers each of the four error shapes plus the success shapes, and confirm none of them throws. Include an unsigned failure body — this catches the common bug where signature verification runs before the failure check.
Test data
TBD Seeded test data and test credentials are not published. There are no standard test users, no reference campaigns and no sample offers you can rely on.
Ask Cheggout to configure, in UAT:
- A campaign for your channel with a known trigger code
- At least one campaign that reliably returns a reward, and one that reliably returns none
- Deals offers with known stock, including one at zero stock
- An offer with a
purchase_limitlow enough to hit
Without the second item you cannot test your "no reward" path, which is the path users will hit most often.
What to verify per module
Authentication
- A signed request is accepted
- A deliberately corrupted
SIGNis rejected withSignature Mismatch! - Cheggout's response signature verifies
- An unsigned failure body does not crash your client
- A
401triggers exactly one re-mint and one retry, then gives up
Scratch cards
- Reference token is fetched on a schedule and cached, not per request
-
GetRewardcreates a card and returns tracking URLs - Replaying the same
extTransactionIdreturns the same cards - An empty
rewardsarray renders nothing and raises no alert - Reveal returns a reward and it is persisted before rendering
-
BETTER LUCK NEXT TIMEshows your no-luck state - A second reveal of the same card returns
REWARD NOT FOUNDand your code recovers via history - Both
couponTypevariants render — a points reward has no coupon code - Impression fires on display; click fires on scratch
- Reward history paginates and terminates correctly
Deals and coupons
- Catalogue is cached and served from cache
- Inventory is re-checked within its TTL before a buy action
- Zero stock disables the buy action
- Coins are burned before delivery is requested
- Every delivery error path either retries with the same reference or refunds
-
COUPON_EXHAUSTED,NON_ELIGIBLE,MAX_LIMIT_REACHEDandINVALID_OFFEReach refund - Coupons are persisted at delivery
- Reconciliation via
getUserCouponsmatches your ledger
Marketplace and SSO
- A session is minted only after your own authentication succeeds
-
virtualIdandsessionIdare passed together at launch - The user lands inside Cheggout with no login prompt
- Back and home return control to your app as expected
- A deliberately wrong
sessionIdfails cleanly rather than hanging
Advertisement
- Placements render in both logged-in and pre-login states
- Impression fires when a banner becomes visible, not when it is merely loaded
- Click fires and opens the right destination
- Rotating banners honour the returned duration
- Missing or empty placement responses degrade gracefully
Failures teams hit first
| Symptom | Cause |
|---|---|
Signature Mismatch! on every call | Signing the decoded JSON instead of the Base64 BDATA string |
401 on reveal, but creation works | Sending the reference token where the user token is required |
| Client throws on an error response | Verifying the signature before checking for the failure shape |
| A field silently missing | Wrong key case — several payloads match case-sensitively |
| Request never reaches the API | Egress IPs not whitelisted |
| "No reward" treated as an outage | Empty rewards is a success, not an error |
| Reward lost after a crash | Not persisting the reveal response before rendering |
| Duplicate cards after a retry | Generating a new extTransactionId instead of replaying the old one |
| Points reward renders blank | UI assumes a coupon code exists |
Load and resilience
TBD No rate limits, quotas or SLA are published, so a load test could trip an undocumented limit. Agree expected peak volumes and any load-testing window with Cheggout before you run one.
Resilience checks worth doing regardless:
- Simulate a timeout on reveal and confirm your code reconciles through history rather than retrying blindly.
- Simulate a delivery failure after a coin burn and confirm the refund path runs.
- Expire a token deliberately and confirm the refresh-and-retry-once path works.
- Return an unexpected body and confirm you log it and fail safely rather than crashing.
Before you switch to production
Run through the go-live checklist. Then read Production rollout for phasing and monitoring.