Completed
Push — master ( 640beb...30b766 )
by Leith
27s queued 12s
created

setCustomerAccountTransactionsLast24Hours()   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 1
crap 2
1
<?php
2
3
namespace Omnipay\Redsys\Message;
4
5
use DateTime;
6
use DateTimeZone;
7
use Omnipay\Common\Message\AbstractRequest;
8
use Omnipay\Common\Exception\InvalidRequestException;
9
10
/**
11
 * Redsys Purchase Request
12
 */
13
class PurchaseRequest extends AbstractRequest
14
{
15
    /** @var string */
16
    protected $liveEndpoint = 'https://sis.redsys.es/sis/realizarPago';
17
    /** @var string */
18
    protected $testEndpoint = 'https://sis-t.redsys.es:25443/sis/realizarPago';
19
    /** @var array */
20
    protected static $consumerLanguages = array(
21
        'es' => '001', // Spanish
22
        'en' => '002', // English
23
        'ca' => '003', // Catalan - same as Valencian (010)
24
        'fr' => '004', // French
25
        'de' => '005', // German
26
        'nl' => '006', // Dutch
27
        'it' => '007', // Italian
28
        'sv' => '008', // Swedish
29
        'pt' => '009', // Portuguese
30
        'pl' => '011', // Polish
31
        'gl' => '012', // Galician
32 2
        'eu' => '013', // Basque
33
    );
34 2
35
    /** @var string 250x400 */
36
    const CHALLENGE_WINDOW_SIZE_250_400 = "01";
37 4
    /** @var string 390x400 */
38
    const CHALLENGE_WINDOW_SIZE_390_400 = "02";
39 4
    /** @var string 500x600 */
40
    const CHALLENGE_WINDOW_SIZE_500_600 = "03";
41
    /** @var string 600x400 */
42 8
    const CHALLENGE_WINDOW_SIZE_600_400 = "04";
43
    /** @var string Fullscreen window (default) */
44 8
    const CHALLENGE_WINDOW_SIZE_FULLSCREEN = "05";
45
46
    /** @var string No 3DS Requestor authentication occurred (i.e. cardholder logged in as guest) */
47
    const ACCOUNT_AUTHENTICATION_METHOD_NONE = "01";
48
    /** @var string Login to the cardholder account at the 3DS Requestor system using 3DS Requestor's own credentials */
49
    const ACCOUNT_AUTHENTICATION_METHOD_OWN_CREDENTIALS = "02";
50
    /** @var string Login to the cardholder account at the 3DS Requestor system using federated ID */
51
    const ACCOUNT_AUTHENTICATION_METHOD_FEDERATED_ID = "03";
52 7
    /** @var string Login to the cardholder account at the 3DS Requestor system using issuer credentials */
53
    const ACCOUNT_AUTHENTICATION_METHOD_ISSUER_CREDENTIALS = "04";
54 7
    /** @var string Login to the cardholder account at the 3DS Requestor system using third-party authentication */
55 1
    const ACCOUNT_AUTHENTICATION_METHOD_THIRD_PARTY_AUTHENTICATION = "05";
56 1
    /** @var string Login to the cardholder account at the 3DS Requestor system using FIDO Authenticator */
57 1
    const ACCOUNT_AUTHENTICATION_METHOD_FIDO = "06";
58 1
59 7
    /** @var string No account (guest check-out) */
60 7
    const CUSTOMER_ACCOUNT_CREATED_NONE = "01";
61 7
    /** @var string Created during this transaction */
62
    const CUSTOMER_ACCOUNT_CREATED_THIS_TRANSACTION = "02";
63 7
    /** @var string Less than 30 days */
64
    const CUSTOMER_ACCOUNT_CREATED_LAST_30_DAYS = "03";
65
    /** @var string Between 30 and 60 days */
66 15
    const CUSTOMER_ACCOUNT_CREATED_LAST_60_DAYS = "04";
67
    /** @var string More than 60 day */
68 15
    const CUSTOMER_ACCOUNT_CREATED_MORE_THAN_60_DAYS = "05";
69
70
    /** @var string Modified in this session */
71 23
    const CUSTOMER_ACCOUNT_MODIFIED_THIS_TRANSACTION = "01";
72
    /** @var string Less than 30 days */
73 23
    const CUSTOMER_ACCOUNT_MODIFIED_LAST_30_DAYS = "02";
74
    /** @var string Between 30 and 60 days */
75
    const CUSTOMER_ACCOUNT_MODIFIED_LAST_60_DAYS = "03";
76 7
    /** @var string More than 60 day */
77
    const CUSTOMER_ACCOUNT_MODIFIED_MORE_THAN_60_DAYS = "04";
78 7
79
    /** @var string Unchanged */
80
    const CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_NONE = "01";
81 7
    /** @var string Modified in this session */
82
    const CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_THIS_TRANSACTION = "02";
83 7
    /** @var string Less than 30 days */
84
    const CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_LAST_30_DAYS = "03";
85
    /** @var string Between 30 and 60 days */
86 11
    const CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_LAST_60_DAYS = "04";
87
    /** @var string More than 60 day */
88 11
    const CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_MORE_THAN_60_DAYS = "05";
89
90
    /** @var string No account (guest check-out) */
91 23
    const PAYMENT_METHOD_CREATED_NONE = "01";
92
    /** @var string Created during this transaction */
93 23
    const PAYMENT_METHOD_CREATED_THIS_TRANSACTION = "02";
94
    /** @var string Less than 30 days */
95
    const PAYMENT_METHOD_CREATED_LAST_30_DAYS = "03";
96 11
    /** @var string Between 30 and 60 days */
97
    const PAYMENT_METHOD_CREATED_LAST_60_DAYS = "04";
98 11
    /** @var string More than 60 day */
99
    const PAYMENT_METHOD_CREATED_MORE_THAN_60_DAYS = "05";
100
101 23
    /** @var string For the first time */
102
    const SHIPPING_ADDRESS_USAGE_THIS_TRANSACTION = "01";
103 23
    /** @var string Less than 30 days */
104
    const SHIPPING_ADDRESS_USAGE_LAST_30_DAYS = "02";
105
    /** @var string Between 30 and 60 days */
106 11
    const SHIPPING_ADDRESS_USAGE_LAST_60_DAYS = "03";
107
    /** @var string More than 60 day */
108 11
    const SHIPPING_ADDRESS_USAGE_MORE_THAN_60_DAYS = "04";
109
110
    /** @var string Electronic delivery */
111 23
    const DELIVERY_TIMEFRAME_ELECTRONIC_DELIVERY = "01";
112
    /** @var string Same day shipping */
113 23
    const DELIVERY_TIMEFRAME_SAME_DAY = "02";
114
    /** @var string Next day shipping */
115
    const DELIVERY_TIMEFRAME_NEXT_DAY = "03";
116
    /** @var string Shipping in 2 or more days */
117
    const DELIVERY_TIMEFRAME_2_OR_MORE_DAYS = "04";
118
119
    /** @var string Ship to cardholder's billing address */
120
    const SHIPPING_TO_BILLING_ADDRESS = "01";
121 15
    /** @var string Ship to another verified address on file with merchant */
122
    const SHIPPING_TO_ANOTHER_VERIFIED_ADDRESS = "02";
123 15
    /** @var string Ship to address that is different than the cardholder's billing address */
124 15
    const SHIPPING_DIFFERENT_BILLING_ADDRESS = "03";
125 15
    /** @var string Pick-up at local store (Store address shall be populated in shipping address fields) */
126 15
    const SHIPPING_PICK_UP = "04";
127 15
    /** @var string Digital goods (includes online services, electronic gift cards and redemption codes) */
128 15
    const SHIPPING_DIGITAL = "05";
129 15
    /** @var string Travel and Event tickets, not shipped */
130
    const SHIPPING_TRAVEL = "06";
131 15
    /** @var string Other (for example, Gaming, digital services not shipped, emedia subscriptions, etc.) */
132 15
    const SHIPPING_OTHER = "07";
133
134 15
    /** @var string Exemption due to low amount (transactions up to € 30) */
135 15
    const SCA_EXEMPTION_LOW_AMOUNT = 'LMV';
136
    /** @var string Exemption due to low risk */
137 2
    const SCA_EXEMPTION_LOW_RISK = 'TRA';
138
    /** @var string Exemption for payments identified as corporate. */
139 2
    const SCA_EXEMPTION_CORPORATE = 'COR';
140
    /**
141
     * @var string Transactions initiated by the merchant, in which there is no intervention by the customer. They are
142
     *             outside the scope of PSD2.
143 2
     */
144 2
    const SCA_EXEMPTION_MERCHANT_INITIATED = 'MIT';
145 2
146 2
    public function getCardholder()
147 2
    {
148 2
        return $this->getParameter('cardholder');
149 2
    }
150
151 2
    public function setCardholder($value)
152 2
    {
153 2
        return $this->setParameter('cardholder', $value);
154 2
    }
155 2
156 2
    public function getConsumerLanguage()
157 2
    {
158 2
        return $this->getParameter('consumerLanguage');
159
    }
160
161 1
    /**
162
     * Set the language presented to the consumer
163 1
     *
164
     * @param null|string|int Either the ISO 639-1 code to be converted, or the gateway's own numeric language code
165 1
     */
166
    public function setConsumerLanguage($value)
167
    {
168 1
        if (is_int($value)) {
169 1
            if ($value < 0 || $value > 13) {
170 1
                $value = 1;
171 1
            }
172 1
            $value = str_pad($value, 3, '0', STR_PAD_LEFT);
173 1
        } elseif (!is_numeric($value)) {
174 1
            $value = isset(self::$consumerLanguages[$value]) ? self::$consumerLanguages[$value] : '001';
175 1
        }
176
177 1
        return $this->setParameter('consumerLanguage', $value);
178
    }
179
180 7
    public function getHmacKey()
181
    {
182 7
        return $this->getParameter('hmacKey');
183
    }
184
185 1
    public function setHmacKey($value)
186
    {
187
        return $this->setParameter('hmacKey', $value);
188
    }
189
190
    public function getMerchantData()
191
    {
192
        return $this->getParameter('merchantData');
193
    }
194
195
    public function setMerchantData($value)
196
    {
197
        return $this->setParameter('merchantData', $value);
198
    }
199
200
    public function getMerchantId()
201
    {
202
        return $this->getParameter('merchantId');
203
    }
204
205
    public function setMerchantId($value)
206
    {
207
        return $this->setParameter('merchantId', $value);
208
    }
209
210
    public function getMerchantName()
211
    {
212
        return $this->getParameter('merchantName');
213
    }
214
215
    public function setMerchantName($value)
216
    {
217
        return $this->setParameter('merchantName', $value);
218
    }
219
220
    public function getTerminalId()
221
    {
222
        return $this->getParameter('terminalId');
223
    }
224
225
    public function setTerminalId($value)
226
    {
227
        return $this->setParameter('terminalId', $value);
228
    }
229
230
    /**
231
     * Get the use3ds field
232
     *
233
     * Controls the presence of the Ds_Merchant_Emv3Ds structure
234
     *
235
     * @return bool
236
     */
237
    public function getUse3DS()
238
    {
239
        return (bool) $this->getParameter('use3ds');
240
    }
241
242
    /**
243
     * Set the use3ds field
244
     *
245
     * Controls the presence of the Ds_Merchant_Emv3Ds structure
246
     *
247
     * @param bool $value
248
     * @return self
249
     */
250
    public function setUse3DS($value)
251
    {
252
        return $this->setParameter('use3ds', $value);
253
    }
254
255
    /**
256
     * Get the homePhoneCountryPrefix field
257
     *
258
     * Corresponds to the Ds_Merchant_Emv3Ds.homePhone.cc field
259
     *
260
     * @return null|string
261
     */
262
    public function getHomePhoneCountryPrefix()
263
    {
264
        return $this->getParameter('homePhoneCountryPrefix');
265
    }
266
267
    /**
268
     * Set the homePhoneCountryPrefix field
269
     *
270
     * Corresponds to the Ds_Merchant_Emv3Ds.homePhone.cc field
271
     *
272
     * @param null|string $value
273
     * @return self
274
     */
275
    public function setHomePhoneCountryPrefix($value)
276
    {
277
        return $this->setParameter('homePhoneCountryPrefix', $value);
278
    }
279
280
    /**
281
     * Get the homePhone field
282
     *
283
     * Corresponds to the Ds_Merchant_Emv3Ds.homePhone.subscriber field
284
     *
285
     * @return null|string
286
     */
287
    public function getHomePhone()
288
    {
289
        return $this->getParameter('homePhone');
290
    }
291
292
    /**
293
     * Set the homePhone field
294
     *
295
     * Corresponds to the Ds_Merchant_Emv3Ds.homePhone.subscriber field
296
     *
297
     * @param null|string $value
298
     * @return self
299
     */
300
    public function setHomePhone($value)
301
    {
302
        return $this->setParameter('homePhone', $value);
303
    }
304
305
    /**
306
     * Get the mobilePhoneCountryPrefix field
307
     *
308
     * Corresponds to the Ds_Merchant_Emv3Ds.mobilePhone.cc field
309
     *
310
     * @return null|string
311
     */
312
    public function getMobilePhoneCountryPrefix()
313
    {
314
        return $this->getParameter('mobilePhoneCountryPrefix');
315
    }
316
317
    /**
318
     * Set the mobilePhoneCountryPrefix field
319
     *
320
     * Corresponds to the Ds_Merchant_Emv3Ds.mobilePhone.cc field
321
     *
322
     * @param null|string $value
323
     * @return self
324
     */
325
    public function setMobilePhoneCountryPrefix($value)
326
    {
327
        return $this->setParameter('mobilePhoneCountryPrefix', $value);
328
    }
329
330
    /**
331
     * Get the mobilePhone field
332
     *
333
     * Corresponds to the Ds_Merchant_Emv3Ds.mobilePhone.subscriber field
334
     *
335
     * @return null|string
336
     */
337
    public function getMobilePhone()
338
    {
339
        return $this->getParameter('mobilePhone');
340
    }
341
342
    /**
343
     * Set the mobilePhone field
344
     *
345
     * Corresponds to the Ds_Merchant_Emv3Ds.mobilePhone.subscriber field
346
     *
347
     * @param null|string $value
348
     * @return self
349
     */
350
    public function setMobilePhone($value)
351
    {
352
        return $this->setParameter('mobilePhone', $value);
353
    }
354
355
    /**
356
     * Get the workPhoneCountryPrefix field
357
     *
358
     * Corresponds to the Ds_Merchant_Emv3Ds.workPhone.cc field
359
     *
360
     * @return null|string
361
     */
362
    public function getWorkPhoneCountryPrefix()
363
    {
364
        return $this->getParameter('workPhoneCountryPrefix');
365
    }
366
367
    /**
368
     * Set the workPhoneCountryPrefix field
369
     *
370
     * Corresponds to the Ds_Merchant_Emv3Ds.workPhone.cc field
371
     *
372
     * @param null|string $value
373
     * @return self
374
     */
375
    public function setWorkPhoneCountryPrefix($value)
376
    {
377
        return $this->setParameter('workPhoneCountryPrefix', $value);
378
    }
379
380
    /**
381
     * Get the workPhone field
382
     *
383
     * Corresponds to the Ds_Merchant_Emv3Ds.workPhone.subscriber field
384
     *
385
     * @return null|string
386
     */
387
    public function getWorkPhone()
388
    {
389
        return $this->getParameter('workPhone');
390
    }
391
392
    /**
393
     * Set the workPhone field
394
     *
395
     * Corresponds to the Ds_Merchant_Emv3Ds.workPhone.subscriber field
396
     *
397
     * @param null|string $value
398
     * @return self
399
     */
400
    public function setWorkPhone($value)
401
    {
402
        return $this->setParameter('workPhone', $value);
403
    }
404
405
    /**
406
     * Get the addressMatch field
407
     *
408
     * Corresponds to the Ds_Merchant_Emv3Ds.addrMatch field
409
     *
410
     * @return string  Either 'Y' or 'N'
411
     */
412
    public function getAddressMatch()
413
    {
414
        $match = $this->getParameter('addressMatch');
415
416
        if ($match === null) {
417
            $match = false;
418
            $card = $this->getCard();
419
            if ($card !== null) {
420
                $match = $card->getShippingAddress1() === $card->getBillingAddress1()
421
                    && $card->getShippingAddress2() === $card->getBillingAddress2()
422
                    && $card->getShippingAddress3() === $card->getBillingAddress3()
423
                    && $card->getShippingCity() === $card->getBillingCity()
424
                    && $card->getShippingPostcode() === $card->getBillingPostcode()
425
                    && $card->getShippingState() === $card->getBillingState()
426
                    && $card->getShippingCountry() === $card->getBillingCountry();
427
            }
428
        }
429
430
        return $match ? "Y" : "N";
431
    }
432
433
    /**
434
     * Set the addressMatch field
435
     *
436
     * Corresponds to the Ds_Merchant_Emv3Ds.addrMatch field
437
     *
438
     * @param null|boolean $value
439
     * @return self
440
     */
441
    public function setAddressMatch($value)
442
    {
443
        return $this->setParameter('addressMatch', $value);
444
    }
445
446
    /**
447
     * Get the challengeWindowSize field
448
     *
449
     * Corresponds to the Ds_Merchant_Emv3Ds.challengeWindowSize field
450
     *
451
     * @return null|string One of the self::CHALLENGE_WINDOW_SIZE_* constants
452
     */
453
    public function getChallengeWindowSize()
454
    {
455
        return $this->getParameter('challengeWindowSize');
456
    }
457
458
    /**
459
     * Set the challengeWindowSize field
460
     *
461
     * Corresponds to the Ds_Merchant_Emv3Ds.challengeWindowSize field
462
     *
463
     * @param null|string $value One of the self::CHALLENGE_WINDOW_SIZE_* constants
464
     * @return self
465
     * @throws InvalidRequestException if $value is invalid.
466
     */
467
    public function setChallengeWindowSize($value)
468
    {
469
        if (in_array(
470
            $value,
471
            [
472
                null,
473
                self::CHALLENGE_WINDOW_SIZE_250_400,
474
                self::CHALLENGE_WINDOW_SIZE_390_400,
475
                self::CHALLENGE_WINDOW_SIZE_500_600,
476
                self::CHALLENGE_WINDOW_SIZE_600_400,
477
                self::CHALLENGE_WINDOW_SIZE_FULLSCREEN,
478
            ]
479
        )) {
480
            return $this->setParameter('challengeWindowSize', $value);
481
        }
482
        throw new InvalidRequestException("Invalid challengeWindowSize parameter");
483
    }
484
485
    /**
486
     * Get the customerAdditionalInformation field
487
     *
488
     * Corresponds to the Ds_Merchant_Emv3Ds.acctID field
489
     *
490
     * @return null|string
491
     */
492
    public function getCustomerAdditionalInformation()
493
    {
494
        return $this->getParameter('customerAdditionalInformation');
495
    }
496
497
    /**
498
     * Set the customerAdditionalInformation field
499
     *
500
     * Corresponds to the Ds_Merchant_Emv3Ds.acctID field
501
     *
502
     * @param null|string $value
503
     * @return self
504
     */
505
    public function setCustomerAdditionalInformation($value)
506
    {
507
        return $this->setParameter('customerAdditionalInformation', $value);
508
    }
509
510
    /**
511
     * Get the 3DsRequestAuthenticationMethodData field
512
     *
513
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthData field in Redsys
514
     * documentation.
515
     *
516
     * @return null|string
517
     */
518
    public function get3DsRequestAuthenticationMethodData()
519
    {
520
        return $this->getParameter('3DsRequestAuthenticationMethodData');
521
    }
522
523
    /**
524
     * Set the 3DsRequestAuthenticationMethodData field
525
     *
526
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthData field in the Redsys
527
     * documentation.
528
     *
529
     * @param null|string $value
530
     * @return self
531
     */
532
    public function set3DsRequestAuthenticationMethodData($value)
533
    {
534
        return $this->setParameter('3DsRequestAuthenticationMethodData', $value);
535
    }
536
537
    /**
538
     * Get the 3DsRequestAuthenticationMethod field
539
     *
540
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthMethod field in Redsys
541
     * documentation.
542
     *
543
     * @return null|string One of the self::ACCOUNT_AUTHENTICATION_METHOD_* constants.
544
     */
545
    public function get3DsRequestAuthenticationMethod()
546
    {
547
        return $this->getParameter('3DsRequestAuthenticationMethod');
548
    }
549
550
    /**
551
     * Set the 3DsRequestAuthenticationMethod field
552
     *
553
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthMethod field in the Redsys
554
     * documentation.
555
     *
556
     * @param null|string $value One of the self::ACCOUNT_AUTHENTICATION_METHOD_* constants.
557
     * @return self
558
     * @throws InvalidRequestException if $value is invalid.
559
     */
560 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...
561
    {
562
        if (in_array(
563
            $value,
564
            [
565
                null,
566
                self::ACCOUNT_AUTHENTICATION_METHOD_NONE,
567
                self::ACCOUNT_AUTHENTICATION_METHOD_OWN_CREDENTIALS,
568
                self::ACCOUNT_AUTHENTICATION_METHOD_FEDERATED_ID,
569
                self::ACCOUNT_AUTHENTICATION_METHOD_ISSUER_CREDENTIALS,
570
                self::ACCOUNT_AUTHENTICATION_METHOD_THIRD_PARTY_AUTHENTICATION,
571
                self::ACCOUNT_AUTHENTICATION_METHOD_FIDO,
572
            ]
573
        )) {
574
            return $this->setParameter('3DsRequestAuthenticationMethod', $value);
575
        }
576
        throw new InvalidRequestException("Invalid 3DsRequestAuthenticationMethod parameter");
577
    }
578
579
    /**
580
     * Get the 3DsRequestAuthenticationTime field
581
     *
582
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthTimestamp field
583
     *
584
     * @return null|string
585
     */
586
    public function get3DsRequestAuthenticationTime()
587
    {
588
        return $this->getParameter('3DsRequestAuthenticationTime');
589
    }
590
591
    /**
592
     * Set the 3DsRequestAuthenticationTime field
593
     *
594
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthTimestamp field
595
     *
596
     * @param null|DateTime|int $value
597
     * @return self
598
     */
599
    public function set3DsRequestAuthenticationTime($value)
600
    {
601
        return $this->setParameter('3DsRequestAuthenticationTime', $this->formatDateTime($value, "YmdHi"));
602
    }
603
604
    /**
605
     * Get the customerAccountCreatedIndicator field
606
     *
607
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccAgeInd field
608
     *
609
     * @return null|string One of the CUSTOMER_ACCOUNT_CREATED_* constants
610
     */
611
    public function getCustomerAccountCreatedIndicator()
612
    {
613
        return $this->getParameter('customerAccountCreatedIndicator');
614
    }
615
616
    /**
617
     * Set the customerAccountCreatedIndicator field
618
     *
619
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccAgeInd field
620
     *
621
     * @param null|string $value One of the CUSTOMER_ACCOUNT_CREATED_* constants
622
     * @return self
623
     * @throws InvalidRequestException if $value is invalid.
624
     */
625
    public function setCustomerAccountCreatedIndicator($value)
626
    {
627
        if (in_array(
628
            $value,
629
            [
630
                null,
631
                self::CUSTOMER_ACCOUNT_CREATED_NONE,
632
                self::CUSTOMER_ACCOUNT_CREATED_THIS_TRANSACTION,
633
                self::CUSTOMER_ACCOUNT_CREATED_LAST_30_DAYS,
634
                self::CUSTOMER_ACCOUNT_CREATED_LAST_60_DAYS,
635
                self::CUSTOMER_ACCOUNT_CREATED_MORE_THAN_60_DAYS,
636
            ]
637
        )) {
638
            return $this->setParameter('customerAccountCreatedIndicator', $value);
639
        }
640
        throw new InvalidRequestException("Invalid customerAccountCreatedIndicator parameter");
641
    }
642
643
    /**
644
     * Get the customerAccountCreatedDate field
645
     *
646
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccDate field
647
     *
648
     * @return null|string
649
     */
650
    public function getCustomerAccountCreatedDate()
651
    {
652
        return $this->getParameter('customerAccountCreatedDate');
653
    }
654
655
    /**
656
     * Set the customerAccountCreatedDate field
657
     *
658
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccDate field
659
     *
660
     * @param null|DateTime|int $value
661
     * @return self
662
     */
663
    public function setCustomerAccountCreatedDate($value)
664
    {
665
        return $this->setParameter('customerAccountCreatedDate', $this->formatDateTime($value, "Ymd"));
666
    }
667
668
    /**
669
     * Get the customerAccountChangedIndicator field
670
     *
671
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccChangeInd field
672
     *
673
     * @return null|string One of the CUSTOMER_ACCOUNT_MODIFIED_* constants
674
     */
675
    public function getCustomerAccountChangedIndicator()
676
    {
677
        return $this->getParameter('customerAccountChangedIndicator');
678
    }
679
680
    /**
681
     * Set the customerAccountChangedIndicator field
682
     *
683
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccChangeInd field
684
     *
685
     * @param null|string $value One of the CUSTOMER_ACCOUNT_MODIFIED_* constants
686
     * @return self
687
     * @throws InvalidRequestException if $value is invalid.
688
     */
689
    public function setCustomerAccountChangedIndicator($value)
690
    {
691
        if (in_array(
692
            $value,
693
            [
694
                null,
695
                self::CUSTOMER_ACCOUNT_MODIFIED_THIS_TRANSACTION,
696
                self::CUSTOMER_ACCOUNT_MODIFIED_LAST_30_DAYS,
697
                self::CUSTOMER_ACCOUNT_MODIFIED_LAST_60_DAYS,
698
                self::CUSTOMER_ACCOUNT_MODIFIED_MORE_THAN_60_DAYS,
699
            ]
700
        )) {
701
            return $this->setParameter('customerAccountChangedIndicator', $value);
702
        }
703
        throw new InvalidRequestException("Invalid customerAccountChangedIndicator parameter");
704
    }
705
706
    /**
707
     * Get the customerAccountChangedDate field
708
     *
709
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccChange field
710
     *
711
     * @return null|string
712
     */
713
    public function getCustomerAccountChangedDate()
714
    {
715
        return $this->getParameter('customerAccountChangedDate');
716
    }
717
718
    /**
719
     * Set the customerAccountChangedDate field
720
     *
721
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccChange field
722
     *
723
     * @param null|DateTime|int $value
724
     * @return self
725
     */
726
    public function setCustomerAccountChangedDate($value)
727
    {
728
        return $this->setParameter('customerAccountChangedDate', $this->formatDateTime($value, "Ymd"));
729
    }
730
731
    /**
732
     * Get the customerPasswordAgeIndicator field
733
     *
734
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccPwChangeInd field
735
     *
736
     * @return null|string One of the CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_* constants
737
     */
738
    public function getCustomerPasswordChangedIndicator()
739
    {
740
        return $this->getParameter('customerPasswordAgeIndicator');
741
    }
742
743
    /**
744
     * Set the customerPasswordAgeIndicator field
745
     *
746
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccPwChangeInd field
747
     *
748
     * @param null|string $value One of the CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_* constants
749
     * @return self
750
     * @throws InvalidRequestException if $value is invalid.
751
     */
752
    public function setCustomerPasswordChangedIndicator($value)
753
    {
754
        if (in_array(
755
            $value,
756
            [
757
                null,
758
                self::CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_NONE,
759
                self::CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_THIS_TRANSACTION,
760
                self::CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_LAST_30_DAYS,
761
                self::CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_LAST_60_DAYS,
762
                self::CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_MORE_THAN_60_DAYS,
763
            ]
764
        )) {
765
            return $this->setParameter('customerPasswordAgeIndicator', $value);
766
        }
767
        throw new InvalidRequestException("Invalid customerPasswordAgeIndicator parameter");
768
    }
769
770
    /**
771
     * Get the customerPasswordChangedDate field
772
     *
773
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccPwChange field
774
     *
775
     * @return null|string
776
     */
777
    public function getCustomerPasswordChangedDate()
778
    {
779
        return $this->getParameter('customerPasswordChangedDate');
780
    }
781
782
    /**
783
     * Set the customerPasswordChangedDate field
784
     *
785
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccPwChange field
786
     *
787
     * @param null|DateTime|int $value
788
     * @return self
789
     */
790
    public function setCustomerPasswordChangedDate($value)
791
    {
792
        return $this->setParameter('customerPasswordChangedDate', $this->formatDateTime($value, "Ymd"));
793
    }
794
795
    /**
796
     * Get the customerPurchasesInLast6Months field
797
     *
798
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.nbPurchaseAccount field
799
     *
800
     * @return null|int
801
     */
802
    public function getCustomerPurchasesInLast6Months()
803
    {
804
        return $this->getParameter('customerPurchasesInLast6Months');
805
    }
806
807
    /**
808
     * Set the customerPurchasesInLast6Months field
809
     *
810
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.nbPurchaseAccount field
811
     *
812
     * @param null|int $value
813
     * @return self
814
     */
815
    public function setCustomerPurchasesInLast6Months($value)
816
    {
817
        return $this->setParameter('customerPurchasesInLast6Months', $value);
818
    }
819
820
    /**
821
     * Get the customerAccountCardProvisionsLast24Hours field
822
     *
823
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.provisionAttemptsDay field
824
     *
825
     * @return null|int
826
     */
827
    public function getCustomerAccountCardProvisionsLast24Hours()
828
    {
829
        return $this->getParameter('customerAccountCardProvisionsLast24Hours');
830
    }
831
832
    /**
833
     * Set the customerAccountCardProvisionsLast24Hours field
834
     *
835
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.provisionAttemptsDay field
836
     *
837
     * @param null|int $value
838
     * @return self
839
     */
840
    public function setCustomerAccountCardProvisionsLast24Hours($value)
841
    {
842
        return $this->setParameter('customerAccountCardProvisionsLast24Hours', $value);
843
    }
844
845
    /**
846
     * Get the customerAccountTransactionsLast24Hours field
847
     *
848
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.txnActivityDay field
849
     *
850
     * @return null|int
851
     */
852
    public function getCustomerAccountTransactionsLast24Hours()
853
    {
854
        return $this->getParameter('customerAccountTransactionsLast24Hours');
855
    }
856
857
    /**
858
     * Set the customerAccountTransactionsLast24Hours field
859
     *
860
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.txnActivityDay field
861
     *
862
     * @param null|int $value
863
     * @return self
864
     */
865
    public function setCustomerAccountTransactionsLast24Hours($value)
866
    {
867
        return $this->setParameter('customerAccountTransactionsLast24Hours', $value);
868
    }
869
870
    /**
871
     * Get the customerAccountTransactionsLastYear field
872
     *
873
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.txnActivityYear field
874
     *
875
     * @return null|int
876
     */
877
    public function getCustomerAccountTransactionsLastYear()
878
    {
879
        return $this->getParameter('customerAccountTransactionsLastYear');
880
    }
881
882
    /**
883
     * Set the customerAccountTransactionsLastYear field
884
     *
885
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.txnActivityYear field
886
     *
887
     * @param null|int $value
888
     * @return self
889
     */
890
    public function setCustomerAccountTransactionsLastYear($value)
891
    {
892
        return $this->setParameter('customerAccountTransactionsLastYear', $value);
893
    }
894
895
    /**
896
     * Get the customerPaymentMethodCreatedIndicator field
897
     *
898
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.paymentAccInd field
899
     *
900
     * @return null|string One of the PAYMENT_METHOD_CREATED_* constants
901
     */
902
    public function getCustomerPaymentMethodCreatedIndicator()
903
    {
904
        return $this->getParameter('customerPaymentMethodCreatedIndicator');
905
    }
906
907
    /**
908
     * Set the customerPaymentMethodCreatedIndicator field
909
     *
910
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.paymentAccInd field
911
     *
912
     * @param null|string $value One of the PAYMENT_METHOD_CREATED_* constants
913
     * @return self
914
     * @throws InvalidRequestException if $value is invalid.
915
     */
916
    public function setCustomerPaymentMethodCreatedIndicator($value)
917
    {
918
        if (in_array(
919
            $value,
920
            [
921
                null,
922
                self::PAYMENT_METHOD_CREATED_NONE,
923
                self::PAYMENT_METHOD_CREATED_THIS_TRANSACTION,
924
                self::PAYMENT_METHOD_CREATED_LAST_30_DAYS,
925
                self::PAYMENT_METHOD_CREATED_LAST_60_DAYS,
926
                self::PAYMENT_METHOD_CREATED_MORE_THAN_60_DAYS,
927
            ]
928
        )) {
929
            return $this->setParameter('customerPaymentMethodCreatedIndicator', $value);
930
        }
931
        throw new InvalidRequestException("Invalid customerPaymentMethodCreatedIndicator parameter");
932
    }
933
934
    /**
935
     * Get the customerPaymentMethodCreatedDate field
936
     *
937
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.paymentAccAge field
938
     *
939
     * @return null|string
940
     */
941
    public function getCustomerPaymentMethodCreatedDate()
942
    {
943
        return $this->getParameter('customerPaymentMethodCreatedDate');
944
    }
945
946
    /**
947
     * Set the customerPaymentMethodCreatedDate field
948
     *
949
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.paymentAccAge field
950
     *
951
     * @param null|DateTime|int $value
952
     * @return self
953
     */
954
    public function setCustomerPaymentMethodCreatedDate($value)
955
    {
956
        return $this->setParameter('customerPaymentMethodCreatedDate', $this->formatDateTime($value, "Ymd"));
957
    }
958
959
    /**
960
     * Get the shippingAddressFirstUsedIndicator field
961
     *
962
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipAddressUsageInd field
963
     *
964
     * @return null|string One of the SHIPPING_ADDRESS_USAGE_* constants
965
     */
966
    public function getShippingAddressFirstUsedIndicator()
967
    {
968
        return $this->getParameter('shippingAddressFirstUsedIndicator');
969
    }
970
971
    /**
972
     * Set the shippingAddressFirstUsedIndicator field
973
     *
974
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipAddressUsageInd field
975
     *
976
     * @param null|string $value One of the SHIPPING_ADDRESS_USAGE_* constants
977
     * @return self
978
     * @throws InvalidRequestException if $value is invalid.
979
     */
980
    public function setShippingAddressFirstUsedIndicator($value)
981
    {
982
        if (in_array(
983
            $value,
984
            [
985
                null,
986
                self::SHIPPING_ADDRESS_USAGE_THIS_TRANSACTION,
987
                self::SHIPPING_ADDRESS_USAGE_LAST_30_DAYS,
988
                self::SHIPPING_ADDRESS_USAGE_LAST_60_DAYS,
989
                self::SHIPPING_ADDRESS_USAGE_MORE_THAN_60_DAYS,
990
            ]
991
        )) {
992
            return $this->setParameter('shippingAddressFirstUsedIndicator', $value);
993
        }
994
        throw new InvalidRequestException("Invalid shippingAddressFirstUsedIndicator parameter");
995
    }
996
997
    /**
998
     * Get the shippingAddressFirstUsedDate field
999
     *
1000
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipAddressUsage field
1001
     *
1002
     * @return null|string
1003
     */
1004
    public function getShippingAddressFirstUsedDate()
1005
    {
1006
        return $this->getParameter('shippingAddressFirstUsedDate');
1007
    }
1008
1009
    /**
1010
     * Set the shippingAddressFirstUsedDate field
1011
     *
1012
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipAddressUsage field
1013
     *
1014
     * @param null|DateTime|int $value
1015
     * @return self
1016
     */
1017
    public function setShippingAddressFirstUsedDate($value)
1018
    {
1019
        return $this->setParameter('shippingAddressFirstUsedDate', $this->formatDateTime($value, "Ymd"));
1020
    }
1021
1022
    /**
1023
     * Get the shippingNameCustomerNameMatch field
1024
     *
1025
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipNameIndicator field
1026
     *
1027
     * @return null|boolean
1028
     */
1029
    public function getShippingNameCustomerNameMatch()
1030
    {
1031
        return $this->getParameter('shippingNameCustomerNameMatch');
1032
    }
1033
1034
    /**
1035
     * Set the shippingNameCustomerNameMatch field
1036
     *
1037
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipNameIndicator field
1038
     *
1039
     * @param null|boolean $value
1040
     * @return self
1041
     */
1042
    public function setShippingNameCustomerNameMatch($value)
1043
    {
1044
        return $this->setParameter('shippingNameCustomerNameMatch', $value);
1045
    }
1046
1047
    /**
1048
     * Get the customerHasSuspiciousActivity field
1049
     *
1050
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.suspiciousAccActivity field
1051
     *
1052
     * @return null|boolean
1053
     */
1054
    public function getCustomerHasSuspiciousActivity()
1055
    {
1056
        return $this->getParameter('customerHasSuspiciousActivity');
1057
    }
1058
1059
    /**
1060
     * Set the customerHasSuspiciousActivity field
1061
     *
1062
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.suspiciousAccActivity field
1063
     *
1064
     * @param null|boolean $value
1065
     * @return self
1066
     */
1067
    public function setCustomerHasSuspiciousActivity($value)
1068
    {
1069
        return $this->setParameter('customerHasSuspiciousActivity', $value);
1070
    }
1071
1072
    /**
1073
     * Get the deliveryEmail field
1074
     *
1075
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.deliveryEmailAddress field
1076
     *
1077
     * @return null|string
1078
     */
1079
    public function getDeliveryEmail()
1080
    {
1081
        return $this->getParameter('deliveryEmail');
1082
    }
1083
1084
    /**
1085
     * Set the deliveryEmail field
1086
     *
1087
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.deliveryEmailAddress field
1088
     *
1089
     * @param null|string $value
1090
     * @return self
1091
     */
1092
    public function setDeliveryEmail($value)
1093
    {
1094
        return $this->setParameter('deliveryEmail', $value);
1095
    }
1096
1097
    /**
1098
     * Get the deliveryTimeframeIndicator field
1099
     *
1100
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.deliveryTimeframe field
1101
     *
1102
     * @return null|string One of the DELIVERY_TIMEFRAME_* constants
1103
     */
1104
    public function getDeliveryTimeframeIndicator()
1105
    {
1106
        return $this->getParameter('deliveryTimeframeIndicator');
1107
    }
1108
1109
    /**
1110
     * Set the deliveryTimeframeIndicator field
1111
     *
1112
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.deliveryTimeframe field
1113
     *
1114
     * @param null|string $value One of the DELIVERY_TIMEFRAME_* constants
1115
     * @return self
1116
     * @throws InvalidRequestException if $value is invalid.
1117
     */
1118
    public function setDeliveryTimeframeIndicator($value)
1119
    {
1120
        if (in_array(
1121
            $value,
1122
            [
1123
                null,
1124
                self::DELIVERY_TIMEFRAME_ELECTRONIC_DELIVERY,
1125
                self::DELIVERY_TIMEFRAME_SAME_DAY,
1126
                self::DELIVERY_TIMEFRAME_NEXT_DAY,
1127
                self::DELIVERY_TIMEFRAME_2_OR_MORE_DAYS,
1128
            ]
1129
        )) {
1130
            return $this->setParameter('deliveryTimeframeIndicator', $value);
1131
        }
1132
        throw new InvalidRequestException("Invalid deliveryTimeframeIndicator parameter");
1133
    }
1134
1135
    /**
1136
     * Get the giftCardAmount field
1137
     *
1138
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardAmount field
1139
     *
1140
     * @return null|int
1141
     */
1142
    public function getGiftCardAmount()
1143
    {
1144
        return $this->getParameter('giftCardAmount');
1145
    }
1146
1147
    /**
1148
     * Set the giftCardAmount field
1149
     *
1150
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardAmount field
1151
     *
1152
     * @param null|int $value
1153
     * @return self
1154
     */
1155
    public function setGiftCardAmount($value)
1156
    {
1157
        return $this->setParameter('giftCardAmount', $value);
1158
    }
1159
1160
    /**
1161
     * Get the giftCardCount field
1162
     *
1163
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardCount field
1164
     *
1165
     * @return null|int
1166
     */
1167
    public function getGiftCardCount()
1168
    {
1169
        return $this->getParameter('giftCardCount');
1170
    }
1171
1172
    /**
1173
     * Set the giftCardCount field
1174
     *
1175
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardCount field
1176
     *
1177
     * @param null|int $value
1178
     * @return self
1179
     */
1180
    public function setGiftCardCount($value)
1181
    {
1182
        return $this->setParameter('giftCardCount', $value);
1183
    }
1184
1185
    /**
1186
     * Get the giftCardCurrency field
1187
     *
1188
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardCurr field
1189
     *
1190
     * @return null|string ISO-4217 currency code
1191
     */
1192
    public function getGiftCardCurrency()
1193
    {
1194
        return $this->getParameter('giftCardCurrency');
1195
    }
1196
1197
    /**
1198
     * Set the giftCardCurrency field
1199
     *
1200
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardCurr field
1201
     *
1202
     * @param null|string $value ISO-4217 currency code
1203
     * @return self
1204
     */
1205
    public function setGiftCardCurrency($value)
1206
    {
1207
        return $this->setParameter('giftCardCurrency', $value);
1208
    }
1209
1210
    /**
1211
     * Get the purchasingPreOrder field
1212
     *
1213
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.preOrderPurchaseInd field
1214
     *
1215
     * @return null|boolean True if the customer is purchasing a preorder
1216
     */
1217
    public function getPurchasingPreOrder()
1218
    {
1219
        return $this->getParameter('purchasingPreOrder');
1220
    }
1221
1222
    /**
1223
     * Set the purchasingPreOrder field
1224
     *
1225
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.preOrderPurchaseInd field
1226
     *
1227
     * @param null|boolean $value True if the customer is purchasing a preorder
1228
     * @return self
1229
     */
1230
    public function setPurchasingPreOrder($value)
1231
    {
1232
        return $this->setParameter('purchasingPreOrder', $value);
1233
    }
1234
1235
    /**
1236
     * Get the preOrderDate field
1237
     *
1238
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.preOrderDate field
1239
     *
1240
     * @return null|string
1241
     */
1242
    public function getPreOrderDate()
1243
    {
1244
        return $this->getParameter('preOrderDate');
1245
    }
1246
1247
    /**
1248
     * Set the preOrderDate field
1249
     *
1250
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.preOrderDate field
1251
     *
1252
     * @param null|DateTime|int $value
1253
     * @return self
1254
     */
1255
    public function setPreOrderDate($value)
1256
    {
1257
        return $this->setParameter('preOrderDate', $this->formatDateTime($value, "Ymd"));
1258
    }
1259
1260
    /**
1261
     * Get the customerHasPurchasedProductBefore field
1262
     *
1263
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.reorderItemsInd field
1264
     *
1265
     * @return null|boolean
1266
     */
1267
    public function getCustomerHasPurchasedProductBefore()
1268
    {
1269
        return $this->getParameter('customerHasPurchasedProductBefore');
1270
    }
1271
1272
    /**
1273
     * Set the customerHasPurchasedProductBefore field
1274
     *
1275
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.reorderItemsInd field
1276
     *
1277
     * @param null|boolean $value
1278
     * @return self
1279
     */
1280
    public function setCustomerHasPurchasedProductBefore($value)
1281
    {
1282
        return $this->setParameter('customerHasPurchasedProductBefore', $value);
1283
    }
1284
1285
    /**
1286
     * Get the shippingAddressIndicator field
1287
     *
1288
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.shipIndicator field
1289
     *
1290
     * @return null|string One of the self::SHIPPING_* constants
1291
     */
1292
    public function getShippingAddressIndicator()
1293
    {
1294
        return $this->getParameter('shippingAddressIndicator');
1295
    }
1296
1297
    /**
1298
     * Set the shippingAddressIndicator field
1299
     *
1300
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.shipIndicator field
1301
     *
1302
     * @param null|string $value One of the self::SHIPPING_* constants
1303
     * @return self
1304
     * @throws InvalidRequestException if $value is invalid.
1305
     */
1306 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...
1307
    {
1308
        if (in_array(
1309
            $value,
1310
            [
1311
                null,
1312
                self::SHIPPING_TO_BILLING_ADDRESS,
1313
                self::SHIPPING_TO_ANOTHER_VERIFIED_ADDRESS,
1314
                self::SHIPPING_DIFFERENT_BILLING_ADDRESS,
1315
                self::SHIPPING_PICK_UP,
1316
                self::SHIPPING_DIGITAL,
1317
                self::SHIPPING_TRAVEL,
1318
                self::SHIPPING_OTHER,
1319
            ]
1320
        )) {
1321
            return $this->setParameter('shippingAddressIndicator', $value);
1322
        }
1323
        throw new InvalidRequestException("Invalid shippingAddressIndicator parameter");
1324
    }
1325
1326
    /**
1327
     * Get the SCA exemption field
1328
     *
1329
     * Corresponds to the Ds_Merchant_Excep_Sca field
1330
     *
1331
     * @return null|string One of the self::SCA_EXEMPTION_* constants
1332
     */
1333
    public function getScaExemptionIndicator()
1334
    {
1335
        return $this->getParameter('scaExemptionIndicator');
1336
    }
1337
1338
    /**
1339
     * Set the SCA exemption field
1340
     *
1341
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.shipIndicator field
1342
     *
1343
     * @param null|string $value One of the self::SCA_EXEMPTION_* constants
1344
     * @return self
1345
     * @throws InvalidRequestException if $value is invalid.
1346
     */
1347
    public function setScaExemptionIndicator($value)
1348
    {
1349
        if (in_array(
1350
            $value,
1351
            [
1352
                null,
1353
                self::SCA_EXEMPTION_LOW_AMOUNT,
1354
                self::SCA_EXEMPTION_LOW_RISK,
1355
                self::SCA_EXEMPTION_CORPORATE,
1356
                self::SCA_EXEMPTION_MERCHANT_INITIATED,
1357
            ]
1358
        )) {
1359
            return $this->setParameter('scaExemptionIndicator', $value);
1360
        }
1361
        throw new InvalidRequestException("Invalid scaExemptionIndicator parameter");
1362
    }
1363
1364
    /**
1365
     * Override the abstract method to add requirement that it must start with 4 numeric characters
1366
     *
1367
     * @param string|int $value The transaction ID (merchant order) to set for the transaction
1368
     */
1369
    public function setTransactionId($value)
1370
    {
1371
        $start = substr($value, 0, 4);
1372
        $numerics = 0;
1373
        foreach (str_split($start) as $char) {
1374
            if (is_numeric($char)) {
1375
                $numerics++;
1376
            } else {
1377
                break;
1378
            }
1379
        }
1380
        $value = str_pad(substr($start, 0, $numerics), 4, 0, STR_PAD_LEFT).substr($value, $numerics);
1381
1382
        parent::setTransactionId($value);
1383
    }
1384
1385
    /**
1386
     * Get the basic data fields that don't require any 3DS/SCA fields
1387
     */
1388
    public function getBaseData()
1389
    {
1390
        $this->validate('merchantId', 'terminalId', 'amount', 'currency');
1391
1392
        return [
1393
            // mandatory fields
1394
            'Ds_Merchant_MerchantCode'       => $this->getMerchantId(),
1395
            'Ds_Merchant_Terminal'           => $this->getTerminalId(),
1396
            'Ds_Merchant_TransactionType'    => '0',                          // Authorisation
1397
            'Ds_Merchant_Amount'             => $this->getAmountInteger(),
1398
            'Ds_Merchant_Currency'           => $this->getCurrencyNumeric(),  // uses ISO-4217 codes
1399
            'Ds_Merchant_Order'              => $this->getTransactionId(),
1400
            'Ds_Merchant_MerchantUrl'        => $this->getNotifyUrl(),
1401
            // optional fields
1402
            'Ds_Merchant_ProductDescription' => $this->getDescription(),
1403
            'Ds_Merchant_Cardholder'         => $this->getCardholder(),
1404
            'Ds_Merchant_UrlOK'              => $this->getReturnUrl(),
1405
            'Ds_Merchant_UrlKO'              => $this->getReturnUrl(),
1406
            'Ds_Merchant_MerchantName'       => $this->getMerchantName(),
1407
            'Ds_Merchant_ConsumerLanguage'   => $this->getConsumerLanguage(),
1408
            'Ds_Merchant_MerchantData'       => $this->getMerchantData(),
1409
        ];
1410
    }
1411
1412
    public function get3DSAccountInfoData()
1413
    {
1414
        $data = array_filter([
1415
            'chAccAgeInd'           => $this->getCustomerAccountCreatedIndicator(),
1416
            'chAccDate'             => $this->getCustomerAccountCreatedDate(),
1417
            'chAccChangeInd'        => $this->getCustomerAccountChangedIndicator(),
1418
            'chAccChange'           => $this->getCustomerAccountChangedDate(),
1419
            'chAccPwChangeInd'      => $this->getCustomerPasswordChangedIndicator(),
1420
            'chAccPwChange'         => $this->getCustomerPasswordChangedDate(),
1421
            'paymentAccInd'         => $this->getCustomerPaymentMethodCreatedIndicator(),
1422
            'paymentAccAge'         => $this->getCustomerPaymentMethodCreatedDate(),
1423
            'shipAddressUsageInd'   => $this->getShippingAddressFirstUsedIndicator(),
1424
            'shipAddressUsage'      => $this->getShippingAddressFirstUsedDate(),
1425
        ]);
1426
        // checks that can't rely on a simple filter (which could remove or add values unintentionally)
1427
        if ($this->getShippingNameCustomerNameMatch() !== null) {
1428
            $data['shipNameIndicator'] = $this->getShippingNameCustomerNameMatch() ? "01" : "02";
1429
        }
1430
        if ($this->getCustomerHasSuspiciousActivity() !== null) {
1431
            $data['suspiciousAccActivity'] = $this->getCustomerHasSuspiciousActivity() ? "02" : "01";
1432
        }
1433
        if ($this->getCustomerPurchasesInLast6Months() !== null) {
1434
            $data['nbPurchaseAccount'] = $this->getCustomerPurchasesInLast6Months();
1435
        }
1436
        if ($this->getCustomerAccountCardProvisionsLast24Hours() !== null) {
1437
            $data['provisionAttemptsDay'] = $this->getCustomerAccountCardProvisionsLast24Hours();
1438
        }
1439
        if ($this->getCustomerAccountTransactionsLast24Hours() !== null) {
1440
            $data['txnActivityDay'] = $this->getCustomerAccountTransactionsLast24Hours();
1441
        }
1442
        if ($this->getCustomerAccountTransactionsLastYear() !== null) {
1443
            $data['txnActivityYear'] = $this->getCustomerAccountTransactionsLastYear();
1444
        }
1445
1446
        return $data;
1447
    }
1448
1449
    public function getMerchantRiskData()
1450
    {
1451
        $data = array_filter([
1452
            'deliveryEmailAddress' => $this->getDeliveryEmail(),
1453
            'deliveryTimeframe'    => $this->getDeliveryTimeframeIndicator(),
1454
            'giftCardCount'        => $this->getGiftCardCount(),
1455
            'giftCardCurr'         => $this->getGiftCardCurrency(),
1456
            'preOrderDate'         => $this->getPreOrderDate(),
1457
            'shipIndicator'        => $this->getShippingAddressIndicator(),
1458
        ]);
1459
        if ($this->getGiftCardAmount() !== null) {
1460
            $data['giftCardAmount'] = (int) $this->getGiftCardAmount();
1461
        }
1462
        if ($this->getPurchasingPreOrder() !== null) {
1463
            $data['preOrderPurchaseInd'] = $this->getPurchasingPreOrder() ? "02" : "01";
1464
        }
1465
        if ($this->getCustomerHasPurchasedProductBefore() !== null) {
1466
            $data['reorderItemsInd'] = $this->getCustomerHasPurchasedProductBefore() ? "02" : "01";
1467
        }
1468
1469
        return $data;
1470
    }
1471
1472
    public function getData()
1473
    {
1474
        $data = $this->getBaseData();
1475
        if ($this->getScaExemptionIndicator() !== null) {
1476
            $data['Ds_Merchant_Excep_Sca'] = $this->getScaExemptionIndicator();
1477
        }
1478
1479
        // only generate an EMV 3DS request if requested to
1480
        if ($this->getUse3DS()) {
1481
            // Validating the presence of the card under the assumption that at least an address is required
1482
            // NOTE: normally would validate() for other submission params, but the minimum depends on bank contract
1483
            $this->validate('card');
1484
            $card = $this->getCard();
1485
1486
            $homePhone = array_filter([
1487
                'cc'         => $this->getHomePhoneCountryPrefix(),
1488
                'subscriber' => $this->getHomePhone(),
1489
            ]);
1490
            $mobilePhone = array_filter([
1491
                'cc'         => $this->getMobilePhoneCountryPrefix(),
1492
                'subscriber' => $this->getMobilePhone(),
1493
            ]);
1494
            $workPhone = array_filter([
1495
                'cc'         => $this->getWorkPhoneCountryPrefix(),
1496
                'subscriber' => $this->getWorkPhone(),
1497
            ]);
1498
            $threeDSAuthInfo = array_filter([
1499
                'threeDSReqAuthData'      => $this->get3DsRequestAuthenticationMethodData(),
1500
                'threeDSReqAuthMethod'    => $this->get3DsRequestAuthenticationMethod(),
1501
                'threeDSReqAuthTimestamp' => $this->get3DsRequestAuthenticationTime(),
1502
            ]);
1503
            $emv3DsParameters = array_filter([
1504
                'cardholderName'                     => $this->getCardholder(),
1505
                'email'                              => $card->getEmail(),
1506
                'homePhone'                          => $homePhone,
1507
                'mobilePhone'                        => $mobilePhone,
1508
                'workPhone'                          => $workPhone,
1509
                'shipAddrLine1'                      => $card->getShippingAddress1(),
1510
                'shipAddrLine2'                      => $card->getShippingAddress2(),
1511
                'shipAddrLine3'                      => $card->getShippingAddress3(),
1512
                'shipAddrCity'                       => $card->getShippingCity(),
1513
                'shipAddrPostCode'                   => $card->getShippingPostcode(),
1514
                'shipAddrState'                      => $card->getShippingState(),
1515
                'shipAddrCountry'                    => $card->getShippingCountry(),
1516
                'billAddrLine1'                      => $card->getBillingAddress1(),
1517
                'billAddrLine2'                      => $card->getBillingAddress2(),
1518
                'billAddrLine3'                      => $card->getBillingAddress3(),
1519
                'billAddrCity'                       => $card->getBillingCity(),
1520
                'billAddrPostCode'                   => $card->getBillingPostcode(),
1521
                'billAddrState'                      => $card->getBillingState(),
1522
                'billAddrCountry'                    => $card->getBillingCountry(),
1523
                'addrMatch'                          => $this->getAddressMatch(),
1524
                'challengeWindowSize'                => $this->getChallengeWindowSize(),
1525
                'acctID'                             => $this->getCustomerAdditionalInformation(),
1526
                'threeDSRequestorAuthenticationInfo' => $threeDSAuthInfo,
1527
            ]);
1528
1529
            $acctInfo = $this->get3DSAccountInfoData();
1530
            if ($acctInfo !== []) {
1531
                $emv3DsParameters['acctInfo'] = $acctInfo;
1532
            }
1533
1534
            $merchantRiskIndicator = $this->getMerchantRiskData();
1535
            if ($merchantRiskIndicator !== []) {
1536
                $emv3DsParameters['merchantRiskIndicator'] = $merchantRiskIndicator;
1537
            }
1538
1539
            if ($emv3DsParameters !== []) {
1540
                $data['Ds_Merchant_Emv3Ds'] = $emv3DsParameters;
1541
            }
1542
        }
1543
1544
        return $data;
1545
    }
1546
1547
    public function sendData($data)
1548
    {
1549
        $security = new Security;
1550
1551
        $encoded_data = $security->encodeMerchantParameters($data);
1552
1553
        $response_data = array(
1554
            'Ds_SignatureVersion'   => Security::VERSION,
1555
            'Ds_MerchantParameters' => $encoded_data,
1556
            'Ds_Signature'          => $security->createSignature(
1557
                $encoded_data,
1558
                $data['Ds_Merchant_Order'],
1559
                $this->getHmacKey()
1560
            ),
1561
        );
1562
1563
        return $this->response = new PurchaseResponse($this, $response_data);
1564
    }
1565
1566
    public function getEndpoint()
1567
    {
1568
        return $this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint;
1569
    }
1570
1571
    /**
1572
     * Convert a DateTime or timestamp to a formatted date.
1573
     *
1574
     * @param DateTime|int|null $date   The date to format.
1575
     * @param string            $format The format to use.
1576
     *
1577
     * @return string|null The formatted date, or null if date isn't a timestamp or DateTime object.
1578
     */
1579
    protected function formatDateTime($date, $format)
1580
    {
1581
        if (is_int($date)) {
1582
            return (new DateTime('@'.$date))->format($format);
1583
        } elseif ($date instanceof DateTime) {
1584
            return $date->setTimezone(new DateTimeZone('UTC'))->format($format);
1585
        }
1586
    }
1587
}
1588