Introduction
Embedded Payments allow seamless integration of payments directly into your platform without redirecting the users away. Two modes are available — pick based on the payment method and your preferred UX:| Mode | Parameter | Customer experience |
|---|---|---|
| QR Code | generate_qr: true | Customer scans a QR code rendered in your UI with their banking or wallet app |
| Direct Link | generate_direct_link: true | Customer is redirected to the payment provider’s page, then back to your site |
Serving international customers? Once you’ve completed this setup, see Borderless QR to display real-time currency conversion for cross-border payments.
Live Demo
Try the embedded payments live demo to see QR code and direct link flows in action before you integrate.Core Concept
The integration flow is the same for both modes — only thegenerate_* parameter and how you present the payment to the customer differ.
Create a Payment Request
Call
POST /v1/payment-requests with either generate_qr: true or generate_direct_link: true.Present to Customer
For QR: render the returned QR code in your UI. For direct link: redirect the customer to the provider URL.
Supported Methods
Some methods support both modes — choose whichever fits your UI.| Payment Method | Code | QR | Direct Link |
|---|---|---|---|
| PayNow | paynow_online | ✓ | |
| ShopeePay | shopee_pay | ✓ | |
| QRIS | doku_qris (Indonesia), ifpay_qris (others) | ✓ | |
| WeChatPay | wechat_pay | ✓ | |
| PromptPay | opn_prompt_pay | ✓ | |
| TrueMoney | opn_true_money_qr | ✓ | |
| GrabPay | grabpay_direct | ✓ | ✓ |
| GrabPay PayLater | grabpay_paylater | ✓ | ✓ |
| UPI | upi_qr | ✓ | |
| GCash (QR) | gcash_qr | ✓ | |
| GCash (Direct Link) | gcash | ✓ | |
| QRPH | qrph_netbank | ✓ | |
| Touch ‘n Go | touch_n_go | ✓ | ✓ |
| DuitNow | duitnow | ✓ | |
| Atome | atome | ✓ | |
| VietQR | vietqr_zalopay | ✓ | |
| ZaloPay | zalopay | ✓ | ✓ |
| ShopBack (QR) | shopback_qr (SG only) | ✓ | |
| ShopBack (Direct Link) | shopback (SG only) | ✓ |
Authentication
Before integration, it’s essential to understand how Hitpay APIs are authenticated. Hitpay utilizes API keys to grant access to the API. You can locate this key in your dashboard under “API keys.” Hitpay requires the API key to be included in all API requests to the server. This key should be placed in a header that follows the format shown below:X-BUSINESS-API-KEY: meowmeowmeow
Step 1: Create a Payment Request
POST /v1/payment-requestsRequest Parameters
| Parameter | Type | Description |
|---|---|---|
| amount | string | Required. The amount to be paid. |
| currency | string | Required. The currency (e.g., "sgd"). |
| payment_methods[] | array | Required. The payment method. Only one method must be specified. |
| generate_qr | boolean | Set to true to generate QR code data. |
| generate_direct_link | boolean | Set to true to generate a provider redirect URL. |
| redirect_url | string | Required when using generate_direct_link. URL to redirect the customer after payment. |
| name | string | Optional. Customer name. |
| string | Optional. Customer email. | |
| phone | string | Optional. Customer phone number. |
| purpose | string | Optional. Payment purpose. |
| reference_number | string | Optional. Your internal reference number. |
Pass either
generate_qr: true or generate_direct_link: true — not both in the same request and only one payment method.- QR Code
- Direct Link
Step 2: Present to Customer
- QR Code
- Direct Link
Use the 
qr_code_data.qr_code value from the response to render a scannable QR code in your UI.
Step 3: Customer Completes Payment
The customer scans the QR code with their banking app, or completes payment on the provider’s page. For direct link payments, the provider redirects the customer back to yourredirect_url with reference (payment request ID) and status query parameters:
Step 4: Handle Webhooks and Server Communication
After the payment is processed, handle webhooks to receive payment notifications and update the payment status in your system.What is a Webhook?
A webhook is a POST request sent from HitPay’s server to your server about the payment confirmation. You must mark your order as paid ONLY after the webhook is received and validated.Register Your Webhook
To receive payment notifications, register a webhook URL from your HitPay Dashboard:- Navigate to Developers > Webhook Endpoints in your dashboard
- Click on New Webhook
- Enter a name and your webhook URL
- Select the
payment_request.completedevent - Save your webhook configuration

Webhook Payload
When a payment is completed, HitPay sends a JSON payload to your registered webhook URL with the following headers:| HTTP Header | Description |
|---|---|
| Hitpay-Signature | HMAC-SHA256 signature of the JSON payload, using your salt value |
| Hitpay-Event-Type | completed |
| Hitpay-Event-Object | payment_request |
| User-Agent | HitPay v2.0 |
Sample Webhook Payload
Validating the Webhook
To ensure the webhook is authentic, validate theHitpay-Signature header:
- Receive the JSON payload and
Hitpay-Signaturefrom the request - Use your salt value (from the dashboard) as the secret key
- Compute HMAC-SHA256 of the JSON payload using your salt
- Compare the computed signature with
Hitpay-Signature- they must match
FAQs
What about the 'webhook' parameter in the API?
What about the 'webhook' parameter in the API?
The
webhook parameter in the payment request API is deprecated and will be removed in a future version.Why the change?- The new registered webhook system supports JSON payloads with richer data
- You can subscribe to multiple event types (not just payment completion)
- Centralized management from your dashboard
- Better scalability - one webhook URL handles all your payment requests
- Register your webhook URL in Settings > API Keys
- Subscribe to
payment_request.completedevent - Update your webhook handler to accept JSON payloads
- Remove the
webhookparameter from your API calls
Webhook Signature Mismatch?
Webhook Signature Mismatch?
Possible reasons for signature mismatch:
- Ensure you are using the correct salt value from the correct environment (Sandbox or Production)
- Make sure you are computing the HMAC-SHA256 of the raw JSON payload
- Verify the signature is being read from the
Hitpay-Signatureheader
Facing Invalid Business API Key Error?
Facing Invalid Business API Key Error?
Possible reasons for this error:
- You are using a production key in the sandbox or a sandbox key in production. Make sure the API base URL is correct.
- You are missing headers. Ensure you include both the ‘Content-Type’ and ‘X-Requested-With’ headers.
How do I handle cancelled or abandoned QR code payments?
How do I handle cancelled or abandoned QR code payments?
QR code payments (PayNow, GrabPay, etc.) cannot be cancelled once generated — unlike card payments, there is no cancel endpoint. Even if the user leaves your checkout page, they may have already scanned or screenshotted the QR code.Recommended approach:
- When you generate a QR code, record the creation timestamp and treat the payment as "pending" on your end.
- If you do not receive a successful payment webhook within 10–15 minutes of QR creation, you can safely assume the payment was abandoned and cancel the order on your side.
- PayNow QR codes are valid for 5 minutes — this is the window in which the customer must scan the code.
- However, once scanned, the customer's banking app may still allow them to complete the payment after the 5-minute mark.
- A 10–15 minute buffer from QR creation accounts for this delay.
Production Checklist
Production Checklist
Ensure the following before moving to production:
- Change the base URL for all API calls to
https://api.hit-pay.com/v1/ - Complete payment method setup in production
- Update API keys and Salt values from the production dashboard
- Register your webhook URL in production
Why does my charges `webhook status` show as failed?
Why does my charges `webhook status` show as failed?
If you are using a payment plugin, after every successful payment, a webhook is sent to your store to acknowledge the payment confirmation. Your order is marked as paid through this webhook.A webhook status showing as "failed" indicates that Hitpay failed to communicate with your server. This can happen for the following reasons:
- Your store may have a security feature that blocked Hitpay's request.
- Your server was unavailable during this time.
- Production:
3.1.13.32,52.77.254.34 - Sandbox:
54.179.156.147
