1final class Checkout
2{
3 public function pay(Order $order): string
4 {
5 if ($order->amount <= 0) {
6 throw new InvalidOrder($order->id);
7 }
8
9 $link = match ($order->provider) {
10 'mono' => new MonoLink($this->config['mono_token'], $order),
11 'liqpay' => new LiqPayLink($this->config['liqpay_public'], $this->config['liqpay_private'], $order),
12 // 'wayforpay' => ...
13 };
14
15 $this->log->info('payment link created', ['order' => $order->id]);
16
17 return $link->url();
18 }
19}
1<?php
2
3final class Order
4{
5 public function __construct(
6 public readonly int $id,
7 public readonly int $amount,
8 ) {}
9}
10
111interface PaymentLink
12{
13 public function url(): string;
14}
15
16final class MonoLink implements PaymentLink
17{
18 public function __construct(private readonly Order $order) {}
19
20 public function url(): string
21 {
22 return "https://mono.example/invoice/{$this->order->id}?amount={$this->order->amount}";
23 }
24}
25
26final class LiqPayLink implements PaymentLink
27{
28 public function __construct(private readonly Order $order) {}
29
30 public function url(): string
31 {
32 $amount = number_format($this->order->amount / 100, 2, '.', '');
33
34 return "https://liqpay.example/checkout?order={$this->order->id}&amount={$amount}";
35 }
36}
37
382abstract class Checkout
39{
40 public function pay(Order $order): string
41 {
42 if ($order->amount <= 0) {
43 throw new InvalidArgumentException("Замовлення #{$order->id}: сума має бути більшою за нуль");
44 }
45
46 return $this->createLink($order)->url();
47 }
48
49 abstract protected function createLink(Order $order): PaymentLink;
50}
51
523final class MonoCheckout extends Checkout
53{
54 protected function createLink(Order $order): MonoLink
55 {
56 return new MonoLink($order);
57 }
58}
59
60final class LiqPayCheckout extends Checkout
61{
62 protected function createLink(Order $order): LiqPayLink
63 {
64 return new LiqPayLink($order);
65 }
66}
67
68$order = new Order(id: 1042, amount: 125_000);
69
704foreach ([new MonoCheckout(), new LiqPayCheckout()] as $checkout) {
71 echo str_pad($checkout::class, 16), $checkout->pay($order), "\n";
72}
73
74try {
75 (new MonoCheckout())->pay(new Order(id: 1043, amount: 0));
76} catch (InvalidArgumentException $e) {
77 echo 'Помилка: ', $e->getMessage(), "\n";
78}