Skip to main content

Mobile Money Subscriptions

Spotflow supports recurring billing through mobile money, allowing you to charge customers on a set schedule using their mobile money wallets.
How MoMo subscriptions differ from card subscriptionsCard subscriptions charge the customer automatically in the background after the first payment. Mobile money networks do not allow silent background charges. Because of telecom rules, the customer must approve each recurring payment directly on their phone.Spotflow handles this with a semi-automated workflow that sends reminders, renewal links, payment prompts, and retries on your behalf.

What Spotflow Handles for You

  • Reminder emails sent to customers before their next billing date
  • Renewal checkout links included in every reminder so customers can pay early
  • Direct phone prompts (STK Push) sent on the due date for one-tap approval
  • Automatic retries if the due-date payment fails
  • Webhooks sent to your server whenever a subscription changes state

Supported Regions and Providers

CountryProvider
GhanaMTN Mobile Money, Vodafone Cash, AirtelTigo Money
KenyaM-Pesa
Support for more providers and regions is ongoing. Contact support@spotflow.one to check availability for your requested region.

How Card and Mobile Money Subscriptions Compare

Card SubscriptionsMobile Money Subscriptions
How recurring charges workCard token stored after first paymentCustomer approves each renewal
Customer action requiredFirst payment onlyPhone prompt approval on each due date
Renewal triggerAutomatic via stored tokenAutomatic phone prompt on due date
Failure scenarioCard decline or expiryInsufficient balance, prompt ignored, or timeout
Supported currenciesUSD, NGN, GHS, and othersDepends on provider and region

The Subscription Lifecycle

1

Create a Subscription Plan

Before subscribing a customer, create a plan that sets the price, currency, and billing frequency.
    {
      "title": "Standard Monthly Plan",
      "frequency": "monthly",
      "internalReference": "PLAN-STD-001",
      "pricingOptions": [
        { "amount": 123, "currency": "NGN" }
      ]
    }
See Create Plan below for all available fields including trials, cycle limits, and end dates.
2

Collect the First Payment

Start the subscription by initiating a payment with the customer’s mobile money details and the planId.
    {
      "reference": "SUB-10001",
      "planId": "9743add1-5f71-4d8d-a2aa-1ec5dc554a93",
      "currency": "GHS",
      "localCurrency": "GHS",
      "amount": 10,
      "channel": "mobile_money",
      "customer": {
        "name": "John Doe",
        "phoneNumber": "233XXXXXXXXX",
        "email": "john@example.com"
      },
      "mobileMoney": {
        "phoneNumber": "233XXXXXXXXX",
        "provider": "telecel"
      }
    }
If you omit planId, the payment is treated as a one-time charge, not a subscription.
Once the first payment succeeds, the subscription becomes active and the billing cycle begins.
3

Receive Renewal Reminders

Spotflow automatically sends reminder emails with a secure checkout link before each billing date.
  • Weekly plans: Reminder sent 3 days before expiry
  • Monthly and yearly plans: Reminders sent 1 week before expiry, then again 3 days before
4

Due Date Prompt

If the customer has not renewed early using the checkout link, Spotflow sends an automatic payment prompt directly to their phone on the due date. The customer approves it by entering their mobile wallet PIN.
5

Handle Retries or Cancellation

If the due-date payment fails:
  • A retry email with a fresh checkout link is sent every 3 days after the due date
  • If no payment is received by the 4th day after the due date, the subscription is automatically cancelled

Create Plan

Endpoint: POST /api/v1/plans
{
  "title": "Standard Monthly Plan",
  "frequency": "monthly",
  "internalReference": "PLAN-STD-001",
  "pricingOptions": [
    { "amount": 123, "currency": "NGN" }
  ],
  "trial": {
    "periodInDays": 7,
    "pricingList": [
      { "amount": 0, "currency": "NGN" }
    ]
  },
  "endDate": "2026-10-29",
  "cycleCount": 3,
  "retrial": 2
}

Request Body

FieldTypeRequiredDescription
titlestringYesName of the subscription plan
frequencystringYesHow often to bill: weekly, monthly, yearly
internalReferencestringYesYour own internal reference for the plan
pricingOptionsarrayYesList of prices per currency
trialobjectNoTrial configuration. See Plan Trials
endDatedatetimeNoThe date all subscription cycles end
cycleCountintegerNoMaximum number of billing cycles before the subscription completes
retrialintegerNoNumber of retry attempts for failed payments. Applies to card subscriptions only

Retrial Limits by Frequency

FrequencyMaximum Retries
Hourly2
Daily6
Weekly9
Monthly10
Yearly10
retrial defaults to 0, which means no retries. Set a value above 0 to enable automatic payment retries on card subscriptions.

Subscription Statuses

StatusWhat it means
activeThe subscription is running and waiting for the next billing cycle
failedAll retry attempts were exhausted and payment was never collected
completedThe subscription reached its set end date or cycle count
cancelledThe subscription was stopped by you, the customer, or the system after non-payment

Subscription Management Endpoints

MethodEndpointDescription
GET/subscriptionsReturns a paginated list of all subscriptions
GET/subscriptions/{subscription-id}Returns details for a single subscription
GET/subscriptions/count/{plan-id}Returns a count of subscriptions grouped by status for a plan
POST/subscriptions/{subscription-id}/activateReactivates a cancelled subscription
POST/subscriptions/{subscription-id}/cancelCancels an active subscription

Webhooks and Events

Spotflow sends a POST request to your webhook URL whenever a subscription changes state. All events share the same payload structure.

Payload Structure

{
  "event": "event_name",
  "data": {
    "id": "subscription-id",
    "customerId": "customer-id",
    "planId": "plan-id",
    "status": "subscription-status",
    "amount": 10,
    "currency": "GHS",
    "regionName": "Ghana",
    "startDate": "2026-05-15T12:55:45.407Z",
    "nextPaymentDate": "2026-05-22T12:55:45.407Z",
    "createdAt": "2026-05-15T12:55:45.408Z",
    "metadata": {}
  }
}

Event Reference

EventWhen it fires
subscription_createdA new subscription was created successfully
subscription_activatedA cancelled subscription was reactivated
subscription_renewedA recurring payment succeeded before expiry
subscription_cancelledA subscription was cancelled
subscription_payment_failedA single recurring payment attempt failed
subscription_failedAll retry attempts were exhausted and the subscription failed
subscription_completedThe subscription reached its configured end condition
{
  "event": "subscription_created",
  "data": {
    "id": "913e4921-60e0-4883-b042-aa57d7b97380",
    "customerId": "fdfa9e33-babb-44da-add0-a48a9b2e5854",
    "planId": "9743add1-5f71-4d8d-a2aa-1ec5dc554a93",
    "status": "active",
    "amount": 10,
    "currency": "GHS",
    "regionName": "Ghana",
    "startDate": "2026-05-15T12:55:45.407Z",
    "nextPaymentDate": "2026-05-22T12:55:45.407Z",
    "createdAt": "2026-05-15T12:55:45.408Z",
    "metadata": {}
  }
}
{
  "event": "subscription_activated",
  "data": {
    "id": "913e4921-60e0-4883-b042-aa57d7b97380",
    "customerId": "fdfa9e33-babb-44da-add0-a48a9b2e5854",
    "planId": "9743add1-5f71-4d8d-a2aa-1ec5dc554a93",
    "status": "active",
    "amount": 10,
    "currency": "GHS",
    "regionName": "Ghana",
    "startDate": "2026-05-15T12:55:45.407Z",
    "nextPaymentDate": "2026-05-22T12:55:45.407Z",
    "createdAt": "2026-05-15T12:55:45.408Z",
    "metadata": {}
  }
}
{
  "event": "subscription_renewed",
  "data": {
    "id": "913e4921-60e0-4883-b042-aa57d7b97380",
    "customerId": "fdfa9e33-babb-44da-add0-a48a9b2e5854",
    "planId": "9743add1-5f71-4d8d-a2aa-1ec5dc554a93",
    "status": "active",
    "amount": 10,
    "currency": "GHS",
    "regionName": "Ghana",
    "startDate": "2026-05-15T12:55:45.407Z",
    "nextPaymentDate": "2026-05-22T12:55:45.407Z",
    "createdAt": "2026-05-15T12:55:45.408Z",
    "metadata": {}
  }
}
{
  "event": "subscription_cancelled",
  "data": {
    "id": "913e4921-60e0-4883-b042-aa57d7b97380",
    "customerId": "fdfa9e33-babb-44da-add0-a48a9b2e5854",
    "planId": "9743add1-5f71-4d8d-a2aa-1ec5dc554a93",
    "status": "cancelled",
    "amount": 10,
    "currency": "GHS",
    "regionName": "Ghana",
    "startDate": "2026-05-15T12:55:45.407Z",
    "nextPaymentDate": "2026-05-22T12:55:45.407Z",
    "createdAt": "2026-05-15T12:55:45.408Z",
    "metadata": {}
  }
}
{
  "event": "subscription_payment_failed",
  "data": {
    "id": "913e4921-60e0-4883-b042-aa57d7b97380",
    "customerId": "fdfa9e33-babb-44da-add0-a48a9b2e5854",
    "planId": "9743add1-5f71-4d8d-a2aa-1ec5dc554a93",
    "status": "active",
    "amount": 10,
    "currency": "GHS",
    "regionName": "Ghana",
    "startDate": "2026-05-15T12:55:45.407Z",
    "nextPaymentDate": "2026-05-22T12:55:45.407Z",
    "createdAt": "2026-05-15T12:55:45.408Z",
    "metadata": {}
  }
}
{
  "event": "subscription_failed",
  "data": {
    "id": "913e4921-60e0-4883-b042-aa57d7b97380",
    "customerId": "fdfa9e33-babb-44da-add0-a48a9b2e5854",
    "planId": "9743add1-5f71-4d8d-a2aa-1ec5dc554a93",
    "status": "failed",
    "amount": 10,
    "currency": "GHS",
    "regionName": "Ghana",
    "startDate": "2026-05-15T12:55:45.407Z",
    "nextPaymentDate": "2026-05-22T12:55:45.407Z",
    "createdAt": "2026-05-15T12:55:45.408Z",
    "metadata": {}
  }
}
{
  "event": "subscription_completed",
  "data": {
    "id": "913e4921-60e0-4883-b042-aa57d7b97380",
    "customerId": "fdfa9e33-babb-44da-add0-a48a9b2e5854",
    "planId": "9743add1-5f71-4d8d-a2aa-1ec5dc554a93",
    "status": "completed",
    "amount": 10,
    "currency": "GHS",
    "regionName": "Ghana",
    "startDate": "2026-05-15T12:55:45.407Z",
    "nextPaymentDate": "2026-05-22T12:55:45.407Z",
    "createdAt": "2026-05-15T12:55:45.408Z",
    "metadata": {}
  }
}

Cancelling a Mobile Money Subscription


Best Practices

  • Always collect the customer’s phone number at sign-up. Spotflow needs it to send the payment prompt to the right wallet.
  • Tell customers what to expect. Let them know upfront that they will receive a phone prompt to approve recurring charges. Unexpected prompts are the most common reason for declines.
  • Build a re-enrolment flow. If a mandate expires or a subscription is cancelled due to non-payment, customers should be able to restart easily with the same plan.
  • Notify before the first charge after a trial. Spotflow triggers the charge automatically when a trial ends. Send your own reminder 24 hours before so the customer expects the prompt and has funds in their wallet.
  • Test everything in test mode first. Simulate approvals, failures, and retries before going live.
Free trials and discounts are fully supported for mobile money subscriptions. See Plan Trials, Discounts & Currency Rules.

Need Help?

Reach out to the Spotflow team at support@spotflow.one