# Custom/Advanced Integration

### How to Retrieve the Stripe Subscription ID from Your Backend <a href="#retrieve-subscription-id" id="retrieve-subscription-id"></a>

Most applications store the Stripe subscription ID in their own database after a successful checkout. Here are examples for different backend frameworks:

[Node.js](https://app.staysignal.com/dashboard/widget-setup/integration#nodejs)[PHP](https://app.staysignal.com/dashboard/widget-setup/integration#php)[Ruby](https://app.staysignal.com/dashboard/widget-setup/integration#ruby)[Python](https://app.staysignal.com/dashboard/widget-setup/integration#python)

#### Node.js/Express Example <a href="#nodejs" id="nodejs"></a>

```javascript
// Example: Fetching Stripe subscription ID from your database (Node.js/Express)
app.get('/account', async (req, res) => {
  // Assume you have a User model with a reference to a Subscription
  const user = await User.findById(req.user.id).populate('subscription');
  const subscriptionId = user.subscription?.stripeSubscriptionId;
  res.json({ subscriptionId });
});
```

#### PHP (Laravel) Example <a href="#php" id="php"></a>

```php
// Example: Fetching Stripe subscription ID from your database (Laravel)
public function showAccount() {
    $user = Auth::user();
    $subscription = $user->subscription;
    $subscriptionId = $subscription ? $subscription->stripe_subscription_id : null;
    return response()->json(['subscriptionId' => $subscriptionId]);
}
```

#### Ruby on Rails Example <a href="#ruby" id="ruby"></a>

```ruby
# Example: Fetching Stripe subscription ID from your database (Rails)
class AccountController < ApplicationController
  def show
    @subscription_id = current_user.subscription&.stripe_subscription_id
    render json: { subscriptionId: @subscription_id }
  end
end
```

#### Python (Django) Example <a href="#python" id="python"></a>

```python
# Example: Fetching Stripe subscription ID from your database (Django)
def account_view(request):
    subscription = Subscription.objects.filter(user=request.user).first()
    subscription_id = subscription.stripe_subscription_id if subscription else None
    return JsonResponse({'subscriptionId': subscription_id})
```

#### Fetching from Stripe API (Node.js Example)

```javascript
// Using Stripe Node.js SDK
const stripe = require('stripe')('sk_test_your_stripe_secret_key');

async function getCustomerSubscriptions(customerId) {
  try {
    const subscriptions = await stripe.subscriptions.list({
      customer: customerId,
      status: 'active',
      limit: 1
    });
    if (subscriptions.data.length > 0) {
      return subscriptions.data[0].id; // Returns the subscription ID
    }
    return null;
  } catch (error) {
    console.error('Error fetching from Stripe:', error);
    throw error;
  }
}
```

Note: Never expose your Stripe secret key in client-side code. Always fetch subscription IDs securely from your backend.

#### Opting Out of Automatic Cancellation <a href="#opt-out" id="opt-out"></a>

If you have your own cancellation flow and want to prevent Staysignal from automatically cancelling subscriptions, you can opt out in two ways:

* **Config option:** Pass `cancelOptOut: true` to the widget init config in JavaScript.
* **Button attribute:** Add `data-ss-cancel-optout="true"` to your cancel button element.

**Precedence:** If either method is set, cancellation is skipped and a message is logged to the console.

#### Advanced Flows After Cancellation <a href="#advanced-flows" id="advanced-flows"></a>

After a cancellation, you may want to trigger additional actions (e.g., send a survey, update your CRM, or notify your team). Use the `onComplete` callback in the widget config to run custom logic after a successful cancellation:

```javascript
StaySignal.init({
  siteId: 'YOUR_SITE_ID',
  onComplete: (result) => {
    // Custom logic after cancellation
    fetch('/api/notify-team', {
      method: 'POST',
      body: JSON.stringify({ subscriptionId: result.subscriptionId })
    });
  }
});
```

#### Other Advanced Options <a href="#other-options" id="other-options"></a>

* Use `onError` callback to handle errors in your own UI.
* Integrate with your analytics or logging system in `onComplete` or `onError`.
* Customize the widget appearance or behavior using additional config options (see documentation).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://staysignal.gitbook.io/staysignal-docs/integration-guides/custom-advanced-integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
