JFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr{ gilour
<?php namespace Common\Billing\Gateways\Paypal; use Common\Billing\GatewayException; use Common\Billing\Models\Price; use Common\Billing\Models\Product; use Illuminate\Support\Str; class PaypalPlans { use InteractsWithPaypalRestApi; public function sync(Product $product): bool { $product->load('prices'); // there's only one global product on PayPal and not one per plan as on stripe $productId = config('services.paypal.product_id'); $response = $this->paypal()->get("catalogs/products/$productId"); if (!$response->successful()) { $this->paypal()->post('catalogs/products', [ 'id' => $productId, 'name' => config('services.paypal.product_name'), 'type' => 'DIGITAL', ]); } // create any local product prices (plans) on PayPal, that don't exist there already $product->prices->each(function (Price $price) use ($product) { if ( !$price->paypal_id || !$this->planExistsOnPaypal($price->paypal_id) ) { $this->create($product, $price); } }); return true; } protected function planExistsOnPaypal(string $paypalPlanId): bool { $response = $this->paypal()->get("billing/plans/{$paypalPlanId}"); return $response->successful(); } protected function create(Product $product, Price $price): bool { $response = $this->paypal()->post('billing/plans', [ 'name' => $product->name, 'product_id' => config('services.paypal.product_id'), 'status' => 'ACTIVE', 'payment_preferences' => [ 'auto_bill_outstanding' => true, 'payment_failure_threshold' => 2, ], 'billing_cycles' => [ [ 'frequency' => [ 'interval_unit' => Str::upper($price->interval), 'interval_count' => $price->interval_count, ], 'tenure_type' => 'REGULAR', 'sequence' => 1, 'total_cycles' => 0, // infinite 'pricing_scheme' => [ 'fixed_price' => [ 'value' => number_format( $price->amount, 2, '.', '', ), 'currency_code' => Str::upper($price->currency), ], ], ], ], ]); if (!$response->successful()) { throw new GatewayException('Could not create plan on PayPal'); } $price->fill(['paypal_id' => $response['id']])->save(); return true; } public function delete(Product $product): bool { $statuses = $product->prices->map(function (Price $price) { $response = $this->paypal()->post( "billing/plans/{$price->paypal_id}/deactivate", ); return $response->successful(); }); return $statuses->every(fn($status) => $status); } }