Skip to Content

SubscriptionStatusNotification

When the subscription status actually changes, the platform sends an XML notification to the project’s callback URL. The body is signed with the same HMAC-SHA256 formula — the Now and Signature fields are inside the notification. The first delivery is delayed by 15 seconds after the status change.

EventWhen it arrives
APPROVEDThe subscription is confirmed: a correct PIN in ApproveSubscription or a successful card / SBP payment. SubscriptionStatus=Active
REJECTEDThe card payment was declined. SubscriptionStatus=ApprovingFailed
CANCELLEDAfter CancelSubscription. SubscriptionStatus=Cancelled
APPROVED_BILLINGA scheduled charge succeeded: BillingIteration grows, PaidUntil shifts
REJECTED_BILLING_ATTEMPTA charge attempt failed, a retry follows. SubscriptionStatus=Redelivering, BillingErrorCode=210
REJECTED_BILLINGAttempts exhausted — three in a row. SubscriptionStatus=RenewingFailed, the subscription is closed
FINISHEDAll billing cycles are done. SubscriptionStatus=Closed

Charge-cycle events arrive only if <TestInfo><BillingPeriodSeconds> was passed at creation — without it the sandbox performs no charges. In production those notifications follow the project schedule and make up the bulk of the traffic.

Delivery parameterValue
First callback delay15 sec after the status change
Retries173 retries on the same schedule as one-off payments: 2 s × 2, 5 s × 2, 10 s × 2, 1 min × 14, 5 min × 21, 10 min × 132 — a day from the first delivery
HTTP timeout60 sec

The merchant acknowledges receipt with a 200 response. Deduplicate notifications by the X-Event-Id header (also sent as RequestID) — it does not change between delivery attempts, the attempt number is separate in X-Event-Attempt. This circuit does not know the Idempotency-Key / Idempotence-Key headers.

Notification body
<?xml version="1.0" encoding="utf-8"?> <Request> <SubscriptionID>12345678</SubscriptionID> <SubscriptionProjectID>2001</SubscriptionProjectID> <SubscriberID>1234567</SubscriberID> <Subscriber_MSISDN>79001234567</Subscriber_MSISDN> <EventType>APPROVED</EventType> <SubscriptionStatus>Active</SubscriptionStatus> <BillingIteration>1</BillingIteration> <BillingAttempt>1</BillingAttempt> <Country>ru</Country> <OperatorID>22</OperatorID> <CustomerPrice currency="RUB" amount="0.00"/> <BillingOperationID>b4da05e2-1d77-40c9-85ac-0bb3835de8b5</BillingOperationID> <BillingErrorCode>0</BillingErrorCode> <PaidUntil>2026-07-25T12:00:00+03:00</PaidUntil> <Now>20260625120015</Now> <Signature>d2f36558ca5455beb28b4ec090ffbea1cf9425106b5dbeb2f93538603956da53</Signature> </Request>

ContentRequest — the service SMS text

Before every successful charge the platform asks the partner for the service SMS text: the Service-Method: ContentRequest header, EventType=Content_request. The expected answer is StatusName=REQUEST_ACCEPTED with a ContentMessage block carrying the parameter values.

SMS text request
<?xml version="1.0" encoding="utf-8"?> <Request> <SubscriptionID>10000003</SubscriptionID> <EventType>Content_request</EventType> <BillingIteration>1</BillingIteration> <ContentMessage><Parameter Name="BODY"/></ContentMessage> </Request>

Notification signature verification

# Extract the fields from the body and recompute the signature NOW=$(xmllint --xpath 'string(//Now)' notification.xml) PID=$(xmllint --xpath 'string(//SubscriptionProjectID)' notification.xml) GOT=$(xmllint --xpath 'string(//Signature)' notification.xml) EXPECTED=$(printf '%s%s' "$PID" "$NOW" \ | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $NF}') [ "$GOT" = "$EXPECTED" ] && echo OK || echo MISMATCH