Open Access to "Benefit Balances" via Velo API

Recently, I tried to implement custom logic in Velo to validate the number of classes remaining for a student before allowing a booking. It seems absurd that, even though there is a “balance” or “credit” system in Wix Bookings/Pricing Plans, this value cannot be accessed or manipulated via code (Velo).

When attempting to elevate privileges and query the backend, the system denies access to data that belongs to the business. Limiting the display of these balances solely to native widgets prevents developers from creating custom workflows (such as balance-based redirects or pre-payment validations). It would be great if the Balances endpoint were queryable and editable via Velo without the current permission restrictions, as I have a pending development task that I haven’t been able to complete because of this. If anyone has been able to access this or has a successful solution, I would appreciate your help.

Are you able to share the code you tried? Once elevated, you should be able to work with it - so something seems missing there.

If you could also share the docs you’re referencing, that would help too :slight_smile:

Hi noahlovell,

Thanks for following up. To provide some context for this issue: the goal is to check a member’s remaining balance (class credits) via Velo in order to perform a conditional redirect before the user reaches the booking checkout.

I raised this exact scenario on the official Wix Studio Discord, and the conclusion there was clear: it is currently impossible to access this specific data due to permission restrictions hardcoded into the API core, which persist even when attempting privilege escalation (elevate) or backend-to-backend calls.

The “solution” suggested on Discord was to build a parallel database to manually “mirror” the logic of Wix Bookings. Frankly, this strikes me as an architectural absurdity. Forcing a developer to duplicate data, manually manage synchronization states, and risk counting errors because the platform blocks access to information that already exists in its system is a critical barrier.

It’s disappointing that a platform seeking to be taken seriously by high-level developers restricts access to basic business logic under a supposed security layer, rather than providing a secure API scope to query it. If Wix wants to compete as a professional development environment, we shouldn’t have to ‘hack’ solutions or reinvent the wheel just to get a simple balance number.

I’ve attached a screenshot of the Discord discussion confirming that this is currently a technical dead end. I hope this can be escalated to the Product team as an infrastructure priority.

I see that this was a fellow community member who replied in Discord.

You mentioned you wrote some code. Would you be able to share it? - it’ll make understanding and taking this with the team a little easier :slight_smile:

Here’s one of the many ways I tried to get this information.

import { fetch } from ‘wix-fetch’;

// SUSTITUYE CON TU API KEY REAL
const MI_API_KEY = “TU_API_KEY_AQUI”;

export async function consultarBalanceV3(orderId) {
// Endpoint oficial de la API v2/v3 para Órdenes
const url = https://www.wixapis.com/pricing-plans/v2/orders/${orderId};

try {
    const response = await fetch(url, {
        method: 'GET',
        headers: {
            'Authorization': MI_API_KEY,
            'Content-Type': 'application/json'
        }
    });

    const data = await response.json();

    if (response.ok && data.order) {
        // Buscamos el beneficio funcional (el programa de clases)
        const beneficio = data.order.benefits && data.order.benefits[0];

        if (beneficio && beneficio.entitlement) {
            const total = beneficio.entitlement.quantity || 0;
            const usados = beneficio.status?.usedQuantity || 0;
            
            return {
                exito: true,
                remaining: total - usados,
                planName: data.order.planName
            };
        }
        return { exito: false, mensaje: "El plan no tiene beneficios numéricos." };
    }

    return { exito: false, mensaje: data.message || "Error al consultar API V3" };

} catch (err) {
    return { exito: false, error: err.message };
}

}

another way I tried to get the information.

import { balances } from ‘wix-benefit-programs-v1’;
import { elevate } from ‘wix-auth’;

export async function getBalance(memberId) {
const elevatedQuery = elevate(balances.queryBalances);
try {
return await elevatedQuery({ filter: { beneficiary: { memberId } } });
} catch (err) {
// This ALWAYS returns: “Insufficient permission: BENEFIT_PROGRAMS.BALANCE_READ”
return err;
}
}

When writing code within the Wix Editors, you’ll want to use the SDKs (rather than REST), since the Wix Editors will automatically provide all of the auth for you (no need for API keys) - you simply can use the SDK methods etc.

I also notice that wix-benefit-programs-v1 isn’t valid and doesn’t appear to exist.

I’d recommend reading the Benefit Programs SDK - Introduction - and seeing whats available there for your use case

"Thank you for your response, noahlovell.

I fully understand the advantage of using native SDKs over REST to handle authentication automatically; in fact, that was my first choice. However, my comment isn’t based on a lack of familiarity with the documentation, but rather on having exhausted the options offered by the SDK without success.

I have thoroughly reviewed the ‘Benefit Programs SDK’ documentation (and related ones such as Entitlements and Pricing Plans). The problem persists: the SDK’s balances.queryBalances() method returns an ‘Insufficient permission: BENEFIT_PROGRAMS.BALANCE_READ’ error even when executed from the backend and attempting to elevate privileges with wix-auth (elevate).

If, as you mention, the SDK is the correct approach and the resource exists, could you please indicate the exact method or share a working code snippet that allows a developer to query a member’s class balance from the backend?

My research suggests that, although the method is documented, access is restricted at the infrastructure level for third-party applications or custom code, allowing only display in native widgets. If I am mistaken, I would greatly appreciate specific technical guidance, as this is the point that is blocking the logical flow of my application.

I look forward to your technical feedback.

I suspect this is because of trying to combine both Velo and SDK. It’s usually best to use one or the other.

wix-auth is Velo, and the Benefits SDK is SDK.

To elevate SDKs you use import { auth } from "@wix/essentials" and then auth.elevate(methodHere)


Something like this will return all of the benefit pools for a specific member ID provided to the function:

import { Permissions, webMethod } from 'wix-web-module';
import { auth } from "@wix/essentials";
import { pools } from "@wix/benefit-programs";

export const getMemberBalance = webMethod(Permissions.Anyone, async (memberId) => {
    const elevatedQueryPools = auth.elevate(pools.queryPools);

    try {
        const queryResult = await elevatedQueryPools({
            filter: {
                $and: [
                    { status: { $eq: "ACTIVE" } },
                    {
                        $or: [
                            { "beneficiary.memberId": { $eq: memberId } },
                            { "beneficiary.wixUserId": { $eq: memberId } } 
                        ]
                    }
                ]
            },
            cursorPaging: { limit: 50 }
        });

        if (!queryResult.pools || queryResult.pools.length === 0) {
            return { balance: "0", message: "No active benefit pools found for this ID." };
        }

        console.log("Full Results", queryResult)

        return queryResult.pools.map(pool => ({
            poolId: pool._id,
            programName: pool.program?.displayName || "Benefit Program",
            amount: pool.details?.creditConfiguration?.amount || "0",
            unit: pool.details?.creditConfiguration?.unitDisplayName || 'Credits',
            status: pool.status
        }));

    } catch (error) {
        console.error("Benefit Programs SDK Error:", error);
        throw new Error(`Failed to retrieve balance: ${error.message}`);
    }
});

Results:

Hi, noahlovell,

Thanks for the code—it’s been a huge help. By implementing it with @wix/essentials and @wix/benefit-programs, I was finally able to resolve the permission error and get a response from the system.

However, the result I get is the package’s initial value (for example, ‘4 credits’), but it doesn’t reflect the user’s remaining balance. If the user has already attended 3 classes, I need the system to return ‘1’, but the current code keeps returning ‘4’.

I’ve checked the pool object returned by the query, but it’s not clear to me which property stores the current usage or net balance. Is there a property like pool.usage.used or a specific counter within pool.details that I should check to get the actual balance and not just the upper limit?

My goal is that when that balance reaches zero, the Velo flow redirects the user to the purchase page. Could you tell me how to access that ‘remaining credits’ value within the pool object?

Thanks again for the technical guide."

Hi, noahlovell,
I see you weren’t able to provide a code to retrieve this value. Does that mean it’s not possible to access it?
If that’s the case, I recommend that Wix make this value accessible, since it’s quite important, and it’s very tedious to have to create a parallel database just to duplicate a value they already have—all we need is to be able to access it to add some logic. :slightly_smiling_face:

I imagine you’ll want to use the Balances API which will provide you more info about what credits are available for users

Here’s the balance object - https://dev.wix.com/docs/api-reference/business-solutions/benefit-programs/balances/balance-object?apiView=SDK

Since I don’t know the full scope of your project, I don’t know what the code will look like for your needs, but this should help

1 Like