# Standalone customer portal

This guide covers the customer portal integration from a developers point of view. It assumes that you have already setup your Products in Bunny and enabled them to be visible for self service.

{% hint style="warning" %}
TLDR... This integration involves using the API to generate a token that will be appended to a customer portal url that you will redirect the user over to for subscription management.
{% endhint %}

### Setup API credentials

Make a request from your backend to obtain the portal security token using the [portalSessionCreate](https://docs.bunny.com/developer/using-the-graphql-api/mutations/portalsessioncreate) graphql request.

The API client will need to have the **security:read** and **security:write** scopes enabled.

Use the API client to [generate a new access token](https://docs.bunny.com/developer/using-the-graphql-api/authorizing-api-requests) with the security scopes.

### Request a portal token

The portal token is obtained using the [portalSessionCreate](https://docs.bunny.com/developer/using-the-graphql-api/mutations/portalsessioncreate) graphql request.

{% tabs %}
{% tab title="GraphQL" %}
**Attributes**

{% code overflow="wrap" %}

```json
{
  "tenantCode": "superdesk-123",
  "expiry": 123 // optional - default 24 hours
}
```

{% endcode %}

**Mutation**

{% code overflow="wrap" %}

```graphql
mutation portalSessionCreate ($tenantCode: String!, $expiry: Int!) {
  portalSessionCreate (tenantCode: $tenantCode, expiry: $expiry) {
      errors
      token
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="Node.js" %}

```javascript
res = await bunny.createPortalSession("superdesk-123");
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
res = BunnyApp::PortalSession.create(
    tenant_code: 'superdesk-123'
)
```

{% endtab %}
{% endtabs %}

On success the response will contain a token attribute. You need to extract this token and use it in the next step.

{% code overflow="wrap" %}

```json
{
    "data": {
        "portalSessionCreate": {
            "errors": null,
            "token": "eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2ODE4MzY4NDUsImlzcyI6Imh0dHBzOi8vYnVubnkuYnVubnkuY29tIiwiYXVkIjoicG9ydGFsIiwiaWF0IjoxNjgxNzUwNDQ1LCJzdWJkb21haW4iOiJidW5ueSIsInVpZCI6NDA1LCJ1aWRfdHlwZSI6IlRlbmFudCIsInJlYWNoX2lkIjo1NDAsInJlYWNoX3R5cGUiOiJBY2NvdW50Iiwic2NvcGUiOiJwcm9kdWN0OnJlYWQgYmlsbGluZzpyZWFkIHN0YW5kYXJkOndyaXRlIHN0YW5kYXJkOnJlYWQiLCJvYmplY3RfaWQiOjQwNSwib2JqZWN0X3R5cGUiOiJUZW5hbnQifQ.78epnLpeJBs2UX1SrjxYdkKkEL_x4iy_AlAo6LuxQQkA7O5jvgEA00X3Zh9Z-MdLoBhGtSrK3Kv-Gb2lOAb3tQ"
        }
    }
}
```

{% endcode %}

### Redirect to the customer portal

The final step is to redirect the browser to the customer portal by appending the token to the base url for your customer portal.

```
https://{{subdomain}}.bunny.com/portal?token={{token}}
```

You can also redirect to specific pages within the customer portal by including the path to that page.

{% code overflow="wrap" %}

```
// subscriptions
https://{{subdomain}}.bunny.com/portal/subscriptions?token={{token}}

// transactions
https://{{subdomain}}.bunny.com/portal/transactions?token={{token}}

// payment methods
https://{{subdomain}}.bunny.com/portal/payment-method?token={{token}}
```

{% endcode %}
