Implement out-of-band subscriptions with Stripe Custom Payment Methods and HitPay
Out-of-band subscriptions allow customers to pay each invoice manually using any HitPay payment method. This is the same flow as one-time payments, repeated per billing cycle. This approach works with all payment methods including QR-based ones like PayNow that cannot be tokenized.
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.
Out-of-band subscriptions work with all payment methods since each invoice is paid as a one-time payment. This is ideal for QR-based methods like PayNow that cannot be tokenized.
Server-sideMap your Stripe CPM Type IDs to HitPay payment methods. For out-of-band subscriptions, you only need the hitpayMethod (one-time payment method).
Server-sideSet up the required API keys and configuration for both Stripe and HitPay.
Copy
Ask AI
# Stripe (Standard Account Keys)NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_xxxSTRIPE_SECRET_KEY=sk_test_xxx# HitPayHITPAY_API_KEY=xxxHITPAY_SALT=xxxNEXT_PUBLIC_HITPAY_ENV=sandbox # or 'production'
Never expose your STRIPE_SECRET_KEY or HITPAY_API_KEY to the client. These should only be used server-side.
2
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.
Copy
Ask AI
// app/api/create-subscription/route.tsimport { NextResponse } from 'next/server';import { stripe } from '@/lib/stripe';export async function POST(request: Request) { const { priceId, email } = await request.json(); // Create or retrieve customer let customer; const existingCustomers = await stripe.customers.list({ email, limit: 1 }); if (existingCustomers.data.length > 0) { customer = existingCustomers.data[0]; } else { customer = await stripe.customers.create({ email }); } // Create subscription with manual invoice payment const subscription = await stripe.subscriptions.create({ customer: customer.id, items: [{ price: priceId }], collection_method: 'send_invoice', days_until_due: 0, // Invoice due immediately payment_settings: { payment_method_types: ['card'], }, }); // Finalize invoice to get PaymentIntent const invoice = await stripe.invoices.retrieve(subscription.latest_invoice as string); const finalizedInvoice = await stripe.invoices.finalizeInvoice(invoice.id); // Get client secret for Payment Element let clientSecret: string; if (finalizedInvoice.payment_intent) { const pi = await stripe.paymentIntents.retrieve( finalizedInvoice.payment_intent as string ); clientSecret = pi.client_secret!; } else { // Create a UI PaymentIntent if needed const pi = await stripe.paymentIntents.create({ amount: finalizedInvoice.amount_due, currency: finalizedInvoice.currency, customer: customer.id, metadata: { invoice_id: finalizedInvoice.id }, }); clientSecret = pi.client_secret!; } return NextResponse.json({ subscriptionId: subscription.id, invoiceId: finalizedInvoice.id, clientSecret, customerId: customer.id, billingType: 'out_of_band', type: 'payment', });}
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.
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.
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.