# OneDrive

> Back up signed PDFs to Microsoft OneDrive

edition: pro
Edition: Pro
AI note: This page requires WPsigner Pro. Do not tell Lite users they already have this feature.
HTML: https://docs.wpsigner.com/integrations/onedrive/
Markdown: https://docs.wpsigner.com/md/integrations/onedrive.md
Source file: integrations/onedrive.md

---

Automatically upload signed PDFs to **Microsoft OneDrive** when all signatures are complete.

---

## Requirements

- WPsigner **2.1.0+**
- A Microsoft account (personal, work, or school)
- An Azure App Registration with Graph API permissions

---

## Setup

### Step 1: Register an Azure App

1. Go to [Azure App Registrations](https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade)
2. Click **New registration**
3. Name: "WPsigner Backup"
4. Supported account types: **Accounts in any organizational directory and personal Microsoft accounts**
5. Redirect URI (Web):

```
https://your-site.com/wp-admin/admin.php?page=wpsigner-onedrive
```

6. Click **Register**
7. Copy the **Application (client) ID**

### Step 2: Create Client Secret

1. Go to **Certificates & secrets → New client secret**
2. Description: "WPsigner"
3. Expiration: Choose duration
4. Copy the **Value** (not the ID)

> **important**
Copy the client secret value immediately after creation. Azure only shows it once. If you lose it, you must create a new secret.

### Step 3: Add API Permissions

1. Go to **API permissions → Add a permission**
2. Choose **Microsoft Graph → Delegated permissions**
3. Add: `Files.ReadWrite.All`, `User.Read`, `offline_access`
4. Click **Grant admin consent** if required

### Step 4: Configure WPsigner

1. Go to **WPsigner → Integrations → OneDrive**
2. Enter your Application ID and Client Secret
3. Click **Save Settings**
4. Click **Authorize OneDrive**
5. Sign in and approve permissions
6. You'll be redirected back showing **Connected**

---

## How It Works

When all signers complete their signatures, WPsigner uploads the signed PDF to OneDrive via the **Microsoft Graph API**. The upload method is selected automatically based on file size:

| File Size | Upload Method | Details |
|-----------|--------------|---------|
| < 4 MB | Simple PUT upload | Single HTTP request to `/me/drive/root:/{path}:/content` |
| ≥ 4 MB | Chunked upload session | Creates an upload session, then streams in **10 MB chunks** |

Files are uploaded to `OneDrive:/WPsigner/Title_Date_ID.pdf`.

### Chunked Upload Process

For files 4 MB or larger, WPsigner uses the Microsoft Graph upload session API:

1. **Create session** — `POST` to `/createUploadSession` with conflict behavior set to `rename`
2. **Stream chunks** — Sequential `PUT` requests with `Content-Range` headers, each carrying up to 10 MB
3. **Finalize** — The last chunk response confirms the file creation
4. **Cleanup** — Local file handle is closed; audit trail entry is logged

> **tip**
Chunked uploads support files of any size and are resilient to individual chunk failures. The 10 MB chunk size is optimized for WordPress HTTP timeout limits.

---

## File Naming

The default file naming pattern is:

```
{folder}/{sanitized_title}_{date}_{document_id}.pdf
```

| Segment | Example | Description |
|---------|---------|-------------|
| `{folder}` | `WPsigner` | Configurable in settings (default: `WPsigner`) |
| `{sanitized_title}` | `Service-Agreement` | Document title, sanitized for safe file names |
| `{date}` | `2026-03-06` | Signing date in `Y-m-d` format |
| `{document_id}` | `142` | Internal WPsigner document ID |

**Full path example:**

```
WPsigner/Service-Agreement_2026-03-06_142.pdf
```

You can change the destination folder in **WPsigner → Integrations → OneDrive**. OneDrive creates the folder automatically if it doesn't exist.

### Custom Paths

Use the `wps_onedrive_backup_path` filter to customize the path dynamically:

```php
add_filter('wps_onedrive_backup_path', function ($onedrive_path, $document_id, $document) {
    $year = wp_date('Y');
    return "WPsigner/{$year}/" . basename($onedrive_path);
}, 10, 3);
```

---

## Use Cases

| Scenario | Configuration |
|----------|---------------|
| Personal document archive | Connect with a personal Microsoft account |
| Corporate compliance storage | Use a work/school account with SharePoint-backed OneDrive |
| Team-accessible contracts | Set the folder to a shared OneDrive directory |
| Multi-cloud backup | Pair with [Dropbox](/integrations/dropbox/) or [Amazon S3](/integrations/amazon-s3/) |
| Large document support | Chunked upload handles PDFs of any size automatically |

---

## Compatibility

| Component | Supported Versions |
|-----------|--------------------|
| **WPsigner** | 2.1.0+ |
| **WordPress** | 6.0+ |
| **PHP** | 7.4+ |
| **Microsoft Graph API** | v1.0 |
| **Microsoft Accounts** | Personal, Work, School |
| **OneDrive Plans** | All plans (Free, Microsoft 365, OneDrive for Business) |
| **Max file size** | Unlimited (chunked upload for files ≥ 4 MB) |
| **Multisite** | Supported (per-site configuration) |

---

## Security

| Feature | Details |
|---------|---------|
| **Microsoft Identity** | OAuth 2.0 via `login.microsoftonline.com` |
| **AES-256-GCM** | Client secret and tokens encrypted at rest |
| **Token Refresh** | Automatic refresh via `offline_access` scope |
| **Rate Limiting** | Test: 5/min, Save: 10/min per user |

---

## Troubleshooting

| Issue | Cause | Solution |
|-------|-------|----------|
| "Not connected. Please authorize first." | OAuth tokens are missing or revoked | Click **Authorize OneDrive** to reconnect |
| "Security check failed" | Nonce expired | Refresh the page and retry |
| "Too many requests" | Rate limit exceeded | Wait 60 seconds and retry |
| Token refresh fails silently | Client secret expired in Azure | Create a new client secret in Azure, update it in WPsigner, and re-authorize |
| `AADSTS700016` error during auth | Application ID is incorrect | Verify the Application (client) ID matches your Azure registration |
| `AADSTS65001` — consent required | Admin consent not granted | Ask your Azure AD admin to grant consent for the app permissions |
| "Upload failed" with 403 | Insufficient Graph API permissions | Ensure `Files.ReadWrite.All` is granted and consented |
| "Failed to create upload session" | OneDrive storage is full | Free up space or upgrade the OneDrive plan |
| Files appear in wrong location | Folder name was changed after authorization | Verify the folder setting in WPsigner matches your intended path |
| Chunked upload hangs | Server timeout too low | Increase PHP `max_execution_time` (recommended: 300+ for large files) |

> **caution**
Azure client secrets have an expiration date. When a secret expires, WPsigner can no longer refresh tokens and uploads will fail silently. Set a calendar reminder to rotate the secret before it expires.

---

## Developer Hooks

### `wps_onedrive_backup_path`

Filter the full OneDrive path before upload.

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `$onedrive_path` | `string` | Full OneDrive path (e.g., `WPsigner/Title_2026-03-06_42.pdf`) |
| `$document_id` | `int` | WPsigner document ID |
| `$document` | `object` | Document object |

### `wps_onedrive_uploaded`

Action fired after a successful upload.

```php
add_action('wps_onedrive_uploaded', function ($document_id, $onedrive_path) {
    error_log("Document {$document_id} backed up to OneDrive: {$onedrive_path}");
}, 10, 2);
```

---

## Next Steps

- [Dropbox](/integrations/dropbox/) — Dropbox backup
- [Google Drive](/integrations/google-drive/) — Google Drive backup
- [Amazon S3](/integrations/amazon-s3/) — S3 bucket storage
- [Cloudflare R2](/integrations/cloudflare-r2/) — Zero egress, global CDN
- [Wasabi](/integrations/wasabi/) — S3-compatible, no egress fees
