#aaron_app-keys

1 messages ¡ Page 1 of 1 (latest)

sterile agateBOT
#

👋 Welcome to your new thread!

⏲️ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

🔗 This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1279075169024872448

📝 Have more to share? Add more details, code, screenshots, videos, etc. below.

sudden acorn
#
    static async connectStripeAccount(request) {
        try {
            // Wix Routers are known to fire twice sometimes. This is a workaround to prevent that.
            const authCode = request.query.code;
            const ranTwice = globalThis.authCode?.includes(authCode);
            if (ranTwice) {
                console.log("RAN TWICE", authCode);
                return redirect("/dashboard");
            } else {
                globalThis.authCode = Array.isArray(globalThis.authCode) ? [...globalThis.authCode, authCode] : [authCode];
            }

            const user = await Users.getCurrentUser();
            if (!user) {
                throw new Error("Priceable user not found.");
            }
            // redirect if user is already connected
            if (user.stripeRefreshToken) {
                return redirect("/dashboard");
            } else {
                // build request
                const secretKey = await keys.stripeSecretKey;
                const headers = {
                    "Authorization": "Basic " + Buffer.from(`${secretKey}:`).toString("base64"),
                    "Content-Type": "application/x-www-form-urlencoded"
                };
                const bodyParams = {
                    code: authCode,
                    grant_type: "authorization_code"
                };
                const accessTokenExpiresAt = new Date(Date.now() + ONE_HOUR);
                const response = await fetch(StripeUrls.stripeRefreshUrl(), {
                    method: "POST",
                    headers: headers,
                    body: new URLSearchParams(bodyParams).toString()
                });
                // save stripe user id and refresh token
                const responseData = await response.json();
                if (responseData["error"] === "access_denied") {
                    this.logger.error(`User ${user.id} denied Stripe access.`);
                    return redirect("/onboard");
                }
                if (responseData["error"] === "invalid_grant") {
                    throw new StripeInvalidGrantError(responseData["error_description"]);
                }
                const refreshToken = responseData["refresh_token"];
                const accessToken = responseData["access_token"];
                const stripeUserId = responseData["stripe_user_id"];
                if (refreshToken && stripeUserId && accessToken) {
                    const priceableUser = await Users.getPriceableUser();
                    const client = new StripeClient(priceableUser);
                    // const customer = await client.createCustomer({
                    //     data: {
                    //         email: user.loginEmail,
                    //         metadata: {
                    //             priceable_user_id: user._id
                    //         }
                    //     }
                    // });
                    await weivData.update("Users", {
                        ...user,
                        // stripeCustomerId: customer.id,
                        stripeUserId: stripeUserId,
                        stripeRefreshToken: await crypto.encrypt(refreshToken),
                        stripeAccessToken: await crypto.encrypt(accessToken),
                        stripeAccessTokenExpiresAt: accessTokenExpiresAt,
                        stripeConnectedAt: new Date()
                    })
                    console.log("refreshToken", refreshToken);
                    console.log("accessToken", accessToken);
                    EmailClient.sendStripeConnectedEmail(user);
                    return redirect("/");
                } else {
                    throw new Error("Stripe account not found.");
                }
            }
        } catch (error) {
            this.logger.fromErrors(error);
            return notFound("Encountered an error when trying to connect Stripe account.");
        }
    }```
#

This is the code that's running when we get the ?code= param back from a user connecting their Stripe

#

But then any subsequent API calls used with their data give us the error: invalid_request_error: Expired API Key provided: rk_test_*********************************************************************************************xNaeqE. Platform access may have been revoked.

#

I have no idea what's going wrong, I've been at this for hours CryingCool

vague badge
#

Can you share a connect account id where this happened

sudden acorn
#

Sure, where can I find the account ID?

#

Oh I guess we save it lol

#

hold on

#

"acct_1PentdCDIXxitiYy"

#

I see this unauthorized event fire immediately after the authorized event, and it's fired Automatically

vague badge
#

Ok I see what's happening here. So if you re-use the the authorization code you get during the OAuth flow, the connect account is disconnected from the platform. OAuth tokens should only be consumed once

#

Otherwise this happens

#

I'm assuming this is due to the wix router firing multiple times?

#

Not sure, but the issue here is the token is being consumed more than once

sudden acorn
#

hmm