Completed
Pull Request — master (#5)
by Leith
08:09
created

PurchaseRequest::getHomePhone()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
namespace Omnipay\Redsys\Message;
4
5
use DateTime;
6
use DateTimeZone;
7
use OmniPay\CreditCard;
8
use Omnipay\Common\Message\AbstractRequest;
9
use Omnipay\Common\Exception\InvalidRequestException;
10
11
/**
12
 * Redsys Purchase Request
13
 *
14
 * @todo consider shifting date formatters out of getData() and into parameter setters so that request->all() has sensible values
15
 */
16
class PurchaseRequest extends AbstractRequest
17
{
18
    /** @var string */
19
    protected $liveEndpoint = 'https://sis.redsys.es/sis/realizarPago';
20
    /** @var string */
21
    protected $testEndpoint = 'https://sis-t.redsys.es:25443/sis/realizarPago';
22
    /** @var array */
23
    protected static $consumerLanguages = array(
24
        'es' => '001', // Spanish
25
        'en' => '002', // English
26
        'ca' => '003', // Catalan - same as Valencian (010)
27
        'fr' => '004', // French
28
        'de' => '005', // German
29
        'nl' => '006', // Dutch
30
        'it' => '007', // Italian
31
        'sv' => '008', // Swedish
32 2
        'pt' => '009', // Portuguese
33
        'pl' => '011', // Polish
34 2
        'gl' => '012', // Galician
35
        'eu' => '013', // Basque
36
    );
37 4
38
    /** @var string 250x400 */
39 4
    const CHALLENGE_WINDOW_SIZE_250_400 = "01";
40
    /** @var string 390x400 */
41
    const CHALLENGE_WINDOW_SIZE_390_400 = "02";
42 8
    /** @var string 500x600 */
43
    const CHALLENGE_WINDOW_SIZE_500_600 = "03";
44 8
    /** @var string 600x400 */
45
    const CHALLENGE_WINDOW_SIZE_600_400 = "04";
46
    /** @var string Fullscreen window (default) */
47
    const CHALLENGE_WINDOW_SIZE_FULLSCREEN = "05";
48
49
    /** @var string No 3DS Requestor authentication occurred (i.e. cardholder logged in as guest) */
50
    const ACCOUNT_AUTHENTICATION_METHOD_NONE = "01";
51
    /** @var string Login to the cardholder account at the 3DS Requestor system using 3DS Requestor's own credentials */
52 7
    const ACCOUNT_AUTHENTICATION_METHOD_OWN_CREDENTIALS = "02";
53
    /** @var string Login to the cardholder account at the 3DS Requestor system using federated ID */
54 7
    const ACCOUNT_AUTHENTICATION_METHOD_FEDERATED_ID = "03";
55 1
    /** @var string Login to the cardholder account at the 3DS Requestor system using issuer credentials */
56 1
    const ACCOUNT_AUTHENTICATION_METHOD_ISSUER_CREDENTIALS = "04";
57 1
    /** @var string Login to the cardholder account at the 3DS Requestor system using third-party authentication */
58 1
    const ACCOUNT_AUTHENTICATION_METHOD_THIRD_PARTY_AUTHENTICATION = "05";
59 7
    /** @var string Login to the cardholder account at the 3DS Requestor system using FIDO Authenticator */
60 7
    const ACCOUNT_AUTHENTICATION_METHOD_FIDO = "06";
61 7
62
    /** @var string No account (guest check-out) */
63 7
    const CUSTOMER_ACCOUNT_CREATED_NONE = "01";
64
    /** @var string Created during this transaction */
65
    const CUSTOMER_ACCOUNT_CREATED_THIS_TRANSACTION = "02";
66 15
    /** @var string Less than 30 days */
67
    const CUSTOMER_ACCOUNT_CREATED_LAST_30_DAYS = "03";
68 15
    /** @var string Between 30 and 60 days */
69
    const CUSTOMER_ACCOUNT_CREATED_LAST_60_DAYS = "04";
70
    /** @var string More than 60 day */
71 23
    const CUSTOMER_ACCOUNT_CREATED_MORE_THAN_60_DAYS = "05";
72
73 23
    /** @var string Modified in this session */
74
    const CUSTOMER_ACCOUNT_MODIFIED_THIS_TRANSACTION = "01";
75
    /** @var string Less than 30 days */
76 7
    const CUSTOMER_ACCOUNT_MODIFIED_LAST_30_DAYS = "02";
77
    /** @var string Between 30 and 60 days */
78 7
    const CUSTOMER_ACCOUNT_MODIFIED_LAST_60_DAYS = "03";
79
    /** @var string More than 60 day */
80
    const CUSTOMER_ACCOUNT_MODIFIED_MORE_THAN_60_DAYS = "04";
81 7
82
    /** @var string Unchanged */
83 7
    const CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_NONE = "01";
84
    /** @var string Modified in this session */
85
    const CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_THIS_TRANSACTION = "02";
86 11
    /** @var string Less than 30 days */
87
    const CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_LAST_30_DAYS = "03";
88 11
    /** @var string Between 30 and 60 days */
89
    const CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_LAST_60_DAYS = "04";
90
    /** @var string More than 60 day */
91 23
    const CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_MORE_THAN_60_DAYS = "05";
92
93 23
    /** @var string No account (guest check-out) */
94
    const PAYMENT_METHOD_CREATED_NONE = "01";
95
    /** @var string Created during this transaction */
96 11
    const PAYMENT_METHOD_CREATED_THIS_TRANSACTION = "02";
97
    /** @var string Less than 30 days */
98 11
    const PAYMENT_METHOD_CREATED_LAST_30_DAYS = "03";
99
    /** @var string Between 30 and 60 days */
100
    const PAYMENT_METHOD_CREATED_LAST_60_DAYS = "04";
101 23
    /** @var string More than 60 day */
102
    const PAYMENT_METHOD_CREATED_MORE_THAN_60_DAYS = "05";
103 23
104
    /** @var string For the first time */
105
    const SHIPPING_ADDRESS_USAGE_THIS_TRANSACTION = "01";
106 11
    /** @var string Less than 30 days */
107
    const SHIPPING_ADDRESS_USAGE_LAST_30_DAYS = "02";
108 11
    /** @var string Between 30 and 60 days */
109
    const SHIPPING_ADDRESS_USAGE_LAST_60_DAYS = "03";
110
    /** @var string More than 60 day */
111 23
    const SHIPPING_ADDRESS_USAGE_MORE_THAN_60_DAYS = "04";
112
113 23
    /** @var string Electronic delivery */
114
    const DELIVERY_TIMEFRAME_ELECTRONIC_DELIVERY = "01";
115
    /** @var string Same day shipping */
116
    const DELIVERY_TIMEFRAME_SAME_DAY = "02";
117
    /** @var string Next day shipping */
118
    const DELIVERY_TIMEFRAME_NEXT_DAY = "03";
119
    /** @var string Shipping in 2 or more days */
120
    const DELIVERY_TIMEFRAME_2_OR_MORE_DAYS = "04";
121 15
122
    /** @var string Ship to cardholder's billing address */
123 15
    const SHIPPING_TO_BILLING_ADDRESS = "01";
124 15
    /** @var string Ship to another verified address on file with merchant */
125 15
    const SHIPPING_TO_ANOTHER_VERIFIED_ADDRESS = "02";
126 15
    /** @var string Ship to address that is different than the cardholder's billing address */
127 15
    const SHIPPING_DIFFERENT_BILLING_ADDRESS = "03";
128 15
    /** @var string Pick-up at local store (Store address shall be populated in shipping address fields) */
129 15
    const SHIPPING_PICK_UP = "04";
130
    /** @var string Digital goods (includes online services, electronic gift cards and redemption codes) */
131 15
    const SHIPPING_DIGITAL = "05";
132 15
    /** @var string Travel and Event tickets, not shipped */
133
    const SHIPPING_TRAVEL = "06";
134 15
    /** @var string Other (for example, Gaming, digital services not shipped, emedia subscriptions, etc.) */
135 15
    const SHIPPING_OTHER = "07";
136
137 2
    /** @var string Exemption due to low amount (transactions up to € 30) */
138
    const SCA_EXCEMPTION_LOW_AMOUNT = 'LMV';
139 2
    /** @var string Exemption due to low risk */
140
    const SCA_EXCEMPTION_LOW_RISK = 'TRA';
141
    /** @var string Exemption for payments identified as corporate. */
142
    const SCA_EXCEMPTION_CORPORATE = 'COR';
143 2
    /**
144 2
     * @var string Transactions initiated by the merchant, in which there is no intervention by the customer. They are
145 2
     *             outside the scope of PSD2.
146 2
     */
147 2
    const SCA_EXCEMPTION_MERCHANT_INITIATED = 'MIT';
148 2
149 2
    public function getCardholder()
150
    {
151 2
        return $this->getParameter('cardholder');
152 2
    }
153 2
154 2
    public function setCardholder($value)
155 2
    {
156 2
        return $this->setParameter('cardholder', $value);
157 2
    }
158 2
159
    public function getConsumerLanguage()
160
    {
161 1
        return $this->getParameter('consumerLanguage');
162
    }
163 1
164
    /**
165 1
     * Set the language presented to the consumer
166
     *
167
     * @param null|string|int Either the ISO 639-1 code to be converted, or the gateway's own numeric language code
168 1
     */
169 1
    public function setConsumerLanguage($value)
170 1
    {
171 1
        if (is_int($value)) {
172 1
            if ($value < 0 || $value > 13) {
173 1
                $value = 1;
174 1
            }
175 1
            $value = str_pad($value, 3, '0', STR_PAD_LEFT);
176
        } elseif (!is_numeric($value)) {
177 1
            $value = isset(self::$consumerLanguages[$value]) ? self::$consumerLanguages[$value] : '001';
178
        }
179
180 7
        return $this->setParameter('consumerLanguage', $value);
181
    }
182 7
183
    public function getHmacKey()
184
    {
185 1
        return $this->getParameter('hmacKey');
186
    }
187
188
    public function setHmacKey($value)
189
    {
190
        return $this->setParameter('hmacKey', $value);
191
    }
192
193
    public function getMerchantData()
194
    {
195
        return $this->getParameter('merchantData');
196
    }
197
198
    public function setMerchantData($value)
199
    {
200
        return $this->setParameter('merchantData', $value);
201
    }
202
203
    public function getMerchantId()
204
    {
205
        return $this->getParameter('merchantId');
206
    }
207
208
    public function setMerchantId($value)
209
    {
210
        return $this->setParameter('merchantId', $value);
211
    }
212
213
    public function getMerchantName()
214
    {
215
        return $this->getParameter('merchantName');
216
    }
217
218
    public function setMerchantName($value)
219
    {
220
        return $this->setParameter('merchantName', $value);
221
    }
222
223
    public function getTerminalId()
224
    {
225
        return $this->getParameter('terminalId');
226
    }
227
228
    public function setTerminalId($value)
229
    {
230
        return $this->setParameter('terminalId', $value);
231
    }
232
233
    /**
234
     * Get the use3ds field
235
     *
236
     * Controls the presence of the Ds_Merchant_Emv3Ds structure
237
     *
238
     * @return bool
239
     */
240
    public function getUse3DS()
241
    {
242
        return (bool) $this->getParameter('use3ds');
243
    }
244
245
    /**
246
     * Set the use3ds field
247
     *
248
     * Controls the presence of the Ds_Merchant_Emv3Ds structure
249
     *
250
     * @param bool $value
251
     * @return self
252
     */
253
    public function setUse3DS($value)
254
    {
255
        return $this->setParameter('use3ds', $value);
256
    }
257
258
    /**
259
     * Get the homePhoneCountryPrefix field
260
     *
261
     * Corresponds to the Ds_Merchant_Emv3Ds.homePhone.cc field
262
     *
263
     * @return null|string
264
     */
265
    public function getHomePhoneCountryPrefix()
266
    {
267
        return $this->getParameter('homePhoneCountryPrefix');
268
    }
269
270
    /**
271
     * Set the homePhoneCountryPrefix field
272
     *
273
     * Corresponds to the Ds_Merchant_Emv3Ds.homePhone.cc field
274
     *
275
     * @param null|string $value
276
     * @return self
277
     */
278
    public function setHomePhoneCountryPrefix($value)
279
    {
280
        return $this->setParameter('homePhoneCountryPrefix', $value);
281
    }
282
283
    /**
284
     * Get the homePhone field
285
     *
286
     * Corresponds to the Ds_Merchant_Emv3Ds.homePhone.subscriber field
287
     *
288
     * @return null|string
289
     */
290
    public function getHomePhone()
291
    {
292
        return $this->getParameter('homePhone');
293
    }
294
295
    /**
296
     * Set the homePhone field
297
     *
298
     * Corresponds to the Ds_Merchant_Emv3Ds.homePhone.subscriber field
299
     *
300
     * @param null|string $value
301
     * @return self
302
     */
303
    public function setHomePhone($value)
304
    {
305
        return $this->setParameter('homePhone', $value);
306
    }
307
308
    /**
309
     * Get the mobilePhoneCountryPrefix field
310
     *
311
     * Corresponds to the Ds_Merchant_Emv3Ds.mobilePhone.cc field
312
     *
313
     * @return null|string
314
     */
315
    public function getMobilePhoneCountryPrefix()
316
    {
317
        return $this->getParameter('mobilePhoneCountryPrefix');
318
    }
319
320
    /**
321
     * Set the mobilePhoneCountryPrefix field
322
     *
323
     * Corresponds to the Ds_Merchant_Emv3Ds.mobilePhone.cc field
324
     *
325
     * @param null|string $value
326
     * @return self
327
     */
328
    public function setMobilePhoneCountryPrefix($value)
329
    {
330
        return $this->setParameter('mobilePhoneCountryPrefix', $value);
331
    }
332
333
    /**
334
     * Get the mobilePhone field
335
     *
336
     * Corresponds to the Ds_Merchant_Emv3Ds.mobilePhone.subscriber field
337
     *
338
     * @return null|string
339
     */
340
    public function getMobilePhone()
341
    {
342
        return $this->getParameter('mobilePhone');
343
    }
344
345
    /**
346
     * Set the mobilePhone field
347
     *
348
     * Corresponds to the Ds_Merchant_Emv3Ds.mobilePhone.subscriber field
349
     *
350
     * @param null|string $value
351
     * @return self
352
     */
353
    public function setMobilePhone($value)
354
    {
355
        return $this->setParameter('mobilePhone', $value);
356
    }
357
358
    /**
359
     * Get the workPhoneCountryPrefix field
360
     *
361
     * Corresponds to the Ds_Merchant_Emv3Ds.workPhone.cc field
362
     *
363
     * @return null|string
364
     */
365
    public function getWorkPhoneCountryPrefix()
366
    {
367
        return $this->getParameter('workPhoneCountryPrefix');
368
    }
369
370
    /**
371
     * Set the workPhoneCountryPrefix field
372
     *
373
     * Corresponds to the Ds_Merchant_Emv3Ds.workPhone.cc field
374
     *
375
     * @param null|string $value
376
     * @return self
377
     */
378
    public function setWorkPhoneCountryPrefix($value)
379
    {
380
        return $this->setParameter('workPhoneCountryPrefix', $value);
381
    }
382
383
    /**
384
     * Get the workPhone field
385
     *
386
     * Corresponds to the Ds_Merchant_Emv3Ds.workPhone.subscriber field
387
     *
388
     * @return null|string
389
     */
390
    public function getWorkPhone()
391
    {
392
        return $this->getParameter('workPhone');
393
    }
394
395
    /**
396
     * Set the workPhone field
397
     *
398
     * Corresponds to the Ds_Merchant_Emv3Ds.workPhone.subscriber field
399
     *
400
     * @param null|string $value
401
     * @return self
402
     */
403
    public function setWorkPhone($value)
404
    {
405
        return $this->setParameter('workPhone', $value);
406
    }
407
408
    /**
409
     * Get the addressMatch field
410
     *
411
     * Corresponds to the Ds_Merchant_Emv3Ds.addrMatch field
412
     *
413
     * @return string  Either 'Y' or 'N'
414
     */
415
    public function getAddressMatch()
416
    {
417
        $match = $this->getParameter('addressMatch');
418
419
        if ($match === null) {
420
            $match = false;
421
            $card = $this->getCard();
422
            if ($card !== null) {
423
                $match = $card->getShippingAddress1() === $card->getBillingAddress1()
424
                    && $card->getShippingAddress2() === $card->getBillingAddress2()
425
                    && $card->getShippingAddress3() === $card->getBillingAddress3()
426
                    && $card->getShippingCity() === $card->getBillingCity()
427
                    && $card->getShippingPostcode() === $card->getBillingPostcode()
428
                    && $card->getShippingState() === $card->getBillingState()
429
                    && $card->getShippingCountry() === $card->getBillingCountry();
430
            }
431
        }
432
433
        return $match ? "Y" : "N";
434
    }
435
436
    /**
437
     * Set the addressMatch field
438
     *
439
     * Corresponds to the Ds_Merchant_Emv3Ds.addrMatch field
440
     *
441
     * @param null|boolean $value
442
     * @return self
443
     */
444
    public function setAddressMatch($value)
445
    {
446
        return $this->setParameter('addressMatch', $value);
447
    }
448
449
    /**
450
     * Get the challengeWindowSize field
451
     *
452
     * Corresponds to the Ds_Merchant_Emv3Ds.challengeWindowSize field
453
     *
454
     * @return null|string One of the self::CHALLENGE_WINDOW_SIZE_* constants
455
     */
456
    public function getChallengeWindowSize()
457
    {
458
        return $this->getParameter('challengeWindowSize');
459
    }
460
461
    /**
462
     * Set the challengeWindowSize field
463
     *
464
     * Corresponds to the Ds_Merchant_Emv3Ds.challengeWindowSize field
465
     *
466
     * @param null|string $value One of the self::CHALLENGE_WINDOW_SIZE_* constants
467
     * @return self
468
     * @throws InvalidRequestException if $value is invalid.
469
     */
470
    public function setChallengeWindowSize($value)
471
    {
472
        if (in_array(
473
            $value,
474
            [
475
                null,
476
                self::CHALLENGE_WINDOW_SIZE_250_400,
477
                self::CHALLENGE_WINDOW_SIZE_390_400,
478
                self::CHALLENGE_WINDOW_SIZE_500_600,
479
                self::CHALLENGE_WINDOW_SIZE_600_400,
480
                self::CHALLENGE_WINDOW_SIZE_FULLSCREEN,
481
            ]
482
        )) {
483
            return $this->setParameter('challengeWindowSize', $value);
484
        }
485
        throw new InvalidRequestException("Invalid challengeWindowSize parameter");
486
    }
487
488
    /**
489
     * Get the customerAdditionalInformation field
490
     *
491
     * Corresponds to the Ds_Merchant_Emv3Ds.acctID field
492
     *
493
     * @return null|string
494
     */
495
    public function getCustomerAdditionalInformation()
496
    {
497
        return $this->getParameter('customerAdditionalInformation');
498
    }
499
500
    /**
501
     * Set the customerAdditionalInformation field
502
     *
503
     * Corresponds to the Ds_Merchant_Emv3Ds.acctID field
504
     *
505
     * @param null|string $value
506
     * @return self
507
     */
508
    public function setCustomerAdditionalInformation($value)
509
    {
510
        return $this->setParameter('customerAdditionalInformation', $value);
511
    }
512
513
    /**
514
     * Get the 3DsRequestAuthenticationMethodData field
515
     *
516
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthData field in Redsys
517
     * documentation.
518
     *
519
     * @return null|string
520
     */
521
    public function get3DsRequestAuthenticationMethodData()
522
    {
523
        return $this->getParameter('3DsRequestAuthenticationMethodData');
524
    }
525
526
    /**
527
     * Set the 3DsRequestAuthenticationMethodData field
528
     *
529
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthData field in the Redsys
530
     * documentation.
531
     *
532
     * @param null|string $value
533
     * @return self
534
     */
535
    public function set3DsRequestAuthenticationMethodData($value)
536
    {
537
        return $this->setParameter('3DsRequestAuthenticationMethodData', $value);
538
    }
539
540
    /**
541
     * Get the 3DsRequestAuthenticationMethod field
542
     *
543
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthMethod field in Redsys
544
     * documentation.
545
     *
546
     * @return null|string One of the self::ACCOUNT_AUTHENTICATION_METHOD_* constants.
547
     */
548
    public function get3DsRequestAuthenticationMethod()
549
    {
550
        return $this->getParameter('3DsRequestAuthenticationMethod');
551
    }
552
553
    /**
554
     * Set the 3DsRequestAuthenticationMethod field
555
     *
556
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthMethod field in the Redsys
557
     * documentation.
558
     *
559
     * @param null|string $value One of the self::ACCOUNT_AUTHENTICATION_METHOD_* constants.
560
     * @return self
561
     * @throws InvalidRequestException if $value is invalid.
562
     */
563 View Code Duplication
    public function set3DsRequestAuthenticationMethod($value)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
564
    {
565
        if (in_array(
566
            $value,
567
            [
568
                null,
569
                self::ACCOUNT_AUTHENTICATION_METHOD_NONE,
570
                self::ACCOUNT_AUTHENTICATION_METHOD_OWN_CREDENTIALS,
571
                self::ACCOUNT_AUTHENTICATION_METHOD_FEDERATED_ID,
572
                self::ACCOUNT_AUTHENTICATION_METHOD_ISSUER_CREDENTIALS,
573
                self::ACCOUNT_AUTHENTICATION_METHOD_THIRD_PARTY_AUTHENTICATION,
574
                self::ACCOUNT_AUTHENTICATION_METHOD_FIDO,
575
            ]
576
        )) {
577
            return $this->setParameter('3DsRequestAuthenticationMethod', $value);
578
        }
579
        throw new InvalidRequestException("Invalid 3DsRequestAuthenticationMethod parameter");
580
    }
581
582
    /**
583
     * Get the 3DsRequestAuthenticationTime field
584
     *
585
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthTimestamp field
586
     *
587
     * @return null|DateTime|int
588
     */
589
    public function get3DsRequestAuthenticationTime()
590
    {
591
        return $this->getParameter('3DsRequestAuthenticationTime');
592
    }
593
594
    /**
595
     * Set the 3DsRequestAuthenticationTime field
596
     *
597
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthTimestamp field
598
     *
599
     * @param null|DateTime|int $value
600
     * @return self
601
     */
602
    public function set3DsRequestAuthenticationTime($value)
603
    {
604
        return $this->setParameter('3DsRequestAuthenticationTime', $value);
605
    }
606
607
    /**
608
     * Get the customerAccountCreatedIndicator field
609
     *
610
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccAgeInd field
611
     *
612
     * @return null|string One of the CUSTOMER_ACCOUNT_CREATED_* constants
613
     */
614
    public function getCustomerAccountCreatedIndicator()
615
    {
616
        return $this->getParameter('customerAccountCreatedIndicator');
617
    }
618
619
    /**
620
     * Set the customerAccountCreatedIndicator field
621
     *
622
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccAgeInd field
623
     *
624
     * @param null|string $value One of the CUSTOMER_ACCOUNT_CREATED_* constants
625
     * @return self
626
     * @throws InvalidRequestException if $value is invalid.
627
     */
628
    public function setCustomerAccountCreatedIndicator($value)
629
    {
630
        if (in_array(
631
            $value,
632
            [
633
                null,
634
                self::CUSTOMER_ACCOUNT_CREATED_NONE,
635
                self::CUSTOMER_ACCOUNT_CREATED_THIS_TRANSACTION,
636
                self::CUSTOMER_ACCOUNT_CREATED_LAST_30_DAYS,
637
                self::CUSTOMER_ACCOUNT_CREATED_LAST_60_DAYS,
638
                self::CUSTOMER_ACCOUNT_CREATED_MORE_THAN_60_DAYS,
639
            ]
640
        )) {
641
            return $this->setParameter('customerAccountCreatedIndicator', $value);
642
        }
643
        throw new InvalidRequestException("Invalid customerAccountCreatedIndicator parameter");
644
    }
645
646
    /**
647
     * Get the customerAccountCreatedDate field
648
     *
649
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccDate field
650
     *
651
     * @return null|DateTime|int
652
     */
653
    public function getCustomerAccountCreatedDate()
654
    {
655
        return $this->getParameter('customerAccountCreatedDate');
656
    }
657
658
    /**
659
     * Set the customerAccountCreatedDate field
660
     *
661
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccDate field
662
     *
663
     * @param null|DateTime|int $value
664
     * @return self
665
     */
666
    public function setCustomerAccountCreatedDate($value)
667
    {
668
        return $this->setParameter('customerAccountCreatedDate', $value);
669
    }
670
671
    /**
672
     * Get the customerAccountChangedIndicator field
673
     *
674
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccChangeInd field
675
     *
676
     * @return null|string One of the CUSTOMER_ACCOUNT_MODIFIED_* constants
677
     */
678
    public function getCustomerAccountChangedIndicator()
679
    {
680
        return $this->getParameter('customerAccountChangedIndicator');
681
    }
682
683
    /**
684
     * Set the customerAccountChangedIndicator field
685
     *
686
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccChangeInd field
687
     *
688
     * @param null|string $value One of the CUSTOMER_ACCOUNT_MODIFIED_* constants
689
     * @return self
690
     * @throws InvalidRequestException if $value is invalid.
691
     */
692
    public function setCustomerAccountChangedIndicator($value)
693
    {
694
        if (in_array(
695
            $value,
696
            [
697
                null,
698
                self::CUSTOMER_ACCOUNT_MODIFIED_THIS_TRANSACTION,
699
                self::CUSTOMER_ACCOUNT_MODIFIED_LAST_30_DAYS,
700
                self::CUSTOMER_ACCOUNT_MODIFIED_LAST_60_DAYS,
701
                self::CUSTOMER_ACCOUNT_MODIFIED_MORE_THAN_60_DAYS,
702
            ]
703
        )) {
704
            return $this->setParameter('customerAccountChangedIndicator', $value);
705
        }
706
        throw new InvalidRequestException("Invalid customerAccountChangedIndicator parameter");
707
    }
708
709
    /**
710
     * Get the customerAccountChangedDate field
711
     *
712
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccChange field
713
     *
714
     * @return null|DateTime|int
715
     */
716
    public function getCustomerAccountChangedDate()
717
    {
718
        return $this->getParameter('customerAccountChangedDate');
719
    }
720
721
    /**
722
     * Set the customerAccountChangedDate field
723
     *
724
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccChange field
725
     *
726
     * @param null|DateTime|int $value
727
     * @return self
728
     */
729
    public function setCustomerAccountChangedDate($value)
730
    {
731
        return $this->setParameter('customerAccountChangedDate', $value);
732
    }
733
734
    /**
735
     * Get the customerPasswordAgeIndicator field
736
     *
737
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccPwChangeInd field
738
     *
739
     * @return null|string One of the CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_* constants
740
     */
741
    public function getCustomerPasswordChangedIndicator()
742
    {
743
        return $this->getParameter('customerPasswordAgeIndicator');
744
    }
745
746
    /**
747
     * Set the customerPasswordAgeIndicator field
748
     *
749
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccPwChangeInd field
750
     *
751
     * @param null|string $value One of the CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_* constants
752
     * @return self
753
     * @throws InvalidRequestException if $value is invalid.
754
     */
755
    public function setCustomerPasswordChangedIndicator($value)
756
    {
757
        if (in_array(
758
            $value,
759
            [
760
                null,
761
                self::CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_NONE,
762
                self::CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_THIS_TRANSACTION,
763
                self::CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_LAST_30_DAYS,
764
                self::CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_LAST_60_DAYS,
765
                self::CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_MORE_THAN_60_DAYS,
766
            ]
767
        )) {
768
            return $this->setParameter('customerPasswordAgeIndicator', $value);
769
        }
770
        throw new InvalidRequestException("Invalid customerPasswordAgeIndicator parameter");
771
    }
772
773
    /**
774
     * Get the customerPasswordChangedDate field
775
     *
776
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccPwChange field
777
     *
778
     * @return null|DateTime|int
779
     */
780
    public function getCustomerPasswordChangedDate()
781
    {
782
        return $this->getParameter('customerPasswordChangedDate');
783
    }
784
785
    /**
786
     * Set the customerPasswordChangedDate field
787
     *
788
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccPwChange field
789
     *
790
     * @param null|DateTime|int $value
791
     * @return self
792
     */
793
    public function setCustomerPasswordChangedDate($value)
794
    {
795
        return $this->setParameter('customerPasswordChangedDate', $value);
796
    }
797
798
    /**
799
     * Get the customerPurchasesInLast6Months field
800
     *
801
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.nbPurchaseAccount field
802
     *
803
     * @return null|int
804
     */
805
    public function getCustomerPurchasesInLast6Months()
806
    {
807
        return $this->getParameter('customerPurchasesInLast6Months');
808
    }
809
810
    /**
811
     * Set the customerPurchasesInLast6Months field
812
     *
813
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.nbPurchaseAccount field
814
     *
815
     * @param null|int $value
816
     * @return self
817
     */
818
    public function setCustomerPurchasesInLast6Months($value)
819
    {
820
        return $this->setParameter('customerPurchasesInLast6Months', $value);
821
    }
822
823
    /**
824
     * Get the customerAccountCardProvisionsLast24Hours field
825
     *
826
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.provisionAttemptsDay field
827
     *
828
     * @return null|int
829
     */
830
    public function getCustomerAccountCardProvisionsLast24Hours()
831
    {
832
        return $this->getParameter('customerAccountCardProvisionsLast24Hours');
833
    }
834
835
    /**
836
     * Set the customerAccountCardProvisionsLast24Hours field
837
     *
838
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.provisionAttemptsDay field
839
     *
840
     * @param null|int $value
841
     * @return self
842
     */
843
    public function setCustomerAccountCardProvisionsLast24Hours($value)
844
    {
845
        return $this->setParameter('customerAccountCardProvisionsLast24Hours', $value);
846
    }
847
848
    /**
849
     * Get the customerAccountTransactionsLast24Hours field
850
     *
851
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.txnActivityDay field
852
     *
853
     * @return null|int
854
     */
855
    public function getCustomerAccountTransactionsLast24Hours()
856
    {
857
        return $this->getParameter('customerAccountTransactionsLast24Hours');
858
    }
859
860
    /**
861
     * Set the customerAccountTransactionsLast24Hours field
862
     *
863
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.txnActivityDay field
864
     *
865
     * @param null|int $value
866
     * @return self
867
     */
868
    public function setCustomerAccountTransactionsLast24Hours($value)
869
    {
870
        return $this->setParameter('customerAccountTransactionsLast24Hours', $value);
871
    }
872
873
    /**
874
     * Get the customerAccountTransactionsLastYear field
875
     *
876
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.txnActivityYear field
877
     *
878
     * @return null|int
879
     */
880
    public function getCustomerAccountTransactionsLastYear()
881
    {
882
        return $this->getParameter('customerAccountTransactionsLastYear');
883
    }
884
885
    /**
886
     * Set the customerAccountTransactionsLastYear field
887
     *
888
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.txnActivityYear field
889
     *
890
     * @param null|int $value
891
     * @return self
892
     */
893
    public function setCustomerAccountTransactionsLastYear($value)
894
    {
895
        return $this->setParameter('customerAccountTransactionsLastYear', $value);
896
    }
897
898
    /**
899
     * Get the customerPaymentMethodCreatedIndicator field
900
     *
901
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.paymentAccInd field
902
     *
903
     * @return null|string One of the PAYMENT_METHOD_CREATED_* constants
904
     */
905
    public function getCustomerPaymentMethodCreatedIndicator()
906
    {
907
        return $this->getParameter('customerPaymentMethodCreatedIndicator');
908
    }
909
910
    /**
911
     * Set the customerPaymentMethodCreatedIndicator field
912
     *
913
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.paymentAccInd field
914
     *
915
     * @param null|string $value One of the PAYMENT_METHOD_CREATED_* constants
916
     * @return self
917
     * @throws InvalidRequestException if $value is invalid.
918
     */
919
    public function setCustomerPaymentMethodCreatedIndicator($value)
920
    {
921
        if (in_array(
922
            $value,
923
            [
924
                null,
925
                self::PAYMENT_METHOD_CREATED_NONE,
926
                self::PAYMENT_METHOD_CREATED_THIS_TRANSACTION,
927
                self::PAYMENT_METHOD_CREATED_LAST_30_DAYS,
928
                self::PAYMENT_METHOD_CREATED_LAST_60_DAYS,
929
                self::PAYMENT_METHOD_CREATED_MORE_THAN_60_DAYS,
930
            ]
931
        )) {
932
            return $this->setParameter('customerPaymentMethodCreatedIndicator', $value);
933
        }
934
        throw new InvalidRequestException("Invalid customerPaymentMethodCreatedIndicator parameter");
935
    }
936
937
    /**
938
     * Get the customerPaymentMethodCreatedDate field
939
     *
940
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.paymentAccAge field
941
     *
942
     * @return null|DateTime|int
943
     */
944
    public function getCustomerPaymentMethodCreatedDate()
945
    {
946
        return $this->getParameter('customerPaymentMethodCreatedDate');
947
    }
948
949
    /**
950
     * Set the customerPaymentMethodCreatedDate field
951
     *
952
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.paymentAccAge field
953
     *
954
     * @param null|DateTime|int $value
955
     * @return self
956
     */
957
    public function setCustomerPaymentMethodCreatedDate($value)
958
    {
959
        return $this->setParameter('customerPaymentMethodCreatedDate', $value);
960
    }
961
962
    /**
963
     * Get the shippingAddressFirstUsedIndicator field
964
     *
965
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipAddressUsageInd field
966
     *
967
     * @return null|string One of the SHIPPING_ADDRESS_USAGE_* constants
968
     */
969
    public function getShippingAddressFirstUsedIndicator()
970
    {
971
        return $this->getParameter('shippingAddressFirstUsedIndicator');
972
    }
973
974
    /**
975
     * Set the shippingAddressFirstUsedIndicator field
976
     *
977
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipAddressUsageInd field
978
     *
979
     * @param null|string $value One of the SHIPPING_ADDRESS_USAGE_* constants
980
     * @return self
981
     * @throws InvalidRequestException if $value is invalid.
982
     */
983
    public function setShippingAddressFirstUsedIndicator($value)
984
    {
985
        if (in_array(
986
            $value,
987
            [
988
                null,
989
                self::SHIPPING_ADDRESS_USAGE_THIS_TRANSACTION,
990
                self::SHIPPING_ADDRESS_USAGE_LAST_30_DAYS,
991
                self::SHIPPING_ADDRESS_USAGE_LAST_60_DAYS,
992
                self::SHIPPING_ADDRESS_USAGE_MORE_THAN_60_DAYS,
993
            ]
994
        )) {
995
            return $this->setParameter('shippingAddressFirstUsedIndicator', $value);
996
        }
997
        throw new InvalidRequestException("Invalid shippingAddressFirstUsedIndicator parameter");
998
    }
999
1000
    /**
1001
     * Get the shippingAddressFirstUsedDate field
1002
     *
1003
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipAddressUsage field
1004
     *
1005
     * @return null|DateTime|int
1006
     */
1007
    public function getShippingAddressFirstUsedDate()
1008
    {
1009
        return $this->getParameter('shippingAddressFirstUsedDate');
1010
    }
1011
1012
    /**
1013
     * Set the shippingAddressFirstUsedDate field
1014
     *
1015
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipAddressUsage field
1016
     *
1017
     * @param null|DateTime|int $value
1018
     * @return self
1019
     */
1020
    public function setShippingAddressFirstUsedDate($value)
1021
    {
1022
        return $this->setParameter('shippingAddressFirstUsedDate', $value);
1023
    }
1024
1025
    /**
1026
     * Get the shippingNameCustomerNameMatch field
1027
     *
1028
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipNameIndicator field
1029
     *
1030
     * @return null|boolean
1031
     */
1032
    public function getShippingNameCustomerNameMatch()
1033
    {
1034
        return $this->getParameter('shippingNameCustomerNameMatch');
1035
    }
1036
1037
    /**
1038
     * Set the shippingNameCustomerNameMatch field
1039
     *
1040
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipNameIndicator field
1041
     *
1042
     * @param null|boolean $value
1043
     * @return self
1044
     */
1045
    public function setShippingNameCustomerNameMatch($value)
1046
    {
1047
        return $this->setParameter('shippingNameCustomerNameMatch', $value);
1048
    }
1049
1050
    /**
1051
     * Get the customerHasSuspiciousActivity field
1052
     *
1053
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.suspiciousAccActivity field
1054
     *
1055
     * @return null|boolean
1056
     */
1057
    public function getCustomerHasSuspiciousActivity()
1058
    {
1059
        return $this->getParameter('customerHasSuspiciousActivity');
1060
    }
1061
1062
    /**
1063
     * Set the customerHasSuspiciousActivity field
1064
     *
1065
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.suspiciousAccActivity field
1066
     *
1067
     * @param null|boolean $value
1068
     * @return self
1069
     */
1070
    public function setCustomerHasSuspiciousActivity($value)
1071
    {
1072
        return $this->setParameter('customerHasSuspiciousActivity', $value);
1073
    }
1074
1075
    /**
1076
     * Get the deliveryEmail field
1077
     *
1078
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.deliveryEmailAddress field
1079
     *
1080
     * @return null|string
1081
     */
1082
    public function getDeliveryEmail()
1083
    {
1084
        return $this->getParameter('deliveryEmail');
1085
    }
1086
1087
    /**
1088
     * Set the deliveryEmail field
1089
     *
1090
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.deliveryEmailAddress field
1091
     *
1092
     * @param null|string $value
1093
     * @return self
1094
     */
1095
    public function setDeliveryEmail($value)
1096
    {
1097
        return $this->setParameter('deliveryEmail', $value);
1098
    }
1099
1100
    /**
1101
     * Get the deliveryTimeframeIndicator field
1102
     *
1103
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.deliveryTimeframe field
1104
     *
1105
     * @return null|string One of the DELIVERY_TIMEFRAME_* constants
1106
     */
1107
    public function getDeliveryTimeframeIndicator()
1108
    {
1109
        return $this->getParameter('deliveryTimeframeIndicator');
1110
    }
1111
1112
    /**
1113
     * Set the deliveryTimeframeIndicator field
1114
     *
1115
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.deliveryTimeframe field
1116
     *
1117
     * @param null|string $value One of the DELIVERY_TIMEFRAME_* constants
1118
     * @return self
1119
     * @throws InvalidRequestException if $value is invalid.
1120
     */
1121
    public function setDeliveryTimeframeIndicator($value)
1122
    {
1123
        if (in_array(
1124
            $value,
1125
            [
1126
                null,
1127
                self::DELIVERY_TIMEFRAME_ELECTRONIC_DELIVERY,
1128
                self::DELIVERY_TIMEFRAME_SAME_DAY,
1129
                self::DELIVERY_TIMEFRAME_NEXT_DAY,
1130
                self::DELIVERY_TIMEFRAME_2_OR_MORE_DAYS,
1131
            ]
1132
        )) {
1133
            return $this->setParameter('deliveryTimeframeIndicator', $value);
1134
        }
1135
        throw new InvalidRequestException("Invalid deliveryTimeframeIndicator parameter");
1136
    }
1137
1138
    /**
1139
     * Get the giftCardAmount field
1140
     *
1141
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardAmount field
1142
     *
1143
     * @return null|int
1144
     */
1145
    public function getGiftCardAmount()
1146
    {
1147
        return $this->getParameter('giftCardAmount');
1148
    }
1149
1150
    /**
1151
     * Set the giftCardAmount field
1152
     *
1153
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardAmount field
1154
     *
1155
     * @param null|int $value
1156
     * @return self
1157
     */
1158
    public function setGiftCardAmount($value)
1159
    {
1160
        return $this->setParameter('giftCardAmount', $value);
1161
    }
1162
1163
    /**
1164
     * Get the giftCardCount field
1165
     *
1166
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardCount field
1167
     *
1168
     * @return null|int
1169
     */
1170
    public function getGiftCardCount()
1171
    {
1172
        return $this->getParameter('giftCardCount');
1173
    }
1174
1175
    /**
1176
     * Set the giftCardCount field
1177
     *
1178
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardCount field
1179
     *
1180
     * @param null|int $value
1181
     * @return self
1182
     */
1183
    public function setGiftCardCount($value)
1184
    {
1185
        return $this->setParameter('giftCardCount', $value);
1186
    }
1187
1188
    /**
1189
     * Get the giftCardCurrency field
1190
     *
1191
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardCurr field
1192
     *
1193
     * @return null|string ISO-4217 currency code
1194
     */
1195
    public function getGiftCardCurrency()
1196
    {
1197
        return $this->getParameter('giftCardCurrency');
1198
    }
1199
1200
    /**
1201
     * Set the giftCardCurrency field
1202
     *
1203
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardCurr field
1204
     *
1205
     * @param null|string $value ISO-4217 currency code
1206
     * @return self
1207
     */
1208
    public function setGiftCardCurrency($value)
1209
    {
1210
        return $this->setParameter('giftCardCurrency', $value);
1211
    }
1212
1213
    /**
1214
     * Get the purchasingPreOrder field
1215
     *
1216
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.preOrderPurchaseInd field
1217
     *
1218
     * @return null|boolean True if the customer is purchasing a preorder
1219
     */
1220
    public function getPurchasingPreOrder()
1221
    {
1222
        return $this->getParameter('purchasingPreOrder');
1223
    }
1224
1225
    /**
1226
     * Set the purchasingPreOrder field
1227
     *
1228
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.preOrderPurchaseInd field
1229
     *
1230
     * @param null|boolean $value True if the customer is purchasing a preorder
1231
     * @return self
1232
     */
1233
    public function setPurchasingPreOrder($value)
1234
    {
1235
        return $this->setParameter('purchasingPreOrder', $value);
1236
    }
1237
1238
    /**
1239
     * Get the preOrderDate field
1240
     *
1241
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.preOrderDate field
1242
     *
1243
     * @return null|DateTime|int
1244
     */
1245
    public function getPreOrderDate()
1246
    {
1247
        return $this->getParameter('preOrderDate');
1248
    }
1249
1250
    /**
1251
     * Set the preOrderDate field
1252
     *
1253
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.preOrderDate field
1254
     *
1255
     * @param null|DateTime|int $value
1256
     * @return self
1257
     */
1258
    public function setPreOrderDate($value)
1259
    {
1260
        return $this->setParameter('preOrderDate', $value);
1261
    }
1262
1263
    /**
1264
     * Get the customerHasPurchasedProductBefore field
1265
     *
1266
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.reorderItemsInd field
1267
     *
1268
     * @return null|boolean
1269
     */
1270
    public function getCustomerHasPurchasedProductBefore()
1271
    {
1272
        return $this->getParameter('customerHasPurchasedProductBefore');
1273
    }
1274
1275
    /**
1276
     * Set the customerHasPurchasedProductBefore field
1277
     *
1278
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.reorderItemsInd field
1279
     *
1280
     * @param null|boolean $value
1281
     * @return self
1282
     */
1283
    public function setCustomerHasPurchasedProductBefore($value)
1284
    {
1285
        return $this->setParameter('customerHasPurchasedProductBefore', $value);
1286
    }
1287
1288
    /**
1289
     * Get the shippingAddressIndicator field
1290
     *
1291
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.shipIndicator field
1292
     *
1293
     * @return null|string One of the self::SHIPPING_* constants
1294
     */
1295
    public function getShippingAddressIndicator()
1296
    {
1297
        return $this->getParameter('shippingAddressIndicator');
1298
    }
1299
1300
    /**
1301
     * Set the shippingAddressIndicator field
1302
     *
1303
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.shipIndicator field
1304
     *
1305
     * @param null|string $value One of the self::SHIPPING_* constants
1306
     * @return self
1307
     * @throws InvalidRequestException if $value is invalid.
1308
     */
1309 View Code Duplication
    public function setShippingAddressIndicator($value)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1310
    {
1311
        if (in_array(
1312
            $value,
1313
            [
1314
                null,
1315
                self::SHIPPING_TO_BILLING_ADDRESS,
1316
                self::SHIPPING_TO_ANOTHER_VERIFIED_ADDRESS,
1317
                self::SHIPPING_DIFFERENT_BILLING_ADDRESS,
1318
                self::SHIPPING_PICK_UP,
1319
                self::SHIPPING_DIGITAL,
1320
                self::SHIPPING_TRAVEL,
1321
                self::SHIPPING_OTHER,
1322
            ]
1323
        )) {
1324
            return $this->setParameter('shippingAddressIndicator', $value);
1325
        }
1326
        throw new InvalidRequestException("Invalid shippingAddressIndicator parameter");
1327
    }
1328
1329
    /**
1330
     * Get the SCA exemption field
1331
     *
1332
     * Corresponds to the Ds_Merchant_Excep_Sca field
1333
     *
1334
     * @return null|string One of the self::SCA_EXCEMPTION_* constants
1335
     */
1336
    public function getScaExemptionIndicator()
1337
    {
1338
        return $this->getParameter('scaExemptionIndicator');
1339
    }
1340
1341
    /**
1342
     * Set the SCA exemption field
1343
     *
1344
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.shipIndicator field
1345
     *
1346
     * @param null|string $value One of the self::SCA_EXCEMPTION_* constants
1347
     * @return self
1348
     * @throws InvalidRequestException if $value is invalid.
1349
     */
1350
    public function setScaExemptionIndicator($value)
1351
    {
1352
        if (in_array(
1353
            $value,
1354
            [
1355
                null,
1356
                self::SCA_EXCEMPTION_LOW_AMOUNT,
1357
                self::SCA_EXCEMPTION_LOW_RISK,
1358
                self::SCA_EXCEMPTION_CORPORATE,
1359
                self::SCA_EXCEMPTION_MERCHANT_INITIATED,
1360
            ]
1361
        )) {
1362
            return $this->setParameter('scaExemptionIndicator', $value);
1363
        }
1364
        throw new InvalidRequestException("Invalid scaExemptionIndicator parameter");
1365
    }
1366
1367
    /**
1368
     * Override the abstract method to add requirement that it must start with 4 numeric characters
1369
     *
1370
     * @param string|int $value The transaction ID (merchant order) to set for the transaction
1371
     */
1372
    public function setTransactionId($value)
1373
    {
1374
        $start = substr($value, 0, 4);
1375
        $numerics = 0;
1376
        foreach (str_split($start) as $char) {
1377
            if (is_numeric($char)) {
1378
                $numerics++;
1379
            } else {
1380
                break;
1381
            }
1382
        }
1383
        $value = str_pad(substr($start, 0, $numerics), 4, 0, STR_PAD_LEFT).substr($value, $numerics);
1384
1385
        parent::setTransactionId($value);
1386
    }
1387
1388
    public function getData()
1389
    {
1390
        $data = $this->getBaseData();
1391
        if ($this->getScaExemptionIndicator() !== null) {
1392
            $data['Ds_Merchant_Excep_Sca'] = $this->getScaExemptionIndicator();
1393
        }
1394
1395
        // only generate an EMV 3DS request if requested to
1396
        if ($this->getUse3DS()) {
1397
            // Validating the presence of the card under the assumption that at least an address is required
1398
            // NOTE: normally would validate() for other submission params, but the minimum depends on bank contract
1399
            $this->validate('card');
1400
            $card = $this->getCard();
1401
1402
            $homePhone = array_filter([
1403
                'cc'         => $this->getHomePhoneCountryPrefix(),
1404
                'subscriber' => $this->getHomePhone(),
1405
            ]);
1406
            $mobilePhone = array_filter([
1407
                'cc'         => $this->getMobilePhoneCountryPrefix(),
1408
                'subscriber' => $this->getMobilePhone(),
1409
            ]);
1410
            $workPhone = array_filter([
1411
                'cc'         => $this->getWorkPhoneCountryPrefix(),
1412
                'subscriber' => $this->getWorkPhone(),
1413
            ]);
1414
            $threeDSAuthInfo = array_filter([
1415
                'threeDSReqAuthData'      => $this->get3DsRequestAuthenticationMethodData(),
1416
                'threeDSReqAuthMethod'    => $this->get3DsRequestAuthenticationMethod(),
1417
                'threeDSReqAuthTimestamp' => $this->formatDateTime($this->get3DsRequestAuthenticationTime(), "YmdHi"),
0 ignored issues
show
Bug introduced by
It seems like $this->get3DsRequestAuthenticationTime() targeting Omnipay\Redsys\Message\P...estAuthenticationTime() can also be of type null; however, Omnipay\Redsys\Message\P...quest::formatDateTime() does only seem to accept object<DateTime>|integer, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
1418
            ]);
1419
            $emv3DsParameters = array_filter([
1420
                'cardholderName'                     => $this->getCardholder(),
1421
                'email'                              => $card->getEmail(),
1422
                'homePhone'                          => $homePhone,
1423
                'mobilePhone'                        => $mobilePhone,
1424
                'workPhone'                          => $workPhone,
1425
                'shipAddrLine1'                      => $card->getShippingAddress1(),
1426
                'shipAddrLine2'                      => $card->getShippingAddress2(),
1427
                'shipAddrLine3'                      => $card->getShippingAddress3(),
1428
                'shipAddrCity'                       => $card->getShippingCity(),
1429
                'shipAddrPostCode'                   => $card->getShippingPostcode(),
1430
                'shipAddrState'                      => $card->getShippingState(),
1431
                'shipAddrCountry'                    => $card->getShippingCountry(),
1432
                'billAddrLine1'                      => $card->getBillingAddress1(),
1433
                'billAddrLine2'                      => $card->getBillingAddress2(),
1434
                'billAddrLine3'                      => $card->getBillingAddress3(),
1435
                'billAddrCity'                       => $card->getBillingCity(),
1436
                'billAddrPostCode'                   => $card->getBillingPostcode(),
1437
                'billAddrState'                      => $card->getBillingState(),
1438
                'billAddrCountry'                    => $card->getBillingCountry(),
1439
                'addrMatch'                          => $this->getAddressMatch(),
1440
                'challengeWindowSize'                => $this->getChallengeWindowSize(),
1441
                'acctID'                             => $this->getCustomerAdditionalInformation(),
1442
                'threeDSRequestorAuthenticationInfo' => $threeDSAuthInfo,
1443
            ]);
1444
1445
            $acctInfo = array_filter([
1446
                'chAccAgeInd'           => $this->getCustomerAccountCreatedIndicator(),
1447
                'chAccDate'             => $this->formatDateTime($this->getCustomerAccountCreatedDate(), "Ymd"),
0 ignored issues
show
Bug introduced by
It seems like $this->getCustomerAccountCreatedDate() targeting Omnipay\Redsys\Message\P...merAccountCreatedDate() can also be of type null; however, Omnipay\Redsys\Message\P...quest::formatDateTime() does only seem to accept object<DateTime>|integer, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
1448
                'chAccChangeInd'        => $this->getCustomerAccountChangedIndicator(),
1449
                'chAccChange'           => $this->formatDateTime($this->getCustomerAccountChangedDate(), "Ymd"),
0 ignored issues
show
Bug introduced by
It seems like $this->getCustomerAccountChangedDate() targeting Omnipay\Redsys\Message\P...merAccountChangedDate() can also be of type null; however, Omnipay\Redsys\Message\P...quest::formatDateTime() does only seem to accept object<DateTime>|integer, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
1450
                'chAccPwChangeInd'      => $this->getCustomerPasswordChangedIndicator(),
1451
                'chAccPwChange'         => $this->formatDateTime($this->getCustomerPasswordChangedDate(), "Ymd"),
0 ignored issues
show
Bug introduced by
It seems like $this->getCustomerPasswordChangedDate() targeting Omnipay\Redsys\Message\P...erPasswordChangedDate() can also be of type null; however, Omnipay\Redsys\Message\P...quest::formatDateTime() does only seem to accept object<DateTime>|integer, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
1452
                'paymentAccInd'         => $this->getCustomerPaymentMethodCreatedIndicator(),
1453
                'paymentAccAge'         => $this->formatDateTime($this->getCustomerPaymentMethodCreatedDate(), "Ymd"),
0 ignored issues
show
Bug introduced by
It seems like $this->getCustomerPaymentMethodCreatedDate() targeting Omnipay\Redsys\Message\P...mentMethodCreatedDate() can also be of type null; however, Omnipay\Redsys\Message\P...quest::formatDateTime() does only seem to accept object<DateTime>|integer, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
1454
                'shipAddressUsageInd'   => $this->getShippingAddressFirstUsedIndicator(),
1455
                'shipAddressUsage'      => $this->formatDateTime($this->getShippingAddressFirstUsedDate(), "Ymd"),
0 ignored issues
show
Bug introduced by
It seems like $this->getShippingAddressFirstUsedDate() targeting Omnipay\Redsys\Message\P...gAddressFirstUsedDate() can also be of type null; however, Omnipay\Redsys\Message\P...quest::formatDateTime() does only seem to accept object<DateTime>|integer, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
1456
            ]);
1457
            // checks that can't rely on a simple filter (which could remove or add values unintentionally)
1458
            if ($this->getShippingNameCustomerNameMatch() !== null) {
1459
                $acctInfo['shipNameIndicator'] = $this->getShippingNameCustomerNameMatch() ? "01" : "02";
1460
            }
1461
            if ($this->getCustomerHasSuspiciousActivity() !== null) {
1462
                $acctInfo['suspiciousAccActivity'] = $this->getCustomerHasSuspiciousActivity() ? "02" : "01";
1463
            }
1464
            // @todo switch to if()s so no need to evaluate else paths
1465
            if ($this->getCustomerPurchasesInLast6Months() !== null) {
1466
                $acctInfo['nbPurchaseAccount'] = $this->getCustomerPurchasesInLast6Months();
1467
            }
1468
            if ($this->getCustomerAccountCardProvisionsLast24Hours() !== null) {
1469
                $acctInfo['provisionAttemptsDay'] = $this->getCustomerAccountCardProvisionsLast24Hours();
1470
            }
1471
            if ($this->getCustomerAccountTransactionsLast24Hours() !== null) {
1472
                $acctInfo['txnActivityDay'] = $this->getCustomerAccountTransactionsLast24Hours();
1473
            }
1474
            if ($this->getCustomerAccountTransactionsLastYear() !== null) {
1475
                $acctInfo['txnActivityYear'] = $this->getCustomerAccountTransactionsLastYear();
1476
            }
1477
            $emv3DsParameters += ($acctInfo === []
1478
                ? []
1479
                : ['acctInfo' => $acctInfo]
1480
            );
1481
1482
            $merchantRiskIndicator = array_filter([
1483
                'deliveryEmailAddress' => $this->getDeliveryEmail(),
1484
                'deliveryTimeframe'    => $this->getDeliveryTimeframeIndicator(),
1485
                'giftCardCount'        => $this->getGiftCardCount(),
1486
                'giftCardCurr'         => $this->getGiftCardCurrency(),
1487
                'preOrderDate'         => $this->formatDateTime($this->getPreOrderDate(), "Ymd"),
0 ignored issues
show
Bug introduced by
It seems like $this->getPreOrderDate() targeting Omnipay\Redsys\Message\P...uest::getPreOrderDate() can also be of type null; however, Omnipay\Redsys\Message\P...quest::formatDateTime() does only seem to accept object<DateTime>|integer, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
1488
                'shipIndicator'        => $this->getShippingAddressIndicator(),
1489
            ]);
1490
            if ($this->getGiftCardAmount() !== null) {
1491
                $merchantRiskIndicator['giftCardAmount'] = (int) $this->getGiftCardAmount();
1492
            }
1493
            if ($this->getPurchasingPreOrder() !== null) {
1494
                $merchantRiskIndicator['preOrderPurchaseInd'] = $this->getPurchasingPreOrder() ? "02" : "01";
1495
            }
1496
            if ($this->getCustomerHasPurchasedProductBefore() !== null) {
1497
                $merchantRiskIndicator['reorderItemsInd'] = $this->getCustomerHasPurchasedProductBefore() ? "02" : "01";
1498
            }
1499
            if ($merchantRiskIndicator !== []) {
1500
                $emv3DsParameters['merchantRiskIndicator'] = $merchantRiskIndicator;
1501
            }
1502
1503
            if ($emv3DsParameters !== []) {
1504
                $data['Ds_Merchant_Emv3Ds'] = $emv3DsParameters;
1505
            }
1506
        }
1507
1508
        return $data;
1509
    }
1510
1511
    /**
1512
     * Get the basic data fields that don't require any 3DS/SCA fields
1513
     */
1514
    public function getBaseData()
1515
    {
1516
        $this->validate('merchantId', 'terminalId', 'amount', 'currency');
1517
1518
        return [
1519
            // mandatory fields
1520
            'Ds_Merchant_MerchantCode'       => $this->getMerchantId(),
1521
            'Ds_Merchant_Terminal'           => $this->getTerminalId(),
1522
            'Ds_Merchant_TransactionType'    => '0',                          // Authorisation
1523
            'Ds_Merchant_Amount'             => $this->getAmountInteger(),
1524
            'Ds_Merchant_Currency'           => $this->getCurrencyNumeric(),  // uses ISO-4217 codes
1525
            'Ds_Merchant_Order'              => $this->getTransactionId(),
1526
            'Ds_Merchant_MerchantUrl'        => $this->getNotifyUrl(),
1527
            // optional fields
1528
            'Ds_Merchant_ProductDescription' => $this->getDescription(),
1529
            'Ds_Merchant_Cardholder'         => $this->getCardholder(),
1530
            'Ds_Merchant_UrlOK'              => $this->getReturnUrl(),
1531
            'Ds_Merchant_UrlKO'              => $this->getReturnUrl(),
1532
            'Ds_Merchant_MerchantName'       => $this->getMerchantName(),
1533
            'Ds_Merchant_ConsumerLanguage'   => $this->getConsumerLanguage(),
1534
            'Ds_Merchant_MerchantData'       => $this->getMerchantData(),
1535
        ];
1536
    }
1537
1538
    public function sendData($data)
1539
    {
1540
        $security = new Security;
1541
1542
        $encoded_data = $security->encodeMerchantParameters($data);
1543
1544
        $response_data = array(
1545
            'Ds_SignatureVersion'   => Security::VERSION,
1546
            'Ds_MerchantParameters' => $encoded_data,
1547
            'Ds_Signature'          => $security->createSignature(
1548
                $encoded_data,
1549
                $data['Ds_Merchant_Order'],
1550
                $this->getHmacKey()
1551
            ),
1552
        );
1553
1554
        return $this->response = new PurchaseResponse($this, $response_data);
1555
    }
1556
1557
    public function getEndpoint()
1558
    {
1559
        return $this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint;
1560
    }
1561
1562
    /**
1563
     * Convert a DateTime or timestamp to a formatted date.
1564
     *
1565
     * @param DateTime|int $date The date to format.
1566
     * @param string $format The format to use.
1567
     *
1568
     * @return string|null The formatted date, or null if date isn't a timestamp or DateTime object.
1569
     */
1570
    protected function formatDateTime($date, $format)
1571
    {
1572
        if (is_int($date)) {
1573
            return (new DateTime('@'.$date))->format($format);
1574
        } elseif ($date instanceof DateTime) {
1575
            return $date->setTimezone(new DateTimeZone('UTC'))->format($format);
1576
        }
1577
    }
1578
}
1579