Trigger order intermediate action
[POST] /api/v2/order/intermediate-action
Drives the step between creating an order and the user actually paying. What it does depends on the deposit's transfer type:
otp_stk_push
Submits the OTP code the user received by SMS or WhatsApp. That unlocks the USSD prompt.
stk_push
Sends a new USSD prompt to the user's phone. Use it when the first one did not arrive.
redirect
Accepted, but a no-op. See below.
Only call this on stk_push, otp_stk_push or redirect. On other transfer types — including the manual bank flow — most providers reject it outright with 400 "Provider does not support post-initializing deposit". It is not a harmless no-op.
This endpoint also requires the end-user-creation capability on your account; without it every call returns 403. See Integration guide.
Before you call
Check order.deposit.transferInstructions:
isIntermediateActionAvailablemust betrue.Now must be at or after
intermediateActionNextAttemptAvailableAt.intermediateActionAttemptsmust still be belowintermediateActionMaxAttempts.fieldsForIntermediateActionlists what to send —otpCodeonotp_stk_push, nothing on a plainstk_pushretry.
Do not call it once the attempts are exhausted. A call made when intermediateActionAttempts has already reached intermediateActionMaxAttempts does not fail harmlessly — it moves the order to deposit_expired and then returns 400 "The order is expired". Count the attempts on your side and stop before the cap.
See Transfer types explanation for worked examples of both push types.
Request
Submitting an OTP code:
Retrying an STK push:
Response
Returns the updated order — the same Order object as Get order.
On stk_push and otp_stk_push, read deposit.transferInstructions again: intermediateActionAttempts, intermediateActionNextAttemptAvailableAt and intermediateActionExecuted will have moved, and they tell you whether another retry is allowed.
On redirect nothing moves. The call exists so that a client which treats every transfer type the same is not rejected; it records nothing and none of the counters change. Sending the user to transferInstructions.paymentUrl is what actually matters.
Last updated

