1<?php
2
3final class PaymentOrder
4{
5 public function __construct(
6 public readonly string $recipient,
7 public readonly string $iban,
8 public readonly string $edrpou,
9 public readonly int $amount,
10 public readonly string $purpose,
11 ) {}
12}
13
14final class PaymentOrderBuilder
15{
16 private string $recipient = '';
17 private string $iban = '';
18 private string $edrpou = '';
19 private int $amount = 0;
20 private string $purpose = '';
21 private ?int $vatPercent = null;
22
231 public function to(string $recipient, string $iban, string $edrpou): self
24 {
25 $this->recipient = $recipient;
26 $this->iban = $iban;
27 $this->edrpou = $edrpou;
28
29 return $this;
30 }
31
32 public function amount(int $kopecks): self
33 {
34 $this->amount = $kopecks;
35
36 return $this;
37 }
38
39 public function purpose(string $text): self
40 {
41 $this->purpose = $text;
42
43 return $this;
44 }
45
46 public function withVat(int $percent = 20): self
47 {
48 $this->vatPercent = $percent;
49
50 return $this;
51 }
52
53 public function build(): PaymentOrder
54 {
552 if (! preg_match('/^UA\d{27}$/', $this->iban)) {
56 throw new InvalidArgumentException("IBAN «{$this->iban}» не схожий на український");
57 }
58 if ($this->amount <= 0 || $this->purpose === '') {
59 throw new InvalidArgumentException('Потрібні сума й призначення платежу');
60 }
61
623 $purpose = $this->vatPercent === null
63 ? "{$this->purpose}, без ПДВ"
64 : sprintf('%s, у т.ч. ПДВ %d%% %s грн', $this->purpose, $this->vatPercent, uah($this->vat()));
65
66 return new PaymentOrder($this->recipient, $this->iban, $this->edrpou, $this->amount, $purpose);
67 }
68
69 private function vat(): int
70 {
71 return intdiv($this->amount * $this->vatPercent, 100 + $this->vatPercent);
72 }
73}
74
75function uah(int $kopecks): string
76{
77 return number_format($kopecks / 100, 2, ',', ' ');
78}
79
804$order = (new PaymentOrderBuilder())
81 ->to('ТОВ «Кодова фабрика»', 'UA213223130000026007233566001', '41234567')
82 ->amount(1_250_000)
83 ->purpose('Оплата за розробку згідно з рахунком № 17')
84 ->withVat()
85 ->build();
86
87echo "Отримувач: {$order->recipient}\n";
88echo 'Сума: ', uah($order->amount), " грн\n";
89echo "Призначення: {$order->purpose}\n\n";
90
91try {
92 (new PaymentOrderBuilder())
93 ->to('ТОВ «Кодова фабрика»', 'UA2132', '41234567')
94 ->amount(500_000)
95 ->build();
96} catch (InvalidArgumentException $e) {
97 echo 'Не створено: ', $e->getMessage(), "\n";
98}