Move to App (Vouchers)
Description / Background
To enhance user engagement and promote mobile app usage, we’ve updated our promotional offer policies on the website. Moving forward, only restaurant-subsidized vouchers will be accepted on the website, while gift card redemptions and platform-subsidized vouchers will be available exclusively through the Hungry Hub mobile app. To support this transition, we’ve added a banner announcement and updated the wording across both desktop and mobile versions of the website to clearly communicate these changes.
Objectives
- user can see the move to app banner on store page, cart, checkout page, profile, my offers and gift card page, and homepage
- user can see the
(Points can be earned and used only for App bookings)text when sign up using app - Only display the banner for active user account, not for inactive accounts
- Admin can set restaurant to
accept only restaurant subsidized voucher? (only for website)
_20250827155322_image_9a4038d9_6566.png)
- Admin can't implement both
accept only restaurant subsidized voucher? (only for website)andaccept booking without package?at the same restaurant setting
Scope
banner on store page, cart, checkout page, profile, my offers and gift card page, and homepage
How to set Move to App
- Open Admin Dashboard
- Open Restaurants → Restaurant List
- Pick the restaurant → click edit
_20250827155322_Screenshot_from_2025-07-17_14-24-20_e417dd23_3886.png)
- Checked on
Accept Restaurant-Subsidize Voucher? (only for website)
_20250827155322_image_31084f8c_1398.png)
- Save the setting
Sequence Diagram / Flow
-
ERD
_20250827155322_booking_dev_-_restaurant_voucher_settings_0886b686_4416.png)
Backend Implementation
- New table
restaurant_voucher_settingswith fieldaccept_subsidize_voucher(boolean). - Linked to
Restaurantvia a one-to-one (has_one) association. - Migration and data backfill script for existing restaurants.
- Associations:
Restaurantnow hashas_one :voucher_setting.- Accepts nested attributes for
voucher_setting.
- Form Update:
- Admin form includes a checkbox to toggle “Accept Restaurant-Subsidize Voucher? (only for website)”.
- Validation:
- Validation prevents enabling both “accept booking without package” and “accept restaurant-subsidize voucher” at the same time.
- Automatic Setting Creation:
- When a restaurant is created, a corresponding
RestaurantVoucherSettingis automatically created.
- When a restaurant is created, a corresponding
voucher_usable_on_website?(voucher)in the voucher form checks:- If a feature flag (
:enable_move_voucher_to_app) is OFF, all vouchers are usable everywhere. - If ON:
- On the web, only allow use if the restaurant both accepts subsidized vouchers and the voucher is subsidized by the restaurant (not HungryHub).
- Otherwise, restrict usage to app only.
- If a feature flag (
- Returns a translated error if a voucher is not usable on the web.
- New Helper Methods In
Voucher, added:-
* `subsidized_by_restaurant?`subsidized_by_hungryhub?
-
- Serializers (partner, v5, history) now expose
accept_subsidize_voucherso clients (web/app/frontend) can know if the restaurant allows these vouchers. - Voucher validation now takes a
client_typeparam, defaulting toweb. - Added
not_usable_on_websitemessage to English, Thai, and Chinese locales for when a voucher is not valid on the website. - Adds new images for Hungry Points and Referral programs, tailored per country and language (English and Thai).
-
* `hh-hungry-points-all-countries-en.png`, `hh-hungry-points-all-countries-th.png`hh-hungry-points-sgp-en.png,hh-hungry-points-sgp-th.pnghh-hungry-points-tha-en.png,hh-hungry-points-tha-th.pnghh-referral-all-countries-en.png,hh-referral-all-countries-th.pnghh-referral-sgp-en.png,hh-referral-sgp-th.pnghh-referral-tha-en.png,hh-referral-tha-th.png
-
- Improves the
registration_confirmationmethod:- Uses
User.find_byinstead ofUser.findfor safer user lookup. - Adds error handling if the user is not found.
- Refactors mail and logging logic for better reliability.
- Uses
- Updates SQL query in the voucher transaction logic for clarity and correctness.
- Adds error handling for phone validation and logging in user model.
- Adds two new instance methods:
thai_phone_number?: Checks if the user’s phone is a valid Thai number.singapore_phone_number?: Checks if the user’s phone is a valid Singaporean number.
- Improves phone validation by adding error handling and more robust error reporting.
- Refactors how phone validation errors are added to provide clearer messages.
- Email Template Updates
- Points Expiration Emails (CN, EN, TH):
- Replaces images of points with new, country-agnostic images (
hh-hungry-points-all-countries-en.png, etc.).
- Replaces images of points with new, country-agnostic images (
- Voucher Confirmation Emails:
- Adds a note under the gift card button stating that "Gift Card applies only for App bookings" (with a Thai translation for the TH template).
- Welcome Email (
welcome-to-hungry-hub-2022.html.erb):- Changes points image to the new country-agnostic image.
- Dynamically selects the referral image based on the user’s phone number—shows the Thailand, Singapore, or all-countries image as appropriate.
[
github.com
https://github.com/hungryhub-team/hh-server/pull/6839/files
](https://github.com/hungryhub-team/hh-server/pull/6839/files)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/6889
](https://github.com/hungryhub-team/hh-server/pull/6889)
Hybrid Implementation
- A reusable banner (
SuggestUseApp) is added to various booking and restaurant pages, prompting users to use the Hungry Hub app for more benefits (like earning/using points, redeeming gift cards, and applying promo codes). - Clicking the banner (on desktop) opens a modal popup (
SuggestUseAppPopup) with app store links and promotional graphics. - New images are added for app store badges and the promotional banner.
- The
SuggestUseAppbanner/component is now shown on:- Booking pages (desktop and mobile)
- Booking confirmation page
- Restaurant detail pages (mobile)
- Search and top brands entry points
- In the featured program sections for restaurants, a note is added:
"Earn and use points, apply promo codes, and redeem gift cards — only for app bookings"
- In the booking flow, mobile and desktop layouts are updated to include the new promotional banner at key points.
- Voucher Validation: The client type is now sent as part of the voucher validation payload, allowing the backend to identify if the booking is from web, Android, or iOS.
- Global Store Link: Introduces a universal app store link (
UNIVERSAL_STORE_LINK) for easier redirection. - Store Updates:
- Adds a new
acceptSubsidizeVoucherboolean property to the restaurant detail store to support subsidized vouchers.
- Adds a new
- Refactors how initial data (like client type, language, and domain) is set for API requests across multiple entry points.
- Adds new translation keys and updates language files in all supported languages for:
- The new app-only promotional message
- Pop-up titles and banners
- Other minor clarifications and corrections in the booking/restaurant text.
- When the restaurant supports subsidized vouchers and the user is not in hybrid (app) mode, the promo entry area now shows:
"Apply restaurant promo code here"
[
github.com
https://github.com/hungryhub-team/hh-pegasus/pull/1830/files
](https://github.com/hungryhub-team/hh-pegasus/pull/1830/files)
PRD & Task
PRD: Private (https://app.clickup.com/9003122396/docs/8ca1fpw-7922/8ca1fpw-51796)
Private (https://app.clickup.com/t/86cz67f9y) Private (https://app.clickup.com/t/86czhe0tw)
Design
[
www.figma.com
https://www.figma.com/design/E2sAC4MSEFIe6vigVXDowz/Move-to-App?node-id=0-1&t=bQsa850AKgXmNVFF-1
](https://www.figma.com/design/E2sAC4MSEFIe6vigVXDowz/Move-to-App?node-id=0-1&t=bQsa850AKgXmNVFF-1)
API Blueprint
| Method | Path | URL | Description | Payload |
|---|---|---|---|---|
| all | partner, v5, history | add new params accept_subsidize_voucher so clients (web/app/frontend) can know if the restaurant allows these vouchers |
New Query
DB Schema / Database Migration
New table restaurant_voucher_settings with field accept_subsidize_voucher (boolean).
Improvement:
| Feature Name | Date | What Changed | Description |
|---|---|---|---|