1. Overview
HitPay Gateway for Gravity Forms by PatSaTECH turns any Gravity Forms form into a HitPay checkout. When the form is submitted, the add-on creates a HitPay payment request for the form total and sends the visitor to HitPay’s secure checkout page, where they pay by card, PayNow, Apple Pay, Google Pay, GrabPay, ShopeePay, FPX, GCash, QRIS or any other method enabled in your HitPay account. Card data never touches your site.
It is built on the official Gravity Forms Payment Add-On Framework, so each entry gets its native payment status, transaction ID, notes and Sales report data. An entry is marked Paid only after HitPay confirms the payment (status check or signed webhook). Notifications, post creation and other add-on feeds can wait until then, and refunds are made from the entry screen.
2. Features
- HitPay checkout page
- Cards, PayNow, wallets & local methods
- Choose which methods to show
- Payment Add-On Framework
- Sandbox & Live API keys
- API key checked on save
- Signed webhooks (Hitpay-Signature)
- Return status never trusted
- Amount & currency verification
- Per-entry lock: never paid twice
- Full & partial refunds from the entry
- Dashboard refunds noted
- Card brand & last 4 in the notes
- Clear minimum-amount message
- Unpaid entries marked Failed on a timer
- Delayed notifications & posts
- Post Payment Actions for other feeds
- HitPay SMS always off
- Debug log (no secrets logged)
- Translation-ready (.pot)
3. Requirements
| Component | Minimum |
|---|---|
| WordPress | 6.0 (tested up to 7.1.3) |
| Gravity Forms | 2.5 (tested up to 2.10.3) |
| PHP | 7.4 |
| SSL / HTTPS | Required. HitPay does not deliver webhooks to localhost or IP addresses. |
| HitPay account | A verified HitPay account (live) or a free sandbox account (testing), its API key, and an Event Webhook with its salt |
| Form currency | One HitPay supports, see Currencies |
Tested on: WordPress 7.1.3, Gravity Forms 2.10.3, PHP 8.1.34, HitPay sandbox (Singapore, SGD). See Tested on.
4. Installation
- In WordPress admin go to Plugins → Add New → Upload Plugin.
- Choose
gravityforms-hitpay-1.0.0.zipand click Install Now. - Activate HitPay Gateway for Gravity Forms. Gravity Forms must be active.
FTP: upload the gravityforms-hitpay folder to /wp-content/plugins/ and activate it.
Step-by-step setup with screenshots
- Card payment, entry marked Paid with “Method: Card (Visa ending 4242)”; the admin notification was sent only when the payment was received (entry 9620)
- Declined card: no failure webhook, the HitPay request stays payable and the entry stays Processing until the time limit (entry 9621)
- Partial refund (5.00), a refund larger than the balance refused (“exceeds refundable balance”), then the rest (7.00): entry Refunded
- Unpaid entry marked Failed by the time limit (entry 9622)
Click any screenshot to open it full size. API keys, salts, HitPay payment-request, charge and refund IDs, email addresses and IP addresses are blurred or left out.
Part A: HitPay dashboard
Copy your API key
In the HitPay dashboard (sandbox:
dashboard.sandbox.hit-pay.com) open Developers → API Keys and copy the API key. Full details: Getting your HitPay API key and webhook salt.SCREENSHOT TODO: HitPay Developers → API Keys (key and salt blurred).Add an Event Webhook for this site
Open Developers → Event Webhooks, add a webhook with the URL
https://your-site.com/?callback=gravityforms-hitpay, tick the 5 events (Payment Request Completed, Payment Request Failed, Charge Created, Charge Updated, Charge Failed) and save. Open it and copy its salt; each Event Webhook has its own salt.SCREENSHOT TODO: HitPay Developers → Event Webhooks with the URL and the 5 events ticked (salt blurred).
Part B: WordPress / Gravity Forms
Activate the add-on
Upload
gravityforms-hitpay-1.0.0.zipunder Plugins → Add New → Upload Plugin and activate it.
HitPay Gateway for Gravity Forms 1.0.0 active. Paste the API key and webhook salt
Go to Forms → Settings → HitPay, choose Mode: Sandbox, paste the Sandbox API key and the Sandbox webhook salt and click Save Settings. The add-on checks the key with HitPay. The Webhook field shows the URL to use (
https://your-site.com/?callback=gravityforms-hitpay).
Mode, sandbox and live API keys and webhook salts (masked), and the webhook URL. 
Automatic webhook setup (off by default), payment methods, HitPay receipt email, the unpaid-entry time limit, default country and debug log. Create a HitPay feed
Open your form, go to Settings → HitPay → Add New, set Transaction Type: Products and Services, choose the payment amount, map the billing fields (Email is required) and, if you like, tick Send notifications only when payment is received. See Creating a HitPay feed.

HitPay feed: name, transaction type, payment amount, billing information and delayed notifications.
Part C: Test payment
Pay on HitPay’s checkout page
Submit the form. The visitor is sent to HitPay’s page, which shows the amount and the methods enabled on your account. In the sandbox open the Card tab and pay with
4242 4242 4242 4242, any future expiry and any CVC.
HitPay’s checkout page with the PayNow QR code and the Card tab (captured from a WooCommerce test order; Gravity Forms entries use the same page; email blurred). Confirmation
The visitor returns to your form’s confirmation. If HitPay is still confirming the payment, they see “Your payment is being confirmed” instead and are asked not to pay again.

Form confirmation after payment. Entry is marked Paid
The entry’s Payment Status becomes Paid, the HitPay payment ID is the Transaction ID, and a note records the method, for example “Method: Card (Visa ending 4242)”. Delayed notifications and feeds run now.

Entry 9620 Paid, with the HitPay notes, the admin notification sent at payment and the Refund via HitPay box (IDs, IP and email blurred).
5. Getting your HitPay API key and webhook salt
- Sandbox (for testing): sign up for free at dashboard.sandbox.hit-pay.com (no real money moves). Live: sign in at dashboard.hit-pay.com once HitPay has verified your business. The sandbox and live accounts are separate, each with its own API key and webhooks.
- Turn on the methods you want under Settings → Payment Methods (cards may need a bank account and HitPay’s card onboarding first; in the sandbox dummy details are enough).
- Open Developers → API Keys and copy the API key. SCREENSHOT TODO: HitPay dashboard → Developers → API Keys, with the key and salt blurred. Not included: the test captures of this page showed real secrets, so they were not used.
- Open Developers → Event Webhooks and click Add (the button name may differ slightly). Give it any name (for example your site name), paste the webhook URL shown in the plugin settings, tick the 5 events listed under Webhooks and save. SCREENSHOT TODO: HitPay dashboard → Developers → Event Webhooks → new webhook form with the URL and the 5 events ticked (salt blurred).
- Open the webhook you just saved and copy its salt. Each Event Webhook has its own salt: use the salt of the webhook that points to this site, not the salt of another webhook or another site.
- Paste the API key and the webhook salt into Forms → Settings → HitPay (Sandbox API key and Sandbox webhook salt, or the live fields) and save. The plugin checks the API key with HitPay straight away.
- Repeat in your live account at dashboard.hit-pay.com when you go live (only the sandbox was used for this guide).
6. Add-on settings
Forms → Settings → HitPay
| Setting | Description |
|---|---|
| Mode | Live or Sandbox (default Sandbox). The sandbox and live HitPay accounts are separate. Entries keep the mode they were created in. |
| Sandbox / Live API key | From HitPay → Developers → API Keys. Checked with HitPay when you save. |
| Sandbox / Live webhook salt | The salt of the Event Webhook you added for this site (each webhook has its own salt). If your dashboard shows no salt on the webhook, use the salt shown next to your API key. |
| Webhook | Your webhook URL (https://your-site.com/?callback=gravityforms-hitpay) and the events to tick, with optional Register sandbox / live webhook now buttons. |
| Automatic webhook setup | Off by default. When ticked, the add-on tries to register the webhook through the HitPay API when a key is saved and the salt is empty. Adding the webhook in the dashboard is the recommended way. |
| Payment methods | Optional, comma-separated HitPay method codes (for example card, paynow_online, grabpay_direct). Empty = every method enabled in your HitPay account. |
| HitPay receipt email | Also let HitPay email its own receipt (your Gravity Forms notifications are sent either way). HitPay SMS is always off. |
| Mark unpaid entries Failed after (minutes) | Default 60. The HitPay checkout link expires at the same time; the add-on checks HitPay once more, deletes the unpaid payment request and marks the entry Failed. 0 disables it. |
| Default country | Two-letter code used to format phone numbers in E.164 when the form has no country. |
| Debug log | Logs webhooks, API calls and info messages (needs Forms → Settings → Logging enabled for this add-on). Errors are always logged; API keys and salts never are. |
7. Webhooks (Event Webhook, 5 events)
Add one Event Webhook for this site in the HitPay dashboard under Developers → Event Webhooks and paste its salt into the add-on. The settings page shows the exact URL.
Webhook URL: https://your-site.com/?callback=gravityforms-hitpay
| # | Event to tick in the HitPay dashboard | What the plugin does |
|---|---|---|
| 1 | Payment Request Completedpayment_request.completed | The plugin reads the payment request again from the HitPay API; if it is completed and the amount and currency match, the order / entry is marked paid (card brand and last four digits in the note). |
| 2 | Payment Request Failedpayment_request.failed | Records that HitPay ended the payment request without a payment (for example an expired request). |
| 3 | Charge Createdcharge.created | Triggers the same API check, so a payment is recorded even if the payment-request event is late. |
| 4 | Charge Updatedcharge.updated | Notes refunds made in the HitPay dashboard and keeps the refunded total in step. |
| 5 | Charge Failedcharge.failed | Records a failed charge when HitPay sends one. |
Hitpay-Signature header must be the HMAC-SHA256 of the raw request body with the webhook salt. The add-on then reads the payment request again from the HitPay API before it changes the entry, so a forged or replayed webhook cannot mark an entry Paid. Payments are also confirmed by status checks when the visitor returns, by follow-up checks and an hourly sweep, so a missed webhook never leaves a paid entry unpaid. Allow /?callback=gravityforms-hitpay through any firewall or security plugin.8. Creating a HitPay feed
- Edit the form → Settings → HitPay → Add New.
- Name the feed and set Transaction Type to Products and Services (one-time payments; subscriptions are not supported).
- Payment Amount: Form Total or a product field.
- Billing Information: map First Name, Last Name, Email (required), Phone, Address and Country (also used to format the phone number).
- Optional: Notifications (send only when payment is received) and Conditional Logic.
- Save the feed.
9. Payment flow & entry statuses
| Situation | Entry payment status |
|---|---|
| Visitor sent to HitPay, not paid yet | Processing; note “HitPay payment request created … waiting for the payment result.” |
| HitPay still confirming | Processing; “being confirmed” message; checked again automatically |
| Payment completed (amount and currency match) | Paid; transaction ID = HitPay payment ID; note with the method |
| Card declined on HitPay’s page | Stays Processing: HitPay keeps the request payable and sends no failure webhook (see HitPay behaviour) |
| HitPay reports the request failed | Failed, with the reason in the notes; the visitor sees a message above the form and can submit again |
| Time limit reached without a payment | Failed; the unpaid HitPay payment request is deleted |
| Fully refunded | Refunded |
10. Refunds
- Open a Paid entry. The Refund via HitPay box shows the refundable balance.
- Enter an amount (leave it blank for a full refund), an optional reason, and click Refund via HitPay.
- Notes record the refund request and its completion. When refunds reach the paid amount the entry becomes Refunded and the box shows “Nothing left to refund.”

- A refund larger than the balance is refused with “exceeds refundable balance” (tested: 10.00 against 7.00 left).
- Refunds made in the HitPay dashboard are noted on the entry through the Charge Updated webhook.
- Some methods cannot be refunded through HitPay (for example DuitNow, WeChat Pay, over-the-counter methods, Atome in Malaysia). The box then shows a clear message instead of the refund form.
11. HitPay behaviour to know (declines, minimum amount, time limit)
Failed card payments stay pending on HitPay
When a card is declined, HitPay shows “Your card was declined.” on its own checkout page and the visitor can try another card or method there. The HitPay payment request stays pending and payable, and HitPay sends no failure webhook for the declined attempt. So the entry stays Processing: it becomes Paid if the visitor then pays, and otherwise it is marked Failed by the time limit (Mark unpaid entries Failed after, default 60 minutes), when the add-on also deletes the unpaid payment request so the old link can no longer be paid (tested: entries 9621 and 9622).

Minimum amount 0.30
HitPay accepts payments from 0.30 (in the form currency) up to 999,999,999.99. For a smaller total HitPay refuses the payment request and the visitor sees: “This amount is below HitPay’s minimum payment amount, so it cannot be paid online. Please change the amount or contact us.” The detailed HitPay error is kept in the entry notes.
Methods not activated on your account
If the Payment methods setting lists a method HitPay has not activated for your account, HitPay refuses the request and the visitor gets a friendly message. Leave the setting empty to show only what HitPay has enabled.
Times are in Singapore time
HitPay reports times in Singapore time without a time zone. The add-on converts them, so expiry and notes match your WordPress time zone.
12. Testing with the HitPay sandbox (test cards)
Use any future expiry date (for example 12/30), any 3-digit CVC and any name. Card numbers are from HitPay’s sandbox test-card list (the sandbox banner on HitPay’s page links to it).
| Scenario | Card | What happens |
|---|---|---|
| Success | Visa 4242 4242 4242 4242 | Paid. Used for the successful test payments (order 6500, entry 9620). |
| Declined | 4000 0000 0000 0002 | HitPay shows “Your card was declined.” on its own page and the customer can try another card or method there. HitPay sends no failure webhook for this, so the order / entry stays unpaid until it is paid or the time limit is reached (order 6501, entry 9621). |
- PayNow (SGD) shows a QR code in the sandbox; scan it with any QR reader, not a banking app (HitPay’s sandbox instructions).
- Cards in the sandbox: if the Card tab is missing, turn cards on under Settings → Payment Methods in the HitPay sandbox dashboard (it may ask for a dummy bank account and a test card-processing onboarding first).
- Methods that are not activated on your account are rejected by HitPay; the customer sees a friendly message and can choose another method (tested with GrabPay, order 6508).
13. Notifications & Post Payment Actions
- Notifications: in the feed tick Send notifications only when payment is received and choose which notifications wait (tested: the admin notification for entry 9620 was sent only when the payment was confirmed). You can also use the Payment Completed, Payment Failed and Payment Refunded notification events.
- Post Payment Actions: Process [add-on] feed only when payment is received for other add-ons such as Mailchimp or User Registration.
- Posts: Create post only when payment is received.
14. Countries, currencies & payment methods
Who can use HitPay. HitPay is a payment platform for small and medium businesses in South-East Asia; its core markets are Singapore, Malaysia and the Philippines. A live account needs HitPay’s business verification. Anyone can open a free sandbox account at dashboard.sandbox.hit-pay.com to test, but HitPay does not offer production accounts to businesses in every country (for example, India-based merchants cannot get one). Check with HitPay before you buy.
Currencies. SGD MYR USD AUD NZD PHP HKD THB EUR CAD GBP IDR AED KRW CNY INR JPY CHF BND SAR SEK DKK NOK PLN QAR TWD ZAR VND. Local methods appear only for their own currency (for example PayNow for SGD, FPX for MYR, GCash for PHP).
Amount limits. HitPay accepts payments from 0.30 up to 999,999,999.99 in the form currency. Below 0.30 HitPay refuses the payment; the plugin then tells the customer clearly that the amount is below HitPay’s minimum (tested with a 0.10 order).
Payment methods. HitPay’s checkout page shows the methods enabled in your HitPay account (Settings → Payment Methods): cards, Apple Pay, Google Pay, PayNow, GrabPay, ShopeePay, FPX, GCash, QRIS and more, depending on your country and currency. Use the plugin’s Payment methods setting to show only some of them (for example card, paynow_online).
Set the form currency under Forms → Settings → Currency; it must be one HitPay accepts. Currencies Gravity Forms does not list by default are added by the add-on.
Finding the payment in HitPay
In the HitPay dashboard open Payments → Transactions. The Charges list shows every payment with its date, customer, charge ID, amount, fee, method (for example Visa •••• 4242) and status (Succeeded, Refunded…). The HitPay payment ID is also the entry’s transaction ID.

15. Debug logs
Enable Forms → Settings → Logging, turn on logging for HitPay Gateway for Gravity Forms, and tick Debug log in the HitPay settings. View the log from Forms → Settings → Logging. Errors and webhook receipts are always logged; API keys and salts are never logged. Turn logging off again when you are done.
16. Troubleshooting & FAQ
The API key was rejected
Check the Mode matches the key: sandbox keys only work in Sandbox mode, live keys only in Live. The sandbox and live HitPay accounts are separate.
Paid in HitPay but the entry is still Processing
Check that the Event Webhook points to https://your-site.com/?callback=gravityforms-hitpay, that its 5 events are ticked, and that the salt in the add-on is the salt of that webhook. Make sure no firewall blocks the URL and that WP-Cron runs. Opening the entry also triggers a check; see the log.
The card was declined but the entry is still Processing
That is how HitPay works: the payment request stays payable and no failure webhook is sent. The entry is marked Failed automatically after the time limit if it is not paid.
“This amount is below HitPay’s minimum payment amount”
HitPay’s minimum is 0.30. Make sure the form total cannot be lower.
Subscriptions?
No. One-time payments (Products and Services) only.
17. Tested on
- WordPress 7.1.3
- Gravity Forms 2.10.3
- PHP 8.1.34; PHP 7.4 or later required
- HitPay sandbox (Singapore account, SGD). Live payments not yet tested.
- Scenarios: card payment with the brand and last four in the notes, delayed notification, declined card (entry left Processing, then Failed by the time limit), partial and full refunds, over-refund refused, unpaid entry marked Failed
18. Changelog
1.0.0 — 2026-10-18
- Initial release on the Gravity Forms Payment Add-On Framework.
- HitPay Payment Request API with the HitPay checkout page; every method enabled on the account, or a chosen list.
- Sandbox and live API keys checked on save; one Event Webhook with 5 events, verified with Hitpay-Signature.
- Return status never trusted; every change re-checked with the API under a per-entry lock.
- Full and partial refunds from the entry; dashboard refunds noted.
- Clear minimum-amount and method messages; unpaid entries marked Failed on a timer; hourly sweep.
- Delayed notifications, posts and Post Payment Actions; E.164 phone numbers; debug logging (no secrets).
19. Support
PatSaTECH · [email protected] · www.patsatech.com
Please include your WordPress, Gravity Forms and PHP versions, the mode (sandbox or live) and the relevant log lines (never send your API key or salt).









