Completed
Branch php72 (009b60)
by John
05:27
created

AuthnetJsonResponse::isPrePaidCard()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * This file is part of the AuthnetJSON package.
6
 *
7
 * (c) John Conde <[email protected]>
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
namespace JohnConde\Authnet;
14
15
/**
16
 * Adapter for the Authorize.Net JSON API
17
 *
18
 * @package     AuthnetJSON
19
 * @author      John Conde <[email protected]>
20
 * @copyright   John Conde <[email protected]>
21
 * @license     http://www.apache.org/licenses/LICENSE-2.0.html Apache License, Version 2.0
22
 * @link        https://github.com/stymiee/authnetjson
23
 * @see         https://developer.authorize.net/api/reference/
24
 *
25
 * @property    object  $messages
26
 * @property    string  $directResponse
27
 * @property    string  $validationDirectResponse
28
 * @property    object  $transactionResponse
29
 *
30
 * @method null createTransactionRequest(array $array)                                 process a payment
31
 * @method null sendCustomerTransactionReceiptRequest(array $array)                    get a list of unsettled transactions
32
 * @method null ARBCancelSubscriptionRequest(array $array)                             cancel a subscription
33
 * @method null ARBCreateSubscriptionRequest(array $array)                             create a subscription
34
 * @method null ARBGetSubscriptionStatusRequest(array $array)                          get a subscription's status
35
 * @method null ARBUpdateSubscriptionRequest(array $array)                             update a subscription
36
 * @method null createCustomerPaymentProfileRequest(array $array)                      create a payment profile
37
 * @method null createCustomerProfileRequest(array $array)                             create a customer profile
38
 * @method null createCustomerProfileTransactionRequest_authCapture(array $array)      process an Authorization and Capture transaction (Sale)
39
 * @method null createCustomerProfileTransactionRequest_authOnly(array $array)         process an Authorization Only transaction
40
 * @method null createCustomerProfileTransactionRequest_captureOnly(array $array)      process a Capture Only transaction
41
 * @method null createCustomerProfileTransactionRequest_priorAuthCapture(array $array) process a Prior Authorization Capture transaction
42
 * @method null createCustomerProfileTransactionRequest_refund(array $array)           process a Refund (credit)
43
 * @method null createCustomerProfileTransactionRequest_void(array $array)             void a transaction
44
 * @method null createCustomerShippingAddressRequest(array $array)                     create a shipping profile
45
 * @method null deleteCustomerPaymentProfileRequest(array $array)                      delete a payment profile
46
 * @method null deleteCustomerProfileRequest(array $array)                             delete a customer profile
47
 * @method null deleteCustomerShippingAddressRequest(array $array)                     delete a shipping profile
48
 * @method null getCustomerPaymentProfileRequest(array $array)                         retrieve a payment profile
49
 * @method null getCustomerProfileIdsRequest(array $array)                             retrieve a list of profile IDs
50
 * @method null getCustomerProfileRequest(array $array)                                retrieve a customer profile
51
 * @method null getCustomerShippingAddressRequest(array $array)                        retrieve a shipping address
52
 * @method null getHostedProfilePageRequest(array $array)                              retrieve a hosted payment page token
53
 * @method null updateCustomerPaymentProfileRequest(array $array)                      update a customer profile
54
 * @method null updateCustomerProfileRequest(array $array)                             update a customer profile
55
 * @method null updateCustomerShippingAddressRequest(array $array)                     update a shipping address
56
 * @method null updateSplitTenderGroupRequest(array $array)                            update a split tender transaction
57
 * @method null validateCustomerPaymentProfileRequest(array $array)                    validate a payment profile
58
 * @method null getBatchStatisticsRequest(array $array)                                get a summary of a settled batch
59
 * @method null getSettledBatchListRequest(array $array)                               get a list of settled batches
60
 * @method null getTransactionDetailsRequest(array $array)                             get the details of a transaction
61
 * @method null getTransactionListRequest(array $array)                                get a list of transaction in a batch
62
 * @method null getUnsettledTransactionListRequest(array $array)                       get a list of unsettled transactions
63
 */
64
class AuthnetJsonResponse
65
{
66
    /**
67
     * @const Indicates the status code of an approved transaction
68
     */
69
    public const STATUS_APPROVED = 1;
70
71
    /**
72
     * @const Indicates the status code of an declined transaction
73
     */
74
    public const STATUS_DECLINED = 2;
75
76
    /**
77
     * @const Indicates the status code of an transaction which has encountered an error
78
     */
79
    public const STATUS_ERROR = 3;
80
81
    /**
82
     * @const Indicates the status code of a transaction held for review
83
     */
84
    public const STATUS_HELD = 4;
85
86
    /**
87
     * @const Indicates the status code of a transaction held for review
88
     */
89
    public const STATUS_PAYPAL_NEED_CONSENT = 5;
90
91
    /**
92
     * @var     object  SimpleXML object representing the API response
93
     */
94
    private $response;
95
96
    /**
97
     * @var     string  JSON string that is the response sent by Authorize.Net
98
     */
99
    private $responseJson;
100
101
    /**
102
     * @var     object  TransactionResponse
103
     */
104
    private $transactionInfo;
105
106
    /**
107
     * Creates the response object with the response json returned from the API call
108
     *
109
     * @param   string  $responseJson   Response from Authorize.Net
110
     * @throws  AuthnetInvalidJsonException
111
     */
112
    public function __construct(string $responseJson)
113
    {
114
        $this->responseJson = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $responseJson);
115
        if (($this->response = json_decode($this->responseJson, false)) === null) {
116
            throw new AuthnetInvalidJsonException('Invalid JSON returned by the API');
117
        }
118
119
        if ($this->directResponse || $this->validationDirectResponse) {
120
            $dr = $this->directResponse ?: $this->validationDirectResponse;
121
            $this->transactionInfo = new TransactionResponse($dr);
122
        }
123
    }
124
125
    /**
126
     * Outputs the response JSON in a human readable format
127
     *
128
     * @return  string  HTML table containing debugging information
129
     */
130
    public function __toString()
131
    {
132
        $output  = '<table id="authnet-response">'."\n";
133
        $output .= '<caption>Authorize.Net Response</caption>'."\n";
134
        $output .= '<tr>'."\n\t\t".'<th colspan="2"><b>Response JSON</b></th>'."\n".'</tr>'."\n";
135
        $output .= '<tr><td colspan="2"><pre>'."\n";
136
        $output .= $this->responseJson."\n";
137
        $output .= '</pre></td></tr>'."\n";
138
        $output .= '</table>';
139
140
        return $output;
141
    }
142
143
    /**
144
     * Gets a response variable from the API response
145
     *
146
     * @param   string  $var    unused
147
     * @return  string          requested variable from the API call response
148
     */
149
    public function __get(string $var)
150
    {
151
        return $this->response->{$var} ?? null;
152
    }
153
154
    /**
155
     * Checks if the API call is not in an error state
156
     *
157
     * @return  bool    Whether the transaction was in an successful state
158
     */
159
    public function isSuccessful() : bool
160
    {
161
        return strtolower($this->messages->resultCode) === 'ok';
162
    }
163
164
    /**
165
     * Checks if the API is reporting an error with the API call
166
     *
167
     * @return  bool    Whether the transaction was in an error state
168
     */
169
    public function isError() : bool
170
    {
171
        return strtolower($this->messages->resultCode) === 'error';
172
    }
173
174
    /**
175
     * Checks if a transaction was approved
176
     *
177
     * @return bool     true if the transaction is approved
178
     */
179
    public function isApproved() : bool
180
    {
181
        return $this->isSuccessful() && $this->checkTransactionStatus(self::STATUS_APPROVED);
182
    }
183
184
    /**
185
     * Checks if a transaction was completed using a prepaid card
186
     *
187
     * @return bool     true if the transaction was completed using a prepaid card
188
     */
189
    public function isPrePaidCard() : bool
190
    {
191
        return isset($this->transactionResponse->prePaidCard);
192
    }
193
194
    /**
195
     * Checks if a transaction was declined
196
     *
197
     * @return bool     true if the transaction is declined
198
     */
199
    public function isDeclined() : bool
200
    {
201
        return $this->isSuccessful() && $this->checkTransactionStatus(self::STATUS_DECLINED);
202
    }
203
204
    /**
205
     * Check to see if the ResponseCode matches the expected value
206
     *
207
     * @param  integer $status
208
     * @return bool Check to see if the ResponseCode matches the expected value
209
     */
210
    protected function checkTransactionStatus(int $status) : bool
211
    {
212
        if ($this->transactionInfo instanceof TransactionResponse) {
213
            $match = (int) $this->transactionInfo->getTransactionResponseField('ResponseCode') === $status;
214
        } else {
215
            $match = (int) $this->transactionResponse->responseCode === $status;
216
        }
217
        return $match;
218
    }
219
220
    /**
221
     * Gets the transaction response field for AIM and CIM transactions.
222
     *
223
     * @param   mixed  $field  Name or key of the transaction field to be retrieved
224
     * @return  string Transaction field to be retrieved
225
     * @throws  AuthnetTransactionResponseCallException
226
     */
227
    public function getTransactionResponseField($field) : string
228
    {
229
        if ($this->transactionInfo instanceof TransactionResponse) {
230
            return $this->transactionInfo->getTransactionResponseField($field);
231
        }
232
        throw new AuthnetTransactionResponseCallException('This API call does not have any transaction response data');
233
    }
234
235
    /**
236
     * Gets the transaction response from Authorize.Net in JSON format for logging purposes
237
     *
238
     * @return  string transaction response from Authorize.Net in JSON format
239
     */
240
    public function getRawResponse() : string
241
    {
242
        return $this->responseJson;
243
    }
244
245
    /**
246
     * An alias of self::getErrorText()
247
     *
248
     * @return  string Error response from Authorize.Net
249
     */
250
    public function getErrorMessage() : string
251
    {
252
        return $this->getErrorText();
253
    }
254
255
    /**
256
     * If an error has occurred, returns the error message
257
     *
258
     * @return  string Error response from Authorize.Net
259
     */
260
    public function getErrorText() : string
261
    {
262
        return $this->getError('text');
263
    }
264
265
    /**
266
     * If an error has occurred, returns the error message
267
     *
268
     * @return  string Error response from Authorize.Net
269
     */
270
    public function getErrorCode() : string
271
    {
272
        return $this->getError('code');
273
    }
274
275
    /**
276
     * @param  string   $type     Whether to get the error code or text
277
     * @return string
278
     */
279
    private function getError(string $type) : string
280
    {
281
        $msg = '';
282
        if ($this->isError()) {
283
            $prop = sprintf('error%s', ucfirst($type));
284
            $msg = $this->messages->message[0]->{$type};
285
            if (@$this->transactionResponse->errors[0]->{$prop}) {
286
                $msg = $this->transactionResponse->errors[0]->{$prop};
287
            }
288
        }
289
        return $msg;
290
    }
291
}
292