Skip to main content

Prerequisites

To generate payment portal URLs, you’ll need your organisational API credentials. See Authentication Guide.

Generating payment portal URLs

Use the Get Balance Withdrawal URL endpoint to generate a URL for users to access their payments portal. Response:
{
  "balance_withdrawal_url": "https://payments.axle.energy/auth/ext/{jwt_token}",
  "url_expiry_timestamp": "2024-01-15T14:30:00Z"
}

Two-factor authentication

When enforce_two_factor_auth is enabled, users must verify their email address before accessing the portal. Currently supported verification methods: Email only. Note that this requires email to be supplied while onboarding the site. We send a verification code to the user’s registered email address. They must enter this code to proceed.

Redirect handling

The redirect_uri parameter specifies where users are sent after completing their action in the payments portal. Implementation depends on how users open the balance page URL:
  • If opening in a browser external to your app, redirect_uri should be a deep link back to your app
  • If it’s in a modal browser pop-up within your app, it should be a ‘magic string’ which allows them to exit the modal
We don’t currently append any additional information (such as success/failure status or transaction IDs) to the redirect URI. If there’s specific information that would be useful for your application flow, please let us know and we can look at adding it to our implementation.

When to hide transactions

The hide_transactions parameter is useful in two scenarios:
  1. One-off payment flow: When you want a focused experience where users simply withdraw and return, without browsing their full history
  2. Avoiding duplication: When you already display transaction history in your own app and don’t want users seeing the same information twice

Auto-redirect behaviour

When auto_redirect_to_setup is true:
  • If the user has no bank account linked, they skip the balance page entirely and go straight into the bank account setup flow
  • If the user already has a bank account, they see the normal balance page
This is useful for streamlined onboarding flows where you want users to set up their payment method without distraction.

Example: Python

import requests

API_BASE = "https://api.axle.energy"
API_TOKEN = "your_bearer_token"

def get_payment_url(site_id: str) -> str:
    response = requests.get(
        f"{API_BASE}/rewards/{site_id}/url/balance",
        params={
            "enforce_two_factor_auth": True,
            "redirect_uri": "/rewards/balance",
            "hide_transactions": False,
            "auto_redirect_to_setup": False,
        },
        headers={"Authorization": f"Bearer {API_TOKEN}"}
    )
    response.raise_for_status()
    return response.json()["balance_withdrawal_url"]

JWT token structure

The generated URL contains a JWT with the following claims:
{
  "sub": "organisation_name",
  "internal_site_id": "uuid",
  "allowed_origin": "*.axle.energy",
  "type": "rewards",
  "permitted_url_stubs": ["/rewards"],
  "two_factor_auth": true,
  "redirect_uri": "/rewards/balance",
  "hide_transactions": false,
  "auto_redirect_to_setup": false,
  "exp": 1705329000
}
Default expiry: 60 minutes from generation. For the best user experience, we recommend following this pattern:
  1. Call the Get Balance Info endpoint, which returns:
    • The user’s current balance
    • The minimum withdrawal threshold
    • Other relevant account information
  2. Use that info to control UI state:
    • Show/enable a “withdraw” button if balance is above the minimum threshold
    • Grey out or hide the button if below the threshold
    • Display helpful messaging about why withdrawal isn’t available
  3. Call Get Withdrawal URL when the user clicks the enabled button
This pattern prevents users from entering the withdrawal flow only to discover they can’t actually withdraw, creating a smoother experience.