Files
HotLunches/payp/FLOW_DIAGRAM.md
T
2026-10-19 15:22:52 -07:00

240 lines
11 KiB
Markdown

# PayPal Merchant Onboarding Flow
## BEFORE FIX (The Problem) ❌
```
┌─────────────────────────────────────────────────────────────────┐
│ 1. User clicks "Connect with PayPal" │
│ → onboard.php creates referral │
│ → Saves to pending_onboarding.json │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 2. Redirected to PayPal Onboarding │
│ → User sees business account signup │
│ → User CLOSES browser WITHOUT completing ❌ │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 3. Returns to return.php │
│ → Queries PayPal API for merchant_id │
│ → PayPal returns: "NEG5HMUKCTQNL" (PARTNER ID!) ❌ │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 4. OLD CODE: Accepts partner ID as merchant ID ❌ │
│ → Saves "NEG5HMUKCTQNL" to merchants.json │
│ → WRONG! This is YOUR ID, not the merchant's! │
└─────────────────────────────────────────────────────────────────┘
↓
STUCK FOREVER 😞
```
---
## AFTER FIX (The Solution) ✅
```
┌─────────────────────────────────────────────────────────────────┐
│ 1. User clicks "Connect with PayPal" │
│ → onboard.php creates referral │
│ → Saves to pending_onboarding.json │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 2. Redirected to PayPal Onboarding │
│ → User sees business account signup │
└─────────────────────────────────────────────────────────────────┘
↙ ↘
SCENARIO A SCENARIO B
(Incomplete) (Complete)
┌──────────────────────────┐ ┌──────────────────────────┐
│ User CLOSES browser │ │ User COMPLETES all │
│ WITHOUT finishing ❌ │ │ steps at PayPal ✅ │
└──────────────────────────┘ └──────────────────────────┘
↓ ↓
┌──────────────────────────┐ ┌──────────────────────────┐
│ Returns to return.php │ │ Returns to return.php │
│ PayPal returns: │ │ PayPal returns: │
│ "NEG5HMUKCTQNL" │ │ "ABC123XYZ456" ✅ │
│ (partner ID) │ │ (real merchant ID) │
└──────────────────────────┘ └──────────────────────────┘
↓ ↓
┌──────────────────────────┐ ┌──────────────────────────┐
│ NEW CODE: │ │ NEW CODE: │
│ ✅ REJECTS partner ID │ │ ✅ ACCEPTS merchant ID │
│ ✅ Marks as incomplete │ │ ✅ Saves to merchants │
│ ✅ Shows warning │ │ ✅ Shows success │
└──────────────────────────┘ └──────────────────────────┘
↓ ↓
┌──────────────────────────┐ ┌──────────────────────────┐
│ Dashboard shows: │ │ Dashboard shows: │
│ ⚠️ Incomplete │ │ ✅ Connected │
│ "Complete PayPal │ │ "Ready to accept │
│ signup to continue" │ │ payments" │
└──────────────────────────┘ └──────────────────────────┘
```
---
## Data Structure Comparison
### BEFORE FIX ❌
```json
// pending_onboarding.json
{
"school_ab32258ab0": {
"school": "m",
"created_at": 1760884706,
"partner_referral_id": "YzU2NGVl...",
"referral_token": "YzU2NGVl...",
"merchant_id": "NEG5HMUKCTQNL", ← WRONG! This is partner ID
"status": "connected" ← FALSE! Not really connected
}
}
```
### AFTER FIX - Incomplete ⚠️
```json
// pending_onboarding.json
{
"school_ab32258ab0": {
"school": "m",
"created_at": 1760884706,
"partner_referral_id": "YzU2NGVl...",
"referral_token": "YzU2NGVl...",
"status": "incomplete_onboarding", ← Honest status
"note": "Merchant did not complete PayPal onboarding",
"last_return_at": 1760885000
}
}
```
### AFTER FIX - Complete ✅
```json
// pending_onboarding.json
{
"school_3387003d82": {
"school": "b",
"created_at": 1760797314,
"partner_referral_id": "MTQ2Njlm...",
"referral_token": "MTQ2Njlm...",
"merchant_id": "796GQ4VM8SWSQ", ← CORRECT! Different ID
"status": "connected", ← TRUE! Really connected
"connected_at": 1760797400
}
}
// merchants.json
{
"b": {
"merchant_id": "796GQ4VM8SWSQ",
"tracking_id": "school_3387003d82",
"connected_at": 1760797400
}
}
```
---
## Key Changes in Code
### return.php
```php
// OLD CODE ❌
if (!empty($resp['body']['merchant_id'])) {
$merchantId = $resp['body']['merchant_id']; // Accepts ANY ID
}
// NEW CODE ✅
if (!empty($resp['body']['merchant_id'])) {
$foundId = $resp['body']['merchant_id'];
// CRITICAL: Don't accept partner's own ID
if (strcasecmp($foundId, $config['partner_merchant_id']) !== 0) {
$merchantId = $foundId; // Only accept if different
}
}
```
### sync_merchants.php
```php
// OLD CODE ❌
if (!empty($resp['body']['merchant_id'])) {
$merchantId = $resp['body']['merchant_id']; // Blindly accepts
}
// NEW CODE ✅
if (!empty($resp['body']['merchant_id'])) {
$foundId = $resp['body']['merchant_id'];
// Don't accept partner ID - means onboarding not completed
if (strcasecmp($foundId, $config['partner_merchant_id']) !== 0) {
$merchantId = $foundId;
}
}
```
---
## Testing Scenarios
### Test 1: Incomplete Onboarding ⚠️
1. Click "Connect with PayPal"
2. See PayPal signup page
3. **Immediately click "Return to School Lunch App"**
4. **Expected Result**:
- ⚠️ "Onboarding Incomplete" warning
- Status: `incomplete_onboarding`
- NO merchant_id saved
### Test 2: Complete Onboarding ✅
1. Click "Connect with PayPal"
2. See PayPal signup page
3. **Complete ALL steps** (business info, email verification, etc.)
4. Click "Return to Application"
5. **Expected Result**:
- ✅ "Onboarding completed" success message
- Status: `connected`
- Merchant ID saved (NOT `NEG5HMUKCTQNL`)
### Test 3: Sync Pending ⏳
1. Complete onboarding but merchant_id not immediately available
2. Click "🔄 Sync Now"
3. **Expected Result**:
- System queries PayPal API
- Retrieves merchant_id
- Updates status to `connected`
---
## Success Indicators ✅
You'll know it's working when:
1. **Different Merchant IDs**: Each merchant gets unique ID (not `NEG5HMUKCTQNL`)
2. **Clear Status**: See `connected` or `incomplete_onboarding` (not stuck)
3. **Warning Messages**: Incomplete onboardings show warnings
4. **Real Payments**: Can create orders with actual merchant IDs
---
## Your Real Example 🎯
From your `sync_debug.json`, school "b" worked correctly:
```json
{
"ts": 1760884845,
"track": "school_3387003d82",
"school": "b",
"attempt": "by-tracking",
"status": 200,
"body": {
"merchant_id": "796GQ4VM8SWSQ", ← SUCCESS! ✅
"tracking_id": "school_3387003d82"
}
}
```
This is what ALL your merchants should look like! 🎉