In Bangladesh, most online payments never touch a card processor. They move through bKash, Nagad or Rocket, and for a shop that has not yet been approved for merchant API access, the working version is simple: send money to this number, then tell us the transaction ID.
There are separate plugins for each brand. Installing three of them means three settings screens, three sets of checkout markup, and three separate places for the same bug to hide.
One base class, three thin gateways
We built a single gateway base that owns everything the three methods share — the settings fields, the checkout inputs, validation, the optional send-money fee, and how the payment details are rendered on the thank-you page, in the order email and on the admin order screen. Each brand is then a few lines: an ID, a display name, and its default instructions.
The practical payoff shows up during maintenance. When the mobile-number rule needed tightening, it was tightened once and all three methods changed together. Nothing drifted, because there was only ever one copy of the rule.
Collecting proof at the moment of payment
The checkout asks for two things: the mobile number the customer paid from, and the transaction ID their app returned. Both are validated on the server against the Bangladeshi mobile format, so a mistyped number is caught before the order exists rather than discovered a day later.
Those two values then follow the order everywhere a human might look for them — the order-received page, the customer email, and a panel on the admin order screen beside the billing address. Someone reconciling against the merchant app should never have to open a second screen or a meta box to find the reference they are checking.
Choosing manual verification on purpose
Automatic verification needs merchant API credentials, which need an approved business account and a review process measured in weeks. For a store launching this month, manual checking against the merchant’s own app is the honest trade-off. The design decision that follows is to make reconciliation fast rather than to pretend it is not happening: put the numbers where the eye already is, and keep them copyable.
Key takeaways
- Shared behaviour belongs in one base class — three near-identical plugins means three chances to fix a bug incompletely.
- Validate payment references server-side at checkout, not during reconciliation the next morning.
- If a step is manual, design for the person doing it: surface the values where they already look.
- Manual gateways are a legitimate starting point, not a placeholder to be embarrassed about.
Related reading: validating Bangladeshi mobile numbers at checkout, why order emails were not reaching Gmail, our WordPress plugin development service.
Running into a similar limitation in your own WooCommerce or WordPress store? Let’s Talk — ArtinTech Solution builds exactly this kind of custom store tooling.