#Asim

1 messages ยท Page 1 of 1 (latest)

raw ridgeBOT
knotty sun
#

hello!

deft stag
#

heyo!

#

So this issue hasn't been reproducible on our end but we've been getting a lot of customer complaints

#

And note that we still have customers that are able to checkout

#

One of the customers was able to get us a console log

#

It seems to be an implementation issue on our end but we can't seem to get a hold of it

knotty sun
#

hrm, how do you redirect the customer? relevant code snippets would be great

deft stag
#

Sure thing! Heres our click listener that handles redirects after we fetch the URL from our backend

    onClick: async () => {
      const url = await post<string>(
        `${env.NEXT_PUBLIC_BACKEND_URL}/api/webhook/checkout`,
        {},
        session || undefined
      );
      await router.push(url);
    },
#

Here is our post helper function

export const post = async <T>(url: string, body: unknown, session?: Session) => {
  const headers: Record<string, string> = {};

  if (session?.accessToken) {
    headers.Authorization = `Bearer ${session.accessToken}`;
  }

  return (
    await axios.post(url, body, {
      headers,
    })
  ).data as T;
};
#

Here is our backend route to handle creating the checkout url

@router.post("/checkout")
async def checkout(
    user: UserBase = Depends(get_current_user),
    session: AsyncSession = Depends(get_db_session),
) -> str:
    query = select(StripeCustomer).where(StripeCustomer.user_id == user.id)
    result = await session.execute(query)
    customer = result.scalar_one_or_none()

    if not customer:
        customer_id = stripe_utils.create_customer(user)
        customer = StripeCustomer(user_id=user.id, customer_id=customer_id)

        session.add(customer)
        await session.commit()

    if stripe_utils.has_subscription(customer.customer_id):
        raise ValueError(f"Customer {customer.customer_id} already has a subscription")

    return stripe_utils.create_checkout_session_url(customer.customer_id)
#

Here is our stripe utils containing helper functions to interact with the stripe package / API:

import stripe

from reworkd_platform.settings import settings
from reworkd_platform.web.api.dependencies import UserBase


class StripeUtils:
    def __init__(self, stripe_api_key: str):
        self._key = stripe_api_key

    def get_customer(self, customer_id: str) -> stripe.Customer:
        return stripe.Customer.retrieve(customer_id, api_key=self._key)

    def create_customer(self, user: UserBase) -> str:
        return stripe.Customer.create(
            api_key=self._key,
            metadata={
                "userId": user.id,
                "email": user.email,
            },
        ).id

    def create_checkout_session_url(
        self,
        customer_id: str,
    ) -> str:
        return stripe.checkout.Session.create(
            api_key=self._key,
            success_url=settings.frontend_url,
            cancel_url=settings.frontend_url,
            allow_promotion_codes=True,
            line_items=[
                {
                    "price": settings.stripe_subscription_price_id,
                    "quantity": 1,
                },
            ],
            mode="subscription",
            customer=customer_id,
        ).url

    def create_billing_portal_url(self, customer_id: str) -> str:
        return stripe.billing_portal.Session.create(
            api_key=self._key,
            customer=customer_id,
            return_url=settings.frontend_url,
            proration_behavior="none",
        ).url

    def has_subscription(self, customer_id: str, status: str = "active") -> bool:
        return not self.list_subscriptions(customer=customer_id, status=status).is_empty

    def list_subscriptions(self, limit: int = 10, **kwargs):
        return stripe.Subscription.list(api_key=self._key, limit=limit, **kwargs)
knotty sun
#

give me a while - looking and thinking

deft stag
#

Appreciate it Alex! Hopefully its not too late where you are

knotty sun
#

no worries, we have 24/5 coverage and we're in normal working hours where we are now ๐Ÿ˜

deft stag
#

ah and the /ru redirect is due to our i18 internationalization

#

tested these somewhat locally + via a VPN and was ok on our end

knotty sun
#

okay, looking at the error message in the screenshot - it's referring to platform.reworkd.dev/api/webhook/checkout and agentgpt.reworkd.ai - which seems to imply that the CORS issue you're seeing in the console is possibly due to your frontend and backend having different origins?

deft stag
#

Yeah not sure why thats appearing, we do have CORS set up correctly to allow traffic from our frontend:

    app.add_middleware(
        CORSMiddleware,
        allow_origins=[settings.frontend_url],
        allow_origin_regex=settings.allowed_origins_regex,
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )
#

(Otherwise none of the other routes would work for anyone ๐Ÿค”)

knotty sun
#

i'm not sure if you can add logging for this - settings.frontend_url -> like the email mentioned, it works fine for en, but doesn't work for ru and there seems to be a redirect

#

so it's possible that some setting isn't configured quite right