Charge Subscription

Charge a customer for an existing subscription.

This endpoint is used by the scheduler for automatic card renewals and can also be used to initiate manual checkout payments for supported manual payment methods.

Use Cases

Use CaseDescription
Auto-recurring card chargeCharges the customer’s saved card when a subscription is due. Usually triggered by EasyCron.
Manual checkoutCreates a checkout/payment flow for methods like mobile_money, bank_transfer, or bank.
Past-due retryRetries a failed card renewal while the subscription is PAST_DUE.

Currency Handling

For plans using Settlement Currency Mode, currency conversion is handled at charge time using the latest available rate.

Charge Subscription Details

FieldData TypeRequiredDescription
subscriptionIdstringYesThe subscription ID to charge. Get this from the subscription creation response
paymentMethodstringNoPayment collection method. Values: card (default), mobile_money, bank_transfer, bank
redirectUrlstringNoCustom redirect URL after checkout/payment. Useful for manual payment methods.

After collecting the necessary subscription details. Make a POST request to our subscription endpoint.

Note : Before making a post request, the secret key should be specified in the header.

-H "x-api-key: your_secret_key".
{{host}}/v1/subscriptions/charge
{
  "subscriptionId": "358yne17-306e-4f28-bd44-421952542549",
  "paymentMethod": "mobile_money",
  "redirectUrl": "https://merchant.com/thank-you"
}
{
  "status": true,
  "message": "Success",
  "code": 200,
  "data": {}
}

{
  "status": true,
  "message": "Success",
  "code": 201,
  "data": {
    "authorizationUrl": "https://checkout.provider.com/xxxx",
    "accessCode": "xxxx",
    "reference": "KYSHI-123456789"
  }
}

{
  "status": true,
  "message": "Success",
  "code": 200,
  "data": {
    "status": false,
    "message": "Insufficient funds",
    "subscriptionId": "358yne17-306e-4f28-bd44-421952542549",
    "isActive": false,
    "subscriptionStatus": "PAST_DUE",
    "nextRetryAt": "2026-05-02T10:00:00.000Z"
  }
}

Card Charge Behavior

For paymentMethod: "card"

Requirements

  • The subscription must be due.
  • The subscription must be ACTIVE or PAST_DUE.
  • A saved reusable card authorization must exist.

Charge Process

  • The system charges the saved card.
  • Duplicate charge attempts for the same subscription billing period are blocked using an internal idempotency lock.

If the Card Charge Succeeds

  • invoice.status = PAYMENT_SUCCEEDED
  • subscription.status = ACTIVE
  • subscription.isActive = true
  • retryCount = 0
  • pastDueAt = null
  • nextRetryAt = null
  • nextPaymentDate = next billing date

If the Card Charge Fails

  • invoice.status = PAYMENT_FAILED
  • subscription.status = PAST_DUE
  • subscription.isActive = false
  • retryCount increases
  • nextRetryAt is set

If Unpaid After Grace Period

  • subscription.status = CANCELLED
  • subscription.isActive = false

Manual Checkout Behavior

For paymentMethod: "mobile_money", bank_transfer, or bank

Flow

  • A checkout/payment flow is initialized.
  • A payment URL or provider response may be returned.
  • The customer must complete payment manually.
  • The subscription becomes active only after successful payment confirmation.

Important Notes

  • This endpoint should not be called repeatedly for the same due cycle.
  • We normally calls this endpoint automatically for card subscriptions.
  • The system prevents double-charging using an internal idempotency lock.
  • Card subscriptions are retried only while PAST_DUE and within the configured retry/grace window.
  • Manual payment methods require customer action each billing cycle.

Error Responses

HTTP StatusError CodeDescription
400VALIDATION_ERRORInvalid request body.
422UNPROCESSABLE_ENTITYSubscription not found or not eligible for charge.
422UNPROCESSABLE_ENTITYSubscription is not due yet.
422UNPROCESSABLE_ENTITYNo card attached for card payment method.
422UNPROCESSABLE_ENTITYNo FX rate found for settlement currency conversion.
422UNPROCESSABLE_ENTITYCard charge failed or provider returned an error.

What’s Next