Integration guide

WHMCS checkout

Connect WHMCS to HandyPay for one-time invoices and recurring subscriptions while keeping test and live billing completely separate.

Setup checklist

  1. Create an API key in the merchant portal. Start with an hp_test_ key.
  2. Store the key in the WHMCS gateway configuration. Never place it in client-side JavaScript or a public template.
  3. Use https://api.handypay.me/api/v1 as the API base URL.
  4. Register a webhook endpoint that can receive payment and subscription lifecycle events.
  5. Run a complete test invoice before replacing the key with an hp_live_ key.

Test safely

Test keys use a dedicated test account. Products, customers, payments, subscriptions, and webhook endpoints created with a test key cannot appear in live activity.

Verify test activity
curl https://api.handypay.me/api/v1/test-payments \
  -H "Authorization: Bearer hp_test_your_api_key_here"
bash

The same activity is visible under Test Mode in the HandyPay merchant portal.

Checkout behavior

Create a hosted payment session for each WHMCS invoice. HandyPay shows eligible payment methods for the merchant, currency, customer, and device. Card checkout remains available when an additional method is not eligible.

Create an invoice checkout
curl -X POST https://api.handypay.me/api/v1/payment-sessions \
  -H "Authorization: Bearer hp_test_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "line_items": [{
      "amount": 4999,
      "currency": "usd",
      "name": "WHMCS invoice #1042",
      "quantity": 1
    }],
    "customer_email": "buyer@example.com",
    "success_url": "https://billing.example.com/payment-complete",
    "cancel_url": "https://billing.example.com/viewinvoice.php?id=1042",
    "metadata": { "whmcs_invoice_id": "1042" }
  }'
bash

Subscriptions and seats

Create a subscription product once, then create a subscription session for the customer. Set quantity for per-seat billing. Active subscriptions can be updated without replacing them.

Change an active seat count
curl -X PATCH https://api.handypay.me/api/v1/subscriptions/sub_123/quantity \
  -H "Authorization: Bearer hp_test_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "quantity": 8,
    "proration_behavior": "create_prorations"
  }'
bash
  • create_prorations places the adjustment on the next invoice.
  • always_invoice invoices the adjustment immediately.
  • none changes the seat count without a prorated adjustment.

Webhooks

Register the WHMCS callback URL with the same key mode used by checkout. A test endpoint receives test events only, and a live endpoint receives live events only.

Register a test webhook
curl -X POST https://api.handypay.me/api/v1/webhook-endpoints \
  -H "Authorization: Bearer hp_test_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://billing.example.com/modules/gateways/callback/handypay.php",
    "events": [
      "payment_intent.succeeded",
      "payment_intent.payment_failed",
      "customer.subscription.updated",
      "customer.subscription.deleted"
    ]
  }'
bash

Troubleshooting

Only card is shown: the other methods are not eligible for that account, currency, customer, or device. Card is the supported fallback.

A test payment is missing: confirm the request used an hp_test_ key, then check the portal Test Mode workspace or GET /v1/test-payments.

WHMCS is not updating: confirm the callback URL is public HTTPS, verify the webhook signature against the raw request body, and return a successful 2xx response only after the invoice update succeeds.