Documentation

Getting started

Introduction

Installation and configuration steps of 99Bio script.

If you're not familiar with the instructions on this page, we offer installation Services for an additional fee.

Requirements

Before installing the script, please make sure your server meets the requirements below.

Requirement Minimum Version / Details
Webserver Apache with mod_rewrite or Nginx
Database MySQL 5.7.7+ or MariaDB 10.3.17+
PHP Version 8.2.x or higher
PHP Extensions BCMath, Ctype, cURL, DOM, Tokenizer, Fileinfo, GD, JSON, MBString, OpenSSL, PCRE, PDO, Session, XML
PHP Functions symlink, readlink

Installation

Creating the database

  1. Create a new MySQL database.
  2. Create a new MySQL username and password.
  3. Assign full privileges to your database username.

Uploading the files

info
Before starting to upload the files, please make sure your file explorer has the option to view hidden files turned on. On some operating systems, the dotfiles are hidden by default.

Upload all the files inside the Script folder on the web root folder of your domain. This folder is generally called public_html, html, or example.com, but depending on your server's configuration, it might be named differently.

Changing the public directory

Configure your web server's document / web root to point to the /public directory of the script. For example, if you've uploaded the script in example.com folder, your web directory should be changed to example.com/public folder.

Finishing the installation

  1. Go to https://example.com/install and follow the installation wizard to complete the installation.
  2. Get your License key from the following link: License Key.
  3. After you've installed the script, login into your user account.

Configuration

Cron job

The script requires a cron job task to be set up on your server in order to automate some of its functions.

Copy the Command field and set up a cron job for it that runs every minute.

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

Some hosting panels might require the cron command in a different format. If needed, you can run it with absolute paths or specific PHP versions:

* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1

Email

  1. Go to Admin Settings
  2. Change the Driver field value to SMTP.
  3. Fill in the rest of the fields with the SMTP credentials from your SMTP provider.

Payment processors

The Admin can add all the payment methods they want and configure their currency and exchange rate from: Admin Payment Methods.

  1. Go to Admin → Payment Methods.
  2. Open the payment gateway you want to configure.
  3. Set the gateway mode with the Sandbox toggle. Enable it while testing, and disable it for live payments.
  4. Set the currency, percentage fee, and fixed fee that should be applied to payments made through that gateway.
  5. Paste the required credentials as JSON in the Credentials field.
  6. Enable Active and save the gateway.

PayPal

  • Log in via the PayPal Developer Dashboard.
  • Go to My apps & credentials, set Live and click Create App to make a new PayPal app.
  • Copy the Client ID & Secret Key and add them into Admin → Payment Methods in your admin panel.
  • Create a webhook for https://yourdomain.com/webhooks/paypal-api and copy the PayPal webhook ID.
{
  "client_id": "...",
  "secret": "...",
  "webhook_id": "..."
}

PayPal Email

For the email-based PayPal gateway, enter the merchant PayPal email address and use https://yourdomain.com/webhooks/paypal-email as the IPN notification URL.

{
  "email": "merchant@example.com"
}

Stripe

Copy your secret key from the Stripe API keys page, create a webhook endpoint for https://yourdomain.com/webhooks/stripe, and copy the webhook signing secret.

{
  "secret_key": "...",
  "webhook_secret": "..."
}

Paddle

This gateway uses Paddle Classic credentials. Copy your Vendor ID, Vendor Auth Code, and Public Key from Paddle, then paste them into the credentials field. You can use Paddle's official guides for finding the Vendor ID and Paddle Classic context.

{
  "vendor_id": "12345",
  "vendor_auth_code": "...",
  "public_key": "..."
}

Razorpay

Create or copy your Razorpay API keys, then configure a webhook for https://yourdomain.com/webhooks/razorpay and copy the webhook secret. You can follow the official Razorpay API keys and Razorpay webhooks guides.

{
  "key_id": "...",
  "key_secret": "...",
  "webhook_secret": "..."
}

Paystack

Copy your public and secret keys from the Paystack Dashboard, then set the webhook URL to https://yourdomain.com/webhooks/paystack. Paystack signs events with the secret key, and the platform uses secret_key to verify webhook signatures. See Paystack's official authentication and webhooks documentation.

{
  "secret_key": "...",
  "public_key": "...",
  "webhook_secret": "..."
}

Offline Payment

For offline payments, no credentials are required. Add the bank transfer or manual payment instructions in the Payment method details field, then enable the gateway.

Social Login

  1. Go to Admin → Settings → Authentication.
  2. Enable the providers you want to use (Google, Apple, Twitter/X).
  3. For each enabled provider, enter the Client ID and Client Secret. Follow the provider's developer console to create an OAuth application. Use the following callback URL in your OAuth app: https://yourdomain.com/auth/{provider}/callback Replace {provider} with: google, apple, or twitter.

Captcha

  1. Go to Admin → Settings → Captcha.
  2. Select your preferred provider: reCAPTCHA, hCaptcha, or Cloudflare Turnstile.
  3. Enter the Site Key and Secret Key for the selected provider. You can obtain these keys from your provider's dashboard.
  4. Captcha will be applied automatically to registration, login (after failed attempts), password recovery, and report forms.

Email Settings

  1. Go to Admin → Settings → Email.
  2. Enter the Sender Name and Sender Address.
  3. Enter your SMTP credentials: Host, Port, Encryption (TLS/SSL), Username, Password.
  4. Click "Send test email" to verify the configuration.

Common SMTP settings

  • Gmail: smtp.gmail.com, port 587, TLS. Note: requires an App Password if 2FA is enabled on the Google account.
  • Mailgun: smtp.mailgun.org, port 587, TLS
  • Postmark: smtp.postmarkapp.com, port 587, TLS
  • Amazon SES: varies by region, port 587, TLS

Google Analytics & Tag Manager

  1. Go to Admin → Settings → Google.
  2. Enter your Google Analytics Measurement ID (format: G-XXXXXXXX).
  3. Enter your Google Tag Manager Container ID (format: GTM-XXXXXXX).
  4. Both are optional. Leave blank to disable.

Google Analytics will automatically track page views across all public pages. Google Tag Manager allows you to manage additional tracking scripts and pixels without modifying the codebase.

Shopify

99Bio uses a global Shopify Storefront API configuration in the admin panel. Creators do not paste Shopify scripts or API keys into their bio link pages.

  1. Go to Admin → Settings → Shopify.
  2. Enter your Shopify Storefront client token.
  3. Confirm the API version and optional cache TTL, then save the settings.
  4. In the creator dashboard, add a Shopify embed and enter the store identifier (shop domain or supported store ID).
  5. Optionally set a Product ID or Collection ID, and choose how many products to show.

If you leave Product ID and Collection ID empty, the embed displays a product grid. If you provide one of those IDs, the embed switches to item mode for that product or collection.

The Shopify block syncs product data server-side. No user-provided Shopify script is injected into the public page.

Storage

  1. Go to Admin → Settings → Storage.
  2. Select your storage provider: Local, Cloudflare R2, Amazon S3, DigitalOcean Spaces, Wasabi, Vultr, or Backblaze B2.
  3. Enter the credentials for the selected provider. All credentials are stored encrypted in the database.
  4. For local storage, run the storage symlink after installation:
php artisan storage:link

This creates a public/storage symlink pointing to storage/app/public.

Provider credential reference

  • Cloudflare R2: Access Key ID, Secret Access Key, Endpoint URL, Bucket, Public URL
  • Amazon S3: Access Key ID, Secret Access Key, Region, Bucket
  • DigitalOcean Spaces: Access Key, Secret Key, Region, Bucket, Endpoint
  • Wasabi / Vultr / Backblaze B2: same fields as S3 + custom endpoint

DNS Configuration

Subdomains & Custom Domains

Two DNS configurations are needed: one for internal subdomains such as {username}.yourdomain.com, and one for user custom domains such as bio.theirdomain.com.

1. For {username}.yourdomain.com (internal subdomains)

In your main domain's DNS, add a wildcard A record:

A    *    YOUR_VPS_IP

This makes any subdomain (for example, miguel.yourdomain.com) point to your VPS. Your web server (Apache/Nginx) must also be configured to accept *.yourdomain.com.

2. For user custom domains (for example, bio.theirdomain.com)

The user adds a CNAME record in their DNS, and you must have an A record for the canonical destination in your domain's DNS:

CNAME    bio    cd.yourdomain.com
A    cd    YOUR_VPS_IP

Summary:

*.yourdomain.com    - for internal subdomains like username.yourdomain.com
cd.yourdomain.com    - destination for user custom domains

For custom domains, each user points their subdomain to cd.yourdomain.com. The canonical domain (cd.yourdomain.com) is configured in Admin → Settings → General.

Update

Backing up

warning Before updating the script, you must make a complete backup of your website.

warning If you've made any modifications to the script's files, your changes will be lost.

Updating

  1. Go to the Upgrades folder, select the version you want, click on the README.html file and follow the steps.

FAQ

  • How can I contact support?

    You can contact us here.
  • What type of hosting should I use?

    We recommend using a VPS for better performance, but the script can run on shared hosting without problems.
  • Is installation included in the price?

    No, installation is not included. We offer installation Services for an extra fee.
  • How can I translate my website?

    You can edit the text strings from Admin Panel https://yourdomain.com/admin/languages and change it according to your needs.
  • Error 404 in the installer

    Check that your .htaccess file has not been corrupted when uploading to your server.
  • Error 500 in the installer or on the home page

    Check that your .env file has not been corrupted when uploading to your server. It must have a dot before the name, and you must have at least PHP 8.2
  • What is the sitemap path?

    The sitemap path is: example.com/sitemap.xml
  • Assets are not uploading or displaying when using local storage. Why?

    Confirm the storage symlink is active. If not, re-create it by running the following commands from your project root:

    rm -rf public/storage
    ln -s storage/app/public public/storage

    Or using the Laravel artisan command:

    php artisan storage:link
  • How do I configure DNS for subdomains and custom domains?

    These are two separate configurations:

    1. For {username}.yourdomain.com (internal subdomains)

    In your main domain's DNS:

    A    *    YOUR_VPS_IP

    This makes any subdomain (for example, miguel.yourdomain.com) point to your VPS. Your web server (Apache/Nginx) must also be configured to accept *.yourdomain.com.

    2. For user custom domains (for example, bio.theirdomain.com)

    The user adds a CNAME record in their DNS, and you must have this A record in your domain's DNS:

    CNAME    bio    cd.yourdomain.com
    A    cd    YOUR_VPS_IP

    Summary:

    *.yourdomain.com    - for internal subdomains like username.yourdomain.com
    cd.yourdomain.com    - destination for user custom domains

    For custom domains, each user points their subdomain to cd.yourdomain.com.