Singapore Expansion
Description / Background
Singapore expansion
Glossary
Private (https://app.clickup.com/9003122396/docs/8ca1fpw-35796/8ca1fpw-41516)
Objectives
- Singaporean citizen can book on hungryhub web and app
- User can sign up using singaporean phone number
- User can see singapore on dropdown city list
- User can see singaporean restaurant when they pick singapore as the city
- User can see singaporean restaurant when their phone number was singaporean
- User can see the price on singapore dollar when their phone number was singaporean
- User can book prepaid booking using "PayNow"
- User can book prepaid booking
- User can pay booking using omise payment
- User can see the singaporean location tag
- User can receive point by booking on singapore restaurant
- User can redeemed the singapore point on singapore restaurant
- User can't redeemed the singapore point on thailand restaurant
- User can see the country flag on the point profile page

- User can see the country flag on the promo code

- User can see the country flag on the gift card

- User can get point from referral code with this condition:
- The referral code currency will follow the sender phone number country currency
- If the sender phone number is not SG or TH, it will use THB currency as default
- Admin can create singaporean restaurant
- Admin can create package for singaporean restaurant
- Admin can set the price to Singapore Dollar if the restaurant is Singaporean Restaurant
- Admin can add singaporean location tags
- Admin can create seven room and table check restaurant for the Singaporean restaurant
- The package price currency will followed the restaurant based setting
- Point setting will followed the restaurant country
- All singapore package can't use we travel together
Scope
All
Booking Point Logic
| Country | Thailand | Singapore |
|---|---|---|
| Total Spend | 100 Baht | 1 dollar |
| Get Point | 1 | 1 |
| Point Value | 1 baht | 1 cent |
The tier calculation will be done by counting for all booking from Singapore and Thailand restaurant, but the point will be separated, when booking from Singapore restaurant will receive Singapore point, and Thailand restaurant booking will receive Thailand point.
List of Hidden / Disabled Feature
-
* Create Saved CC
Location
All Platform
Sequence Diagram / Flow
ERD
-
Android Implementation
- Modernizes and improves the user experience by making city and service type selection dynamic, enhances UI/UX for restaurant sections, standardizes currency/price display, and introduces multiple new visual elements.
- Refactors code for maintainability and scalability as more cities and service types are added to the platform.
- Enables the CheckoutPayload model to store and handle a country code, likely to support features or requirements dependent on the user's country during checkout. The new field is integrated with JSON serialization, making it compatible with backend APIs expecting or sending a country code as part of the checkout payload.
- Improving the PromptPay payment UI and logic, especially to properly support Singapore Dollar (SGD) transactions, ensures currency displays are correct, and fixes how activities are started from fragments for better stability.
- Two new fields are added to the
Attributesmodel:chargePriceV2(charge_price_v2)totalPriceV2(total_price_v2)
- Getter and setter methods are provided for these new fields.
- These fields use
Floatinstead ofintto support decimal values for prices. - When sending analytics/events, the new decimal fields (
totalPriceV2) are included asamount_decimalandlast_booking_value_decimalfor more precise price tracking. - When displaying the amount to the user, the code now prefers using the new decimal field
chargePriceV2(andtotalPriceV2) for calculations and display, improving currency accuracy. - Some unused imports are removed from
PromptPayFragment.java, reducing clutter and potential confusion.
[
github.com
https://github.com/hungryhub-team/hh-android/pull/1576
](https://github.com/hungryhub-team/hh-android/pull/1576)
[
github.com
https://github.com/hungryhub-team/hh-android/pull/1884
](https://github.com/hungryhub-team/hh-android/pull/1884)
[
github.com
https://github.com/hungryhub-team/hh-android/pull/1889
](https://github.com/hungryhub-team/hh-android/pull/1889)
[
github.com
https://github.com/hungryhub-team/hh-android/pull/1956
](https://github.com/hungryhub-team/hh-android/pull/1956)
iOS Implementation
- In String+SubScript.swift, the Singapore Dollar currency format is changed from """ for better clarity:
- Before:
$<amount> - After:
S$<amount>
- Before:
- In Handler.swift, universal link handling is enhanced:
- A new method,
isValidScheme, checks if an incoming URL should be handled in-app. - If the scheme isn’t recognized, the link is opened in the browser and a status flag is set.
- This makes link routing more robust and future-proof.
- A new method,
- The app now sets the default phone code based on city:
- If the user's city is Singapore,
+65is used; otherwise,+66(Thailand).
- If the user's city is Singapore,
- The flag image is now set based on the phone calling code instead of the country code.
- When a user selects a country, the correct calling code is applied and sent to the view model.
- The RegisterViewModel’s outputs are updated:
- Now emits the current phone code (
onPhoneCode). - The terms of service screen receives the latest phone code, not just the UI value.
- A new output,
onHidePromotion, is added to hide promotions for Singapore users or non-Thai phone codes.
- Now emits the current phone code (
- The TermOfService view and its ViewModel are updated to support:
- Passing the phone code to the web view as part of the initial data setup.
- Improved event handling for the web view bridge (e.g.,
onMounted,onAcceptContinue,onCloseView).
- The protocol and its implementations now include a convenience method to call a handler without expecting a response callback.
- New and updated unit tests:
- Cover the new Registration and TermOfService behaviors.
- Ensure correct handling of phone codes and web view bridge methods.
- Verify that initial data for the terms screen includes the correct calling code.
- The app’s version is updated from 7.6.4 to 7.6.5 in the Xcode project.
[
github.com
https://github.com/hungryhub-team/hh-ios-fix/pull/2057
](https://github.com/hungryhub-team/hh-ios-fix/pull/2057)
[
github.com
https://github.com/hungryhub-team/hh-ios-fix/pull/2164
](https://github.com/hungryhub-team/hh-ios-fix/pull/2164)
Backend Implementation
- Changed the ordering of cuisines to use interpolation for locale (
order("title_#{I18n.locale}")). - Updated the
find_country_id_currencymethod to useparamsinstead ofrestaurant_params. - Fixed a typo in a button label from "Adress" to "Address".
- Added a list of countries and a selected country dropdown in the
Signup.vuecomponent. - Removed unnecessary index parameter in
forEachloops. - Added a watcher for
selectedCountryto update the phone input country code. - Added methods to find Singapore in
city.rbandcountry.rb. - Moved the
translates :namemethod inrestaurant.rbfor better organization. - Updated currency handling logic in
restaurant.rbanddynamic_pricings_for_package.rb. - Added logic to set the city based on the country code in the restaurant creation process.
- Added a country selection dropdown in the signup form.
- Added translations for the new country field in both English and Thai.
- Updated the
set_time_zonemethod to use the uppercased currency code. - Removed old OMISE keys.
- Added new OMISE keys for Thailand and Singapore.
- Updated the version of the
omisegem from0.9.1to0.11.0. - Adjusted the position of the
composite_primary_keysgem. - Added logic to handle
payment_provider_overrideand setpayment_providertonilif not overridden. - Added
ip_addressto the reservation parameters. - Updated the
selected_payment_providerstructure to include options for Thailand and Singapore for bothpromptpayandcc. - Added a method to configure OMISE keys based on the country code.
- Refactored image validation logic, ensuring proper validation and clearing of invalid images.
- Included
OmiseHelperand configured OMISE keys based on the restaurant's country code. - Added a new association for users in Singapore and adjusted the
chargesassociation. - Added support for the
paynowsource type and included it in validations. - Added a new case for 'charge.complete' alongside 'charge.create'.
- Changed the default country code to use a constant (
ApiV5::Constants::COUNTRY_CODE_TH) instead of a hardcoded string. - Modified the logic for default country code assignment based on feature flags and country codes.
- Updated the charge handling logic to use constants for Omise charge statuses and validate them.
- Added constants for country codes (
COUNTRY_CODE_TH,COUNTRY_CODE_SG). - Added constants for Omise charge statuses (
OMISE_CHARGE_SUCCESSFUL,OMISE_CHARGE_PENDING) and a list of valid statuses. - New Attribute:
calling_code- It defaults to '66'.
- If the
user_idis present, it returns the user's calling code or the default calling code ('66') if the user's calling code is not present. - If the guest phone number is blank, it returns the default calling code ('66').
- Otherwise, it parses the guest phone number to determine and return the country code.
- New Attribute:
country_calling_code- It extracts the full phone number from
object.user.phone_v2_fullor fromobject.phone(removing the '+' prefix). - It parses the phone number to determine and return the country calling code.
- In case of a
Phonelib::ParseError, it returns an empty string.
- It extracts the full phone number from
- A new file
tiktokSingapore.jsis created under thepublicdirectory. This file contains a script that initializes TikTok analytics for the production environment. - The script checks if the application mode is "production".
- If in production mode, it initializes the TikTok analytics object
ttqwith various methods such aspage,track,identify, etc. - It defines the
loadfunction to load the TikTok analytics script fromhttps://analytics.tiktok.com/i18n/pixel/events.js. - The script then loads the TikTok analytics with a specific SDK ID
CURVEQJC77U4QKJNHA20and tracks the page view. - The new script
tiktokSingapore.jsis included in theThirdPartyScript.astrofile. It is added after the existingtiktok.jsscript and before themetaPixel.jsscript. - Added the method
filter.by_currency_code(params[:currency])to filter vouchers based on the provided currency code. - Added the method
by_currency_code(currency_code)to set the currency code in the filter configuration if it's present. - Updated the
build_collectionsmethod to include_by_currency_code. - Added the private method
_by_currency_codeto filter active collections based on the currency code. - Added the currency code handling when creating a referral voucher by passing
currency_codeto theVoucherForm::Referralinitializer. - Added the
currency_codeattribute and included it in the initializer. - Set a default currency code to 'THB' if not provided.
- Updated the
build_vouchermethod to usecurrency_codeforamount_currencyandcurrency_code. - Added the
valid_currency_for_country!method to validate that the voucher's currency code matches the restaurant's currency code. - Added a filter for
country_idto allow filtering vouchers by country in the admin panel. - Added the
fetch_currency_codemethod to return the voucher's currency code or default to 'THB' if not set. - Updated the
override_vouchers!method to include thecurrency_codewhen creating referral vouchers. - Added a line for the validation error message when the voucher's currency code is not valid for the country.
- Added a migration to update the default country ID for vouchers where it is not set.
- Added a migration to add a default country ID to vouchers.
- Added a migration to add a default currency code to vouchers.
-
[
github.com
https://github.com/hungryhub-team/hh-server/pull/5981#pullrequestreview-2377367138
](https://github.com/hungryhub-team/hh-server/pull/5981#pullrequestreview-2377367138)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/5982
](https://github.com/hungryhub-team/hh-server/pull/5982)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/6314/files
](https://github.com/hungryhub-team/hh-server/pull/6314/files)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/6152/files
](https://github.com/hungryhub-team/hh-server/pull/6152/files)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/6463
](https://github.com/hungryhub-team/hh-server/pull/6463)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/6457
](https://github.com/hungryhub-team/hh-server/pull/6457)
Frontend Implementation
- Added
omise-js-typedtopackage.json. - Modified various methods to handle credit card tokens using Omise instead of GbPrimePay.
- Updated logic in
AddNewCreditCardMobile.vueandCheckOutPage.vueto support Omise tokens. - Refactored token request methods in
CreditCard.tsandBookingPayment.tsto add support for Omise. - Added support for Omise tokens in booking creation flow (e.g.,
createBooking.ts,getBookingProcessData.ts). - Updated
booking.tsstore to includecreditCardProviderandomiseToken. - Consolidated and refactored logic for handling different credit card providers.
- Adjusted country code handling and added checks for Singapore restaurants.
- Added setup data listener on the search suggest page.
- Implemented Singapore payment using Omise.
- Disabled increase button when enable big group is false.
- Fixed menu quantity sometimes being null.
- Removed all arbitrary classes.
- Removed remaining arbitrary classes on some pages.
- Added a hotfix for preorder in availability.
- Removed unused parameters
validGiftCardCodeandvalidGiftCardCode2. - Updated a locator for better accuracy.
- Added a new dependency
omise-js-typed. - Added a new file to create Omise tokens for credit card processing.
- Updated class properties for styling improvements.
- Added keys to
v-forloops for better performance. - Updated class properties for styling adjustments.
- Made styling adjustments for better layout and readability.
- Updated class properties for styling improvements.
- Adjusted some logic in watchers.
- A new parameter
currencyis added to thegetVouchersfunction. - The function signature is updated to include the
currencyparameter. - The payload sent in the request now includes the
currencyparameter. - The error handling block catches any error and returns a response with
isSuccess: false. - The condition to hide offers if the restaurant is in Singapore is removed.
- The
restaurantStoreis imported and used. - A check is added to prevent point redemption if the restaurant is in Singapore.
- The
useBookingChargeStoreis imported and used to get thechargeObject. - The
currencyis determined based on thechargeObject. - The
currencyparameter is included in the request payload when fetching vouchers.
[
github.com
https://github.com/hungryhub-team/hh-pegasus/pull/1119
](https://github.com/hungryhub-team/hh-pegasus/pull/1119)
[
github.com
https://github.com/hungryhub-team/hh-pegasus/pull/1496
](https://github.com/hungryhub-team/hh-pegasus/pull/1496)
[
github.com
https://github.com/hungryhub-team/hh-pegasus/pull/1435
](https://github.com/hungryhub-team/hh-pegasus/pull/1435)
[
github.com
https://github.com/hungryhub-team/hh-pegasus/pull/1315
](https://github.com/hungryhub-team/hh-pegasus/pull/1315)
[
github.com
https://github.com/hungryhub-team/hh-pegasus/pull/1596
](https://github.com/hungryhub-team/hh-pegasus/pull/1596)
PRD & Task
Private (https://app.clickup.com/9003122396/docs/8ca1fpw-7922/8ca1fpw-43316)
Private (https://app.clickup.com/t/86cx2hy2u) Private (https://app.clickup.com/t/86cwy4rw7) Private (https://app.clickup.com/t/86cwhf2t8) Private (https://app.clickup.com/t/86cwjaa6k) Private (https://app.clickup.com/t/86cwhf5mn) Private (https://app.clickup.com/t/86cwhf5z4)
Design
API Blueprint
| Method | Path | URL | Description | Payload |
|---|---|---|---|---|
New Query
DB Schema / Database Migration
Improvement:
| Feature Name | Date | What Changed | Description |
|---|---|---|---|
| Payment Option - Option to Pay Now Offers (Point Redemption, Gift Card, Promo Code) Create Saved CC | 02/12/2024 | Hidden / Disabled Feature | |
| update Singapore Expansion (1 month after launch) | 06/03/2025 | add promo code, gift card and point update |