235 lines
9.0 KiB
PHP
235 lines
9.0 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Log;
|
|
use App\Models\PackagePurchase;
|
|
use App\Models\Tenant;
|
|
use App\Models\TenantPackage;
|
|
use App\Models\Package;
|
|
|
|
use PaypalServerSdkLib\PaypalServerSdkClientBuilder;
|
|
use PaypalServerSdkLib\Auth\ClientCredentialsAuthCredentialsBuilder;
|
|
use PaypalServerSdkLib\Environment;
|
|
use PaypalServerSdkLib\Logging\LoggingConfigurationBuilder;
|
|
use PaypalServerSdkLib\Logging\RequestLoggingConfigurationBuilder;
|
|
use PaypalServerSdkLib\Logging\ResponseLoggingConfigurationBuilder;
|
|
use PaypalServerSdkLib\Logging\LogLevel;
|
|
use PaypalServerSdkLib\Orders\OrderRequestBuilder;
|
|
use PaypalServerSdkLib\Orders\CheckoutPaymentIntent;
|
|
use PaypalServerSdkLib\Orders\PurchaseUnitRequestBuilder;
|
|
use PaypalServerSdkLib\Orders\AmountWithBreakdownBuilder;
|
|
use PaypalServerSdkLib\Orders\ApplicationContextBuilder;
|
|
use PaypalServerSdkLib\Subscriptions\SubscriptionRequestBuilder;
|
|
use PaypalServerSdkLib\Subscriptions\SubscriberBuilder;
|
|
use PaypalServerSdkLib\Subscriptions\NameBuilder;
|
|
use PaypalServerSdkLib\Subscriptions\ApplicationContextSubscriptionBuilder;
|
|
use PaypalServerSdkLib\Subscriptions\ShippingPreference;
|
|
|
|
class PayPalController extends Controller
|
|
{
|
|
private $client;
|
|
|
|
public function __construct()
|
|
{
|
|
$clientId = config('services.paypal.client_id');
|
|
$clientSecret = config('services.paypal.secret');
|
|
|
|
$this->client = PaypalServerSdkClientBuilder::init()
|
|
->clientCredentialsAuthCredentials(
|
|
ClientCredentialsAuthCredentialsBuilder::init($clientId, $clientSecret)
|
|
)
|
|
->environment(config('app.env') === 'production' ? Environment::PRODUCTION : Environment::SANDBOX)
|
|
->loggingConfiguration(
|
|
LoggingConfigurationBuilder::init()
|
|
->level(LogLevel::INFO)
|
|
->requestConfiguration(RequestLoggingConfigurationBuilder::init()->body(true))
|
|
->responseConfiguration(ResponseLoggingConfigurationBuilder::init()->headers(true))
|
|
)
|
|
->build();
|
|
}
|
|
|
|
public function createOrder(Request $request)
|
|
{
|
|
$request->validate([
|
|
'tenant_id' => 'required|exists:tenants,id',
|
|
'package_id' => 'required|exists:packages,id',
|
|
]);
|
|
|
|
$tenant = Tenant::findOrFail($request->tenant_id);
|
|
$package = Package::findOrFail($request->package_id);
|
|
|
|
$ordersController = $this->client->getOrdersController();
|
|
|
|
$requestBody = OrderRequestBuilder::init(CheckoutPaymentIntent::CAPTURE)
|
|
->purchaseUnits([
|
|
PurchaseUnitRequestBuilder::init()
|
|
->amount(
|
|
AmountWithBreakdownBuilder::init('EUR', number_format($package->price, 2, '.', ''))
|
|
->build()
|
|
)
|
|
->description('Package: ' . $package->name)
|
|
->customId($tenant->id . '_' . $package->id . '_endcustomer_event')
|
|
->build()
|
|
])
|
|
->applicationContext(
|
|
ApplicationContextBuilder::init()
|
|
->shippingPreference(ShippingPreference::NO_SHIPPING)
|
|
->userAction('PAY_NOW')
|
|
->build()
|
|
)
|
|
->build();
|
|
|
|
$collect = [
|
|
'body' => $requestBody,
|
|
'prefer' => 'return=representation'
|
|
];
|
|
|
|
try {
|
|
$response = $ordersController->createOrder($collect);
|
|
|
|
if ($response->statusCode === 201) {
|
|
$result = $response->result;
|
|
$approveLink = collect($result->links)->first(fn($link) => $link->rel === 'approve')?->href;
|
|
|
|
return response()->json([
|
|
'id' => $result->id,
|
|
'approve_url' => $approveLink,
|
|
]);
|
|
}
|
|
|
|
Log::error('PayPal order creation failed', ['response' => $response]);
|
|
return response()->json(['error' => 'Order creation failed'], 400);
|
|
} catch (\Exception $e) {
|
|
Log::error('PayPal order creation exception', ['error' => $e->getMessage()]);
|
|
return response()->json(['error' => 'Order creation failed'], 500);
|
|
}
|
|
}
|
|
|
|
public function captureOrder(Request $request)
|
|
{
|
|
$request->validate(['order_id' => 'required']);
|
|
|
|
$ordersController = $this->client->getOrdersController();
|
|
|
|
$collect = [
|
|
'id' => $request->order_id,
|
|
'prefer' => 'return=representation'
|
|
];
|
|
|
|
try {
|
|
$response = $ordersController->captureOrder($collect);
|
|
|
|
if ($response->statusCode === 201) {
|
|
$result = $response->result;
|
|
$customId = $result->purchaseUnits[0]->customId ?? null;
|
|
|
|
if ($customId) {
|
|
[$tenantId, $packageId, $type] = explode('_', $customId);
|
|
$tenant = Tenant::findOrFail($tenantId);
|
|
$package = Package::findOrFail($packageId);
|
|
|
|
PackagePurchase::create([
|
|
'tenant_id' => $tenant->id,
|
|
'package_id' => $package->id,
|
|
'provider_id' => $result->id,
|
|
'price' => $result->purchaseUnits[0]->amount->value,
|
|
'type' => $type ?? 'endcustomer_event',
|
|
'purchased_at' => now(),
|
|
'refunded' => false,
|
|
]);
|
|
|
|
Log::info('PayPal order captured and purchase created: ' . $result->id);
|
|
}
|
|
|
|
return response()->json(['status' => 'captured', 'order' => $result]);
|
|
}
|
|
|
|
Log::error('PayPal order capture failed', ['response' => $response]);
|
|
return response()->json(['error' => 'Capture failed'], 400);
|
|
} catch (\Exception $e) {
|
|
Log::error('PayPal order capture exception', ['error' => $e->getMessage()]);
|
|
return response()->json(['error' => 'Capture failed'], 500);
|
|
}
|
|
}
|
|
|
|
public function createSubscription(Request $request)
|
|
{
|
|
$request->validate([
|
|
'tenant_id' => 'required|exists:tenants,id',
|
|
'package_id' => 'required|exists:packages,id',
|
|
'plan_id' => 'required', // PayPal plan ID for the package
|
|
]);
|
|
|
|
$tenant = Tenant::findOrFail($request->tenant_id);
|
|
$package = Package::findOrFail($request->package_id);
|
|
|
|
$subscriptionsController = $this->client->getSubscriptionsController();
|
|
|
|
$requestBody = SubscriptionRequestBuilder::init()
|
|
->planId($request->plan_id)
|
|
->subscriber(
|
|
SubscriberBuilder::init()
|
|
->name(
|
|
NameBuilder::init()
|
|
->givenName($tenant->name ?? 'Tenant')
|
|
->build()
|
|
)
|
|
->emailAddress($tenant->email)
|
|
->build()
|
|
)
|
|
->customId($tenant->id . '_' . $package->id . '_reseller_subscription')
|
|
->applicationContext(
|
|
ApplicationContextSubscriptionBuilder::init()
|
|
->shippingPreference(ShippingPreference::NO_SHIPPING)
|
|
->userAction('SUBSCRIBE_NOW')
|
|
->build()
|
|
)
|
|
->build();
|
|
|
|
$collect = [
|
|
'body' => $requestBody,
|
|
'prefer' => 'return=representation'
|
|
];
|
|
|
|
try {
|
|
$response = $subscriptionsController->createSubscription($collect);
|
|
|
|
if ($response->statusCode === 201) {
|
|
$result = $response->result;
|
|
$subscriptionId = $result->id;
|
|
|
|
TenantPackage::create([
|
|
'tenant_id' => $tenant->id,
|
|
'package_id' => $package->id,
|
|
'purchased_at' => now(),
|
|
'expires_at' => now()->addYear(),
|
|
'active' => true,
|
|
]);
|
|
|
|
PackagePurchase::create([
|
|
'tenant_id' => $tenant->id,
|
|
'package_id' => $package->id,
|
|
'provider_id' => $subscriptionId,
|
|
'price' => $package->price,
|
|
'type' => 'reseller_subscription',
|
|
'purchased_at' => now(),
|
|
]);
|
|
|
|
$approveLink = collect($result->links)->first(fn($link) => $link->rel === 'approve')?->href;
|
|
|
|
return response()->json([
|
|
'subscription_id' => $subscriptionId,
|
|
'approve_url' => $approveLink,
|
|
]);
|
|
}
|
|
|
|
Log::error('PayPal subscription creation failed', ['response' => $response]);
|
|
return response()->json(['error' => 'Subscription creation failed'], 400);
|
|
} catch (\Exception $e) {
|
|
Log::error('PayPal subscription creation exception', ['error' => $e->getMessage()]);
|
|
return response()->json(['error' => 'Subscription creation failed'], 500);
|
|
}
|
|
}
|
|
} |