Insurance
API Path
Cancellation and Premium Refund

Cancellation and Premium Refund

Policy cancellation and premium refund are separate operations:

OperationEndpointWhat it does
Policy cancellationPOST /api/v1/insurance/orders/{orderId}/cancelOpens a cancellation request at the provider for the issued policies. Does not refund the premium.
Premium refundPOST /api/v1/insurance/orders/{orderId}/refund-premiumRefunds the premium to the buyer or records a refund you made outside Lunixi.

To refund the premium of a policy in force, first cancel the policy, then refund the premium. This way the buyer does not remain insured without a premium.

Idempotency-Key is required on both endpoints. Authentication and signing: Flows › Authentication.

Policy cancellation

POST /api/v1/insurance/orders/{orderId}/cancel takes no body.

  • The order's policy status must be ISSUED or PARTIALLY_ISSUED. A cancellation request is opened at the provider for every issued policy.
  • If no policy was issued, there is no policy to cancel: 409 insurance.order.state_conflict (reason: policy_not_issued). Refund the premium of a policy that was not issued with a premium refund.
  • If the cancellation was already requested or has a result, the order is returned as it is.
source lunixi-sign.sh
REQ_PATH="/api/v1/insurance/orders/<orderId>/cancel"
lunixi_sign POST "$REQ_PATH"
 
curl -X POST "https://api-gateway.lunixi.com$REQ_PATH" \
  -H "Idempotency-Key: cancel-order-1001" \
  -H "X-Key-Id: $LUNIXI_KEY_ID" \
  -H "X-Date: $DATE" \
  -H "X-Nonce: $NONCE" \
  -H "X-Signature: $SIGNATURE"

The result is finalized later

The provider processes the cancellation request in its own process; the result is not returned immediately.

Policy cancellationState machine: a cancellation request moves an issued policy to CANCEL_PENDING; the provider either cancels it (CANCELLED) or rejects the request, in which case the policy stays in force as ISSUED and errorCode becomes insurance.policy.cancel_failed.POST …/cancelCANCELLEDDECLINEDISSUEDor PARTIALLY_ISSUEDCANCEL_PENDINGdocument still availableCANCELLEDno documenterrorCode: insurance.policy.cancel_failedLEGENDIN FORCERESULT PENDINGFINAL
The provider decides in its own process; follow the result on the order endpoint, per policy in policies[].policyStatus.
MomentThe order's policy status
ResponseCANCEL_PENDING: cancellation requested, result pending.
The provider cancelled all policiesCANCELLED
The provider rejected the cancellationThe policy remains in force: ISSUED or PARTIALLY_ISSUED. errorCode becomes insurance.policy.cancel_failed.

Track the result through the order endpoint. The status per policy is in policies[].policyStatus. The document of a policy pending cancellation is available; the document of a cancelled policy is not.

Premium refund

POST /api/v1/insurance/orders/{orderId}/refund-premium refunds the premium of an order whose premium was collected.

Policy statusResult
FAILED_FINAL, CANCEL_PENDING, CANCELLEDThe refund starts.
NOT_REQUESTEDThe refund starts. If steps at the provider (such as forwarding the payment notification) are still running, 409, reason: policy_in_progress; retry later.
ISSUED, PARTIALLY_ISSUED409, reason: policy_active. Cancel the policy first.
PENDING, UNKNOWN, FAILED_RETRYABLE409, reason: policy_in_progress. Wait for the policy's final result.
  • If the premium was not collected, there is no premium to refund: 412 insurance.premium.not_captured.
  • If the refund is in progress or completed, the order is returned as it is.
  • After the refund starts, the policy cannot be requested. If the policy is still issued after the refund started, the refund is not reversed; a cancellation is requested for the policy automatically. See Concepts › Refund required.

Premium in a Lunixi payment

If the premium was collected in a Lunixi payment, send no body. A partial refund of the premium amount is made from that payment.

MomentRefund status
ResponsePENDING: refund started.
Refund completedREFUNDED; refundedAt is set.
Refund rejectedFAILED; refundErrorCode becomes insurance.refund.rejected. You can start the refund again.

If you send externalRefund for this order, the request returns 422 insurance.validation.invalid (field: externalRefund, reason: not_allowed).

Refund outside Lunixi

If you collected the premium outside Lunixi (confirm-payment), you also make the refund through your own channel and report it to the API. externalRefund is required.

FieldTypeRequiredDescription
externalRefund.externalRefundIdstringYesThe refund ID on your side; 1-128 printable ASCII characters.
externalRefund.refundedAtstringYesThe moment of the refund. ISO 8601 with a time zone; cannot be in the future or before the payment.
{
  "externalRefund": {
    "externalRefundId": "refund-1001",
    "refundedAt": "2025-12-21T09:00:00+03:00"
  }
}
  • In the response the refund status becomes REFUNDED.
  • Repeating with the same externalRefundId returns the order as it is. Sending a different ID for a completed refund returns 409 (reason: already_refunded).

Refund required

If the premium was collected but the policy definitively could not be issued, the order has:

  • policy FAILED_FINAL,
  • refund REQUIRED,
  • overall status FAILED, and errorCode carries the Lunixi code of the error.

In this case the premium must be refunded to the buyer. Refund the premium with the premium refund endpoint. Track your orders' refundStatus field through the order endpoint.

Errors

HTTPcodeWhat to do
404insurance.order.not_foundThe order was not found.
409insurance.order.state_conflictSee details.reason: policy_not_issued, policy_active, policy_in_progress, already_refunded, collected_by_provider.
412insurance.premium.not_capturedThe premium was not collected; there is no premium to refund.
412insurance.provider.not_integratedCancellation is not available right now at the provider in your connection.
422insurance.validation.invalidFix the externalRefund fields; details.errors[] lists the violations.

Common codes: Flows › Responses and errors.

Related