configured()) { return ['ok' => false, 'insufficient' => false, 'balance_minor' => null, 'error' => 'Billing is not configured.']; } try { $res = Http::withToken((string) config('billing.api_key')) ->acceptJson()->timeout(20) ->post(rtrim((string) config('billing.api_url'), '/').'/debit', [ 'user' => $user->public_id, 'amount_minor' => $amountMinor, 'service' => 'pos', 'source' => 'subscription', 'reference' => $reference, 'description' => $description, ]); } catch (\Throwable $e) { Log::warning('POS BillingClient: charge failed', ['user' => $user->public_id, 'error' => $e->getMessage()]); return ['ok' => false, 'insufficient' => false, 'balance_minor' => null, 'error' => 'Could not reach the billing service.']; } if ($res->status() === 402) { return ['ok' => false, 'insufficient' => true, 'balance_minor' => (int) $res->json('balance_minor', 0), 'error' => 'Insufficient wallet balance.']; } if ($res->failed()) { return ['ok' => false, 'insufficient' => false, 'balance_minor' => null, 'error' => 'Billing error ('.$res->status().').']; } return ['ok' => true, 'insufficient' => false, 'balance_minor' => null, 'error' => null]; } /** * @param array $metadata * @return array{checkout_url: string, reference: string} */ public function initiatePlanCheckout( User $user, string $plan, int $months, int $amountMinor, string $returnUrl, array $metadata = [], ): array { $res = Http::withToken((string) config('billing.api_key')) ->acceptJson()->timeout(15) ->post(rtrim((string) config('billing.api_url'), '/').'/plan-checkout', [ 'user' => $user->public_id, 'app' => (string) config('billing.service', 'pos'), 'plan' => $plan, 'months' => $months, 'amount_minor' => $amountMinor, 'return_url' => $returnUrl, 'metadata' => $metadata, ]); $res->throw(); return [ 'checkout_url' => (string) $res->json('checkout_url'), 'reference' => (string) $res->json('reference'), ]; } /** @return array */ public function verifyPlanCheckout(string $reference): array { $res = Http::withToken((string) config('billing.api_key')) ->acceptJson()->timeout(15) ->post(rtrim((string) config('billing.api_url'), '/').'/plan-checkout/verify', [ 'reference' => $reference, ]); if ($res->status() === 422) { return ['paid' => false, 'error' => $res->json('error')]; } $res->throw(); return $res->json(); } }