Completed
Push — master ( c77504...88cec9 )
by Wills
02:28
created

GivePayGatewayClient::generateTokenizationRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 12
nc 1
nop 3
dl 0
loc 17
ccs 0
cts 9
cp 0
crap 2
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
namespace GivePay\Gateway;
4
5
use cURL\Request;
6
use \Exception;
7
use GivePay\Gateway\Transactions\Card;
8
use GivePay\Gateway\Transactions\TerminalType;
9
use GivePay\Gateway\Transactions\TokenRequest;
10
use GivePay\Gateway\Transactions\V0id;
11
use Psr\Log\LoggerInterface;
12
use Psr\Log\NullLogger;
13
14
final class GivePayGatewayClient {
15
16
	public $token_endpoint;
17
18
	public $gateway_url;
19
20
	private $client_secret;
21
22
	private $client_id;
23
24
	private $logger;
25
26
	/**
27
	 * FRP_Gateway constructor.
28
	 *
29
	 * @param string $client_id
30
	 * @param string $client_secret
31
	 * @param string $token_endpoint
32
	 * @param string $gateway_url
33
     * @param LoggerInterface $logger
34
	 */
35
	public function __construct(
36
		$client_id,
37
		$client_secret,
38
		$token_endpoint = 'https://portal.flatratepay.com/connect/token',
39
		$gateway_url = 'https://gateway.givepaycommerce.com',
40
        $logger = null
41
	) {
42
		$this->token_endpoint = $token_endpoint;
43
		$this->gateway_url    = $gateway_url;
44
45
		$this->client_secret = $client_secret;
46
		$this->client_id     = $client_id;
47
48
		if ($logger == null) {
49
		    $this->logger = new NullLogger();
50
        } else {
51
		    $this->logger = $logger;
52
		}
53
	}
54
55
	/**
56
	 * @param string $merchant_id The merchant ID for the website
57
	 * @param string $terminal_id The terminal ID for the website
58
	 * @param Transactions\Sale $sale The transaction information
59
	 *
60
	 * @throws Exception
61
	 * @return TransactionResult
62
	 */
63
	public function chargeAmount( $merchant_id, $terminal_id, $sale ) {
64
		if ( null == $sale ) {
65
			throw new \Exception( '$sale is null' );
66
		}
67
68
		$access_token = $this->getAccessToken( $this->client_id, $this->client_secret, $this->token_endpoint );
69
		if ( null == $access_token ) {
70
			throw new \Exception( 'Could not authorize with gateway.' );
71
		}
72
73
		return $this->makeSaleRequest( $access_token, $merchant_id, $terminal_id, $sale );
74
	}
75
76
	/**
77
	 * @param string $transaction_id
78
	 * @param string $merchant_id
79
	 * @param string $terminal_id
80
	 *
81
	 * @throws Exception
82
	 * @return TransactionResult
83
	 */
84
	public function voidTransaction( $transaction_id, $merchant_id, $terminal_id ) {
85
		if ( null == $transaction_id ) {
86
			throw new Exception( 'Transaction ID is null' );
87
		}
88
89
		$access_token = $this->getAccessToken( $this->client_id, $this->client_secret, $this->token_endpoint );
90
		if ( null == $access_token ) {
91
			throw new Exception( 'Could not authorize with gateway.' );
92
		}
93
94
		return $this->makeVoidRequest( $access_token, $transaction_id, $merchant_id, $terminal_id );
95
	}
96
97
	/**
98
	 * Stores the card and gets a token from the gateway
99
	 *
100
	 * @param string $merchant_id
101
	 * @param string $terminal_id
102
	 * @param Card $card
103
	 *
104
	 * @return string
105
	 * @throws Exception
106
	 */
107
	public function storeCard( $merchant_id, $terminal_id, $card ) {
108
		if ( null == $card ) {
109
			throw new Exception( 'Card is null' );
110
		}
111
112
		$access_token = $this->getAccessToken( $this->client_id, $this->client_secret, $this->token_endpoint );
113
		if ( null == $access_token ) {
114
			throw new Exception( 'Could not store card with gateway.' );
115
		}
116
117
		return $this->makeStoreCardRequest( $access_token, $merchant_id, $terminal_id, $card );
118
	}
119
120
	/**
121
	 * @param string $access_token
122
	 * @param string $merchant_id
123
	 * @param string $terminal_id
124
     * @param Transactions\Sale $sale
125
	 *
126
	 * @return TransactionResult
127
	 */
128
	private function makeSaleRequest( $access_token, $merchant_id, $terminal_id, $sale ) {
129
		$sale_request = $sale->serialize($merchant_id, $terminal_id);
130
		$body = json_encode( $sale_request );
131
132
		$this->logger->info("Starting transaction for $" . $sale->getTotal());
133
134
		$request = new Request($this->gateway_url . 'api/v1/transactions/sale');
135
		$request->getOptions()
136
            ->set(CURLOPT_RETURNTRANSFER, true)
137
            ->set(CURLOPT_POST, true)
138
            ->set(CURLOPT_POSTFIELDS, $body)
139
            ->set(CURLOPT_HTTPHEADER, array(
140
                'Content-Type: application/json',
141
                'Content-Length: ' . strlen($body),
142
                'Accept: application/json',
143
                'Authorization: Bearer ' . $access_token
144
            ));
145
        $response = $request->send();
146
147
        $this->logger->debug( "Transaction completed" );
148
149
		$sale_response = json_decode( $response->getContent() );
150
151
		if ( $sale_response->success ) {
152
			$transaction_id = $sale_response->result->transaction_id;
153
154
            $this->logger->info( 'Payment completed. Transaction ID: ' . $transaction_id );
155
156
			return new TransactionResult( true, $transaction_id );
157
		} else {
158
			$error_message = $sale_response->error->message;
159
			$code          = $sale_response->error->code;
160
161
            $this->logger->debug( "Sale response: " . var_export( $sale_response, true ) );
162
            $this->logger->error( "Payment failed." );
163
164
			return new TransactionResult( false, null, $error_message, $code );
165
		}
166
	}
167
168
	/**
169
	 * Makes a VOID request
170
	 *
171
	 * @param string $access_token
172
	 * @param string $transaction_id
173
	 * @param string $merchant_id
174
	 * @param string $terminal_id
175
	 *
176
	 * @return TransactionResult
177
	 */
178
	private function makeVoidRequest( $access_token, $transaction_id, $merchant_id, $terminal_id ) {
179
	    $void = new V0id(TerminalType::$ECommerce, $transaction_id);
180
		$void_request = $void->serialize($merchant_id, $terminal_id);
181
182
		$body = json_encode( $void_request );
183
184
        $this->logger->info( "Starting void transaction for transaction# " . $transaction_id );
185
186
        $request = new Request($this->gateway_url . 'api/v1/transactions/void');
187
        $request->getOptions()
188
            ->set(CURLOPT_RETURNTRANSFER, true)
189
            ->set(CURLOPT_POST, true)
190
            ->set(CURLOPT_POSTFIELDS, $body)
191
            ->set(CURLOPT_HTTPHEADER, array(
192
                'Content-Type: application/json',
193
                'Content-Length: ' . strlen($body),
194
                'Accept: application/json',
195
                'Authorization: Bearer ' . $access_token
196
            ));
197
        $response = $request->send();
198
199
        $this->logger->debug( "Transaction completed" );
200
201
		$void_response = json_decode( $response->getContent() );
202
203
		if ( $void_response->success ) {
204
			$transaction_id = $void_response->result->transaction_id;
205
206
            $this->logger->info( 'Void completed. Transaction ID: ' . $transaction_id );
207
208
			return new TransactionResult( true, $transaction_id );
209
		} else {
210
			$error_message = $void_response->error->message;
211
			$code          = $void_response->error->code;
212
213
            $this->logger->debug( "Void response: " . var_export( $void_response, true ) );
214
            $this->logger->error( "Void failed." );
215
216
			return new TransactionResult( false, null, $error_message, $code );
217
		}
218
	}
219
220
	/**
221
	 * stores a card in the gateway
222
	 *
223
	 * @param string $access_token
224
	 * @param string $terminal_id
225
	 * @param string $merchant_id
226
	 * @param mixed $card
227
	 *
228
	 * @return string
229
	 */
230
	private function makeStoreCardRequest( $access_token, $merchant_id, $terminal_id, $card ) {
231
		$token_request = new TokenRequest($card, TerminalType::$ECommerce);
232
        $token_request_string = $token_request->serialize($merchant_id, $terminal_id);
233
		$body = json_encode( $token_request_string );
234
235
        $this->logger->info( "Starting request for tokenization" );
236
237
        $request = new Request($this->gateway_url . 'api/v1/transactions/tokenize');
238
        $request->getOptions()
239
            ->set(CURLOPT_RETURNTRANSFER, true)
240
            ->set(CURLOPT_POST, true)
241
            ->set(CURLOPT_POSTFIELDS, $body)
242
            ->set(CURLOPT_HTTPHEADER, array(
243
                'Content-Type: application/json',
244
                'Content-Length: ' . strlen($body),
245
                'Accept: application/json',
246
                'Authorization: Bearer ' . $access_token
247
            ));
248
        $response = $request->send();
249
250
        $this->logger->debug( "Transaction completed" );
251
252
        $token_response = json_decode( $response->getContent() );
253
254
		if ( $token_response->success ) {
255
			$transaction_id = $token_response->result->transaction_id;
256
257
            $this->logger->info( 'Tokenization completed. Transaction ID: ' . $transaction_id );
258
259
			return $token_response->result->token;
260
		} else {
261
            $this->logger->debug( "Tokenization response: " . var_export( $token_response, true ) );
262
            $this->logger->error( "Tokenization failed." );
263
264
			return '';
265
		}
266
	}
267
268
	/**
269
	 * Gets an access token from the auth server
270
	 *
271
	 * @param string $client_id the client ID
272
	 * @param string $client_secret the client secret
273
	 * @param string $token_url the token endpoint
274
	 *
275
	 * @return string
276
	 */
277
	private function getAccessToken( $client_id, $client_secret, $token_url ) {
278
		$token_data = array(
279
			'client_id'     => $client_id,
280
			'grant_type'    => 'client_credentials',
281
			'client_secret' => $client_secret,
282
			'scope'         => 'authorize:transactions capture:transactions sale:transactions refund:transactions void:transactions tokenize:transactions'
283
		);
284
285
        $request = new Request($token_url);
286
        $request->getOptions()
287
            ->set(CURLOPT_RETURNTRANSFER, true)
288
            ->set(CURLOPT_POST, true)
289
            ->set(CURLOPT_POSTFIELDS, $token_data)
290
            ->set(CURLOPT_HTTPHEADER, array(
291
                'Content-Type' => 'application/x-www-form-urlencoded',
292
                'Accept: application/json'
293
            ));
294
        $response = $request->send();
295
296
		if ( $response->hasError() ) {
297
            $this->logger->debug( 'Token response status code was ' . $response->getError()->getCode() );
298
            $this->logger->debug( "Token request ended in failure: " . var_export( $response, true ) );
299
            $this->logger->error( "Gateway authorization failed. Check credentials." );
300
301
			return null;
302
		}
303
304
        $this->logger->debug( "Token request was a success: " . $response->getContent());
305
		$token = json_decode( $response->getContent() );
306
307
		return $token->access_token;
308
	}
309
}