chargebee / chargebee-checkout-samples

36 stars 68 forks source link

"Token has Expired" error when reusing session data. #3

Closed dreadnautxbuddha closed 5 years ago

dreadnautxbuddha commented 5 years ago

So I made a PHP API that returns a portal session object which then stores the API id in the database. After this, the portal pops up, bla bla bla then I close it. Around 5 seconds later, I open the popup again, which calls the portal session API which then fetches the portal session object by id (which I stored in the database earlier). This is where I then get the 401 error saying that the token has expired. But as I've seen from the docs, should last about an hour before expiring.

What am I doing wrong? I checked out your Laravel test server and it keeps on creating a new portal session. Should I stop reusing portal session objects?

main.component.ts

ngOnInit() {
    this.chargebeeService.getInstance().setPortalSession(() => {
      return new Promise((resolve, reject) => {
        this.chargebeeService.portalLogin().subscribe((response) => {
          resolve(response.body);
        });
      });
    });
  }
openSelfServePortal(): void {
    this.chargebeeService.getInstance().createChargebeePortal().open({
    });
  }

chargebee.service.ts

portalLogin(): Observable<HttpResponse<Response>> {
    let body = new URLSearchParams();
    body.append('client_id', this.getClientId());

    return this.http.post<Response>(`${environment.url}/subscription_billing/get_portal_session`, body.toString(), { observe: 'response' });
  }

Lumen API:

    public function getPortalSession()
    {
        $session_id = $this->subscriber->subscription_billing->session_id;
        $session = ($session_id == null) ? $this->subscription->createPortalSession() : $this->subscription->getPortalSession($session_id);

        return response()
            ->json($session->getValues(), 200);
    }

Some model

    public function createPortalSession()
    {
        $result = \ChargeBee_PortalSession::create([
            'redirectUrl' => '<redirect url>',
            'customer' => ['id' => $this->getCustomerRecord()->id]
        ]);

        $this->sub_billing_portal_session = $result->portalSession();

        $this->subscriber->subscription_billing->session_id = $this->sub_billing_portal_session->id;
        $this->subscriber->subscription_billing->save();

        return $this->sub_billing_portal_session;
    }

    public function getPortalSession(string $sessionId)
    {
        $session = \ChargeBee_PortalSession::retrieve($sessionId)->portalSession();

        $this->sub_billing_portal_session = $session;

        return $this->sub_billing_portal_session;
    }
cb-dinesh commented 5 years ago

Hey there!

The portal session ID can only be used once. The duration of 1 hour means that you should use the portal session within 1 hour of generating it, after which it will expire.

You should not be reusing portal session object, instead you can create a new session every time when you need to open Portal.

Cheers!

dreadnautxbuddha commented 5 years ago

Ohh, ok. Thanks for this @cb-dinesh.