Skip to main content

Prerequisites

API key permissions

Subscriptions use the same HUB2 API keys and the same ApiKey, MerchantId and Environment headers as the rest of the API. Grant the key the permissions required by the endpoints you call.

API Keys

Account requirements

  • Your merchant must be registered in Côte d’Ivoire. Otherwise, a subscription intent is refused with a 403 error and the code card_on_file_ineligible_country.
  • Card-on-file must be enabled for your merchant by HUB2. Otherwise, a subscription intent is refused with a 403 error and the code card_on_file_disabled.
  • The same two conditions apply to a subscription link. The link can be created, but the customer cannot complete the enrollment from its page.
  • A closed or suspended merchant cannot use these endpoints (403, codes merchant_closed and merchant_suspended).
  • A parent merchant that owns submerchants must call the endpoints with the MerchantId of the submerchant. With its own MerchantId, it receives a 403 error with the code group_owner_transaction_forbidden. A submerchant only sees and manages the subscriptions it enrolled. See submerchants.

Enroll a customer

Enrollment stores the customer card and creates the subscription. Choose one of the two methods. Create a subscription link The link describes the recurring debit. Share the URL returned in the response with your customer.
When you omit successUrl or failureUrl, the customer lands on a result page hosted by HUB2. The response is a link object. The url field is the page to share, and status is active until the link is used or expires.
Creating a link with the purchaseReference of a link that is still active returns that existing link instead of creating a new one.

What the customer sees

1

The enrollment page

The customer opens the link. The page shows your business name and the recurring amount. The customer enters an e-mail address, ticks the consent box that authorizes the recurring debits, and clicks the enrollment button.
2

The card page

The customer is sent to a secure card page to enter the card and complete the 3D Secure authentication. The customer is not charged at this stage.
3

The return

The customer comes back to your successUrl or failureUrl.
The link is single use. It becomes completed as soon as the customer has been sent to the card page, whatever the final result of the card authentication. If HUB2 refuses the enrollment before the card page, the link stays active and the customer can try again.
Do not use the payment_links.completed or payment_links.paid webhooks, or a redirection to your successUrl, as proof that the subscription exists. Wait for the subscription.created webhook, or list the subscriptions with customerId set to your purchaseReference.

Enroll with a subscription intent

Enroll a customer A subscription intent is created in three steps:
  1. Create the subscription intent from your server.
  2. Send the customer to the card page, by performing the action returned by the API.
  3. Retrieve the outcome of the enrollment.

1. Create the subscription intent

Collect the customer consent in your interface before the call. The consent is mandatory: the request is rejected when it is missing or when given is not true. A scheduled subscription requires amount, frequency and startDate. An on-demand subscription does not accept frequency or startDate, because nothing is scheduled. For an on-demand subscription, amount is ignored in the live environment, but still validated when sent; in sandbox it selects the simulated outcome.
The consent object has three fields:
The consent reference must be unique within your merchant account, submerchants of your group included. Another HUB2 merchant may use the same value. Use a UUID, optionally with a prefix, as in the example. Reusing a reference to retry the same enrollment of the same customer is safe. A reference already used for another customer, or already enrolled for another submerchant of your group, makes the enrollment fail with the failure cause consent_reference_in_use, after the customer has completed the card page. A reference already enrolled in the other mode (sandbox or live), or, for a submerchant, already used by its group owner or another submerchant, is refused immediately with a 409 error and the code card_on_file_consent_reference_in_use when the subscription intent is created.
The response contains the id of the enrollment payment and its status. Keep the paymentId: it identifies the enrollment in the next steps.

2. Send the customer to the card page

When status is action_required, action has the same shape as the nextAction of a payment. Build a form from action.data.url, action.data.method and the fields of action.data.data, and submit it from the customer browser.
The customer enters the card, completes the 3D Secure authentication and comes back to onSuccessRedirectionUrl or onFailedRedirectionUrl. If HUB2 has not recorded an outcome yet when the customer returns, the customer is sent to the failure URL. A redirection is therefore not enough to conclude: always confirm the outcome with the status endpoint or the subscription.created webhook.

3. Retrieve the outcome of the enrollment

Retrieve an enrollment status Subscribe to the subscription.created webhook to learn that the enrollment succeeded. No webhook is sent when an enrollment fails, so poll the status of the enrollment to detect failures and abandoned enrollments.
A failed enrollment returns a failureCause with a code, a message and, for invalid parameters, the list of the parameters concerned in params.
The failure causes specific to an enrollment are: An enrollment can also fail with the other card failure causes, for example card_declined or card_expired. See the complete list in Failure causes for payments. Handle unknown codes as a generic failure. The status endpoint answers 404 when no enrollment with this id belongs to your merchant in the current environment.
This endpoint is limited to 5 requests per 5 seconds for the same enrollment. Beyond that, the API returns HTTP 429 - Too Many Requests. Poll every few seconds and stop once the status is successful or failed. See the rate limits.

Manage subscriptions

Use the id of the subscription, returned as subscriptionId by the enrollment status endpoint, in the endpoints below.

Subscription statuses

List subscriptions

Retrieve a subscription collection
The following filters are available: customerId (exact match on your customer reference), billingMode (rbs_scheduled or merchant_initiated) and status. The results are paginated with page (default 1) and perPage (default 10), and the Content-Range header gives the range and the total. The response is an array of subscriptions. Each item looks like this:
For an on-demand subscription, cybersourceSubscriptionId, frequency, amount and startDate are null.

Suspend a subscription

Suspend a subscription
Only an active or delinquent subscription can be suspended. The call returns the updated subscription and triggers the subscription.suspended webhook. The API does not offer an operation to resume a suspended subscription.

Cancel a subscription

Cancel a subscription
Cancellation is final. It stops future debits only: HUB2 does not refund or prorate any amount already debited. To take a customer back, enroll the customer again.
An active, suspended or delinquent subscription can be cancelled. The call returns the updated subscription and triggers the subscription.cancelled webhook. Cancelling a cancelled or completed subscription is refused with a 409 error.

Charge an on-demand subscription

Charge a subscription Only a merchant_initiated subscription in the active status can be charged.
The response describes the charge:
Amounts in the response, the history and webhooks are decimal strings in major units: a charge of 1500 XOF returns "1500.00", a charge of 1500 EUR cents returns "15.00". indicator is MIT for a debit that you or HUB2 initiate on the stored card, and CIT for an operation initiated by the customer. Retry safely. The reference is your idempotency key for a given subscription. After a timeout or a 5xx error, send the same request again with the same reference and the same amount: the card is never charged twice, and the call returns the charge once its outcome is known. Reusing a reference with a different amount is refused with a 409 error. Use a new reference for each new charge. On-demand charges do not trigger payment.succeeded or payment.failed webhooks. The response of the call and the charge history give the result.

Retrieve the charge history

Retrieve a subscription charge history
The history lists the debits of a subscription, most recent first, with the same page, perPage and Content-Range behavior as the subscription list. Each item has an id, an amount (a decimal string such as "5000.00"), a status (pending, success or failed), a transactionDate, the indicator, and the merchantReference you sent for an on-demand charge (null for a scheduled debit). A scheduled debit first appears as pending. Its final status is set once HUB2 has confirmed the outcome, which can take some time after the debit date.

Webhooks

Subscriptions use the usual webhook mechanism. Register an endpoint and subscribe to the events below. See the Webhooks Integration Guide. The data object of each event contains the fields below. Amounts are decimal strings in major units ("15.00" for 15 EUR).

Important

The data of a scheduled debit differs from the data of a one-off payment: it has no payment id or intentId. Check for subscriptionId before reading data.id: when it is present, the event is a scheduled debit, and a handler that reads data.id first gets no value.
To match an event with a subscription:
  • subscriptionId in the events is the value of the cybersourceSubscriptionId field of the subscription, not its id.
  • transactionReference is the value of the cybersourceReference field of the debit in the charge history.
  • customerId is the customerReference of the intent, or the purchaseReference of the link.
  • For an on-demand subscription, subscriptionId is null, and frequency, amount and startDate are null in subscription.created. Match the event with customerId, and list the subscriptions with this customerId to get the id.
The payment.failed event does not contain a failure cause.

Errors

The API reference lists the HTTP status codes of each endpoint. The error format is described in Error management.

Sandbox

In the sandbox environment, no real card page is displayed. The outcome of an enrollment is simulated, and you read it with the enrollment status endpoint. For a scheduled subscription, the amount of the request selects the outcome: For an on-demand subscription, omit amount to simulate a successful enrollment. Other values select the outcome in the same way as in the table.