How It Works
This integration connects Stripe’s Subscription API with HitPay’s Payment Request API, allowing customers to pay each invoice using local payment methods while keeping all subscription records in Stripe.Key Concepts
| Component | Purpose |
|---|---|
| Stripe Subscription | Manages subscription lifecycle with send_invoice collection method. Generates invoices each billing cycle. |
| HitPay Payment Request | Creates one-time payment requests (QR codes or redirect) for each invoice. |
| Stripe Payment Records | Records each HitPay payment in Stripe for unified reporting and reconciliation. |
API References
HitPay Payment Request API
Create payment requests with QR codes for one-time payments.
Stripe Subscriptions API
Manage subscription lifecycle and invoice generation.
Payment Flow
Step 1: Configure Custom Payment Methods
Register each HitPay payment method as a Custom Payment Method (CPM) type in your Stripe Dashboard and map those CPM Type IDs to HitPay method identifiers in a config file so they appear as options in your checkout.Create Custom Payment Methods on Stripe Dashboard
Stripe DashboardCreate Custom Payment Method types in your Stripe Dashboard for each HitPay payment method you want to offer.
Create CPM in Stripe Dashboard
Follow Stripe’s guide to create Custom Payment Method types and get your CPM Type IDs.
Download Payment Icons
Download official HitPay payment method icons (PayNow, ShopeePay, GrabPay, FPX, and more) optimized for Stripe Custom Payment Methods.
Step 2: Create Subscription
Create a Stripe Subscription withsend_invoice collection method, which tells Stripe to issue invoices that customers pay manually — rather than charging a saved payment method automatically.
Configure Environment Variables
Server-sideSet up the required API keys and configuration for both Stripe and HitPay.
Create Subscription with Send Invoice
Server-sideCreate a Stripe subscription with
send_invoice collection method. This creates invoices that customers pay manually each billing cycle.app/api/create-subscription/route.ts
app/api/create-subscription/route.ts
The key difference from auto-charge is
collection_method: 'send_invoice' with days_until_due: 0, which creates an invoice due immediately that customers pay manually.Step 3: Handle Invoice Payment
When the customer selects a HitPay payment method for an invoice, create a HitPay payment request, display the QR code for them to scan, and mark the invoice as paid once HitPay confirms the payment.Create HitPay Payment Request
Server-sideUse the same HitPay Payment Request endpoint from the one-time payments flow. When a customer selects a custom payment method, create a payment request for the invoice amount.
HitPay Payment Request
See the one-time payments guide for the HitPay payment request implementation.
Display QR Code and Poll for Payment
Client-sideShow the QR code or redirect URL and poll for payment completion. This is the same flow as one-time payments.
components/SubscriptionCheckoutForm.tsx
components/SubscriptionCheckoutForm.tsx
Step 4: Handle Future Invoices
Each billing cycle, Stripe automatically generates a new invoice. Since out-of-band subscriptions don’t use tokenized payment methods, customers pay each invoice manually using the same QR code flow — no webhook or automatic charge required.Future Invoice Flow
InfoEach billing cycle, Stripe automatically generates a new invoice. Since out-of-band subscriptions don’t use tokenized payment methods, customers pay each invoice manually using the same one-time payment flow.How it works:
- Stripe generates a new invoice at the start of each billing cycle
- You notify the customer (via email or your app) that a new invoice is ready
- Customer returns to your payment page and pays the invoice using any HitPay payment method
- The payment is recorded and the invoice is marked as paid
Unlike auto-charge subscriptions, there’s no webhook to automatically charge the customer. You can optionally set up a webhook for
invoice.created to send payment reminders.Testing
- Create a subscription with “Pay Each Invoice” option
- Select a CPM and scan the QR code
- Complete the mock payment in HitPay sandbox
- Verify:
- Invoice marked as
paid_out_of_bandin Stripe - Payment Record created (
prec_*) - Subscription is active
- Invoice marked as
FAQ
Why isn't the invoice being marked as paid?
Why isn't the invoice being marked as paid?
- Check that
paid_out_of_band: trueis passed toinvoices.pay() - Verify the Payment Record was created successfully
- Check server logs for API errors
Why isn't the QR code appearing?
Why isn't the QR code appearing?
- Verify the HitPay API key is correct
- Check that the payment method supports QR codes
- Ensure the amount and currency are valid
Why isn't the payment status updating?
Why isn't the payment status updating?
- Check that polling is running correctly
- Verify HitPay webhook is configured for real-time updates
- Check browser console for network errors