# ECStores Client Onboarding — Standard Operating Procedure

**Version:** 2.0 — 2026-05-20  
**Platform:** ECStores on InMotion shared hosting (ecstores.ca)  
**Billing:** Clients pay through EastCoast WebCraft portal (not directly through ECStores)

---

## Overview — Who Does What

| Step | Who | When |
|---|---|---|
| Discuss plans, confirm store details | Denis | Pre-sale |
| Create client account in ECW (if new) | Denis | Before invoice |
| Pre-create tenant database in cPanel | **Denis** | **Before sending invoice** |
| Create ECStores invoice in ECW admin | Denis | After DB is ready |
| Send invoice to client | Denis | After DB is ready |
| Pay invoice via Stripe | Client | Their timeline |
| Tenant provisioned, welcome email sent | Automatic | On payment |
| Denis verifies store is live | Denis | Within 1 hour of payment |
| Client logs in, changes password | Client | After receiving welcome email |
| Client accesses store via ECW portal | Client | After SSL is live on *.ecstores.ca |

> **Critical:** The tenant database MUST be created in cPanel BEFORE the client pays.  
> If the database doesn't exist when payment completes, auto-provisioning fails and you'll need to retry manually.

---

## Part 1 — Pre-Sale: Confirm Store Details

Before creating anything, confirm with the client:

- [ ] **Subdomain slug** — lowercase letters, numbers, hyphens only. This cannot be changed later.  
  Example: `harbourgifts` → store lives at `harbourgifts.ecstores.ca`
- [ ] **Store name** — the display name shown in their merchant dashboard  
  Example: `Harbour Gifts`
- [ ] **Plan** — Starter ($49/mo), Growth ($99/mo), or Pro ($199/mo)

  | Feature | Starter | Growth | Pro |
  |---|---|---|---|
  | Products | 25 | 100 | Unlimited |
  | Variants | — | ✅ | ✅ |
  | Coupons | — | ✅ | ✅ |
  | Advanced Shipping | — | ✅ | ✅ |
  | Financial Reports | Basic | Standard | Full |
  | Refund Management | — | — | ✅ |
  | Return Requests (RMA) | — | — | ✅ |
  | Expense Tracker | — | — | ✅ |
  | Abandoned Cart Recovery | — | — | ✅ |
  | Customer Lifetime Value | — | — | ✅ |
- [ ] **Client email** — the email address for their merchant admin account (usually same as their ECW portal email)

Write these down before proceeding. You cannot change the subdomain after provisioning.

---

## Part 2 — Create Client Account in ECW (if new)

If the client does not already have an ECW portal account:

1. Log into `https://eastcoastwebcraft.ca/admin/users.php`
2. Click **Add Client**
3. Fill in: Name, Email, Company, Phone
4. Click **Create & Send Setup Link**
5. The client receives a setup email — they click it to set their own password

If they already have an account, skip to Part 3.

---

## Part 3 — Pre-Create the Tenant Database in cPanel

> This step is required because InMotion shared hosting cannot auto-create databases.  
> Do this BEFORE creating the invoice. If you skip it, provisioning will fail when the client pays.

1. Log into cPanel: `https://eastcoastwebcraft.ca:2083`
2. Go to **MySQL Databases**
3. Under **Create New Database**, type the subdomain slug only:
   - Type: `harbourgifts`
   - cPanel saves it as: `n777909_harbourgifts`
4. Scroll to **Add User to Database**:
   - User: `n777909_ecstore_usr`
   - Database: `n777909_harbourgifts`
   - Click **Add**
5. On the privileges page, check **ALL PRIVILEGES** → click **Make Changes**

The database is now ready. ECStores will run migrations into it automatically on provisioning.

---

## Part 4 — Create the ECStores Invoice

1. Go to `https://eastcoastwebcraft.ca/admin/create-invoice.php`
2. Select the client from the dropdown
3. Set **Service Type** → **ECStores**
4. Fill in the ECStores fields:
   - **Subdomain:** the slug you confirmed (e.g. `harbourgifts`)
   - **Store Name:** (e.g. `Harbour Gifts`)
   - **Plan:** Starter / Growth / Pro
5. Fill in Description (e.g. `ECStores Starter Plan — June 2026`)
6. Set Amount to the plan price
7. Set Due Date
8. Leave Status as **Draft** — do NOT send yet
9. Click **Create Invoice**

> The invoice and `ecstores_orders` row are now created with status **Pending**.

---

## Part 5 — Send the Invoice

1. Go to `https://eastcoastwebcraft.ca/admin/invoices.php`
2. Find the draft invoice
3. Change Status from **Draft** to **Sent** → Save

The client can now see the invoice in their portal and click **Pay Now**.

---

## Part 6 — Client Pays (Automatic Provisioning Flow)

When the client pays through Stripe:

1. Stripe checkout completes → client lands on `/portal/payment-success.php`
2. Invoice is marked **Paid**
3. ECW calls the ECStores API: `POST /api/v1/provision`
4. ECStores creates the tenant, runs database migrations, creates the merchant admin account with a random 12-character temporary password
5. `ecstores_orders` row is updated to **Provisioned**
6. Client's `ecstore_slug` is saved in their ECW user record
7. **Two emails are sent to the client automatically:**
   - A plain-text email from ECW (payment-success.php) with store URL and temp password
   - An HTML welcome email from the ECStores system with the same details
8. Client sees the **"Your Store is Live!"** page on screen with their merchant dashboard URL and temp password

**The client's welcome email contains:**
```
Store URL:          https://[slug].ecstores.ca
Merchant Dashboard: https://[slug].ecstores.ca/admin
Login email:        [their email]
Temp password:      [auto-generated 12-char alphanumeric]
```

If provisioning fails during payment, the client sees a "Payment Received" page and is told the team will contact them. Denis receives an alert email with the error. See Part 8.

---

## Part 7 — Denis's Post-Provisioning Verification Checklist

Within one hour of payment (or immediately after clicking Retry):

- [ ] **ECW Admin → ECStores → Orders tab** — order shows **Provisioned** with a date
- [ ] **ECW Admin → ECStores → Tenants tab** — new store appears with **Active** badge
- [ ] **Visit `https://[slug].ecstores.ca/admin`** — Filament login screen loads (requires SSL on *.ecstores.ca)
- [ ] **ECW Admin → Clients** → find the client → confirm **ECStores Slug** field is filled in (auto-set on provisioning)
- [ ] **Check your email** — if provisioning failed, you will have received an alert to `info@eastcoastwebcraft.ca`

> **Note on SSL:** Until a wildcard SSL certificate is installed for `*.ecstores.ca`, visiting the merchant admin URL will show a certificate error. The Magic Link button in the Tenants tab also requires SSL. During this period, clients will need to accept the browser warning or wait for SSL to be live.

---

## Part 8 — Manual Retry After Provisioning Failure

If provisioning failed during payment, the order shows **Failed** in the Orders tab with an error message.

### Step 1 — Fix the root cause

**Most common cause: database was not created**

Error: `Tenant database 'n777909_[slug]' does not exist.`

Fix: Create the database now — follow Part 3 above, then continue.

**Other errors:**
- **HMAC/401 error:** `ECW_API_SECRET` doesn't match between ECW `includes/config.php` and ECStores `.env`
- **cURL error:** ECStores API is unreachable. Check `ECSTORES_API_URL` in `includes/config.php`
- **422 validation error:** Subdomain format invalid (must be lowercase letters, numbers, hyphens only)

### Step 2 — Retry provisioning

1. Go to `https://eastcoastwebcraft.ca/admin/ecstores.php` → **Orders tab**
2. Find the failed order — it shows a "Retry" button with the database name it needs
3. Click **Retry**

On success:
- Order updates to **Provisioned**
- Client's `ecstore_slug` is set automatically
- **Welcome email is sent to the client** with their store URL and temp password (same email as the automatic path)
- Run the verification checklist in Part 7

> **The temp password is in the client's welcome email.** It is not displayed in the ECW admin panel after a retry. If the client doesn't receive the email, you can log into their store admin directly using the Magic Link button in the Tenants tab (requires SSL), or reset their password from the ECStores merchant admin.

---

## Part 9 — Client Experience After Provisioning

### Credentials

The client's login credentials are in the welcome email:
- **Username:** their email address
- **Password:** the temporary password from the welcome email

They log in at: `https://[slug].ecstores.ca/admin`

They should change their password immediately after first login (Profile page in merchant admin).

### ECW Portal Integration

Once their `ecstore_slug` is set, the client's ECW portal shows:
- A **"My Store"** card on their dashboard
- A **"My Store"** link in the portal sidebar navigation
- Clicking either takes them to `/portal/store-login.php` which generates a one-click magic link and redirects them directly into their merchant dashboard — no password needed

> **SSL required for magic link / one-click login.** Until `*.ecstores.ca` has a wildcard SSL certificate installed, the one-click login will fail with a certificate error. Clients will need to use their email credentials to log in directly at `https://[slug].ecstores.ca/admin` during this period.

---

## Part 10 — Ongoing Management

### Suspending a Store (Non-Payment)

1. Go to `https://eastcoastwebcraft.ca/admin/ecstores.php` → **Tenants tab**
2. Find the tenant → click **Suspend**
3. The storefront shows a suspension notice; merchant admin is blocked
4. The client's ECW portal "My Store" card remains but store-login redirects to the suspension page
5. In ECW Admin → Subscriptions → pause the client's ECStores subscription

To reactivate when payment is received:
1. Tenants tab → **Reactivate**
2. Subscriptions → set subscription back to active

### Changing a Tenant's Plan

1. Tenants tab → click **Plan** button on the tenant row
2. Select new plan from dropdown → click **Save**

### Accessing a Store as the Owner (Magic Link)

1. Tenants tab → click the external link icon button on the tenant row
2. Confirms and redirects you directly into their merchant admin dashboard
3. Requires SSL on `*.ecstores.ca`

### Issuing Refunds (Pro plan only)

Pro plan merchants can issue refunds directly from their order page — no need to go to the Stripe dashboard. Three types:
- **Stripe** — processed via Stripe API automatically
- **Manual** — recorded in the system, payment issued externally (e-transfer, cash)
- **Store Credit** — auto-generates a single-use coupon code worth the refund amount

If a Starter or Growth merchant asks how to refund, direct them to their Stripe dashboard to process the refund, then manually update the order status in their ECStores admin.

### Return Management / RMA (Pro plan only)

Pro plan merchants have a full return workflow:
1. **Request Return** button on the order — creates an RMA number, sets order to `return_requested`
2. **Mark Return Received** button — records received quantities, sets order to `return_received`
3. **Refund** button — issues refund and closes the return request automatically

Return requests are viewable under **Returns (RMA)** in the merchant's admin sidebar. If a Starter or Growth merchant asks about returns, they must handle them manually and update order statuses themselves.

### Cancelling a Store Permanently

1. Tenants tab → **Suspend** the tenant
2. ECW Admin → Clients → edit the client → clear the **ECStores Slug** field → Save
3. The "My Store" card disappears from their portal
4. ECW Admin → Subscriptions → cancel the ECStores subscription
5. Optionally: delete the tenant database from cPanel (data is permanently gone)

---

## Part 11 — Moving to Production (ecstores.ca)

When moving from `eastcoastweb.ca` (dev) to `ecstores.ca` (production):

### ECStores server (.env):
```ini
APP_URL=https://ecstores.ca
SESSION_DOMAIN=.ecstores.ca
```

### ECW config.php:
```php
define('ECSTORES_API_URL', 'https://ecstores.ca/api/v1');
```

### cPanel changes:
- Point `ecstores.ca` document root to `/home/n777909/ecstores/public`
- Create wildcard subdomain `*.ecstores.ca` → same document root
- Install wildcard SSL for `*.ecstores.ca`
- Add `ecstores.ca` to `config/tenancy.php` → `central_domains` array
- Remove `eastcoastweb.ca` from `central_domains` (or keep both during transition)

### After changes:
```bash
/opt/cpanel/ea-php83/root/usr/bin/php artisan config:cache
/opt/cpanel/ea-php83/root/usr/bin/php artisan route:cache
```

---

## Quick Reference — Key URLs

| URL | Purpose |
|---|---|
| `https://eastcoastwebcraft.ca/admin/ecstores.php` | Orders, Tenants, Plans management |
| `https://eastcoastwebcraft.ca/admin/users.php` | Client accounts + ECStores Slug field |
| `https://eastcoastwebcraft.ca/admin/create-invoice.php` | Create ECStores invoice |
| `https://eastcoastwebcraft.ca:2083` | cPanel — database creation |
| `https://[slug].ecstores.ca/admin` | Merchant admin dashboard |

## Quick Reference — Key Files

| File | Purpose |
|---|---|
| `eastcoastwebcraft.ca/includes/config.php` | ECW DB, Stripe, ECStores API URL + secret |
| `eastcoastwebcraft.ca/includes/ecstores_api.php` | All ECW → ECStores HTTP calls |
| `eastcoastwebcraft.ca/portal/payment-success.php` | Auto-provisioning trigger on payment |
| `eastcoastwebcraft.ca/portal/store-login.php` | Magic link pass-through for client portal |
| `ecstores/.env` | ECStores server config (APP_URL, ECW_API_SECRET) |
| `ecstores/config/tenancy.php` | Central domains, DB prefix, DB manager |
| `ecstores/app/Services/TenantProvisioningService.php` | Provisioning logic + welcome email |
| `ecstores/app/Mail/StoreWelcomeMail.php` | Welcome email sent to client on provision |
