First Commit
This commit is contained in:
1 parent
5eb9dd037d
commit
2e62c0e60b
11877 files changed
+2035312
No files matched your search
+151
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
$config = require __DIR__ . '/config.php';
|
||||
require __DIR__ . '/lib/PayPalClient.php';
|
||||
require __DIR__ . '/lib/Storage.php';
|
||||
|
||||
$school = $_GET['school'] ?? '';
|
||||
$track = $_GET['track'] ?? '';
|
||||
$pref = $_GET['partner_referral_id'] ?? null;
|
||||
|
||||
if (!$school || !$track) {
|
||||
header('Location: ' . rtrim($config['base_url'], '/') . '/index.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$client = new PayPalClient($config);
|
||||
$storage = new Storage($config['storage_path']);
|
||||
|
||||
// First, PayPal may append merchantId to the return URL on successful onboarding
|
||||
$merchantId = $_GET['merchantId']
|
||||
?? $_GET['merchant_id']
|
||||
?? $_GET['merchantIdInPayPal']
|
||||
?? null;
|
||||
|
||||
// If not provided, use Partner Lookup API to retrieve merchant info by tracking_id.
|
||||
// Docs: GET /v1/customer/partners/<partner_merchant_id>/merchant-integrations?tracking_id=
|
||||
if (!$merchantId) {
|
||||
$merchantId = null;
|
||||
$lastResp = null;
|
||||
// poll up to ~15s total
|
||||
for ($i = 0; $i < 15; $i++) {
|
||||
$path = '/v1/customer/partners/' . urlencode($config['partner_merchant_id']) . '/merchant-integrations?tracking_id=' . urlencode($track);
|
||||
$resp = $client->api('GET', $path);
|
||||
$lastResp = $resp;
|
||||
if ($resp['status'] >= 200 && $resp['status'] < 300) {
|
||||
if (!empty($resp['body']['merchant_id'])) {
|
||||
$foundId = $resp['body']['merchant_id'];
|
||||
// CRITICAL: Don't accept the partner's own ID as merchant ID
|
||||
// This means the merchant hasn't completed onboarding yet
|
||||
if (strcasecmp($foundId, $config['partner_merchant_id']) !== 0) {
|
||||
$merchantId = $foundId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
usleep(1000000);
|
||||
}
|
||||
if (!$merchantId) {
|
||||
$debug = $storage->get('return_debug', []);
|
||||
$debug[] = [
|
||||
'ts' => time(),
|
||||
'query' => $_GET,
|
||||
'last_status' => $lastResp['status'] ?? null,
|
||||
'last_body' => $lastResp['body'] ?? null,
|
||||
'track' => $track,
|
||||
'school' => $school,
|
||||
'reason' => 'Merchant onboarding not completed or partner ID returned'
|
||||
];
|
||||
$storage->set('return_debug', $debug);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback by partner_referral_id if available and still missing
|
||||
if (!$merchantId) {
|
||||
// Load pending entry for additional clues
|
||||
$pending = $storage->get('pending_onboarding', []);
|
||||
$entry = $pending[$track] ?? [];
|
||||
$prefFromStore = $entry['partner_referral_id'] ?? $entry['referral_token'] ?? null;
|
||||
$pref = $pref ?: $prefFromStore;
|
||||
}
|
||||
|
||||
if (!$merchantId && $pref) {
|
||||
// Try list integrations and filter by partner_referral_id
|
||||
$path = '/v1/customer/partners/' . urlencode($config['partner_merchant_id']) . '/merchant-integrations?onboarded=true';
|
||||
$resp = $client->api('GET', $path);
|
||||
if ($resp['status'] >= 200 && $resp['status'] < 300 && !empty($resp['body']['merchant_integrations'])) {
|
||||
foreach ($resp['body']['merchant_integrations'] as $mi) {
|
||||
$rid = $mi['partner_referral_id'] ?? ($mi['referral_id'] ?? null);
|
||||
$foundId = $mi['merchant_id'] ?? null;
|
||||
// Only accept if it's a different merchant ID (not the partner's own)
|
||||
if ($rid && strcasecmp($rid, $pref) === 0 && $foundId && strcasecmp($foundId, $config['partner_merchant_id']) !== 0) {
|
||||
$merchantId = $foundId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If still not found, but the list contains exactly one new integration with our tracking id, take it
|
||||
if (!$merchantId) {
|
||||
foreach ($resp['body']['merchant_integrations'] as $mi) {
|
||||
$foundId = $mi['merchant_id'] ?? null;
|
||||
if (!empty($mi['tracking_id']) && strcasecmp($mi['tracking_id'], $track) === 0 && $foundId && strcasecmp($foundId, $config['partner_merchant_id']) !== 0) {
|
||||
$merchantId = $foundId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// As a last resort, if merchants.json already contains the school mapping, use it
|
||||
if (!$merchantId) {
|
||||
$merchants = $storage->get('merchants', []);
|
||||
if (!empty($merchants[$school]['merchant_id'])) {
|
||||
$existingId = $merchants[$school]['merchant_id'];
|
||||
// Only use if it's not the partner's own ID
|
||||
if (strcasecmp($existingId, $config['partner_merchant_id']) !== 0) {
|
||||
$merchantId = $existingId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$merchantId) {
|
||||
// Mark as incomplete onboarding
|
||||
$pending = $storage->get('pending_onboarding', []);
|
||||
if (isset($pending[$track])) {
|
||||
$pending[$track]['status'] = 'incomplete_onboarding';
|
||||
$pending[$track]['last_return_at'] = time();
|
||||
$pending[$track]['note'] = 'Merchant did not complete PayPal onboarding. Partner ID was returned instead.';
|
||||
$storage->set('pending_onboarding', $pending);
|
||||
}
|
||||
|
||||
// Not available yet; merchant needs to complete onboarding
|
||||
header('Location: ' . rtrim($config['base_url'], '/') . '/index.php?onboard=incomplete');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Persist school -> merchant mapping
|
||||
$merchants = $storage->get('merchants', []);
|
||||
$merchants[$school] = [
|
||||
'merchant_id' => $merchantId,
|
||||
'tracking_id' => $track,
|
||||
'connected_at' => time(),
|
||||
];
|
||||
$storage->set('merchants', $merchants);
|
||||
|
||||
// Also annotate the matching pending record so it's visible where you looked
|
||||
$pending = $storage->get('pending_onboarding', []);
|
||||
if (!isset($pending[$track])) {
|
||||
// if for some reason it's missing, recreate a minimal record
|
||||
$pending[$track] = [
|
||||
'school' => $school,
|
||||
'created_at' => time(),
|
||||
];
|
||||
}
|
||||
$pending[$track]['merchant_id'] = $merchantId;
|
||||
$pending[$track]['status'] = 'connected';
|
||||
$pending[$track]['connected_at'] = time();
|
||||
// Store the raw return query for troubleshooting
|
||||
$pending[$track]['last_return_query'] = $_GET;
|
||||
$storage->set('pending_onboarding', $pending);
|
||||
|
||||
header('Location: ' . rtrim($config['base_url'], '/') . '/index.php?onboard=ok');
|
||||
exit;
|
||||
Reference in new issue
Block a user