AuthnetJsonRequest   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 173
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 54
dl 0
loc 173
ccs 54
cts 54
cp 1
rs 10
c 0
b 0
f 0
wmc 16

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A __set() 0 3 1
A setProcessHandler() 0 3 1
A process() 0 13 5
A makeRequest() 0 9 3
A __call() 0 19 2
A __toString() 0 17 2
A getRawRequest() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * This file is part of the AuthnetJSON package.
7
 *
8
 * (c) John Conde <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Authnetjson;
15
16
use Authnetjson\Exception\AuthnetCannotSetParamsException;
17
use Authnetjson\Exception\AuthnetCurlException;
18
use Authnetjson\Exception\AuthnetInvalidJsonException;
19
use Curl\Curl;
20
21
/**
22
 * Creates a request to the Authorize.Net JSON endpoints.
23
 *
24
 * @package   AuthnetJSON
25
 * @author    John Conde <[email protected]>
26
 * @copyright 2015 - 2023 John Conde <[email protected]>
27
 * @license   http://www.apache.org/licenses/LICENSE-2.0.html Apache License, Version 2.0
28
 * @link      https://github.com/stymiee/authnetjson
29
 * @see       https://developer.authorize.net/api/reference/
30
 *
31
 * @method AuthnetJsonResponse authenticateTestRequest()
32
 * @method AuthnetJsonResponse createTransactionRequest(array $array)
33
 * @method AuthnetJsonResponse sendCustomerTransactionReceiptRequest(array $array)
34
 * @method AuthnetJsonResponse ARBCancelSubscriptionRequest(array $array)
35
 * @method AuthnetJsonResponse ARBCreateSubscriptionRequest(array $array)
36
 * @method AuthnetJsonResponse ARBGetSubscriptionStatusRequest(array $array)
37
 * @method AuthnetJsonResponse ARBUpdateSubscriptionRequest(array $array)
38
 * @method AuthnetJsonResponse getAUJobDetailsRequest(array $array)
39
 * @method AuthnetJsonResponse getAUJobSummaryRequest(array $array)
40
 * @method AuthnetJsonResponse createCustomerPaymentProfileRequest(array $array)
41
 * @method AuthnetJsonResponse createCustomerProfileRequest(array $array)
42
 * @method AuthnetJsonResponse createCustomerProfileTransactionRequest_authCapture(array $array)
43
 * @method AuthnetJsonResponse createCustomerProfileTransactionRequest_authOnly(array $array)
44
 * @method AuthnetJsonResponse createCustomerProfileTransactionRequest_captureOnly(array $array)
45
 * @method AuthnetJsonResponse createCustomerProfileTransactionRequest_priorAuthCapture(array $array)
46
 * @method AuthnetJsonResponse createCustomerProfileTransactionRequest_refund(array $array)
47
 * @method AuthnetJsonResponse createCustomerProfileTransactionRequest_void(array $array)
48
 * @method AuthnetJsonResponse createCustomerShippingAddressRequest(array $array)
49
 * @method AuthnetJsonResponse deleteCustomerPaymentProfileRequest(array $array)
50
 * @method AuthnetJsonResponse deleteCustomerProfileRequest(array $array)
51
 * @method AuthnetJsonResponse deleteCustomerShippingAddressRequest(array $array)
52
 * @method AuthnetJsonResponse getCustomerPaymentProfileRequest(array $array)
53
 * @method AuthnetJsonResponse getCustomerProfileIdsRequest(array $array)
54
 * @method AuthnetJsonResponse getCustomerProfileRequest(array $array)
55
 * @method AuthnetJsonResponse getCustomerShippingAddressRequest(array $array)
56
 * @method AuthnetJsonResponse getHostedPaymentPageRequest(array $array)
57
 * @method AuthnetJsonResponse getHostedProfilePageRequest(array $array)
58
 * @method AuthnetJsonResponse getMerchantDetailsRequest(array $array)
59
 * @method AuthnetJsonResponse getUnsettledTransactionListRequest(array $array)
60
 * @method AuthnetJsonResponse updateCustomerPaymentProfileRequest(array $array)
61
 * @method AuthnetJsonResponse updateCustomerProfileRequest(array $array)
62
 * @method AuthnetJsonResponse updateCustomerShippingAddressRequest(array $array)
63
 * @method AuthnetJsonResponse updateHeldTransactionRequest(array $array)
64
 * @method AuthnetJsonResponse updateSplitTenderGroupRequest(array $array)
65
 * @method AuthnetJsonResponse validateCustomerPaymentProfileRequest(array $array)
66
 * @method AuthnetJsonResponse getBatchStatisticsRequest(array $array)
67
 * @method AuthnetJsonResponse getSettledBatchListRequest(array $array)
68
 * @method AuthnetJsonResponse getTransactionDetailsRequest(array $array)
69
 * @method AuthnetJsonResponse getTransactionListRequest(array $array)
70
 */
71
class AuthnetJsonRequest
72
{
73
    /**
74
     * @var int     Maximum number of retires making HTTP request before failure
75
     */
76
    private const MAX_RETRIES = 3;
77
78
    /**
79
     * @var string  Authorize.Net API login ID
80
     */
81
    private $login;
82
83
    /**
84
     * @var string  Authorize.Net API Transaction Key
85
     */
86
    private $transactionKey;
87
88
    /**
89
     * @var string  URL endpoint for processing a transaction
90
     */
91
    private $url;
92
93
    /**
94
     * @var string  JSON formatted API request
95
     */
96
    private $requestJson;
97
98
    /**
99
     * @var object  Wrapper object representing an endpoint
100
     */
101
    private $processor;
102
103
    /**
104
     * @var int Counts number of retries to make API call. Up to self::MAX_RETRIES
0 ignored issues
show
Bug introduced by
Expected "integer" but found "int" for @var tag in member variable comment
Loading history...
105
     */
106
    private $retries;
107
108
    /**
109
     * Creates the request object by setting the Authorize.Net credentials and URL of the endpoint to be used
110
     * for the API call.
111
     *
112
     * @param string $login Authorize.Net API login ID
113
     * @param string $transactionKey Authorize.Net API Transaction Key
114
     * @param string $api_url URL endpoint for processing a transaction
115
     */
116 2
    public function __construct(string $login, string $transactionKey, string $api_url)
117
    {
118 2
        $this->login = $login;
119 2
        $this->transactionKey = $transactionKey;
120 2
        $this->url = $api_url;
121 2
    }
122
123
    /**
124
     * Outputs the account credentials, endpoint URL, and request JSON in a human-readable format
125
     *
126
     * @return string  HTML table containing debugging information
127
     */
128 1
    public function __toString()
129
    {
130 1
        $output = '<table id="authnet-request">' . "\n";
131 1
        $output .= '<caption>Authorize.Net Request</caption>' . "\n";
132 1
        $output .= '<tr><th colspan="2"><b>Class Parameters</b></th></tr>' . "\n";
133 1
        $output .= '<tr><td><b>API Login ID</b></td><td>' . $this->login . '</td></tr>' . "\n";
134 1
        $output .= '<tr><td><b>Transaction Key</b></td><td>' . $this->transactionKey . '</td></tr>' . "\n";
135 1
        $output .= '<tr><td><b>Authnet Server URL</b></td><td>' . $this->url . '</td></tr>' . "\n";
136 1
        $output .= '<tr><th colspan="2"><b>Request JSON</b></th></tr>' . "\n";
137 1
        if (!empty($this->requestJson)) {
138 1
            $output .= '<tr><td colspan="2"><pre>' . "\n";
139 1
            $output .= $this->requestJson . "\n";
140 1
            $output .= '</pre></td></tr>' . "\n";
141
        }
142 1
        $output .= '</table>';
143
144 1
        return $output;
145
    }
146
147
    /**
148
     * The __set() method should never be used as all values to be made in the API call must be passed as an array
149
     *
150
     * @param string $name unused
151
     * @param mixed $value unused
152
     * @throws AuthnetCannotSetParamsException
153
     */
154 2
    public function __set(string $name, $value)
155
    {
156 2
        throw new AuthnetCannotSetParamsException(sprintf('You cannot set parameters directly in %s.', __CLASS__));
157
    }
158
159
    /**
160
     * Magic method that dynamically creates our API call based on the name of the method in the client code and
161
     * the array passed as its parameter.
162
     *
163
     * @param string $api_call name of the API call to be made
164
     * @param array $args the array to be passed to the API
165
     * @return AuthnetJsonResponse
166
     * @throws AuthnetInvalidJsonException
167
     * @throws AuthnetCurlException
168
     */
169 2
    public function __call(string $api_call, array $args = [])
170
    {
171
        $authentication = [
172
            'merchantAuthentication' => [
173 2
                'name'           => $this->login,
174 2
                'transactionKey' => $this->transactionKey,
175
            ]
176
        ];
177 2
        $call = [];
178 2
        if (count($args)) {
179 2
            $call = $args[0];
180
        }
181
        $parameters = [
182 2
            $api_call => $authentication + $call
183
        ];
184 2
        $this->requestJson = json_encode($parameters);
185
186 2
        $response = $this->process();
187 2
        return new AuthnetJsonResponse($response);
188
    }
189
190
    /**
191
     * Makes POST request with retry logic.
192
     */
193 3
    private function makeRequest(): void
0 ignored issues
show
Coding Style introduced by
Private method name "AuthnetJsonRequest::makeRequest" must be prefixed with an underscore
Loading history...
194
    {
195 3
        $this->retries = 0;
196 3
        while ($this->retries < self::MAX_RETRIES) {
197 3
            $this->processor->post($this->url, $this->requestJson);
198 3
            if (!$this->processor->error) {
199 2
                break;
200
            }
201 1
            $this->retries++;
202
        }
203 3
    }
204
205
    /**
206
     * Tells the handler to make the API call to Authorize.Net.
207
     *
208
     * @return string  JSON string containing API response
209
     * @throws AuthnetCurlException
210
     */
211 73
    private function process(): string
0 ignored issues
show
Coding Style introduced by
Private method name "AuthnetJsonRequest::process" must be prefixed with an underscore
Loading history...
212
    {
213 73
        $this->makeRequest();
214 73
        if (!$this->processor->error && isset($this->processor->response)) {
215 71
            return $this->processor->response;
216
        }
217 2
        $error_message = null;
218 2
        $error_code = null;
219 2
        if ($this->processor->error_code || $this->processor->error_message) {
220 1
            $error_message = $this->processor->error_message;
221 1
            $error_code = $this->processor->error_code;
222
        }
223 2
        throw new AuthnetCurlException(sprintf('Connection error: %s (%s)', $error_message, $error_code));
224
    }
225
226
    /**
227
     * Sets the handler to be used to handle our API call. Mainly used for unit testing as Curl is used by default.
228
     *
229
     * @param Curl $processor
230
     */
231 2
    public function setProcessHandler(Curl $processor): void
232
    {
233 2
        $this->processor = $processor;
234 2
    }
235
236
    /**
237
     * Gets the request sent to Authorize.Net in JSON format for logging purposes.
238
     *
239
     * @return string transaction request sent to Authorize.Net in JSON format
240
     */
241 1
    public function getRawRequest(): string
242
    {
243 1
        return $this->requestJson;
244
    }
245
}
246