Context
WordPress could not run what Corplify needed: a multi-step application tied to payment and admin review.
Corplify is a digital corporate secretary in Johor Bahru. Its team had no developer to bend WordPress and plugins around the workflow, and a custom build beat no-code tools on both speed and cost.
After the first release, the client asked for 3 more things: a portal for referral partners, identity checks on directors and shareholders, and the site in Bahasa Malaysia and Chinese.
The build
One portal covers the whole customer journey, from signup to a filed company. I built it in phases, and the Corplify team reviewed and reprioritised after each one instead of working to a single fixed spec.
- Accounts: signup and login with email OTP and optional 2FA.
- Application: a 5-step form with autosaving drafts and step restore. It now covers 11 services.
- Name checker: SSM company-name search, fuzzy-matched against a live registry.
- Payment gate: applications stay hidden from admin until Stripe confirms payment.
- Admin and comms: review, status tracking, bulk CSV updates, Excel export, status emails and a live chat with human escalation.


Partner portal
Partners refer clients, place orders for them, track their applications and withdraw their commission. 3 calls shaped it.
1 database, 2 views
A partner sees the same application rows as the customer, filtered by partner. Syncing orders between 2 copies drifts, so there is only 1 copy.
3 ways to link a client
A referral link does most of the work. A collapsed “Have a referral code?” field at signup catches links that messaging apps strip. Admin can assign a partner by hand for phone sign-ups. A wrong code never blocks signup.
Partners see less than customers
Partners get masked ID numbers (••••••-••-1234) and no date of birth, gender, race or address. So a partner can’t confirm company details they can’t see. The client confirms, and the partner sees the status.

Identity checks
Directors and shareholders have to prove who they are before Corplify files with SSM. 5 rules shaped the flow.
1. Pick a provider, don’t build one
Liveness and anti-spoofing need specialist tech, so I compared 4 providers. Didit won on cost.
| Provider | Pricing, checked Sept 2026 |
|---|---|
| Didit (chosen) | USD 0.33 a check, 500 free a month |
| iDenfy | USD 1.35 a check, USD 135 monthly minimum |
| Sumsub | USD 1.35 to 1.85 a check, USD 149 to 299 monthly minimum |
| Jumio | Quote only, est. USD 25,000 to 100,000+ a year |
2. Check the right people
Directors, plus shareholders holding 20% or more.
3. Move the check after payment
From 1 Nov 2026, Didit replaces 500 free checks with USD 10 of credit, about 30 checks. Checks before payment would spend that credit on people who never pay.
4. Staff choose the method
Per application, staff send Didit links in 1 email or arrange a video call. A live x/30 counter sits beside the button.
5. 2 fails, then stop
1 failed check shows a warning and 3 options: a new link, a review, or a video call. 2 fails mean no refund and a new application. I wrote this into the Terms and Refund Policy, and customers tick their agreement before submitting.
Translation
The customer site runs in English, Bahasa Malaysia and Chinese. One pass added 373 Malay and 477 Chinese strings. A script listed every translated string in the code and checked each one against the language files.
Emails stay English
The site doesn’t store each customer’s language, so translating at send time would use the admin’s language instead. Fixing that properly is its own project.
Trade-offs
Vanilla PHP, deliberately
No framework and no dependency manager, for full control and a clean handover. The Excel export shows the trade-off: hand-built XML SpreadsheetML instead of a heavier library, so there is nothing to install.
E-signing deferred, not built
A signature has to stand up as legal evidence, and that liability shouldn’t sit in a custom portal. It moves to after launch through a signing API, with SignWell the leading option.
Debugging under a live schema
Several production bugs traced back to one root cause: code assuming database columns that hadn’t been migrated yet, or reading data that had moved tables. A draft save failed silently, applications reopened on step 1, and the admin document viewer broke. Each fix named its root cause instead of patching around it.
Outcomes
Customer portal and partner portal both live.
No usage numbers yet.

Reflection
Shipping solo meant every call, and every fix, was mine. The schema bugs taught me to version the schema alongside the features, not behind them.
I first built the homepage “How it works” section to capture the mouse wheel, 1 step per scroll. With a real wheel, the page got stuck at step 1 and step 5. I removed the scroll lock and snapping. Readers own the scroll bar, which is why this page scrolls normally too.
Next
- E-signing through a signing API.
- Phase 3: marketing to grow the customer base.
Both portals are live. corplify.my
View live site
All work
Resume






