PurchaseRequest   A
last analyzed

Complexity

Total Complexity 35

Size/Duplication

Total Lines 344
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 113
c 0
b 0
f 0
dl 0
loc 344
rs 9.6
wmc 35

19 Methods

Rating   Name   Duplication   Size   Complexity  
A setClient() 0 3 1
A urlFields() 0 5 1
A setForceCard() 0 3 2
A setSignLabel() 0 3 1
A setCart() 0 3 1
A __construct() 0 15 1
A setDisable3DS() 0 3 2
A optionsFields() 0 9 1
A setThreeDSecureChallenge() 0 7 2
A setCardAlias() 0 3 1
A setShippingAddress() 0 3 1
A validate() 0 15 4
A getRequestUri() 0 3 1
A commitmentsFields() 0 13 5
A fieldsToArray() 0 7 1
A baseFields() 0 16 1
A setBillingAddress() 0 3 1
A setDisabledPaymentWays() 0 11 3
A orderContextBase64() 0 21 5
1
<?php
2
3
namespace DansMaCulotte\Monetico\Requests;
4
5
use DansMaCulotte\Monetico\Exceptions\Exception;
6
use DansMaCulotte\Monetico\Exceptions\PurchaseException;
7
use DansMaCulotte\Monetico\Resources\BillingAddressResource;
8
use DansMaCulotte\Monetico\Resources\CartResource;
9
use DansMaCulotte\Monetico\Resources\ClientResource;
10
use DansMaCulotte\Monetico\Resources\ShippingAddressResource;
11
use DateTime;
12
13
class PurchaseRequest extends AbstractRequest
14
{
15
    /** @var string */
16
    public $reference;
17
18
    /** @var string */
19
    public $description;
20
21
    /** @var string */
22
    public $language;
23
24
    /** @var string */
25
    public $email;
26
27
    /** @var float */
28
    public $amount;
29
30
    /** @var string */
31
    public $currency;
32
33
    /** @var \DateTime */
34
    public $dateTime;
35
36
    /** @var */
37
    public $successUrl;
38
39
    /** @var */
40
    public $errorUrl;
41
42
    /** @var array */
43
    public $options;
44
45
    /** @var BillingAddressResource */
46
    public $billingAddress;
47
48
    /** @var ShippingAddressResource */
49
    public $shippingAddress;
50
51
    /** @var ClientResource */
52
    public $client;
53
54
    /** @var CartResource */
55
    public $cart;
56
57
    /** @var array */
58
    public $commitments;
59
60
    /** @var int */
61
    const MAC_COMMITMENTS = 4;
62
63
    /** @var array */
64
    const PAYMENT_WAYS = [
65
        '1euro',
66
        '3xcb',
67
        '4xcb',
68
        'fivory',
69
        'paypal'
70
    ];
71
72
    /** @var array */
73
    const THREE_D_SECURE_CHALLENGES = [
74
        'no_preference',
75
        'challenge_preferred',
76
        'challenge_mandated',
77
        'no_challenge_requested',
78
        'no_challenge_requested_strong_authentication',
79
        'no_challenge_requested_trusted_third_party',
80
        'no_challenge_requested_risk_analysis'
81
    ];
82
83
    /** @var string */
84
    const DATETIME_FORMAT = 'd/m/Y:H:i:s';
85
86
    /** @var string */
87
    const REQUEST_URI = 'paiement.cgi';
88
89
    /**
90
     * InputPayload constructor.
91
     *
92
     * @param array $data
93
     * @param array $commitments
94
     * @param array $options
95
     * @throws Exception
96
     */
97
    public function __construct(array $data = [], array $commitments = [], array $options = [])
98
    {
99
        $this->reference = $data['reference'];
100
        $this->language = strtoupper($data['language']);
101
        $this->dateTime = $data['dateTime'];
102
        $this->description = $data['description'];
103
        $this->email = $data['email'];
104
        $this->amount = $data['amount'];
105
        $this->currency = $data['currency'];
106
        $this->successUrl = $data['successUrl'];
107
        $this->errorUrl = $data['errorUrl'];
108
        $this->options = $options;
109
        $this->commitments = $commitments;
110
111
        $this->validate();
112
    }
113
114
    /**
115
     * @throws Exception
116
     */
117
    public function validate(): bool
118
    {
119
        if (strlen($this->reference) > 50) {
120
            throw Exception::invalidReference($this->reference);
121
        }
122
123
        if (strlen($this->language) !== 2) {
124
            throw Exception::invalidLanguage($this->language);
125
        }
126
127
        if (!$this->dateTime instanceof DateTime) {
0 ignored issues
show
introduced by
$this->dateTime is always a sub-type of DateTime.
Loading history...
128
            throw Exception::invalidDatetime();
129
        }
130
131
        return true;
132
    }
133
134
    /**
135
     * @return string
136
     */
137
    protected static function getRequestUri(): string
138
    {
139
        return self::REQUEST_URI;
140
    }
141
142
    /**
143
     * Define card alias in case of an express payment
144
     *
145
     * @param string $alias Alias card name
146
     */
147
    public function setCardAlias(string $alias): void
148
    {
149
        $this->options['aliascb'] = $alias;
150
    }
151
152
    /**
153
     * Force submission of card informations in case of an express payment
154
     *
155
     * @param bool $value Enable or disable submission
156
     */
157
    public function setForceCard(bool $value = true): void
158
    {
159
        $this->options['forcesaisiecb'] = ($value) ? '1' : '0';
160
    }
161
162
    /**
163
     * Bypass 3DSecure check
164
     *
165
     * @param bool $value Enable or disable bypass
166
     */
167
    public function setDisable3DS(bool $value = true): void
168
    {
169
        $this->options['3dsdebrayable'] = ($value) ? '1' : '0';
170
    }
171
172
    /**
173
     * 3DSecure V2 Choice
174
     *
175
     * @param string $choice
176
     * @throws PurchaseException
177
     */
178
    public function setThreeDSecureChallenge(string $choice): void
179
    {
180
        if (!in_array($choice, self::THREE_D_SECURE_CHALLENGES, true)) {
181
            throw PurchaseException::invalidThreeDSecureChallenge($choice);
182
        }
183
184
        $this->options['threeDsecureChallenge'] = $choice;
185
    }
186
187
    /**
188
     * Change company sign label on payment interface
189
     *
190
     * @param string $label New sign label content
191
     */
192
    public function setSignLabel(string $label): void
193
    {
194
        $this->options['libelleMonetique'] = $label;
195
    }
196
197
    /**
198
     * @param BillingAddressResource $billingAddress
199
     */
200
    public function setBillingAddress(BillingAddressResource $billingAddress): void
201
    {
202
        $this->billingAddress = $billingAddress;
203
    }
204
205
206
    /**
207
     * @param ShippingAddressResource $shippingAddress
208
     */
209
    public function setShippingAddress(ShippingAddressResource $shippingAddress): void
210
    {
211
        $this->shippingAddress = $shippingAddress;
212
    }
213
214
    /**
215
     * @param ClientResource $client
216
     */
217
    public function setClient(ClientResource $client): void
218
    {
219
        $this->client = $client;
220
    }
221
222
    /**
223
     * @param CartResource $cart
224
     */
225
    public function setCart(CartResource $cart): void
226
    {
227
        $this->cart = $cart;
228
    }
229
230
    /**
231
     * Disable ways of payment on payment interface
232
     *
233
     * @param array[string] $ways List of payment ways to disable
0 ignored issues
show
Documentation Bug introduced by
The doc comment array[string] at position 1 could not be parsed: Expected ']' at position 1, but found '['.
Loading history...
234
     */
235
    public function setDisabledPaymentWays(array $ways = []): void
236
    {
237
        $_ways = [];
238
239
        foreach ($ways as $way) {
240
            if (in_array($way, self::PAYMENT_WAYS, true)) {
241
                $_ways[] = $way;
242
            }
243
        }
244
245
        $this->options['desactivemoyenpaiement'] = implode(',', $_ways);
246
    }
247
248
    /**
249
     * Get order context
250
     *
251
     * @return string
252
     */
253
    public function orderContextBase64(): string
254
    {
255
        $contextCommand = [];
256
257
        if ($this->billingAddress) {
258
            $contextCommand['billing'] = $this->billingAddress->getParameters();
259
        }
260
261
        if ($this->shippingAddress) {
262
            $contextCommand['shipping'] = $this->shippingAddress->getParameters();
263
        }
264
265
        if ($this->client) {
266
            $contextCommand['client'] = $this->client->getParameters();
267
        }
268
269
        if ($this->cart) {
270
            $contextCommand['shoppingCart'] = $this->cart->getParameters();
271
        }
272
273
        return base64_encode(json_encode($contextCommand, JSON_UNESCAPED_UNICODE));
274
    }
275
276
    /**
277
     * @param string $eptCode
278
     * @param string $companyCode
279
     * @param string $version
280
     * @return array
281
     */
282
    private function baseFields(string $eptCode, string $companyCode, string $version): array
283
    {
284
        $fields = [
285
            'TPE' => $eptCode,
286
            'date' => $this->dateTime->format(self::DATETIME_FORMAT),
287
            'contexte_commande' => $this->orderContextBase64(),
288
            'lgue' => $this->language,
289
            'mail' => $this->email,
290
            'montant' => $this->amount . $this->currency,
291
            'reference' => $this->reference,
292
            'societe' => $companyCode,
293
            'texte-libre' => $this->description,
294
            'version' => $version
295
        ];
296
297
        return $fields;
298
    }
299
300
    /**
301
     * @return array
302
     */
303
    private function urlFields(): array
304
    {
305
        return [
306
            'url_retour_ok' => $this->successUrl,
307
            'url_retour_err' => $this->errorUrl,
308
        ];
309
    }
310
311
    /**
312
     * @return array
313
     */
314
    private function commitmentsFields(): array
315
    {
316
        $commitmentsCount = count($this->commitments);
317
        $commitments = [
318
            'nbrech' => ($commitmentsCount > 0) ? $commitmentsCount : ''
319
        ];
320
321
        for ($i = 1; $i <= self::MAC_COMMITMENTS; $i++) {
322
            $commitments["dateech${i}"] = ($commitmentsCount >= $i) ? $this->commitments[$i - 1]['date'] : '';
323
            $commitments["montantech${i}"] = ($commitmentsCount >= $i) ? $this->commitments[$i - 1]['amount'] . $this->currency : '';
324
        }
325
326
        return $commitments;
327
    }
328
329
    /**
330
     * @return array
331
     */
332
    private function optionsFields(): array
333
    {
334
        return [
335
            'ThreeDSecureChallenge' => $this->options['threeDsecureChallenge'] ?? '',
336
            '3dsdebrayable' => $this->options['3dsdebrayable'] ?? '',
337
            'aliascb' => $this->options['aliascb'] ?? '',
338
            'desactivemoyenpaiement' => $this->options['desactivemoyenpaiement'] ?? '',
339
            'forcesaisiecb' => $this->options['forcesaisiecb'] ?? '',
340
            'libelleMonetique' => $this->options['libelleMonetique'] ?? '',
341
        ];
342
    }
343
344
    /**
345
     * @param string $eptCode
346
     * @param string $companyCode
347
     * @param string $version
348
     * @return array
349
     */
350
    public function fieldsToArray(string $eptCode, string $companyCode, string $version): array
351
    {
352
        return array_merge(
353
            $this->baseFields($eptCode, $companyCode, $version),
354
            $this->optionsFields(),
355
            $this->commitmentsFields(),
356
            $this->urlFields()
357
        );
358
    }
359
}
360