# SSLCOMMERZ Deployment Guide (Sandbox vs Live)

This project supports **SSLCOMMERZ Hosted Checkout** (redirect flow) and stores payment attempts per `bo_in_id` with:

- `bo_payment_info.invoice` = SSLCOMMERZ `tran_id`
- `bo_payment_info.payment_reason` = `BO_Acc_Payment` or `Deposit`

This guide lists what to change for **sandbox testing** vs **production/live**.

---

## Important URLs & Routes (this project)

### Web pages (public)
- **Pay page**: `GET /sslzcheckout/pay`
  - Supports prefill via query params:
    - `/sslzcheckout/pay?bo_in_id=551`
    - optional: `payment_amount`, `payment_reason`
- **Landing page**: `GET /sslzcheckout?status=...&tran_id=...`

### Initiation (JWT protected)
- **Hosted checkout initiation**: `GET|POST /api/sslzcheckout`
  - Required params:
    - `bo_in_id`
    - `payment_amount`
  - Optional:
    - `payment_reason` = `BO_Acc_Payment` (default) or `Deposit`

### SSLCOMMERZ callbacks (public)
SSLCOMMERZ may hit these via **GET redirect** or **POST**:
- `GET|POST /api/sslzcheckout/success`
- `GET|POST /api/sslzcheckout/fail`
- `GET|POST /api/sslzcheckout/cancel`
- `GET|POST /api/sslzcheckout/ipn`

---

## Sandbox Testing Setup

### 1) `.env` settings (Sandbox)
Set these values in your environment:

```env
APP_ENV=local
APP_DEBUG=true
APP_URL=http://127.0.0.1:8000

SSLCZ_SANDBOX=true
SSLCZ_STORE_ID=<sandbox_store_id>
SSLCZ_STORE_PASSWORD=<sandbox_store_password>

SSLCZ_SANDBOX_BASE_URL=https://sandbox.sslcommerz.com
SSLCZ_LIVE_BASE_URL=https://securepay.sslcommerz.com

# Optional: where to send user after validated success
SSLCZ_FRONTEND_SUCCESS_REDIRECT=https://client.fintra.com.bd/dashboard/myBOAccount

# Expire stuck processing payments after N minutes (default 20)
SSLCZ_PROCESSING_EXPIRE_MINUTES=20
```

Notes:
- Sandbox **embed** (Easy Checkout) would use `https://sandbox.sslcommerz.com/embed.min.js` (this project currently uses hosted checkout page).
- IPN cannot reliably work on localhost unless the server is publicly reachable.

### 2) Clear cached config (after `.env` change)

```bash
php artisan config:clear
php artisan cache:clear
php artisan route:clear
php artisan view:clear
```

### 3) Run migrations

```bash
php artisan migrate
```

### 4) Test hosted checkout
Open:
- `/sslzcheckout/pay?bo_in_id=<your_bo_in_id>`

Fill:
- amount (10–500000)
- reason (BO_Acc_Payment/Deposit)

Submit → redirects to SSLCOMMERZ sandbox gateway.

---

## Live / Production Setup

### 1) Prerequisites
- Your domain must be **publicly reachable via HTTPS**.
- Ensure the callback URLs below can be reached from SSLCOMMERZ:
  - `/api/sslzcheckout/success`
  - `/api/sslzcheckout/fail`
  - `/api/sslzcheckout/cancel`
  - `/api/sslzcheckout/ipn`

### 2) `.env` settings (Live)

```env
APP_ENV=production
APP_DEBUG=false
APP_URL=https://fi-bo.fintra.com.bd

SSLCZ_SANDBOX=false
SSLCZ_STORE_ID=<live_store_id>
SSLCZ_STORE_PASSWORD=<live_store_password>

SSLCZ_LIVE_BASE_URL=https://securepay.sslcommerz.com

# Where to send user after validated success
SSLCZ_FRONTEND_SUCCESS_REDIRECT=https://client.fintra.com.bd/dashboard/myBOAccount

# Expire stuck processing payments after N minutes (default 20)
SSLCZ_PROCESSING_EXPIRE_MINUTES=20
```

Optional overrides (usually leave blank and let the app build from `APP_URL`):

```env
SSLCZ_SUCCESS_URL=
SSLCZ_FAIL_URL=
SSLCZ_CANCEL_URL=
SSLCZ_IPN_URL=
```

If you set these, they must be HTTPS and public, e.g.:
- `https://fi-bo.fintra.com.bd/api/sslzcheckout/success`

### 3) Deploy files to production
Make sure the following are deployed:

- **Config**: `config/sslcommerz.php`, `config/cors.php`
- **Controller/Service**: `app/Http/Controllers/SslCommerzCheckoutController.php`, `app/Services/SslCommerzService.php`
- **Routes**: `routes/api.php`, `routes/web.php`
- **Views**: `resources/views/sslzcheckout-pay.blade.php`, `resources/views/sslzcheckout.blade.php`
- **Middleware** (if used on server): `app/Http/Middleware/HandleCors.php`, `app/Http/Middleware/EnsureUserOwnership.php`, `app/Http/Middleware/JwtCookieToBearer.php`
- **Migrations**:
  - `database/migrations/2026_04_08_000000_add_invoice_and_reason_to_bo_payment_info_table.php`
  - plus any migrations that create/modify `sslcommerz_transactions` (must exist on the server)

### 4) Run migrations on live

```bash
php artisan migrate --force
```

### 5) Clear caches on live (required after deploy)

```bash
php artisan config:clear
php artisan cache:clear
php artisan route:clear
php artisan view:clear
```

Optional (only after verifying things work):

```bash
php artisan config:cache
php artisan route:cache
```

---

## Credentials checklist

You must obtain live/sandbox credentials from SSLCOMMERZ:
- **Store ID**
- **Store Password**

Set them in `.env`:
- `SSLCZ_STORE_ID`
- `SSLCZ_STORE_PASSWORD`

---

## Common production issues

### 1) 405 Method Not Allowed after OTP
Cause: gateway hits `success/fail/cancel` via GET but route only allowed POST.  
Fix: allow `GET|POST` for callbacks.

### 2) Browser shows “information you’re about to submit is not secure”
Cause: using `http://` instead of `https://`.  
Fix: use HTTPS and set `APP_URL=https://...`.

### 3) `{"message":"Access denied"}` on callbacks
Cause: custom CORS middleware blocking non-whitelisted origins.  
Fix: ensure `config/cors.php` has correct origins/patterns and your middleware respects patterns, or do not wrap gateway callbacks with strict CORS checks.

### 4) “Payment is already in processing”
Cause: there is a `bo_payment_info` row with `payment_status='P'` for same `bo_in_id + payment_reason`.  
Fix: this project auto-expires stale `P` attempts older than `SSLCZ_PROCESSING_EXPIRE_MINUTES`.

