---
title: Device Authorization vs. Legacy OAuth Flow
audience: public
summary: Side-by-side comparison of the RFC 8628 device flow and the legacy OAuth redirect chain for plugin onboarding, from the provider, plugin-developer, and merchant perspectives.
---

# WooCommerce Onboarding: Device Authorization vs. Legacy OAuth Flow

A side-by-side comparison of the new RFC 8628 Device Authorization flow and the existing Socialite/OAuth boarding flow, from three perspectives: WeeConnectPay (provider), plugin developers, and merchants.

---

## Executive Summary

The **legacy flow** uses a multi-step OAuth redirect chain: the plugin registers an integration, redirects the merchant to Clover for authentication, Clover redirects back to WeeConnectPay, WeeConnectPay posts credentials back to the plugin's WordPress REST API, and the plugin requests a JWT. This involves 7 steps, 3 redirects, and requires the plugin to expose a callback endpoint.

The **device flow** replaces all of this with a single pattern: the plugin sends its identity and gets a code, the merchant visits the login page, authenticates via Clover OAuth, types the code, and the plugin polls and receives credentials. 3 steps, 0 redirects, no callback endpoint needed.

Both flows produce the same outcome: OAuth client credentials tied to a Clover merchant context and an Integration record.

---

## Flow Comparison

### Legacy OAuth Flow (Current)

```
Plugin                    WeeConnectPay              Clover              Merchant
  |                            |                       |                    |
  |-- POST /integrations ----->|                       |                    |
  |<-- integration_id ---------|                       |                    |
  |                            |                       |                    |
  |-- Redirect merchant ------>|-- Redirect to Clover ->|                   |
  |                            |                       |-- Login & grant -->|
  |                            |<-- OAuth callback -----|                   |
  |                            |                       |                    |
  |                            |-- Boarding service --->|                   |
  |                            |   (12+ Clover API calls,                   |
  |                            |    creates 15 DB records)                  |
  |                            |                       |                    |
  |<-- POST /plugin/register --|   (auth_hash + uuid)  |                   |
  |                            |                       |                    |
  |-- POST /integration/token ->|                      |                    |
  |<-- JWT token --------------|                       |                    |
```

**Steps: 7** | **Redirects: 3** | **Plugin callback: Required** | **Clover API calls: 12+**

### Device Authorization Flow (New)

```
Plugin                    WeeConnectPay              Login Page          Merchant
  |                            |                       |                    |
  |-- POST /connect/authorize ->|                       |                    |
  |   (with platform_data)     |                       |                    |
  |<-- user_code + device_code |                       |                    |
  |                            |                       |                    |
  |   Shows "WDJK-MJHT"       |                       |   Clover OAuth  -->|
  |   to merchant              |                       |   Enters code ---->|
  |                            |                       |<-- Approve --------|
  |                            |                       |                    |
  |-- POST /connect/token ---->|                       |                    |
  |<-- client_id + secret -----|                       |                    |
  |                            |                       |                    |
  |-- POST /oauth/token ------>|                       |                    |
  |<-- Bearer token -----------|                       |                    |
```

**Steps: 4** | **Redirects: 0** | **Plugin callback: None** | **Clover API calls: 0** (at device flow time)

---

## Perspective 1: Merchant Experience

| Aspect | Legacy Flow | Device Flow |
|--------|-------------|-------------|
| **Steps** | Install plugin → Click "Connect to Clover" → Redirected to Clover login → Log in → Grant permissions → Redirected back → Plugin ready | Install plugin → See code in plugin → Go to login page → Authenticate via Clover OAuth → Type code → Click Authorize → Plugin ready |
| **Redirects** | 3 browser redirects (plugin → WeeConnectPay → Clover → WeeConnectPay → plugin) | 0 redirects. Merchant voluntarily opens the login page in a new tab. |
| **Clover login required?** | Yes — must log into Clover during the flow | Yes — merchant authenticates via Clover OAuth directly on the authorization page |
| **Where it happens** | Across multiple domains, multiple browser tabs/windows | Plugin admin + login page in separate tab |
| **Can it fail silently?** | Yes — if plugin callback URL is unreachable (firewall, SSL issue), the flow completes on the WeeConnectPay side but the plugin never receives credentials | No — polling is explicit. If the code expires, the plugin shows a clear "expired" message |
| **Copy-paste secrets?** | No (credentials sent to plugin callback) | No (credentials delivered via polling) |
| **Browser dependency** | Heavy — entire flow is a redirect chain | Light — merchant just types a code |
| **Mobile-friendly** | Difficult — multi-redirect OAuth on mobile is confusing | Yes — type a code on any device |
| **Time to complete** | ~1-3 minutes (depends on Clover login speed) | ~30 seconds |

### Merchant friction points removed

- No more "I got stuck on the Clover login page"
- No more "it redirected me somewhere and then nothing happened"
- No more "my firewall blocked the callback"
- No more "I need to do this on a desktop browser"

---

## Perspective 2: Plugin Developer Experience

| Aspect | Legacy Flow | Device Flow |
|--------|-------------|-------------|
| **Endpoints to implement** | 3: integration creation, OAuth redirect button, callback handler | 2: connect authorize call, polling loop |
| **Callback endpoint** | Must expose `POST /wp-json/weeconnectpay/v1/plugin/register` and accept `integration_id` + `auth_hash` | Not needed |
| **Auth hash management** | Must store `auth_hash` from callback, use it to request JWT via `POST /integration/{uuid}/token` | Not needed — receives `client_id` + `client_secret` directly |
| **Token type received** | JWT (personal access token with custom claims) | Client credentials (`client_id` + `client_secret`) → then standard OAuth token |
| **Token refresh** | Request new JWT with stored `auth_hash` | Standard `client_credentials` grant — no hash needed |
| **Integration creation** | Separate `POST /v1/integrations/woocommerce` call before OAuth | Built into `POST /v1/connect/authorize` via `platform_data` |
| **OAuth knowledge needed** | Must understand Socialite redirect flow, callback handling, intent parameter | Just HTTP POST + polling loop |
| **SSL requirements** | Plugin must have valid SSL (Clover and WeeConnectPay redirect back to it) | No SSL requirement on plugin side (plugin calls out, never receives callbacks) |
| **Firewall concerns** | Plugin callback URL must be reachable from WeeConnectPay servers | None — plugin only makes outbound calls |
| **Error handling** | Complex — must handle redirect failures, callback failures, hash validation failures | Simple — 5 well-defined error codes per RFC 8628 |
| **Code complexity** | ~200-300 lines for full OAuth integration | ~50-80 lines for device flow + polling |
| **Testing** | Difficult — requires browser automation for redirect chain | Easy — all HTTP POST requests, can test with curl |

### What a developer needs to build (Legacy)

1. Integration creation endpoint call
2. "Connect to Clover" redirect button with integration_id and intent params
3. WordPress REST API callback endpoint (`/wp-json/weeconnectpay/v1/plugin/register`)
4. Callback handler that validates and stores `integration_id` + `auth_hash`
5. Token request using `POST /integration/{uuid}/token` with `auth_hash`
6. JWT storage and refresh logic
7. Error handling for redirect failures, callback failures, and token validation

### What a developer needs to build (Device Flow)

1. `POST /v1/connect/authorize` call with `platform_data`
2. Display the user code and verification link to the merchant
3. Polling loop that calls `POST /v1/connect/token` every 5 seconds
4. Store `client_id` + `client_secret` on success
5. Standard `client_credentials` grant for token exchange

---

## Perspective 3: WeeConnectPay (Provider)

| Aspect | Legacy Flow | Device Flow |
|--------|-------------|-------------|
| **Clover API calls during boarding** | 12+ (merchant info, subscription, permissions, PAKMS key, etc.) | 0 at authorize time. Clover boarding happens separately via Clover OAuth login on the authorization page. |
| **Database records created** | 15+ records across 12 tables in a single transaction | 3 records (WordPress, WooCommerce, Integration) at authorize, 2 more (OAuthClient, CloverOauthClient) on approval |
| **Failure surface** | Large — any of the 12 Clover API calls can fail, OAuth redirect can break, plugin callback can timeout | Small — integration creation is simple, approval is a local DB operation |
| **Session management** | Must maintain PHP session across OAuth redirect chain | Stateless API endpoints (no session needed for device flow) |
| **Audit trail** | Implicit — scattered across boarding service logs | Explicit — every step logged with IPs, timestamps, and user identity |
| **Support burden** | High — "my connection failed" could be any of 12+ steps | Low — clear error codes, countdown timer, simple retry |
| **Infrastructure** | Must be reachable from plugin (inbound callback) + must reach Clover API | Only outbound from plugin. Authorization page approval is a separate, independent flow |
| **Credential security** | Auth hash + JWT — hash is transmitted via POST to plugin callback | Client credentials — secret encrypted at rest, delivered once via polling, then cleared |
| **Multi-tenant safety** | Integration linked to Clover context during boarding (clover_app_id, merchant_id set then) | Integration linked at authorize time via `platform_data`. Clover context (merchant, employee) linked at approval time via Clover OAuth authentication |
| **Re-boarding** | Merchant re-does OAuth flow — all 12+ Clover API calls again | Merchant requests new code — only integration lookup (idempotent), then approve |
| **New platform onboarding** | Requires building full OAuth redirect + callback + boarding flow for each platform | Requires only a new `resolveIntegration` method for the platform. Polling, codes, approval are all shared |

### Operational benefits for WeeConnectPay

- **Fewer support tickets**: Clear error messages, countdown timers, no silent failures
- **Faster new platform integration**: Adding PrestaShop or Zoho only requires a platform model + `resolveIntegration` method. No new OAuth flows, callbacks, or boarding services
- **Reduced Clover API dependency**: Device flow doesn't call Clover APIs at all — the Clover context comes from the merchant's Clover OAuth login on the authorization page
- **Better observability**: Every device code has a clear lifecycle with timestamps and IP addresses

---

## What Stays the Same

Both flows ultimately produce:
- An **Integration** record linked to a Clover merchant, employee, and app
- **OAuth client credentials** (client_id + client_secret) or a **JWT** tied to that integration
- The ability to resolve a full **CloverContext** (merchant, employee, app, access token) from the credentials
- Platform models (WordPress, WooCommerce) in the database

The Clover boarding process (creating CloverMerchant, CloverEmployee, CloverAccessToken, etc.) still happens — it just happens when the merchant authenticates via Clover OAuth on the authorization page, not during the plugin setup flow. The device flow separates these concerns: Clover authentication is handled by the Clover OAuth login on the authorization page, plugin credential issuance is the device flow's job.

---

## Migration Path

Since this is not yet in production:
- **New plugins** should implement the device flow exclusively
- **The legacy OAuth redirect flow remains** for the existing WooCommerce plugin until it's updated
- Both flows can coexist — they create the same Integration and credential types
- The existing WooCommerce plugin will be updated to use the device flow in a future release

---

## Recommendation

**Use the Device Authorization flow for all new integrations.** It is simpler for every stakeholder:
- Merchants get a faster, more reliable setup
- Developers write less code with fewer failure modes
- WeeConnectPay gets better observability and fewer support tickets

---

## Multi-Merchant / Franchise Operations

The device flow natively supports connecting multiple websites to different Clover merchants — a common pattern for franchise operations where each location has its own Clover account and its own website.

### How It Works

| Step | Legacy Flow | Device Flow |
|------|-------------|-------------|
| **Connect 3 locations** | Must run the full OAuth redirect chain 3 times, logging into the correct Clover merchant each time. Redirects are confusing when switching between Clover accounts. | Request 3 device codes (one per website). Enter each code on the login page, authenticating via Clover OAuth as the correct merchant before clicking "Verify Code." |
| **Context verification** | None — the OAuth callback assumes the currently-logged-in Clover merchant is correct. If the merchant is logged into the wrong Clover account, the integration silently links to the wrong merchant. | Explicit — the Clover OAuth login determines which merchant the code will be linked to. The merchant verifies their identity before submitting. |
| **Switching merchants** | Must log out of Clover and re-authenticate as a different merchant. | Click "Authorize as different merchant" — triggers a new Clover OAuth login as the correct merchant. |

### Example: 3-Location Franchise

```
Location A (shop-a.example.com) → Code: WDJK-MJHT → Merchant: "Coffee Shop Downtown"
Location B (shop-b.example.com) → Code: XFGN-4R7C → Merchant: "Coffee Shop Uptown"
Location C (shop-c.example.com) → Code: HTPQ-2VKE → Merchant: "Coffee Shop Airport"
```

The franchise owner:
1. Opens all three codes in their browser (each from the respective website's admin)
2. On the WeeConnectPay login page, authenticates via Clover OAuth as "Coffee Shop Downtown"
3. Enters the first code, clicks "Verify Code"
4. Approves the connection
5. Clicks "Authorize as different merchant", authenticates via Clover OAuth as "Coffee Shop Uptown", enters the second code, repeats
6. Clicks "Authorize as different merchant", authenticates via Clover OAuth as "Coffee Shop Airport", enters the third code, repeats

Each website gets credentials tied to its specific Clover merchant. No OAuth redirects, no Clover logouts, no confusion about which account is active.

### Why No Auto-Submit

The code entry page deliberately waits for the merchant to click "Verify Code" after filling all 8 characters. This pause allows the merchant to:
- **Verify identity** — confirm they are authenticated as the correct Clover merchant
- **Authorize as different merchant** — triggers a new Clover OAuth login to switch to a different merchant

This is essential for multi-merchant operations. An auto-submit on the last character would bypass this verification step and could silently link integrations to the wrong merchant.
