Building Recurring Subscription Billing with 4Geeks Payments¶
Overview¶
4Geeks Payments provides robust tools for managing recurring payments and subscriptions, allowing you to automate billing cycles, handle upgrades/downgrades, and manage the full subscription lifecycle — all while handling tax compliance and fraud prevention as your Merchant of Record.
In this tutorial, you will:
- Create subscription plans
- Subscribe customers to plans
- Handle upgrades, downgrades, and cancellations
- Manage the Customer Self-Service Portal
- Handle failed payments and dunning
Prerequisites¶
- An activated 4Geeks Payments account
- API keys (Secret Key)
- Basic understanding of subscription business models
Step 1: Create Subscription Plans¶
Via API¶
const axios = require('axios');
const response = await axios.post('https://api.4geeks.io/v1/plans', {
name: 'Pro Plan',
amount: 4900, // $49.00 in cents
currency: 'USD',
interval: 'month', // 'week', 'month', 'year'
interval_count: 1, // Every 1 month
trial_period_days: 14, // 14-day free trial
metadata: {
features: 'Unlimited projects, Priority support, API access',
tier: 'pro'
}
}, {
headers: {
'Authorization': `Bearer ${SECRET_KEY}`,
'Content-Type': 'application/json'
}
});
console.log('Plan created:', response.data);
// plan_xxxxxxxxxxxxx
Plan Properties¶
| Property | Description | Example |
|---|---|---|
name | Display name of the plan | “Pro Plan” |
amount | Price in cents | 4900 ($49.00) |
currency | Currency code | “USD”, “EUR”, “CRC” |
interval | Billing frequency | “week”, “month”, “year” |
interval_count | Frequency multiplier | 1 (monthly), 3 (quarterly) |
trial_period_days | Free trial length | 14 |
metadata | Custom key-value pairs | { tier: "pro" } |
Step 2: Subscribe a Customer¶
Create Customer First¶
const customer = await axios.post('https://api.4geeks.io/v1/customers', {
email: 'customer@example.com',
name: 'Jane Smith',
metadata: {
company: 'Acme Corp',
signup_source: 'website'
}
}, {
headers: { 'Authorization': `Bearer ${SECRET_KEY}` }
});
const customerId = customer.data.id; // cus_xxxxxxxxxxxxx
Create Subscription¶
const subscription = await axios.post('https://api.4geeks.io/v1/subscriptions', {
customer_id: customerId,
plan_id: 'plan_xxxxxxxxxxxxx',
payment_method_id: 'pm_xxxxxxxxxxxxx', // From checkout form
billing_cycle_anchor: 'now', // or specific date
metadata: {
sales_rep: 'john@example.com'
}
}, {
headers: { 'Authorization': `Bearer ${SECRET_KEY}` }
});
console.log('Subscription created:', subscription.data);
// sub_xxxxxxxxxxxxx
Step 3: Handle Plan Changes¶
Upgrade a Subscription¶
const upgrade = await axios.post('https://api.4geeks.io/v1/subscriptions/sub_xxx/update', {
plan_id: 'plan_enterprise_xxx', // New plan ID
prorate: true, // Prorate the remaining period
billing_cycle_anchor: 'unchanged' // Keep existing cycle
}, {
headers: { 'Authorization': `Bearer ${SECRET_KEY}` }
});
Downgrade a Subscription¶
const downgrade = await axios.post('https://api.4geeks.io/v1/subscriptions/sub_xxx/update', {
plan_id: 'plan_basic_xxx',
prorate: false, // Apply at next billing cycle
billing_cycle_anchor: 'next_cycle'
}, {
headers: { 'Authorization': `Bearer ${SECRET_KEY}` }
});
Cancel a Subscription¶
const cancel = await axios.post('https://api.4geeks.io/v1/subscriptions/sub_xxx/cancel', {
cancel_at_period_end: true // Access continues until period ends
// Or set to false for immediate cancellation
}, {
headers: { 'Authorization': `Bearer ${SECRET_KEY}` }
});
Reactivate a Cancelled Subscription¶
const reactivate = await axios.post('https://api.4geeks.io/v1/subscriptions/sub_xxx/reactivate', {}, {
headers: { 'Authorization': `Bearer ${SECRET_KEY}` }
});
Step 4: Set Up the Customer Portal¶
The Customer Self-Service Portal allows subscribers to manage their own subscriptions.
Enable the Portal¶
- Go to Payments → Settings → Customer Portal
- Enable the portal
- Configure allowed actions:
- Update payment method
- View billing history
- Upgrade/downgrade plan
- Cancel subscription
- Download invoices
Embed the Portal¶
<!-- Redirect to hosted portal -->
<a href="https://pay.4geeks.io/portal/{{ customer.portal_token }}">
Manage Subscription
</a>
<!-- Or embed as iframe -->
<iframe
src="https://pay.4geeks.io/portal/{{ customer.portal_token }}"
width="100%"
height="800"
frameborder="0"
></iframe>
Generate Portal Token¶
const portal = await axios.post('https://api.4geeks.io/v1/customer-portal', {
customer_id: customerId,
return_url: 'https://yoursite.com/account/billing'
}, {
headers: { 'Authorization': `Bearer ${SECRET_KEY}` }
});
console.log('Portal URL:', portal.data.url);
Step 5: Handle Failed Payments (Dunning)¶
Automatic Retry Logic¶
4Geeks Payments automatically retries failed payments:
| Attempt | Timing |
|---|---|
| 1st retry | 3 days after failure |
| 2nd retry | 7 days after failure |
| 3rd retry | 15 days after failure |
Webhook Events for Failed Payments¶
// In your webhook handler
switch (event.type) {
case 'invoice.payment_failed':
// Notify customer about failed payment
sendEmail(customer.email, 'Payment Failed', {
amount: event.data.amount,
retry_date: event.data.next_retry_date
});
break;
case 'invoice.payment_succeeded':
// Confirm successful payment
sendEmail(customer.email, 'Payment Confirmed', {
amount: event.data.amount,
period: event.data.period
});
break;
case 'subscription.past_due':
// Subscription is past due after all retries failed
notifyAdmin('Subscription past due', {
customer: event.data.customer,
amount: event.data.amount
});
break;
case 'subscription.canceled':
// Subscription canceled after failed payments
notifyAdmin('Subscription canceled', {
customer: event.data.customer
});
break;
}
Custom Dunning Emails¶
Configure automated dunning emails in the console:
- Go to Payments → Settings → Dunning
- Customize email templates for:
- Payment failed notification
- Retry attempt notification
- Final notice before cancellation
- Subscription canceled notification
- Set timing for each email
Step 6: Monitor Subscription Metrics¶
Key Metrics to Track¶
| Metric | Description |
|---|---|
| MRR | Monthly Recurring Revenue |
| ARR | Annual Recurring Revenue |
| Churn Rate | % of subscribers who cancel per month |
| Expansion MRR | Revenue from upgrades |
| Contraction MRR | Revenue lost from downgrades |
| Net Revenue Retention | (Starting MRR + Expansion - Contraction - Churn) / Starting MRR |
Access Reports¶
- Go to Payments → Analytics → Subscriptions
- View real-time dashboards for all subscription metrics
- Export reports as CSV for further analysis
Best Practices¶
Pricing Strategy¶
- Offer annual billing with a discount (e.g., 20% off) to improve cash flow
- Use trial periods to reduce friction for new customers
- Implement grandfathered pricing for early adopters
- Consider usage-based or tiered pricing models
Reducing Churn¶
- Send usage reports to show value delivered
- Implement win-back campaigns for canceled subscribers
- Offer pause option instead of cancellation
- Provide proactive support before renewal dates
Compliance¶
- As Merchant of Record, 4Geeks handles tax compliance automatically
- PCI DSS compliance is built-in — card data never touches your servers
- GDPR compliance for EU customers
- Local payment regulations handled per jurisdiction
What’s Next?¶
- Learn about 3D Secure for Fraud Prevention
- Explore Multi-Currency Checkout
- Read about Tax Compliance as MoR
Need Help?¶
- Documentation: docs.4geeks.io/en/payments
- API Reference: docs.4geeks.io/en/api
- Support: Available through the console dashboard
Still questions? Ask the community.