WHMCS services
WHMCS Payment Gateway Integration
I integrate payment gateways with WHMCS for hosting companies and online businesses, including Stripe, PayPal, Razorpay, NowPayments and regional gateways. Each module verifies webhooks, ignores duplicates, handles refunds and 3-D Secure, and is tested in a sandbox before it touches a live payment.
By Shahid Malla, WHMCS developer and hosting infrastructure engineer · Updated
What kinds of WHMCS payment gateway can be integrated?
WHMCS gateways fall into three designs, and the design decides how card data is handled and how renewals work. I pick the design before writing any code.
| Design | How the payment works | Card data on your server |
|---|---|---|
| Hosted or redirect | The customer is sent to the gateway's page to pay. The gateway notifies WHMCS through a callback. Renewals usually need the customer to pay each invoice. | None |
| Tokenized | The gateway stores the card and returns a token. WHMCS keeps only the token and charges it on the due date through the module's capture function. | None, only a token |
| Merchant (card form on your site) | Card details are typed into your site and passed to the gateway. | Passes through your server |
I steer almost every project to the first two designs. The third one pulls your server into much heavier compliance work, and I do not write code that stores card numbers.
Which files make up a WHMCS gateway module?
A gateway module is one main file plus one callback file. The main file is modules/gateways/<name>.php and the callback file is modules/gateways/callback/<name>.php, both using the same lowercase module name.
The main file defines <name>_MetaData() and <name>_config(), which draw the admin settings such as API keys and a test mode switch. A hosted gateway adds <name>_link($params), which returns the pay button or redirect shown on the invoice. A tokenized gateway adds <name>_capture($params) to charge a stored token, and <name>_refund($params) handles refunds. The callback file is a plain endpoint that the gateway calls over HTTPS, and it is where the money logic lives.
How does a callback mark an invoice as paid?
A callback marks an invoice as paid by running a fixed sequence of WHMCS helper functions, after the payment has been verified. The order matters, because each step guards the next.
getGatewayVariables()loads the module's saved settings, which the callback uses to confirm the gateway is active.- Verify the signature on the raw request body before trusting any field in it.
checkCbInvoiceID()confirms the invoice exists in this WHMCS.checkCbTransID()stops processing if this transaction ID was already recorded.logTransaction()writes the raw data and result to the gateway log, which is where I look first when a payment looks wrong.addInvoicePayment()records the payment and fee against the invoice and marks it paid once the balance reaches zero.
I also compare the paid amount with the invoice balance before step six, so a partial or tampered amount is logged instead of being treated as full payment.
How do I stop forged and duplicate webhooks?
Verify the cryptographic signature on every request and record each transaction only once. A callback URL is public, so anyone can send it a fake "paid" message unless the signature is checked.
- Stripe signs each webhook in a
Stripe-Signatureheader and includes a timestamp, so I also reject notifications that are too old. - Razorpay sends an HMAC signature of the request body in an
X-Razorpay-Signatureheader, checked against your webhook secret. - PayPal webhooks are verified by sending the received headers and body back to PayPal's verification API.
- NowPayments signs its instant payment notifications with a secret key that I check on every call.
I compare signatures with hash_equals(), which avoids timing leaks. For duplicates, gateways retry notifications, so the same event can arrive twice or out of order. checkCbTransID() stops a second payment from being recorded, and for events that carry no transaction ID I store the gateway's event ID and ignore repeats. A duplicate still gets a quick success response, so the gateway stops retrying.
How do refunds work?
A refund started from the WHMCS admin area calls the module's refund function, which asks the gateway to return the money and reports the result back. The function returns a status of success, declined or error, plus the gateway's reference.
The harder case is a refund made in the gateway's own dashboard. WHMCS knows nothing about it unless the gateway sends a webhook and the callback handles it, so the invoice would still show as paid. I handle refund events in the callback where the gateway offers them, and I list in the handover notes any case, such as crypto, where the refund stays manual.
What about 3-D Secure and strong customer authentication?
For hosted and redirect gateways, the gateway runs the 3-D Secure challenge itself, so WHMCS has nothing extra to do. The difficult case is a renewal charged on a stored token, because the customer's bank may still demand authentication.
When a charge needs authentication, the module must treat it as a failed attempt, not retry blindly. I record the failure, let WHMCS send its normal payment reminder, and make sure the customer can open the invoice and complete the challenge on a hosted page. This matters most for customers in regions with strong customer authentication rules, such as the EU and UK.
How do currencies and gateway fees work?
WHMCS bills each client in their own currency, and many gateways accept only some. The admin gateway settings let WHMCS convert the invoice to a currency the gateway supports, and I make the callback read the converted amount.
Fees are recorded in the payment so your reports show net income. Some gateways send the fee with the notification, while others expose it only through a separate lookup after settlement. I record the fee when it is available and leave it empty when it is not, and I write down which case applies to your gateway.
How do you test a gateway before going live?
I test in the gateway's sandbox against a staging WHMCS that the internet can reach, because webhooks cannot be tested against a laptop. A public staging address or a tunnel makes that possible.
The test list covers a successful payment, a decline, an expired session, the same webhook sent twice, a late webhook, a partial amount, a currency conversion and a refund. After each case I check the invoice, the gateway log and the gateway dashboard, and they must tell the same story. Only then do I switch to live keys, take one small real payment and refund it.
Which gateways have you integrated?
For the Stripe and Razorpay setups I use most, the step-by-step notes are in WHMCS Stripe integration and WHMCS Razorpay integration.
I work with Stripe, PayPal, Razorpay and NowPayments, and with regional gateways that publish an API reference and a sandbox. WHMCS ships modules for several large gateways, and when one of those already does what you need, I will tell you to use it instead of paying for custom work. I build when the bundled module lacks a feature, such as a local payment method, or when the gateway has no module at all. A new module is a form of custom module development, and a gateway that touches payments is a natural place for a security review.
What will a gateway module of mine never do?
I will not store card numbers or security codes, and I will not build against a gateway that offers no documentation or sandbox. I cannot get a merchant account approved for you, since gateways make that decision. I do not edit WHMCS core files or work from cracked gateway modules. For crypto, price movement and confirmation rules are business decisions that stay with you. If you are setting up from scratch, WHMCS installation and setup includes connecting a gateway in sandbox mode.
Who this is for
- Hosting companies and resellers whose customers cannot pay with a preferred method
- Businesses selling in a region where the bundled WHMCS gateways do not work
- Owners whose existing gateway marks invoices unpaid, paid twice or half paid
- Online businesses adding crypto checkout next to cards
What is included
- A gateway module in modules/gateways with admin settings and a test mode switch
- A callback file in modules/gateways/callback that marks invoices paid
- Webhook signature verification before any data is trusted
- Duplicate and out-of-order notification handling
- Refund support from the WHMCS admin area, where the gateway offers a refund API
- 3-D Secure handling for hosted, tokenized and renewal payments
- Sandbox test run covering success, decline, duplicate, refund and partial payment
- Written documentation and two weeks of post-delivery support
How the work runs
-
1
Read the gateway
I study the gateway's API reference and decide the design: hosted redirect, tokenized card storage or a mix. I list the events WHMCS needs to hear about and agree that with you.
-
2
Build in staging
I write the module and callback in a staging WHMCS reachable from the internet, with sandbox keys, so the gateway can actually send webhooks to it.
-
3
Break it on purpose
I run declines, expired sessions, repeated webhooks, late webhooks, partial amounts and refunds, and check that the invoice and the gateway dashboard always agree.
-
4
Go live carefully
I deploy with live keys, take one small real payment, check the invoice and callback log, then refund it. You approve each step.
-
5
Document and support
You get setup notes, a list of events handled and what to check when a payment looks wrong, plus two weeks of support.
Frequently asked questions
Can you integrate any payment gateway with WHMCS?
In most cases, yes, as long as the gateway publishes an API reference and a sandbox environment. That covers many card, wallet, bank and crypto processors. If the gateway has no sandbox or no documentation, I cannot test safely, and I will say so before quoting rather than build against a live account.
Do you store customer card numbers?
No. I use hosted payment pages, hosted fields or gateway tokens, so card numbers go to the gateway and never reach your WHMCS server or database. This keeps your PCI scope much smaller and removes the most dangerous data from your system. I will not build a module that stores card numbers or security codes.
Why do some invoices show as paid twice or stay unpaid?
Usually the callback does not handle repeated or delayed webhooks properly, or it trusts the data without checking the signature or amount. Gateways retry notifications, so the same event can arrive more than once. A correct callback records each transaction only once and checks the amount before marking an invoice paid.
Can customers pay in a currency different from the invoice?
Yes, if the gateway supports it. WHMCS can convert the invoice to a currency the gateway accepts, using the exchange rates you maintain. I then check the amount the gateway reports against the converted invoice balance, so a rate difference cannot leave an invoice paid short without anyone seeing it.
Can you add crypto payments to WHMCS?
Yes. I work with NowPayments and similar processors. The customer pays on a hosted crypto page, and a signed notification tells WHMCS when payment is confirmed. You decide how many confirmations you wait for and how underpayment and overpayment are handled. Crypto refunds are usually manual, and I will say so in the notes.
How long does a gateway integration take?
Typically four to twelve working days, depending on the gateway and the scope. A hosted redirect gateway with a clean API is quicker. Tokenized renewals, 3-D Secure, refunds and several currencies take longer. I give you a date once I have read the gateway's documentation.
Related services
-
WHMCS Custom Module Development
I build custom WHMCS modules for provisioning, addon, gateway and registrar jobs. Specced in writing, tested i...
-
WHMCS Security Audit and Hack Recovery
I review WHMCS for exposed admin areas, weak access, file and PHP settings, missed security releases and leake...
-
WHMCS Installation and Setup Service
I install and configure WHMCS so it can take real orders: requirements, cron, SSL, cPanel link, billing rules,...
-
WHMCS Support and Maintenance
Ongoing WHMCS care, hourly or monthly: staged upgrades, PHP changes, cron and backup checks, module updates an...
Ready to talk about your project?
Send the details and I reply within one business day with questions, an estimate and a plan.