Passed
Pull Request — master (#11)
by Leith
02:06
created

PurchaseRequest::getBrowserColorDepth()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 0
cp 0
crap 2
rs 10
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 $value 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 getDirectPayment()
181
    {
182 7
        return $this->getParameter('directPayment');
183
    }
184
185 1
    /**
186
     * Set the "directness" of payment
187
     *
188
     * Can be true (merchant initiated), false/null (customer initiated) or "MOTO" (usually call centre initiated)
189
     * Invalid values will be converted to null as that's the most secure option
190
     *
191
     * @param null|bool|string $value
192
     */
193
    public function setDirectPayment($value)
194
    {
195
        if (is_bool($value)) {
196
            // this is fine
197
        } elseif (is_string($value)) {
198
            if (strtoupper($value) == "TRUE") {
199
                $value = true;
200
            } elseif (strtoupper($value) == "FALSE") {
201
                $value = false;
202
            } elseif (strtoupper($value) == "MOTO") {
203
                $value = "MOTO";
204
            } else {
205
                // something invalid
206
                $value = null;
207
            }
208
        } else {
209
            // something invalid
210
            $value = null;
211
        }
212
        return $this->setParameter('directPayment', $value);
213
    }
214
215
    public function getHmacKey()
216
    {
217
        return $this->getParameter('hmacKey');
218
    }
219
220
    public function setHmacKey($value)
221
    {
222
        return $this->setParameter('hmacKey', $value);
223
    }
224
225
    public function getMerchantData()
226
    {
227
        return $this->getParameter('merchantData');
228
    }
229
230
    public function setMerchantData($value)
231
    {
232
        return $this->setParameter('merchantData', $value);
233
    }
234
235
    public function getMerchantId()
236
    {
237
        return $this->getParameter('merchantId');
238
    }
239
240
    public function setMerchantId($value)
241
    {
242
        return $this->setParameter('merchantId', $value);
243
    }
244
245
    public function getMerchantName()
246
    {
247
        return $this->getParameter('merchantName');
248
    }
249
250
    public function setMerchantName($value)
251
    {
252
        return $this->setParameter('merchantName', $value);
253
    }
254
255
    public function getTerminalId()
256
    {
257
        return $this->getParameter('terminalId');
258
    }
259
260
    public function setTerminalId($value)
261
    {
262
        return $this->setParameter('terminalId', $value);
263
    }
264
265
    /**
266
     * Get the protocolVersion field
267
     * Corresponds to the Ds_Merchant_Emv3Ds.protocolVersion. field in Redsys documentation.
268
     *
269
     * @return null|string
270
     *
271
     */
272
    public function getProtocolVersion()
273
    {
274
        return $this->getParameter('protocolVersion');
275
    }
276
277
    /**
278
     * Set the protocolVersion field
279
     *
280
     * Corresponds to the Ds_Merchant_Emv3Ds.protocolVersion field
281
     *
282
     * @param null|string $value
283
     * @return self
284
     */
285
    public function setProtocolVersion($value)
286
    {
287
        return $this->setParameter('protocolVersion', $value);
288
    }
289
290
    /**
291
     * Get the use3ds field
292
     *
293
     * Controls the presence of the Ds_Merchant_Emv3Ds structure
294
     *
295
     * @return bool
296
     */
297
    public function getUse3DS()
298
    {
299
        return (bool) $this->getParameter('use3ds');
300
    }
301
302
    /**
303
     * Set the use3ds field
304
     *
305
     * Controls the presence of the Ds_Merchant_Emv3Ds structure
306
     *
307
     * @param bool $value
308
     * @return self
309
     */
310
    public function setUse3DS($value)
311
    {
312
        return $this->setParameter('use3ds', $value);
313
    }
314
315
    /**
316
     * Get the threeDSCompInd field, which indicates whether the 3DSMethod has been executed
317
     *
318
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSCompInd field in Redsys documentation.
319
     *
320
     * @return null|string Y = Successfully completed, N = Completed with errors, U = 3DSMethod not executed
321
     */
322
    public function getThreeDSCompInd()
323
    {
324
        return $this->getParameter('threeDSCompInd');
325
    }
326
327
    /**
328
     * Set the threeDSCompInd field
329
     *
330
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSCompInd field
331
     *
332
     * @param null|string $value
333
     * @return self
334
     */
335
    public function setThreeDSCompInd($value)
336
    {
337
        return $this->setParameter('threeDSCompInd', $value);
338
    }
339
340
    /**
341
     * Get the threeDSInfo field (the type of request)
342
     *
343
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSInfo field in Redsys documentation.
344
     *
345
     * @return null|string Possible values: CardData, AuthenticationData, ChallengeResponse
346
     */
347
    public function getThreeDSInfo()
348
    {
349
        return $this->getParameter('threeDSInfo');
350
    }
351
352
    /**
353
     * Set the threeDSInfo field
354
     *
355
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSInfo field
356
     *
357
     * @param null|string $value
358
     * @return self
359
     */
360
    public function setThreeDSInfo($value)
361
    {
362
        return $this->setParameter('threeDSInfo', $value);
363
    }
364
365
    /**
366
     * Get the homePhoneCountryPrefix field
367
     *
368
     * Corresponds to the Ds_Merchant_Emv3Ds.homePhone.cc field
369
     *
370
     * @return null|string
371
     */
372
    public function getHomePhoneCountryPrefix()
373
    {
374
        return $this->getParameter('homePhoneCountryPrefix');
375
    }
376
377
    /**
378
     * Set the homePhoneCountryPrefix field
379
     *
380
     * Corresponds to the Ds_Merchant_Emv3Ds.homePhone.cc field
381
     *
382
     * @param null|string $value
383
     * @return self
384
     */
385
    public function setHomePhoneCountryPrefix($value)
386
    {
387
        return $this->setParameter('homePhoneCountryPrefix', $value);
388
    }
389
390
    /**
391
     * Get the homePhone field
392
     *
393
     * Corresponds to the Ds_Merchant_Emv3Ds.homePhone.subscriber field
394
     *
395
     * @return null|string
396
     */
397
    public function getHomePhone()
398
    {
399
        return $this->getParameter('homePhone');
400
    }
401
402
    /**
403
     * Set the homePhone field
404
     *
405
     * Corresponds to the Ds_Merchant_Emv3Ds.homePhone.subscriber field
406
     *
407
     * @param null|string $value
408
     * @return self
409
     */
410
    public function setHomePhone($value)
411
    {
412
        return $this->setParameter('homePhone', $value);
413
    }
414
415
    /**
416
     * Get the mobilePhoneCountryPrefix field
417
     *
418
     * Corresponds to the Ds_Merchant_Emv3Ds.mobilePhone.cc field
419
     *
420
     * @return null|string
421
     */
422
    public function getMobilePhoneCountryPrefix()
423
    {
424
        return $this->getParameter('mobilePhoneCountryPrefix');
425
    }
426
427
    /**
428
     * Set the mobilePhoneCountryPrefix field
429
     *
430
     * Corresponds to the Ds_Merchant_Emv3Ds.mobilePhone.cc field
431
     *
432
     * @param null|string $value
433
     * @return self
434
     */
435
    public function setMobilePhoneCountryPrefix($value)
436
    {
437
        return $this->setParameter('mobilePhoneCountryPrefix', $value);
438
    }
439
440
    /**
441
     * Get the mobilePhone field
442
     *
443
     * Corresponds to the Ds_Merchant_Emv3Ds.mobilePhone.subscriber field
444
     *
445
     * @return null|string
446
     */
447
    public function getMobilePhone()
448
    {
449
        return $this->getParameter('mobilePhone');
450
    }
451
452
    /**
453
     * Set the mobilePhone field
454
     *
455
     * Corresponds to the Ds_Merchant_Emv3Ds.mobilePhone.subscriber field
456
     *
457
     * @param null|string $value
458
     * @return self
459
     */
460
    public function setMobilePhone($value)
461
    {
462
        return $this->setParameter('mobilePhone', $value);
463
    }
464
465
    /**
466
     * Get the workPhoneCountryPrefix field
467
     *
468
     * Corresponds to the Ds_Merchant_Emv3Ds.workPhone.cc field
469
     *
470
     * @return null|string
471
     */
472
    public function getWorkPhoneCountryPrefix()
473
    {
474
        return $this->getParameter('workPhoneCountryPrefix');
475
    }
476
477
    /**
478
     * Set the workPhoneCountryPrefix field
479
     *
480
     * Corresponds to the Ds_Merchant_Emv3Ds.workPhone.cc field
481
     *
482
     * @param null|string $value
483
     * @return self
484
     */
485
    public function setWorkPhoneCountryPrefix($value)
486
    {
487
        return $this->setParameter('workPhoneCountryPrefix', $value);
488
    }
489
490
    /**
491
     * Get the workPhone field
492
     *
493
     * Corresponds to the Ds_Merchant_Emv3Ds.workPhone.subscriber field
494
     *
495
     * @return null|string
496
     */
497
    public function getWorkPhone()
498
    {
499
        return $this->getParameter('workPhone');
500
    }
501
502
    /**
503
     * Set the workPhone field
504
     *
505
     * Corresponds to the Ds_Merchant_Emv3Ds.workPhone.subscriber field
506
     *
507
     * @param null|string $value
508
     * @return self
509
     */
510
    public function setWorkPhone($value)
511
    {
512
        return $this->setParameter('workPhone', $value);
513
    }
514
515
    /**
516
     * Get the addressMatch field
517
     *
518
     * Corresponds to the Ds_Merchant_Emv3Ds.addrMatch field
519
     *
520
     * @return string  Either 'Y' or 'N'
521
     */
522
    public function getAddressMatch()
523
    {
524
        $match = $this->getParameter('addressMatch');
525
526
        if ($match === null) {
527
            $match = false;
528
            $card = $this->getCard();
529
            if ($card !== null) {
530
                $match = $card->getShippingAddress1() === $card->getBillingAddress1()
531
                    && $card->getShippingAddress2() === $card->getBillingAddress2()
532
                    && $card->getShippingAddress3() === $card->getBillingAddress3()
533
                    && $card->getShippingCity() === $card->getBillingCity()
534
                    && $card->getShippingPostcode() === $card->getBillingPostcode()
535
                    && $card->getShippingState() === $card->getBillingState()
536
                    && $card->getShippingCountry() === $card->getBillingCountry();
537
            }
538
        }
539
540
        return $match ? "Y" : "N";
541
    }
542
543
    /**
544
     * Set the addressMatch field
545
     *
546
     * Corresponds to the Ds_Merchant_Emv3Ds.addrMatch field
547
     *
548
     * @param null|boolean $value
549
     * @return self
550
     */
551
    public function setAddressMatch($value)
552
    {
553
        return $this->setParameter('addressMatch', $value);
554
    }
555
556
    /**
557
     * Get the challengeWindowSize field
558
     *
559
     * Corresponds to the Ds_Merchant_Emv3Ds.challengeWindowSize field
560
     *
561
     * @return null|string One of the self::CHALLENGE_WINDOW_SIZE_* constants
562
     */
563
    public function getChallengeWindowSize()
564
    {
565
        return $this->getParameter('challengeWindowSize');
566
    }
567
568
    /**
569
     * Set the challengeWindowSize field
570
     *
571
     * Corresponds to the Ds_Merchant_Emv3Ds.challengeWindowSize field
572
     *
573
     * @param null|string $value One of the self::CHALLENGE_WINDOW_SIZE_* constants
574
     * @return self
575
     * @throws InvalidRequestException if $value is invalid.
576
     */
577
    public function setChallengeWindowSize($value)
578
    {
579
        if (in_array(
580
            $value,
581
            [
582
                null,
583
                self::CHALLENGE_WINDOW_SIZE_250_400,
584
                self::CHALLENGE_WINDOW_SIZE_390_400,
585
                self::CHALLENGE_WINDOW_SIZE_500_600,
586
                self::CHALLENGE_WINDOW_SIZE_600_400,
587
                self::CHALLENGE_WINDOW_SIZE_FULLSCREEN,
588
            ]
589
        )) {
590
            return $this->setParameter('challengeWindowSize', $value);
591
        }
592
        throw new InvalidRequestException("Invalid challengeWindowSize parameter");
593
    }
594
595
    /**
596
     * Get the customerAdditionalInformation field
597
     *
598
     * Corresponds to the Ds_Merchant_Emv3Ds.acctID field
599
     *
600
     * @return null|string
601
     */
602
    public function getCustomerAdditionalInformation()
603
    {
604
        return $this->getParameter('customerAdditionalInformation');
605
    }
606
607
    /**
608
     * Set the customerAdditionalInformation field
609
     *
610
     * Corresponds to the Ds_Merchant_Emv3Ds.acctID field
611
     *
612
     * @param null|string $value
613
     * @return self
614
     */
615
    public function setCustomerAdditionalInformation($value)
616
    {
617
        return $this->setParameter('customerAdditionalInformation', $value);
618
    }
619
620
    /**
621
     * Get the 3DsRequestAuthenticationMethodData field
622
     *
623
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthData field in Redsys
624
     * documentation.
625
     *
626
     * @return null|string
627
     */
628
    public function get3DsRequestAuthenticationMethodData()
629
    {
630
        return $this->getParameter('3DsRequestAuthenticationMethodData');
631
    }
632
633
    /**
634
     * Set the 3DsRequestAuthenticationMethodData field
635
     *
636
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthData field in the Redsys
637
     * documentation.
638
     *
639
     * @param null|string $value
640
     * @return self
641
     */
642
    public function set3DsRequestAuthenticationMethodData($value)
643
    {
644
        return $this->setParameter('3DsRequestAuthenticationMethodData', $value);
645
    }
646
647
    /**
648
     * Get the 3DsRequestAuthenticationMethod field
649
     *
650
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthMethod field in Redsys
651
     * documentation.
652
     *
653
     * @return null|string One of the self::ACCOUNT_AUTHENTICATION_METHOD_* constants.
654
     */
655
    public function get3DsRequestAuthenticationMethod()
656
    {
657
        return $this->getParameter('3DsRequestAuthenticationMethod');
658
    }
659
660
    /**
661
     * Set the 3DsRequestAuthenticationMethod field
662
     *
663
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthMethod field in the Redsys
664
     * documentation.
665
     *
666
     * @param null|string $value One of the self::ACCOUNT_AUTHENTICATION_METHOD_* constants.
667
     * @return self
668
     * @throws InvalidRequestException if $value is invalid.
669
     */
670
    public function set3DsRequestAuthenticationMethod($value)
671
    {
672
        if (in_array(
673
            $value,
674
            [
675
                null,
676
                self::ACCOUNT_AUTHENTICATION_METHOD_NONE,
677
                self::ACCOUNT_AUTHENTICATION_METHOD_OWN_CREDENTIALS,
678
                self::ACCOUNT_AUTHENTICATION_METHOD_FEDERATED_ID,
679
                self::ACCOUNT_AUTHENTICATION_METHOD_ISSUER_CREDENTIALS,
680
                self::ACCOUNT_AUTHENTICATION_METHOD_THIRD_PARTY_AUTHENTICATION,
681
                self::ACCOUNT_AUTHENTICATION_METHOD_FIDO,
682
            ]
683
        )) {
684
            return $this->setParameter('3DsRequestAuthenticationMethod', $value);
685
        }
686
        throw new InvalidRequestException("Invalid 3DsRequestAuthenticationMethod parameter");
687
    }
688
689
    /**
690
     * Get the 3DsRequestAuthenticationTime field
691
     *
692
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthTimestamp field
693
     *
694
     * @return null|string
695
     */
696
    public function get3DsRequestAuthenticationTime()
697
    {
698
        return $this->getParameter('3DsRequestAuthenticationTime');
699
    }
700
701
    /**
702
     * Set the 3DsRequestAuthenticationTime field
703
     *
704
     * Corresponds to the Ds_Merchant_Emv3Ds.threeDSRequestorAuthenticationInfo.threeDSReqAuthTimestamp field
705
     *
706
     * @param null|DateTime|int $value
707
     * @return self
708
     */
709
    public function set3DsRequestAuthenticationTime($value)
710
    {
711
        return $this->setParameter('3DsRequestAuthenticationTime', $this->formatDateTime($value, "YmdHi"));
712
    }
713
714
    /**
715
     * Get the customerAccountCreatedIndicator field
716
     *
717
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccAgeInd field
718
     *
719
     * @return null|string One of the CUSTOMER_ACCOUNT_CREATED_* constants
720
     */
721
    public function getCustomerAccountCreatedIndicator()
722
    {
723
        return $this->getParameter('customerAccountCreatedIndicator');
724
    }
725
726
    /**
727
     * Set the customerAccountCreatedIndicator field
728
     *
729
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccAgeInd field
730
     *
731
     * @param null|string $value One of the CUSTOMER_ACCOUNT_CREATED_* constants
732
     * @return self
733
     * @throws InvalidRequestException if $value is invalid.
734
     */
735
    public function setCustomerAccountCreatedIndicator($value)
736
    {
737
        if (in_array(
738
            $value,
739
            [
740
                null,
741
                self::CUSTOMER_ACCOUNT_CREATED_NONE,
742
                self::CUSTOMER_ACCOUNT_CREATED_THIS_TRANSACTION,
743
                self::CUSTOMER_ACCOUNT_CREATED_LAST_30_DAYS,
744
                self::CUSTOMER_ACCOUNT_CREATED_LAST_60_DAYS,
745
                self::CUSTOMER_ACCOUNT_CREATED_MORE_THAN_60_DAYS,
746
            ]
747
        )) {
748
            return $this->setParameter('customerAccountCreatedIndicator', $value);
749
        }
750
        throw new InvalidRequestException("Invalid customerAccountCreatedIndicator parameter");
751
    }
752
753
    /**
754
     * Get the customerAccountCreatedDate field
755
     *
756
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccDate field
757
     *
758
     * @return null|string
759
     */
760
    public function getCustomerAccountCreatedDate()
761
    {
762
        return $this->getParameter('customerAccountCreatedDate');
763
    }
764
765
    /**
766
     * Set the customerAccountCreatedDate field
767
     *
768
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccDate field
769
     *
770
     * @param null|DateTime|int $value
771
     * @return self
772
     */
773
    public function setCustomerAccountCreatedDate($value)
774
    {
775
        return $this->setParameter('customerAccountCreatedDate', $this->formatDateTime($value, "Ymd"));
776
    }
777
778
    /**
779
     * Get the customerAccountChangedIndicator field
780
     *
781
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccChangeInd field
782
     *
783
     * @return null|string One of the CUSTOMER_ACCOUNT_MODIFIED_* constants
784
     */
785
    public function getCustomerAccountChangedIndicator()
786
    {
787
        return $this->getParameter('customerAccountChangedIndicator');
788
    }
789
790
    /**
791
     * Set the customerAccountChangedIndicator field
792
     *
793
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccChangeInd field
794
     *
795
     * @param null|string $value One of the CUSTOMER_ACCOUNT_MODIFIED_* constants
796
     * @return self
797
     * @throws InvalidRequestException if $value is invalid.
798
     */
799
    public function setCustomerAccountChangedIndicator($value)
800
    {
801
        if (in_array(
802
            $value,
803
            [
804
                null,
805
                self::CUSTOMER_ACCOUNT_MODIFIED_THIS_TRANSACTION,
806
                self::CUSTOMER_ACCOUNT_MODIFIED_LAST_30_DAYS,
807
                self::CUSTOMER_ACCOUNT_MODIFIED_LAST_60_DAYS,
808
                self::CUSTOMER_ACCOUNT_MODIFIED_MORE_THAN_60_DAYS,
809
            ]
810
        )) {
811
            return $this->setParameter('customerAccountChangedIndicator', $value);
812
        }
813
        throw new InvalidRequestException("Invalid customerAccountChangedIndicator parameter");
814
    }
815
816
    /**
817
     * Get the customerAccountChangedDate field
818
     *
819
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccChange field
820
     *
821
     * @return null|string
822
     */
823
    public function getCustomerAccountChangedDate()
824
    {
825
        return $this->getParameter('customerAccountChangedDate');
826
    }
827
828
    /**
829
     * Set the customerAccountChangedDate field
830
     *
831
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccChange field
832
     *
833
     * @param null|DateTime|int $value
834
     * @return self
835
     */
836
    public function setCustomerAccountChangedDate($value)
837
    {
838
        return $this->setParameter('customerAccountChangedDate', $this->formatDateTime($value, "Ymd"));
839
    }
840
841
    /**
842
     * Get the customerPasswordAgeIndicator field
843
     *
844
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccPwChangeInd field
845
     *
846
     * @return null|string One of the CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_* constants
847
     */
848
    public function getCustomerPasswordChangedIndicator()
849
    {
850
        return $this->getParameter('customerPasswordAgeIndicator');
851
    }
852
853
    /**
854
     * Set the customerPasswordAgeIndicator field
855
     *
856
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccPwChangeInd field
857
     *
858
     * @param null|string $value One of the CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_* constants
859
     * @return self
860
     * @throws InvalidRequestException if $value is invalid.
861
     */
862
    public function setCustomerPasswordChangedIndicator($value)
863
    {
864
        if (in_array(
865
            $value,
866
            [
867
                null,
868
                self::CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_NONE,
869
                self::CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_THIS_TRANSACTION,
870
                self::CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_LAST_30_DAYS,
871
                self::CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_LAST_60_DAYS,
872
                self::CUSTOMER_ACCOUNT_PASSWORD_MODIFIED_MORE_THAN_60_DAYS,
873
            ]
874
        )) {
875
            return $this->setParameter('customerPasswordAgeIndicator', $value);
876
        }
877
        throw new InvalidRequestException("Invalid customerPasswordAgeIndicator parameter");
878
    }
879
880
    /**
881
     * Get the customerPasswordChangedDate field
882
     *
883
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccPwChange field
884
     *
885
     * @return null|string
886
     */
887
    public function getCustomerPasswordChangedDate()
888
    {
889
        return $this->getParameter('customerPasswordChangedDate');
890
    }
891
892
    /**
893
     * Set the customerPasswordChangedDate field
894
     *
895
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.chAccPwChange field
896
     *
897
     * @param null|DateTime|int $value
898
     * @return self
899
     */
900
    public function setCustomerPasswordChangedDate($value)
901
    {
902
        return $this->setParameter('customerPasswordChangedDate', $this->formatDateTime($value, "Ymd"));
903
    }
904
905
    /**
906
     * Get the customerPurchasesInLast6Months field
907
     *
908
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.nbPurchaseAccount field
909
     *
910
     * @return null|int
911
     */
912
    public function getCustomerPurchasesInLast6Months()
913
    {
914
        return $this->getParameter('customerPurchasesInLast6Months');
915
    }
916
917
    /**
918
     * Set the customerPurchasesInLast6Months field
919
     *
920
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.nbPurchaseAccount field
921
     *
922
     * @param null|int $value
923
     * @return self
924
     */
925
    public function setCustomerPurchasesInLast6Months($value)
926
    {
927
        return $this->setParameter('customerPurchasesInLast6Months', $value);
928
    }
929
930
    /**
931
     * Get the customerAccountCardProvisionsLast24Hours field
932
     *
933
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.provisionAttemptsDay field
934
     *
935
     * @return null|int
936
     */
937
    public function getCustomerAccountCardProvisionsLast24Hours()
938
    {
939
        return $this->getParameter('customerAccountCardProvisionsLast24Hours');
940
    }
941
942
    /**
943
     * Set the customerAccountCardProvisionsLast24Hours field
944
     *
945
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.provisionAttemptsDay field
946
     *
947
     * @param null|int $value
948
     * @return self
949
     */
950
    public function setCustomerAccountCardProvisionsLast24Hours($value)
951
    {
952
        return $this->setParameter('customerAccountCardProvisionsLast24Hours', $value);
953
    }
954
955
    /**
956
     * Get the customerAccountTransactionsLast24Hours field
957
     *
958
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.txnActivityDay field
959
     *
960
     * @return null|int
961
     */
962
    public function getCustomerAccountTransactionsLast24Hours()
963
    {
964
        return $this->getParameter('customerAccountTransactionsLast24Hours');
965
    }
966
967
    /**
968
     * Set the customerAccountTransactionsLast24Hours field
969
     *
970
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.txnActivityDay field
971
     *
972
     * @param null|int $value
973
     * @return self
974
     */
975
    public function setCustomerAccountTransactionsLast24Hours($value)
976
    {
977
        return $this->setParameter('customerAccountTransactionsLast24Hours', $value);
978
    }
979
980
    /**
981
     * Get the customerAccountTransactionsLastYear field
982
     *
983
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.txnActivityYear field
984
     *
985
     * @return null|int
986
     */
987
    public function getCustomerAccountTransactionsLastYear()
988
    {
989
        return $this->getParameter('customerAccountTransactionsLastYear');
990
    }
991
992
    /**
993
     * Set the customerAccountTransactionsLastYear field
994
     *
995
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.txnActivityYear field
996
     *
997
     * @param null|int $value
998
     * @return self
999
     */
1000
    public function setCustomerAccountTransactionsLastYear($value)
1001
    {
1002
        return $this->setParameter('customerAccountTransactionsLastYear', $value);
1003
    }
1004
1005
    /**
1006
     * Get the customerPaymentMethodCreatedIndicator field
1007
     *
1008
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.paymentAccInd field
1009
     *
1010
     * @return null|string One of the PAYMENT_METHOD_CREATED_* constants
1011
     */
1012
    public function getCustomerPaymentMethodCreatedIndicator()
1013
    {
1014
        return $this->getParameter('customerPaymentMethodCreatedIndicator');
1015
    }
1016
1017
    /**
1018
     * Set the customerPaymentMethodCreatedIndicator field
1019
     *
1020
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.paymentAccInd field
1021
     *
1022
     * @param null|string $value One of the PAYMENT_METHOD_CREATED_* constants
1023
     * @return self
1024
     * @throws InvalidRequestException if $value is invalid.
1025
     */
1026
    public function setCustomerPaymentMethodCreatedIndicator($value)
1027
    {
1028
        if (in_array(
1029
            $value,
1030
            [
1031
                null,
1032
                self::PAYMENT_METHOD_CREATED_NONE,
1033
                self::PAYMENT_METHOD_CREATED_THIS_TRANSACTION,
1034
                self::PAYMENT_METHOD_CREATED_LAST_30_DAYS,
1035
                self::PAYMENT_METHOD_CREATED_LAST_60_DAYS,
1036
                self::PAYMENT_METHOD_CREATED_MORE_THAN_60_DAYS,
1037
            ]
1038
        )) {
1039
            return $this->setParameter('customerPaymentMethodCreatedIndicator', $value);
1040
        }
1041
        throw new InvalidRequestException("Invalid customerPaymentMethodCreatedIndicator parameter");
1042
    }
1043
1044
    /**
1045
     * Get the customerPaymentMethodCreatedDate field
1046
     *
1047
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.paymentAccAge field
1048
     *
1049
     * @return null|string
1050
     */
1051
    public function getCustomerPaymentMethodCreatedDate()
1052
    {
1053
        return $this->getParameter('customerPaymentMethodCreatedDate');
1054
    }
1055
1056
    /**
1057
     * Set the customerPaymentMethodCreatedDate field
1058
     *
1059
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.paymentAccAge field
1060
     *
1061
     * @param null|DateTime|int $value
1062
     * @return self
1063
     */
1064
    public function setCustomerPaymentMethodCreatedDate($value)
1065
    {
1066
        return $this->setParameter('customerPaymentMethodCreatedDate', $this->formatDateTime($value, "Ymd"));
1067
    }
1068
1069
    /**
1070
     * Get the shippingAddressFirstUsedIndicator field
1071
     *
1072
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipAddressUsageInd field
1073
     *
1074
     * @return null|string One of the SHIPPING_ADDRESS_USAGE_* constants
1075
     */
1076
    public function getShippingAddressFirstUsedIndicator()
1077
    {
1078
        return $this->getParameter('shippingAddressFirstUsedIndicator');
1079
    }
1080
1081
    /**
1082
     * Set the shippingAddressFirstUsedIndicator field
1083
     *
1084
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipAddressUsageInd field
1085
     *
1086
     * @param null|string $value One of the SHIPPING_ADDRESS_USAGE_* constants
1087
     * @return self
1088
     * @throws InvalidRequestException if $value is invalid.
1089
     */
1090
    public function setShippingAddressFirstUsedIndicator($value)
1091
    {
1092
        if (in_array(
1093
            $value,
1094
            [
1095
                null,
1096
                self::SHIPPING_ADDRESS_USAGE_THIS_TRANSACTION,
1097
                self::SHIPPING_ADDRESS_USAGE_LAST_30_DAYS,
1098
                self::SHIPPING_ADDRESS_USAGE_LAST_60_DAYS,
1099
                self::SHIPPING_ADDRESS_USAGE_MORE_THAN_60_DAYS,
1100
            ]
1101
        )) {
1102
            return $this->setParameter('shippingAddressFirstUsedIndicator', $value);
1103
        }
1104
        throw new InvalidRequestException("Invalid shippingAddressFirstUsedIndicator parameter");
1105
    }
1106
1107
    /**
1108
     * Get the shippingAddressFirstUsedDate field
1109
     *
1110
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipAddressUsage field
1111
     *
1112
     * @return null|string
1113
     */
1114
    public function getShippingAddressFirstUsedDate()
1115
    {
1116
        return $this->getParameter('shippingAddressFirstUsedDate');
1117
    }
1118
1119
    /**
1120
     * Set the shippingAddressFirstUsedDate field
1121
     *
1122
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipAddressUsage field
1123
     *
1124
     * @param null|DateTime|int $value
1125
     * @return self
1126
     */
1127
    public function setShippingAddressFirstUsedDate($value)
1128
    {
1129
        return $this->setParameter('shippingAddressFirstUsedDate', $this->formatDateTime($value, "Ymd"));
1130
    }
1131
1132
    /**
1133
     * Get the shippingNameCustomerNameMatch field
1134
     *
1135
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipNameIndicator field
1136
     *
1137
     * @return null|boolean
1138
     */
1139
    public function getShippingNameCustomerNameMatch()
1140
    {
1141
        return $this->getParameter('shippingNameCustomerNameMatch');
1142
    }
1143
1144
    /**
1145
     * Set the shippingNameCustomerNameMatch field
1146
     *
1147
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.shipNameIndicator field
1148
     *
1149
     * @param null|boolean $value
1150
     * @return self
1151
     */
1152
    public function setShippingNameCustomerNameMatch($value)
1153
    {
1154
        return $this->setParameter('shippingNameCustomerNameMatch', $value);
1155
    }
1156
1157
    /**
1158
     * Get the customerHasSuspiciousActivity field
1159
     *
1160
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.suspiciousAccActivity field
1161
     *
1162
     * @return null|boolean
1163
     */
1164
    public function getCustomerHasSuspiciousActivity()
1165
    {
1166
        return $this->getParameter('customerHasSuspiciousActivity');
1167
    }
1168
1169
    /**
1170
     * Set the customerHasSuspiciousActivity field
1171
     *
1172
     * Corresponds to the Ds_Merchant_Emv3Ds.acctInfo.suspiciousAccActivity field
1173
     *
1174
     * @param null|boolean $value
1175
     * @return self
1176
     */
1177
    public function setCustomerHasSuspiciousActivity($value)
1178
    {
1179
        return $this->setParameter('customerHasSuspiciousActivity', $value);
1180
    }
1181
1182
    /**
1183
     * Get the deliveryEmail field
1184
     *
1185
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.deliveryEmailAddress field
1186
     *
1187
     * @return null|string
1188
     */
1189
    public function getDeliveryEmail()
1190
    {
1191
        return $this->getParameter('deliveryEmail');
1192
    }
1193
1194
    /**
1195
     * Set the deliveryEmail field
1196
     *
1197
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.deliveryEmailAddress field
1198
     *
1199
     * @param null|string $value
1200
     * @return self
1201
     */
1202
    public function setDeliveryEmail($value)
1203
    {
1204
        return $this->setParameter('deliveryEmail', $value);
1205
    }
1206
1207
    /**
1208
     * Get the deliveryTimeframeIndicator field
1209
     *
1210
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.deliveryTimeframe field
1211
     *
1212
     * @return null|string One of the DELIVERY_TIMEFRAME_* constants
1213
     */
1214
    public function getDeliveryTimeframeIndicator()
1215
    {
1216
        return $this->getParameter('deliveryTimeframeIndicator');
1217
    }
1218
1219
    /**
1220
     * Set the deliveryTimeframeIndicator field
1221
     *
1222
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.deliveryTimeframe field
1223
     *
1224
     * @param null|string $value One of the DELIVERY_TIMEFRAME_* constants
1225
     * @return self
1226
     * @throws InvalidRequestException if $value is invalid.
1227
     */
1228
    public function setDeliveryTimeframeIndicator($value)
1229
    {
1230
        if (in_array(
1231
            $value,
1232
            [
1233
                null,
1234
                self::DELIVERY_TIMEFRAME_ELECTRONIC_DELIVERY,
1235
                self::DELIVERY_TIMEFRAME_SAME_DAY,
1236
                self::DELIVERY_TIMEFRAME_NEXT_DAY,
1237
                self::DELIVERY_TIMEFRAME_2_OR_MORE_DAYS,
1238
            ]
1239
        )) {
1240
            return $this->setParameter('deliveryTimeframeIndicator', $value);
1241
        }
1242
        throw new InvalidRequestException("Invalid deliveryTimeframeIndicator parameter");
1243
    }
1244
1245
    /**
1246
     * Get the giftCardAmount field
1247
     *
1248
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardAmount field
1249
     *
1250
     * @return null|int
1251
     */
1252
    public function getGiftCardAmount()
1253
    {
1254
        return $this->getParameter('giftCardAmount');
1255
    }
1256
1257
    /**
1258
     * Set the giftCardAmount field
1259
     *
1260
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardAmount field
1261
     *
1262
     * @param null|int $value
1263
     * @return self
1264
     */
1265
    public function setGiftCardAmount($value)
1266
    {
1267
        return $this->setParameter('giftCardAmount', $value);
1268
    }
1269
1270
    /**
1271
     * Get the giftCardCount field
1272
     *
1273
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardCount field
1274
     *
1275
     * @return null|int
1276
     */
1277
    public function getGiftCardCount()
1278
    {
1279
        return $this->getParameter('giftCardCount');
1280
    }
1281
1282
    /**
1283
     * Set the giftCardCount field
1284
     *
1285
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardCount field
1286
     *
1287
     * @param null|int $value
1288
     * @return self
1289
     */
1290
    public function setGiftCardCount($value)
1291
    {
1292
        return $this->setParameter('giftCardCount', $value);
1293
    }
1294
1295
    /**
1296
     * Get the giftCardCurrency field
1297
     *
1298
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardCurr field
1299
     *
1300
     * @return null|string ISO-4217 currency code
1301
     */
1302
    public function getGiftCardCurrency()
1303
    {
1304
        return $this->getParameter('giftCardCurrency');
1305
    }
1306
1307
    /**
1308
     * Set the giftCardCurrency field
1309
     *
1310
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.giftCardCurr field
1311
     *
1312
     * @param null|string $value ISO-4217 currency code
1313
     * @return self
1314
     */
1315
    public function setGiftCardCurrency($value)
1316
    {
1317
        return $this->setParameter('giftCardCurrency', $value);
1318
    }
1319
1320
    /**
1321
     * Get the purchasingPreOrder field
1322
     *
1323
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.preOrderPurchaseInd field
1324
     *
1325
     * @return null|boolean True if the customer is purchasing a preorder
1326
     */
1327
    public function getPurchasingPreOrder()
1328
    {
1329
        return $this->getParameter('purchasingPreOrder');
1330
    }
1331
1332
    /**
1333
     * Set the purchasingPreOrder field
1334
     *
1335
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.preOrderPurchaseInd field
1336
     *
1337
     * @param null|boolean $value True if the customer is purchasing a preorder
1338
     * @return self
1339
     */
1340
    public function setPurchasingPreOrder($value)
1341
    {
1342
        return $this->setParameter('purchasingPreOrder', $value);
1343
    }
1344
1345
    /**
1346
     * Get the preOrderDate field
1347
     *
1348
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.preOrderDate field
1349
     *
1350
     * @return null|string
1351
     */
1352
    public function getPreOrderDate()
1353
    {
1354
        return $this->getParameter('preOrderDate');
1355
    }
1356
1357
    /**
1358
     * Set the preOrderDate field
1359
     *
1360
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.preOrderDate field
1361
     *
1362
     * @param null|DateTime|int $value
1363
     * @return self
1364
     */
1365
    public function setPreOrderDate($value)
1366
    {
1367
        return $this->setParameter('preOrderDate', $this->formatDateTime($value, "Ymd"));
1368
    }
1369
1370
    /**
1371
     * Get the customerHasPurchasedProductBefore field
1372
     *
1373
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.reorderItemsInd field
1374
     *
1375
     * @return null|boolean
1376
     */
1377
    public function getCustomerHasPurchasedProductBefore()
1378
    {
1379
        return $this->getParameter('customerHasPurchasedProductBefore');
1380
    }
1381
1382
    /**
1383
     * Set the customerHasPurchasedProductBefore field
1384
     *
1385
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.reorderItemsInd field
1386
     *
1387
     * @param null|boolean $value
1388
     * @return self
1389
     */
1390
    public function setCustomerHasPurchasedProductBefore($value)
1391
    {
1392
        return $this->setParameter('customerHasPurchasedProductBefore', $value);
1393
    }
1394
1395
    /**
1396
     * Get the shippingAddressIndicator field
1397
     *
1398
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.shipIndicator field
1399
     *
1400
     * @return null|string One of the self::SHIPPING_* constants
1401
     */
1402
    public function getShippingAddressIndicator()
1403
    {
1404
        return $this->getParameter('shippingAddressIndicator');
1405
    }
1406
1407
    /**
1408
     * Set the shippingAddressIndicator field
1409
     *
1410
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.shipIndicator field
1411
     *
1412
     * @param null|string $value One of the self::SHIPPING_* constants
1413
     * @return self
1414
     * @throws InvalidRequestException if $value is invalid.
1415
     */
1416
    public function setShippingAddressIndicator($value)
1417
    {
1418
        if (in_array(
1419
            $value,
1420
            [
1421
                null,
1422
                self::SHIPPING_TO_BILLING_ADDRESS,
1423
                self::SHIPPING_TO_ANOTHER_VERIFIED_ADDRESS,
1424
                self::SHIPPING_DIFFERENT_BILLING_ADDRESS,
1425
                self::SHIPPING_PICK_UP,
1426
                self::SHIPPING_DIGITAL,
1427
                self::SHIPPING_TRAVEL,
1428
                self::SHIPPING_OTHER,
1429
            ]
1430
        )) {
1431
            return $this->setParameter('shippingAddressIndicator', $value);
1432
        }
1433
        throw new InvalidRequestException("Invalid shippingAddressIndicator parameter");
1434
    }
1435
1436
    /**
1437
     * Get the SCA exemption field
1438
     *
1439
     * Corresponds to the Ds_Merchant_Excep_Sca field
1440
     *
1441
     * @return null|string One of the self::SCA_EXEMPTION_* constants
1442
     */
1443
    public function getScaExemptionIndicator()
1444
    {
1445
        return $this->getParameter('scaExemptionIndicator');
1446
    }
1447
1448
    /**
1449
     * Set the SCA exemption field
1450
     *
1451
     * Corresponds to the Ds_Merchant_Emv3Ds.MerchantRiskIndicator.shipIndicator field
1452
     *
1453
     * @param null|string $value One of the self::SCA_EXEMPTION_* constants
1454
     * @return self
1455
     * @throws InvalidRequestException if $value is invalid.
1456
     */
1457
    public function setScaExemptionIndicator($value)
1458
    {
1459
        if (in_array(
1460
            $value,
1461
            [
1462
                null,
1463
                self::SCA_EXEMPTION_LOW_AMOUNT,
1464
                self::SCA_EXEMPTION_LOW_RISK,
1465
                self::SCA_EXEMPTION_CORPORATE,
1466
                self::SCA_EXEMPTION_MERCHANT_INITIATED,
1467
            ]
1468
        )) {
1469
            return $this->setParameter('scaExemptionIndicator', $value);
1470
        }
1471
        throw new InvalidRequestException("Invalid scaExemptionIndicator parameter");
1472
    }
1473
1474
    /**
1475
     * Override the abstract method to add requirement that it must start with 4 numeric characters
1476
     *
1477
     * @param string|int $value The transaction ID (merchant order) to set for the transaction
1478
     */
1479
    public function setTransactionId($value)
1480
    {
1481
        $start = substr($value, 0, 4);
1482
        $numerics = 0;
1483
        foreach (str_split($start) as $char) {
1484
            if (is_numeric($char)) {
1485
                $numerics++;
1486
            } else {
1487
                break;
1488
            }
1489
        }
1490
        $value = str_pad(substr($start, 0, $numerics), 4, 0, STR_PAD_LEFT).substr($value, $numerics);
1491
1492
        parent::setTransactionId($value);
1493
    }
1494
1495
    /**
1496
     * Get the browserAcceptHeader field
1497
     *
1498
     * Corresponds to the Ds_Merchant_Emv3Ds.browserAcceptHeader field
1499
     *
1500
     * @return null|string
1501
     */
1502
    public function getBrowserAcceptHeader()
1503
    {
1504
        return $this->getParameter('browserAcceptHeader');
1505
    }
1506
1507
    /**
1508
     * Set the browserAcceptHeader field
1509
     *
1510
     * Corresponds to the Ds_Merchant_Emv3Ds.browserAcceptHeader field
1511
     *
1512
     * @param null|string $value
1513
     * @return self
1514
     */
1515
    public function setBrowserAcceptHeader($value)
1516
    {
1517
        return $this->setParameter('browserAcceptHeader', $value);
1518
    }
1519
1520
    /**
1521
     * Get the browserColorDepth field
1522
     *
1523
     * Corresponds to the Ds_Merchant_Emv3Ds.browserColorDepth field
1524
     *
1525
     * @return null|int
1526
     */
1527
    public function getBrowserColorDepth()
1528
    {
1529
        return $this->getParameter('browserColorDepth');
1530
    }
1531
1532
    /**
1533
     * Set the browserColorDepth field
1534
     *
1535
     * Corresponds to the Ds_Merchant_Emv3Ds.browserColorDepth field
1536
     *
1537
     * @param null|int $value
1538
     * @return self
1539
     */
1540
    public function setBrowserColorDepth($value)
1541
    {
1542
        return $this->setParameter('browserColorDepth', $value);
1543
    }
1544
1545
    /**
1546
     * Get the browserJavaEnabled field
1547
     *
1548
     * Corresponds to the Ds_Merchant_Emv3Ds.browserJavaEnabled field
1549
     *
1550
     * @return null|bool
1551
     */
1552
    public function getBrowserJavaEnabled()
1553
    {
1554
        return $this->getParameter('browserJavaEnabled');
1555
    }
1556
1557
    /**
1558
     * Set the browserJavaEnabled field
1559
     *
1560
     * Corresponds to the Ds_Merchant_Emv3Ds.browserJavaEnabled field
1561
     *
1562
     * @param null|bool $value
1563
     * @return self
1564
     */
1565
    public function setBrowserJavaEnabled($value)
1566
    {
1567
        return $this->setParameter('browserJavaEnabled', $value);
1568
    }
1569
1570
    /**
1571
     * Get the browserLanguage field
1572
     *
1573
     * Corresponds to the Ds_Merchant_Emv3Ds.browserLanguage field
1574
     *
1575
     * @return null|string
1576
     */
1577
    public function getBrowserLanguage()
1578
    {
1579
        return $this->getParameter('browserLanguage');
1580
    }
1581
1582
    /**
1583
     * Set the browserLanguage field
1584
     *
1585
     * Corresponds to the Ds_Merchant_Emv3Ds.browserLanguage field
1586
     *
1587
     * @param null|string $value
1588
     * @return self
1589
     */
1590
    public function setBrowserLanguage($value)
1591
    {
1592
        return $this->setParameter('browserLanguage', $value);
1593
    }
1594
1595
    /**
1596
     * Get the browserScreenHeight field
1597
     *
1598
     * Corresponds to the Ds_Merchant_Emv3Ds.browserScreenHeight field
1599
     *
1600
     * @return null|int
1601
     */
1602
    public function getBrowserScreenHeight()
1603
    {
1604
        return $this->getParameter('browserScreenHeight');
1605
    }
1606
1607
    /**
1608
     * Set the browserScreenHeight field
1609
     *
1610
     * Corresponds to the Ds_Merchant_Emv3Ds.browserScreenHeight field
1611
     *
1612
     * @param null|int $value
1613
     * @return self
1614
     */
1615
    public function setBrowserScreenHeight($value)
1616
    {
1617
        return $this->setParameter('browserScreenHeight', $value);
1618
    }
1619
1620
    /**
1621
     * Get the browserScreenWidth field
1622
     *
1623
     * Corresponds to the Ds_Merchant_Emv3Ds.browserScreenWidth field
1624
     *
1625
     * @return null|int
1626
     */
1627
    public function getBrowserScreenWidth()
1628
    {
1629
        return $this->getParameter('browserScreenWidth');
1630
    }
1631
1632
    /**
1633
     * Set the browserScreenWidth field
1634
     *
1635
     * Corresponds to the Ds_Merchant_Emv3Ds.browserScreenWidth field
1636
     *
1637
     * @param null|int $value
1638
     * @return self
1639
     */
1640
    public function setBrowserScreenWidth($value)
1641
    {
1642
        return $this->setParameter('browserScreenWidth', $value);
1643
    }
1644
1645
    /**
1646
     * Get the browserTZ field
1647
     *
1648
     * Corresponds to the Ds_Merchant_Emv3Ds.browserTZ field
1649
     *
1650
     * @return null|int
1651
     */
1652
    public function getBrowserTZ()
1653
    {
1654
        return $this->getParameter('browserTZ');
1655
    }
1656
1657
    /**
1658
     * Set the browserTZ field
1659
     *
1660
     * Corresponds to the Ds_Merchant_Emv3Ds.browserTZ field
1661
     *
1662
     * @param null|int $value
1663
     * @return self
1664
     */
1665
    public function setBrowserTZ($value)
1666
    {
1667
        return $this->setParameter('browserTZ', $value);
1668
    }
1669
1670
    /**
1671
     * Get the browserUserAgent field
1672
     *
1673
     * Corresponds to the Ds_Merchant_Emv3Ds.browserUserAgent field
1674
     *
1675
     * @return null|string
1676
     */
1677
    public function getBrowserUserAgent()
1678
    {
1679
        return $this->getParameter('browserUserAgent');
1680
    }
1681
1682
    /**
1683
     * Set the browserUserAgent field
1684
     *
1685
     * Corresponds to the Ds_Merchant_Emv3Ds.browserUserAgent field
1686
     *
1687
     * @param null|string $value
1688
     * @return self
1689
     */
1690
    public function setBrowserUserAgent($value)
1691
    {
1692
        return $this->setParameter('browserUserAgent', $value);
1693
    }
1694
1695
    /**
1696
     * Get the basic data fields that don't require any 3DS/SCA fields
1697
     */
1698
    public function getBaseData()
1699
    {
1700
        $this->validate('merchantId', 'terminalId', 'amount', 'currency');
1701
1702
        return [
1703
            // mandatory fields
1704
            'Ds_Merchant_MerchantCode'       => $this->getMerchantId(),
1705
            'Ds_Merchant_Terminal'           => $this->getTerminalId(),
1706
            'Ds_Merchant_TransactionType'    => '0',                          // Authorisation
1707
            'Ds_Merchant_Amount'             => $this->getAmountInteger(),
1708
            'Ds_Merchant_Currency'           => $this->getCurrencyNumeric(),  // uses ISO-4217 codes
1709
            'Ds_Merchant_Order'              => $this->getTransactionId(),
1710
            'Ds_Merchant_MerchantUrl'        => $this->getNotifyUrl(),
1711
            // optional fields
1712
            'Ds_Merchant_ProductDescription' => $this->getDescription(),
1713
            'Ds_Merchant_Cardholder'         => $this->getCardholder(),
1714
            'Ds_Merchant_UrlOK'              => $this->getReturnUrl(),
1715
            'Ds_Merchant_UrlKO'              => $this->getCancelUrl(),
1716
            'Ds_Merchant_MerchantName'       => $this->getMerchantName(),
1717
            'Ds_Merchant_ConsumerLanguage'   => $this->getConsumerLanguage(),
1718
            'Ds_Merchant_MerchantData'       => $this->getMerchantData(),
1719
        ];
1720
    }
1721
1722
    public function get3DSAccountInfoData()
1723
    {
1724
        $data = array_filter([
1725
            'chAccAgeInd'           => $this->getCustomerAccountCreatedIndicator(),
1726
            'chAccDate'             => $this->getCustomerAccountCreatedDate(),
1727
            'chAccChangeInd'        => $this->getCustomerAccountChangedIndicator(),
1728
            'chAccChange'           => $this->getCustomerAccountChangedDate(),
1729
            'chAccPwChangeInd'      => $this->getCustomerPasswordChangedIndicator(),
1730
            'chAccPwChange'         => $this->getCustomerPasswordChangedDate(),
1731
            'paymentAccInd'         => $this->getCustomerPaymentMethodCreatedIndicator(),
1732
            'paymentAccAge'         => $this->getCustomerPaymentMethodCreatedDate(),
1733
            'shipAddressUsageInd'   => $this->getShippingAddressFirstUsedIndicator(),
1734
            'shipAddressUsage'      => $this->getShippingAddressFirstUsedDate(),
1735
        ]);
1736
        // checks that can't rely on a simple filter (which could remove or add values unintentionally)
1737
        if ($this->getShippingNameCustomerNameMatch() !== null) {
1738
            $data['shipNameIndicator'] = $this->getShippingNameCustomerNameMatch() ? "01" : "02";
1739
        }
1740
        if ($this->getCustomerHasSuspiciousActivity() !== null) {
1741
            $data['suspiciousAccActivity'] = $this->getCustomerHasSuspiciousActivity() ? "02" : "01";
1742
        }
1743
        if ($this->getCustomerPurchasesInLast6Months() !== null) {
1744
            $data['nbPurchaseAccount'] = $this->getCustomerPurchasesInLast6Months();
1745
        }
1746
        if ($this->getCustomerAccountCardProvisionsLast24Hours() !== null) {
1747
            $data['provisionAttemptsDay'] = $this->getCustomerAccountCardProvisionsLast24Hours();
1748
        }
1749
        if ($this->getCustomerAccountTransactionsLast24Hours() !== null) {
1750
            $data['txnActivityDay'] = $this->getCustomerAccountTransactionsLast24Hours();
1751
        }
1752
        if ($this->getCustomerAccountTransactionsLastYear() !== null) {
1753
            $data['txnActivityYear'] = $this->getCustomerAccountTransactionsLastYear();
1754
        }
1755
1756
        return $data;
1757
    }
1758
1759
    public function getMerchantRiskData()
1760
    {
1761
        $data = array_filter([
1762
            'deliveryEmailAddress' => $this->getDeliveryEmail(),
1763
            'deliveryTimeframe'    => $this->getDeliveryTimeframeIndicator(),
1764
            'giftCardCount'        => $this->getGiftCardCount(),
1765
            'giftCardCurr'         => $this->getGiftCardCurrency(),
1766
            'preOrderDate'         => $this->getPreOrderDate(),
1767
            'shipIndicator'        => $this->getShippingAddressIndicator(),
1768
        ]);
1769
        if ($this->getGiftCardAmount() !== null) {
1770
            $data['giftCardAmount'] = (int) $this->getGiftCardAmount();
1771
        }
1772
        if ($this->getPurchasingPreOrder() !== null) {
1773
            $data['preOrderPurchaseInd'] = $this->getPurchasingPreOrder() ? "02" : "01";
1774
        }
1775
        if ($this->getCustomerHasPurchasedProductBefore() !== null) {
1776
            $data['reorderItemsInd'] = $this->getCustomerHasPurchasedProductBefore() ? "02" : "01";
1777
        }
1778
1779
        return $data;
1780
    }
1781
1782
    public function getData()
1783
    {
1784
        $data = $this->getBaseData();
1785
1786
        if ($this->getDirectPayment() !== null) {
1787
            $data['Ds_Merchant_DirectPayment'] = $this->getDirectPayment();
1788
        }
1789
1790
        if ($this->getScaExemptionIndicator() !== null) {
1791
            $data['Ds_Merchant_Excep_Sca'] = $this->getScaExemptionIndicator();
1792
        }
1793
1794
        // only generate an EMV 3DS request if requested to
1795
        if ($this->getUse3DS()) {
1796
            // Validating the presence of the card under the assumption that at least an address is required
1797
            // NOTE: normally would validate() for other submission params, but the minimum depends on bank contract
1798
            $this->validate('card');
1799
            $card = $this->getCard();
1800
1801
            $homePhone = array_filter([
1802
                'cc'         => $this->getHomePhoneCountryPrefix(),
1803
                'subscriber' => $this->getHomePhone(),
1804
            ]);
1805
            $mobilePhone = array_filter([
1806
                'cc'         => $this->getMobilePhoneCountryPrefix(),
1807
                'subscriber' => $this->getMobilePhone(),
1808
            ]);
1809
            $workPhone = array_filter([
1810
                'cc'         => $this->getWorkPhoneCountryPrefix(),
1811
                'subscriber' => $this->getWorkPhone(),
1812
            ]);
1813
            // for optional threeDSRequestorAuthenticationInfo param
1814
            $threeDSAuthInfo = array_filter([
1815
                'threeDSReqAuthData'      => $this->get3DsRequestAuthenticationMethodData(),
1816
                'threeDSReqAuthMethod'    => $this->get3DsRequestAuthenticationMethod(),
1817
                'threeDSReqAuthTimestamp' => $this->get3DsRequestAuthenticationTime(),
1818
            ]);
1819
            // for optional DS_MERCHANT_EMV3DS param object
1820
            $emv3DsParameters = array_filter([
1821
                // required parameters for v2
1822
                'browserAcceptHeader'                => $this->getBrowserAcceptHeader(),
1823
                'browserColorDepth'                  => $this->getBrowserColorDepth(),
1824
                'browserIP'                          => $this->getClientIp(),
1825
                'browserJavaEnabled'                 => $this->getBrowserJavaEnabled(),
1826
                'browserLanguage'                    => $this->getBrowserLanguage(),
1827
                'browserScreenHeight'                => $this->getBrowserScreenHeight(),
1828
                'browserScreenWidth'                 => $this->getBrowserScreenWidth(),
1829
                'browserTZ'                          => $this->getBrowserTZ(),
1830
                'browserUserAgent'                   => $this->getBrowserUserAgent(),
1831
                'notificationURL'                    => $this->getNotifyUrl(),
1832
                'protocolVersion'                    => $this->getProtocolVersion(),
1833
                'threeDSCompInd'                     => $this->getThreeDSCompInd(),
1834
                'threeDSInfo'                        => $this->getThreeDSInfo(),
1835
                'threeDSServerTransID'               => $this->getTransactionId(),
1836
                // optional parameters for v2
1837
                'cardholderName'                     => $this->getCardholder(),
1838
                // in Redsys DS_MERCHANT_EMV3DS table as 'E-mail'
1839
                'email'                              => $card->getEmail(),
1840
                'homePhone'                          => $homePhone,
1841
                'mobilePhone'                        => $mobilePhone,
1842
                'workPhone'                          => $workPhone,
1843
                'shipAddrLine1'                      => $card->getShippingAddress1(),
1844
                'shipAddrLine2'                      => $card->getShippingAddress2(),
1845
                'shipAddrLine3'                      => $card->getShippingAddress3(),
1846
                'shipAddrCity'                       => $card->getShippingCity(),
1847
                'shipAddrPostCode'                   => $card->getShippingPostcode(),
1848
                'shipAddrState'                      => $card->getShippingState(),
1849
                'shipAddrCountry'                    => $card->getShippingCountry(),
1850
                'billAddrLine1'                      => $card->getBillingAddress1(),
1851
                'billAddrLine2'                      => $card->getBillingAddress2(),
1852
                'billAddrLine3'                      => $card->getBillingAddress3(),
1853
                'billAddrCity'                       => $card->getBillingCity(),
1854
                'billAddrPostCode'                   => $card->getBillingPostcode(),
1855
                'billAddrState'                      => $card->getBillingState(),
1856
                'billAddrCountry'                    => $card->getBillingCountry(),
1857
                'addrMatch'                          => $this->getAddressMatch(),
1858
                'challengeWindowSize'                => $this->getChallengeWindowSize(),
1859
                'acctID'                             => $this->getCustomerAdditionalInformation(),
1860
                'threeDSRequestorAuthenticationInfo' => $threeDSAuthInfo,
1861
            ]);
1862
1863
            $acctInfo = $this->get3DSAccountInfoData();
1864
            if ($acctInfo !== []) {
1865
                $emv3DsParameters['acctInfo'] = $acctInfo;
1866
            }
1867
1868
            $merchantRiskIndicator = $this->getMerchantRiskData();
1869
            if ($merchantRiskIndicator !== []) {
1870
                $emv3DsParameters['merchantRiskIndicator'] = $merchantRiskIndicator;
1871
            }
1872
1873
            if ($emv3DsParameters !== []) {
1874
                $data['Ds_Merchant_Emv3Ds'] = $emv3DsParameters;
1875
            }
1876
        }
1877
1878
        return $data;
1879
    }
1880
1881
    public function sendData($data)
1882
    {
1883
        $security = new Security;
1884
1885
        $encoded_data = $security->encodeMerchantParameters($data);
1886
1887
        $response_data = array(
1888
            'Ds_SignatureVersion'   => Security::VERSION,
1889
            'Ds_MerchantParameters' => $encoded_data,
1890
            'Ds_Signature'          => $security->createSignature(
1891
                $encoded_data,
1892
                $data['Ds_Merchant_Order'],
1893
                $this->getHmacKey()
1894
            ),
1895
        );
1896
1897
        return $this->response = new PurchaseResponse($this, $response_data);
1898
    }
1899
1900
    public function getEndpoint()
1901
    {
1902
        return $this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint;
1903
    }
1904
1905
    /**
1906
     * Convert a DateTime or timestamp to a formatted date.
1907
     *
1908
     * @param DateTime|int|null $date   The date to format.
1909
     * @param string            $format The format to use.
1910
     *
1911
     * @return string|null The formatted date, or null if date isn't a timestamp or DateTime object.
1912
     */
1913
    protected function formatDateTime($date, $format)
1914
    {
1915
        if (is_int($date)) {
1916
            return (new DateTime('@'.$date))->format($format);
1917
        } elseif ($date instanceof DateTime) {
1918
            return $date->setTimezone(new DateTimeZone('UTC'))->format($format);
1919
        }
1920
    }
1921
}
1922