Subscription payment widget in the sandbox
The subscription payment widget works in the sandbox just as in production: the same embed., mount() / open(), payment methods, methods and webview parameters, events and own-buttons route. The full parameter reference lives in the guide. This page covers what to plug in for the sandbox and how to drive the initial step to an outcome without a real bank.
In this widget success means the initial step succeeded: the first payment or, when the first payment is deferred, an SBP binding without a charge. A browser event does not replace the server notifications about activation and charges.
What you need
| What | In the sandbox |
|---|---|
| SDK | https://subs-sandbox.digitalspb.com/Cards/Sbp/embed.js |
| Credentials and project | The demo credentials from Access & test data |
| Payment methods | The demo project has sbp, alfapay and sberpay enabled, so the choice screen shows right away. T-Pay is disabled in the subscription widget — as in production. Other projects get only SBP by default; the set is changed on request |
| Widget token | From the AuthorizeUrl in the CreateSubscription response |
Step 1. Create the subscription
The subscription is created on the partner’s server — with the same CreateSubscription and CustomerType=Card as in Card & SBP subscription. The project secret and the signature never reach the browser.
<Request>
<SubscriptionProjectID>2001</SubscriptionProjectID>
<CustomerType>Card</CustomerType>
<CustomerId>12345</CustomerId>
<Now>20260625120000</Now>
<Signature>d2f36558ca5455be...</Signature>
</Request>The response carries AuthorizeUrl and SubscriptionStatus=Pending. The widget token sits inside AuthorizeUrl — 32 hexadecimal characters.
The set of methods depends on the subscription terms (§6.8 of the guide):
BillingStartTimeUtc in the request | Response | Methods in the widget |
|---|---|---|
| Omitted or a time in the past | TrialExists=false | Any enabled method — the first period is paid at sign-up |
| A time in the future | TrialExists=true | SBP only — the first payment is deferred, the initial step is a binding without a charge |
If you embed the widget, do not open AuthorizeUrl — that is a separate payment flow, and it conflicts with the widget over the same token.
Step 2. Embed the widget
<div id="bind"></div>
<script src="https://subs-sandbox.digitalspb.com/Cards/Sbp/embed.js"></script>
<script>
SbpWidget.mount('#bind', {
token: '8c0c8870d6fb4ee8a995ae183a44b928', // from the AuthorizeUrl of the CreateSubscription response
methods: ['sbp', 'sberpay'], // optional: narrow the set of methods
onSuccess: function () { location.href = '/subscribed'; },
onFail: function () {},
onExpired: function () {},
onError: function (e) { console.log(e.message, e.code); }
});
</script>There is no invoice here, so invoiceId is not passed — the widget addresses the subscription session by its token. For the modal mode use SbpWidget.open() with the same parameters minus the selector. webview: true turns on WebView mode, as in production.
Step 3. Confirm the initial step
The sandbox has no real banks, so confirmation is replaced with a simulation:
| Method | How to confirm |
|---|---|
| Any | The simulation button inside the widget — it drives the flow to success |
| Alfa Pay, SberPay | The method button opens a bank app imitation with a confirm button |
What happens next:
- The widget polls the state every 5 seconds and sends
success—onSuccessfires. - The subscription becomes
Active, and the partner receives anEventType=APPROVEDcallback — the sandbox sends the first callback with a 15-second delay. - The sandbox sends no separate notification about the first charge: after a successful initial step only
APPROVEDarrives. To see the billing cycle and its notifications, enable it with a<TestInfo>block — see Sandbox hooks: charges. Without it, only activation, rejection and cancellation notifications arrive.
Own buttons — redirect route
The route from §6.12 of the guide works in the sandbox too:
GET https://subs-sandbox.digitalspb.com/Cards/Sbp/pay?token={token}&method=sberpayalfapay and sberpay lead to the bank app imitation, sbp to the widget screen without a method choice. An unknown method, or one not available for the subscription — tpay included — returns 400 as an HTML page.
To get the list of methods without creating a payment, call GET https://subs-sandbox.digitalspb.com/Cards/Sbp/methods with an Authorization: Bearer {token} header.
What to check besides a successful initial step
| What | How to reproduce | What to expect |
|---|---|---|
| Invalid token | Open the widget with someone else’s or a corrupted token | A 401 and the “Link is invalid” screen |
| Empty filter | Pass methods: ['tpay'] | The widget shows the whole available set and calls onError with code: 'method_unavailable'; the sign-up continues |
| Deferred first payment | Create a subscription with a future BillingStartTimeUtc and open the widget | CreateSubscription returns TrialExists=true, the widget offers SBP only; /Cards/Sbp/pay with alfapay or sberpay returns 400 |
| Repeated start | Reload the widget with the same token within its lifetime and choose the same method | The same operation already started: for SBP, the same QR code and no new session |
| Another method for a started operation | Start an operation with one method, reopen the widget with the same token and choose another | The server rejects the choice — 409 METHOD_LOCKED, can_change_method: false; the widget asks to choose the original method |
Reloading a partner page that calls CreateSubscription again creates a new subscription with a new token. The previous operation stays valid, and confirming it activates the previous subscription, not the one on screen. This is the main source of confusion during testing — the test order is in §6.10 of the guide.
Differences from production
| In the sandbox | In production |
|---|---|
SDK — https://subs-sandbox.digitalspb.com/Cards/Sbp/embed.js | SDK — from the payment domain, https://subs.digitalspb.com/Cards/Sbp/embed.js. The default apiBase comes from the script address, so switching environments means switching the embed. address |
| The simulation button and the bank app imitation | Neither exists — the first payment or the binding is confirmed in a real bank |
No money moves: after a successful initial step only APPROVED arrives; charges follow <TestInfo> | The first payment at sign-up, or a binding without a charge and the first charge on schedule (§6.8 of the guide) |
A deferred first payment is switched on by a future BillingStartTimeUtc | It needs free SBP binding support from the project’s payment provider |
The initial step endpoint response (POST /Cards/Sbp/create) carries a sandbox_confirm_url field — the simulation address | No such field; do not build code around it |
| The widget’s legal footnotes (subscription terms, consent to data processing) lead to stubs | They lead to the real documents |