Ozow Hub
On this page12 sections
Build with AI 1 package

A build package is every page for one task, with the API operations they use. Copy the prompt into a coding assistant, or hand it the package itself: slim links to each page, full inlines all of them in one document.

  • Take a recurring paymentEverything needed to collect from a customer on a schedule with One API, from the consent the customer gives once through to each collection and the webhook that reports it.
    View package

This guide walks you through integrating recurring payments via One API. Recurring payments follow a strict two-step process, a consent request that the customer approves once, followed by merchant-initiated collections that happen silently without any further customer action.

This guide uses the One API, Ozow's recommended API for new integrations. Recurring payments are not available on the older Payments API.

Limited availability

Recurring payments are available to approved merchants only. Contact your account manager or support@ozow.com to enquire about eligibility and onboarding.

Before you start

  • Recurring payments must be enabled on your merchant profile by Ozow: contact your account manager to confirm this before integrating
  • Your One API client must have the subscriptions scope, when creating your API client on the Ozow Dashboard, ensure this scope is included. Without it, all subscription endpoints will return an authorisation error
  • You have completed standard One API authentication setup: see Redirect: One API for the token flow
  • If your business operates in a high-risk industry, Customer Identity VerificationCustomer Identity Verification Checking that the payment instrument belongs to the natural person making the payment. Ozow requires it for merchants it has classified as high-risk, on Pay by Bank, Absa Pay, Capitec Pay, Nedbank Direct EFT, FNB Payment Requests and PayShap Request, and can disable those methods where it is not implemented correctly. must be built into the consent step: see Customer Identity Verification

RedirectRedirect Sending the payer to the Ozow payment page to complete the payment, and returning them to your site afterwards. The alternative is embedding the checkout in your own page, where the payer never leaves it. only

The consent step uses a redirect flow. Embedded integration is not supported for recurring payments. Your customer must be redirected to the Ozow-hosted consent page to approve the subscription.

Environments

Environment Base URL Dashboard
Production https://one.ozow.com/v1 dash.ozow.com
Staging https://stagingone.ozow.com/v1 stagingdash.ozow.com

How it works


Core integration

Create a subscription to initiate the consent process. The customer must approve the consent in their Capitec app before any collections can be made.

POST Create Subscription Reference
POST https://one.ozow.com/v1/subscriptions
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json

Request example

{
  "siteCode": "YOUR_SITE_CODE",
  "paymentMethod": "capitec",
  "amount": {
    "currency": "ZAR",
    "value": 500.00
  },
  "amountConstraints": {
    "min": { "currency": "ZAR", "value": 500 },
    "max": { "currency": "ZAR", "value": 600 }
  },
  "description": "Meal kit",
  "merchantReference": "SUB-001",
  "bankReference": "MEALKIT",
  "frequency": "Monthly",
  "firstPaymentDate": "2026-09-01",
  "occurrences": 12
}

Key request fields

Field Type Required Description
siteCode string Yes Your Ozow site codeSite code The unique code for a site registered under a merchant. A site is a place to transact: a website, or a branch of a store. A merchant can have several, and each transaction names the one it belongs to, so sending the wrong code files the payment against the wrong place.
paymentMethod string Recommended Must be capitec. Always specify this explicitly, when card support is added in future, omitting this field will show a payment method selection screen to the customer
amount.currency string Yes Must be ZAR
amount.value number Yes The recurring collection amount, at most 2 decimal places. Must fall inside the amountConstraints band
amountConstraints.min object Yes Lower bound the customer authorises, as currency and value. Whole RandZAR The ISO 4217 code for the South African rand, and the currency every amount on this site is in unless a page says otherwise. Amounts are decimal rand rather than cents, so 100.00 is one hundred rand., no cents
amountConstraints.max object Yes Upper bound the customer authorises, as currency and value. Whole Rand, no cents, at most 100000, and greater than min
description string Yes What the customer is subscribing to, shown to them. At most 20 characters
merchantReference string Yes Unique reference per subscription used for reconciliation. At most 50 characters, no spaces
bankReference string Yes The reference that appears on your bank statement for each payment. At most 20 characters, letters and numbers only
frequency string Yes Collection cadence, Daily, Weekly, Fortnightly, Monthly, Biannually, or Annually
firstPaymentDate string Yes Date from which collections may begin, today or later. Collections cannot be actioned before this date
occurrences number Yes Total number of collections, 1 to 120. For indefinite subscriptions use 120 and create a new subscription when the limit is reached
payableNow object No An immediate first charge, as amount and date. Not bound by amountConstraints
identity object No Customer identity as type, country, and identifier. Required for high-risk industries: see Customer Identity Verification

For the full request schema see One API reference.

Successful response

{
  "subscriptionId": "00000000-0000-0000-0000-000000000000",
  "status": "PendingAuthorization",
  "redirectUrl": "https://pay.ozow.com/subscriptions/00000000-0000-0000-0000-000000000000",
  "links": {
    "self": "https://one.ozow.com/v1/subscriptions/00000000-0000-0000-0000-000000000000",
    "cancel": "https://one.ozow.com/v1/subscriptions/00000000-0000-0000-0000-000000000000",
    "transactions": "https://one.ozow.com/v1/subscriptions/00000000-0000-0000-0000-000000000000/transactions"
  }
}

Store the subscriptionId, you will need it for all subsequent calls.


Redirect your customer's browser to the redirectUrl returned in the response. The customer will:

  1. Land on the Ozow payment page
  2. Enter their Capitec-linked cell phone number
  3. Approve the consent request in their Capitec app

3-minute window

Capitec allows 3 minutes for the customer to approve the consent request in their Capitec app. If the customer does not approve within this window, the consent request lapses and the subscription status changes to Expired. You must create a new subscription and redirect the customer through the consent flow again.

Once the customer approves, Capitec notifies Ozow and the subscription status updates from PendingAuthorization to Active. Only then can collections be actioned.

Customer Identity Verification

If your business operates in a high-risk industry, the Customer Identity Verification check must be included in this consent step; not in the action payment step. See Customer Identity Verification for requirements.


Step 3: Action a payment (trigger collection)

Once the subscription is Active and the firstPaymentDate has been reached, trigger a collection by calling the transaction endpoint.

POST Create Subscription Transaction Reference
POST https://one.ozow.com/v1/subscriptions/{subscriptionId}/transactions
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json

Replace {subscriptionId} with the ID returned in Step 1.

Request example

{
  "amount": { "currency": "ZAR", "value": 500.00 },
  "merchantReference": "SUB-001-SEP"
}

Both fields are required. amount.value must fall inside the amountConstraints band the customer authorised. merchantReference identifies this individual collection, not the subscription itself.

Pre-conditions

Ozow validates all of the following before processing the collection. The call will be rejected if any condition is not met:

  • The subscription exists and has Active status
  • Today's date is on or after the firstPaymentDate specified during consent creation
  • The number of collections has not exceeded the occurrences limit

The customer does not receive any authentication prompt, the debit happens silently based on the consent already granted.


Step 4: Handle the webhook notification

Ozow sends webhookWebhook A URL of yours that Ozow calls when something happens, rather than you polling to find out. The call carries no credential of yours and arrives at a public URL, so authenticate it before acting on it: a hash field on the Payments API, a Svix signature on One API. notifications for subscription events. Subscribe to these events in your One API client webhook configuration:

Event Description
subscription.authorization.success The customer approved the consent, and the subscription can be collected against
subscription.authorization.failed The consent was not approved
subscription.transaction.success An individual collection succeeded
subscription.transaction.failed An individual collection failed
subscription.completed The subscription took all its scheduled occurrences
subscription.canceled The subscription was cancelled. One l, unlike Canceled on the status
subscription.expired The authorisation lapsed before the subscription became active

Subscribe to the name exactly as written. An event name the service does not know is rejected, so a subscription to something close is a subscription that never fires.

Important

A subscription webhook is delivered as thin whatever message type you register it with, so data is the id, status and reason and nothing more. Fetch the subscription or the transaction for detail.

Handle these exactly as described in Step 4: Handle the webhook notification in the One API redirect guide, the same Svix signature verification process applies.


Subscription management

Action Endpoint Description
Get subscription GET /subscriptions/{id} Retrieve details of a specific subscription
List subscriptions GET /subscriptions?siteCode=&status=&limit=&offset= List subscriptions for a site, filterable by status. siteCode is required
Cancel subscription POST /subscriptions/{id}/cancel Cancel an active subscription, communicates directly with Capitec to cancel on their side
List transactions GET /subscriptions/{id}/transactions List all collections made under a specific subscription

Cancellation

Cancelling a subscription communicates directly with Capitec and cancels the consent on their side. This action cannot be undone. No further collections will be possible after cancellation.


Subscription statuses

Status Description
PendingAuthorization Subscription created, customer has not yet approved consent in the Capitec app
Active Customer has approved consent, collections can now be actioned
Canceled Subscription cancelled, no further collections possible
Completed All scheduled occurrences have been collected
Expired The authorisation lapsed before the subscription became active, create a new subscription
Failed The subscription could not be established or sustained
Unknown The status could not be determined

Note

Canceled uses a single l. An individual collection carries its own status, Pending, Successful, or Failed.


Go-live checklist


Next steps

In the API reference

13 entries

Last updated