Test Setup Failed
Push — master ( 4c62c0...259020 )
by Bruce Pinheiro de
02:12
created

CheckoutClient::create()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 2
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
namespace BPCI\SumUp\Checkout;
3
4
use BPCI\SumUp\SumUp;
5
use BPCI\SumUp\OAuth\AccessToken;
6
use BPCI\SumUp\ContextInterface;
7
use BPCI\SumUp\OAuth\AuthenticationHelper;
8
use GuzzleHttp\Exception\BadResponseException;
9
use GuzzleHttp\Exception\ConnectException;
10
use GuzzleHttp\Psr7\Response;
11
use Psr\Http\Message\ResponseInterface;
12
13
/**
14
 * Class CheckoutClient
15
 * @package BPCI\SumUp\Checkout
16
 */
17
class CheckoutClient implements CheckoutClientInterface
18
{
19
	const ENDPOINT = 'checkouts';
20
	protected $context;
21
	protected $lastResponse;
22
23
	function __construct(ContextInterface $context)
24
	{
25
		$this->context = $context;
26
	}
27
28
	/**
29
	 * @inheritDoc
30
	 * @throws BadResponseException
31
	 * @throws ConnectException
32
	 */
33
	public function create(CheckoutInterface $checkout, AccessToken $accessToken = null):? CheckoutInterface
34
	{
35
		return $this->request('post', $checkout, $accessToken, self::getScopes())? $checkout: null;
0 ignored issues
show
Bug introduced by
It seems like $accessToken can also be of type null; however, parameter $accessToken of BPCI\SumUp\Checkout\CheckoutClient::request() does only seem to accept BPCI\SumUp\OAuth\AccessToken, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

35
		return $this->request('post', $checkout, /** @scrutinizer ignore-type */ $accessToken, self::getScopes())? $checkout: null;
Loading history...
36
	}
37
38
	/**
39
	 * @inheritDoc
40
	 * @throws BadResponseException
41
	 * @throws ConnectException
42
	 */
43
	public function get(CheckoutInterface $checkout, AccessToken $accessToken = null):? CheckoutInterface
44
	{
45
		return $this->request('get', $checkout, $accessToken, self::getScopes())? $checkout: null;
0 ignored issues
show
Bug introduced by
It seems like $accessToken can also be of type null; however, parameter $accessToken of BPCI\SumUp\Checkout\CheckoutClient::request() does only seem to accept BPCI\SumUp\OAuth\AccessToken, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

45
		return $this->request('get', $checkout, /** @scrutinizer ignore-type */ $accessToken, self::getScopes())? $checkout: null;
Loading history...
46
	}
47
48
49
	/**
50
	 * @inheritDoc
51
	 * @throws BadResponseException
52
	 * @throws ConnectException
53
	 */
54
	public function complete(CheckoutInterface $checkout, AccessToken $accessToken = null):? CheckoutInterface
55
	{
56
		return $this->request('put', $checkout, $accessToken, self::getScopes())? $checkout: null;
0 ignored issues
show
Bug introduced by
It seems like $accessToken can also be of type null; however, parameter $accessToken of BPCI\SumUp\Checkout\CheckoutClient::request() does only seem to accept BPCI\SumUp\OAuth\AccessToken, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

56
		return $this->request('put', $checkout, /** @scrutinizer ignore-type */ $accessToken, self::getScopes())? $checkout: null;
Loading history...
57
	}
58
59
	/**
60
	 * @param string $action
61
	 * @param CheckoutInterface $checkout
62
	 * @param AccessToken $accessToken
63
	 * @param array $scopes
64
	 * @return bool|null
65
	 * @throws BadResponseException
66
	 * @throws ConnectException
67
	 */
68
	protected function request(string $action, CheckoutInterface $checkout, AccessToken $accessToken, array $scopes):? bool
69
	{
70
		$accessToken = AuthenticationHelper::getValidToken($this->context, $accessToken, $scopes??self::getScopes());
71
72
		$client = SumUp::getClient();
73
		$options = AuthenticationHelper::getOAuthHeader($accessToken);
74
		$options['form_params'] = self::getCheckoutBody($checkout);
75
76
		$uri = self::ENDPOINT . '/' . $checkout->getId();
77
		if($action=='post'){
78
			$uri = self::ENDPOINT;
79
		}
80
81
		/** @var Response $response */
82
		$response = $client->{$action}($uri, $options);
83
		$this->lastResponse = $response;
84
		if($response->getStatusCode() < 300 && $response->getStatusCode() >= 200){
85
			$hydrator = SumUp::getHydrator();
0 ignored issues
show
Bug introduced by
The method getHydrator() does not exist on BPCI\SumUp\SumUp. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

85
			/** @scrutinizer ignore-call */ 
86
   $hydrator = SumUp::getHydrator();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
86
			$data = \GuzzleHttp\json_decode($response->getBody(), true);
87
			$hydrator->hydrate($data, $checkout);
88
			return true;
89
		}
90
91
		return false;
92
	}
93
94
	/**
95
	 * Generate a body to create a new checkout
96
	 *
97
	 * @param CheckoutInterface $checkout
98
	 * @return array
99
	 */
100
	public static function getCheckoutBody(CheckoutInterface $checkout): array
101
	{
102
		return [
103
			"checkout_reference" => $checkout->getReference(),
104
			"amount" => $checkout->getAmount(),
105
			"currency" => $checkout->getCurrency(),
106
			"fee_amount" => $checkout->getFeeAmount(),
107
			"pay_to_email" => $checkout->getPayToEmail(),
108
			"pay_from_email" => $checkout->getPayFromEmail(),
109
			"description" => $checkout->getDescription(),
110
			"return_url" => $checkout->getRedirectUrl(),
111
		];
112
	}
113
114
	public static function getCompleteCheckoutBody(CheckoutInterface $checkout): array
115
	{
116
		$defaultBody = self::getCheckoutBody($checkout);
117
		switch ($checkout->getType()) {
118
			case 'card':
119
				$completeBody = self::getCardBody($checkout);
120
				break;
121
122
			case 'boleto':
123
				$completeBody = self::getBoletoBody($checkout);
124
				break;
125
126
			default:
127
				$completeBody = [];
128
		}
129
130
		return array_merge($defaultBody, $completeBody);
131
	}
132
133
	private static function getCardBody(CheckoutInterface $checkout): array
134
	{
135
		return [
136
			'payment_type' => $checkout->getType(),
137
			'token' => $checkout->getCard()->getToken(),
138
			'customer_id' => $checkout->getCustomer()->getCustomerId()
139
		];
140
	}
141
142
	private static function getBoletoBody(CheckoutInterface $checkout): array
143
	{
144
		$customer = $checkout->getCustomer();
145
		return [
146
			'payment_type' => $checkout->getType(),
147
			'description' => $checkout->getDescription(),
148
			'boleto_details' => [
149
				'cpf_cnpj' => $customer->getCpfCnpj(),
0 ignored issues
show
Bug introduced by
The method getCpfCnpj() does not exist on BPCI\SumUp\Customer\CustomerInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

149
				'cpf_cnpj' => $customer->/** @scrutinizer ignore-call */ getCpfCnpj(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
150
				'payer_name' => $customer->getName(),
151
				'payer_address' => $customer->getAddress(),
152
				'payer_city' => $customer->getAddress()->getCity(),
153
				'payer_state_code' => $customer->getAddress()->getState(),
154
				'payer_post_code' => $customer->getAddress()->getPostalCode()
155
			],
156
		];
157
	}
158
159
	/**
160
	 * @inheritDoc
161
	 */
162
	public static function getScopes(): array
163
	{
164
		return [
165
			'payments',
166
			'boleto'
167
		];
168
	}
169
170
	function getLastResponse(): ResponseInterface
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
171
	{
172
		return $this->lastResponse;
173
	}
174
175
	/**
176
	 * return the context used to created the client.
177
	 * @return ContextInterface
178
	 */
179
	function getContext(): ContextInterface
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
180
	{
181
		return $this->context;
182
	}
183
184
}
185