Passed
Push — master ( f4ebb6...c31285 )
by Gaël
11:14
created

PaymentRequest::optionsFields()   B

Complexity

Conditions 7
Paths 64

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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