PurchaseRequest::setCardReference()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Omnipay\GoCardless\Message;
4
5
use Money\Currency;
6
use Money\Formatter\DecimalMoneyFormatter;
7
use Money\Money;
8
use Money\Number;
9
use Money\Parser\DecimalMoneyParser;
10
use Omnipay\Common\Exception\InvalidRequestException;
11
12
class PurchaseRequest extends AbstractRequest
13
{
14
    protected $action = '/payments';
15
16
    public function getMandateId()
17
    {
18
        return $this->getParameter('mandateId');
19
    }
20
21
    public function setMandateId($value)
22
    {
23
        return $this->setParameter('mandateId', $value);
24
    }
25
26
    /**
27
     * Treat mandate as a 'card' to support createCard pattern
28
     */
29
    public function getCardReference()
30
    {
31
        return $this->getMandateId();
32
    }
33
34
    /**
35
     * Treat mandate as a 'card' to support createCard pattern
36
     */
37
    public function setCardReference($value)
38
    {
39
        return $this->setMandateId($value);
40
    }
41
42
    public function getAppFeeAmount()
43
    {
44
        $money = $this->getAppFeeMoney();
45
46
        if ($money !== null) {
47
            $moneyFormatter = new DecimalMoneyFormatter($this->getCurrencies());
48
49
            return $moneyFormatter->format($money);
50
        }
51
    }
52
53
    public function getAppFeeAmountInteger()
54
    {
55
        $money = $this->getAppFeeMoney();
56
57
        if ($money !== null) {
58
            return (int) $money->getAmount();
59
        }
60
    }
61
62
    /**
63
     * {@see \Omnipay\Common\Message\AbstractRequest::getMoney() is private not protected, so copy-pasted and tweaked
64
     */
65
    protected function getAppFeeMoney($amount = null)
66
    {
67
        $currencyCode = $this->getCurrency() ?: 'USD';
68
        $currency = new Currency($currencyCode);
69
70
        $amount = $amount !== null ? $amount : $this->getParameter('appFeeAmount');
71
72
        if ($amount === null) {
73
            return null;
74
        } elseif ($amount instanceof Money) {
75
            $money = $amount;
76
        } elseif (is_integer($amount)) {
77
            $money = new Money($amount, $currency);
78
        } else {
79
            $moneyParser = new DecimalMoneyParser($this->getCurrencies());
80
81
            $number = Number::fromString($amount);
82
83
            // Check for rounding that may occur if too many significant decimal digits are supplied.
84
            $decimal_count = strlen($number->getFractionalPart());
85
            $subunit = $this->getCurrencies()->subunitFor($currency);
86
            if ($decimal_count > $subunit) {
87
                throw new InvalidRequestException('Amount precision is too high for currency.');
88
            }
89
90
            $money = $moneyParser->parse((string) $number, $currency);
91
        }
92
93
        // Check for a negative amount.
94
        if (!$this->negativeAmountAllowed && $money->isNegative()) {
95
            throw new InvalidRequestException('A negative amount is not allowed.');
96
        }
97
98
        // Check for a zero amount.
99
        if (!$this->zeroAmountAllowed && $money->isZero()) {
100
            throw new InvalidRequestException('A zero amount is not allowed.');
101
        }
102
103
        return $money;
104
    }
105
106
    public function setAppFeeAmount($value)
107
    {
108
        return $this->setParameter('appFeeAmount', $value !== null ? (string) $value : null);
109
    }
110
111
    public function getChargeDate()
112
    {
113
        return $this->getParameter('chargeDate');
114
    }
115
116
    /**
117
     * @param string $value  Format "YYYY-MM-DD"
118
     */
119
    public function setChargeDate($value)
120
    {
121
        return $this->setParameter('chargeDate', $value);
122
    }
123
124
    public function getMetaData()
125
    {
126
        return $this->getParameter('metadata');
127
    }
128
129
    /**
130
     * Meta data parameter is a key-value store
131
     *
132
     * Up to 3 keys are permitted, with key names up to 50 characters and values up to 500 characters
133
     *
134
     * @todo validate input and parse into a valid format
135
     */
136
    public function setMetaData($value)
137
    {
138
        return $this->setParameter('metadata', $value);
139
    }
140
141
    public function getRetryIfPossible()
142
    {
143
        return $this->getParameter('retryIfPossible');
144
    }
145
146
    public function setRetryIfPossible($value)
147
    {
148
        return $this->setParameter('retryIfPossible', $value);
149
    }
150
151
    public function getCustomPaymentReferencesEnabled()
152
    {
153
        return $this->getParameter('customPaymentReferencesEnabled');
154
    }
155
156
    public function setCustomPaymentReferencesEnabled($value)
157
    {
158
        return $this->setParameter('customPaymentReferencesEnabled', $value);
159
    }
160
161
    /**
162
     * Override to ensure able to be used, and is a string
163
     *
164
     * Ranges from 10-140 characters depending on the scheme (if enabled)
165
     */
166
    public function getTransactionId()
167
    {
168
        if (!$this->getCustomPaymentReferencesEnabled()) {
169
            return null;
170
        }
171
        $id = parent::getTransactionId();
172
        return $id === null ? null : $id;
0 ignored issues
show
introduced by
The condition $id === null is always false.
Loading history...
173
    }
174
175
    public function getData()
176
    {
177
        $this->validate('amount', 'currency', 'mandateId');
178
179
        // Required values
180
        $data = [
181
            'amount' => $this->getAmountInteger(),
182
            'currency' => $this->getCurrency(),
183
            'links' => ['mandate' => $this->getMandateId()],
184
        ];
185
186
        // Optional values
187
        $data += array_filter([
188
            'app_fee' => $this->getAppFeeAmountInteger(),
189
            'charge_date' => $this->getChargeDate(),
190
            'description' => $this->getDescription(),
191
            'metadata' => $this->getMetaData(),
192
            'reference' => $this->getTransactionId(),
193
            'retry_if_possible' => $this->getRetryIfPossible(),
194
        ]);
195
196
        return $data;
197
    }
198
199
    /**
200
     * Send the request with specified data
201
     *
202
     * @param  mixed $data The data to send
203
     *
204
     * @return PurchaseResponse
205
     */
206
    public function sendData($data)
207
    {
208
        $response = $this->sendRequest(['payments' => $data]);
209
210
        return $this->response = new PurchaseResponse($this, json_decode($response->getBody()->getContents(), true));
211
    }
212
}
213