Gateway::widgetHtml()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 35
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 19
c 1
b 0
f 0
nc 1
nop 9
dl 0
loc 35
rs 9.6333

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php declare(strict_types=1);
2
3
namespace Getloy;
4
5
use \Exception;
6
use Getloy\PaymentProviders;
7
use Getloy\CallbackDetails;
8
use Getloy\TransactionDetails\OrderDetails;
9
use Getloy\TransactionDetails\PayeeDetails;
10
11
/**
12
 * Gateway
13
 */
14
class Gateway
15
{
16
    protected $getloyToken;
17
    protected $requestOrigin;
18
    protected $paymentProviders = [];
19
20
    public function __construct(
21
        string $getloyToken,
22
        string $requestOrigin = 'getloy-integration-library-php v1.0.0'
23
    ) {
24
25
        $this->getloyToken = $getloyToken;
26
        $this->requestOrigin = $requestOrigin;
27
    }
28
29
    /**
30
     * Getter for the GetLoy token.
31
     *
32
     * @return string
33
     */
34
    public function getloyToken(): string
35
    {
36
        return $this->getloyToken;
37
    }
38
39
    /**
40
     * Register a payment provider
41
     * @param string $paymentMethod Payment method identifier.
42
     * @param array $config Configuration for the payment method.
43
     * @return boolean True if the registration completed successfully.
44
     * @throws Exception If the provided payment method is unsupported or the payment method
45
     *                   configuration is incomplete.
46
     */
47
    public function registerPaymentProvider(string $paymentMethod, array $config): bool
48
    {
49
        $this->paymentProviders[$paymentMethod] = PaymentProviders::paymentProviderFactory(
50
            $paymentMethod,
51
            $config
52
        );
53
        return true;
54
    }
55
56
    /**
57
     * Generates JavaScript code for the GetLoy widget.
58
     * @param array $options The widget options.
59
     * @return string Widget code (without enclosing <scipt> tag).
60
     * @throws Exception if $options array does not include the key `payload`.
61
     */
62
    protected function widgetCode(array $options): string
63
    {
64
        if (!array_key_exists('payload', $options)) {
65
            throw new Exception('Cannot create widget without payload option!');
66
        }
67
        $optionString = '';
68
        foreach ($options as $option => $value) {
69
            $optionString .= sprintf(
70
                "gl(%s, %s);",
71
                json_encode($option),
72
                json_encode($value)
73
            );
74
        }
75
        return sprintf(
76
            "!function(g,e,t,l,o,y){g.GetLoyPayments=t;g[t]||(g[t]=function(){"
77
            . "(g[t].q=g[t].q||[]).push(arguments)});g[t].l=+new Date;o=e.createElement(l);"
78
            . "y=e.getElementsByTagName(l)[0];o.src='https://some.getloy.com/getloy.js';"
79
            . "y.parentNode.insertBefore(o,y)}(window,document,'gl','script');"
80
            . "%s",
81
            $optionString
82
        );
83
    }
84
85
    /**
86
     * Generates HTML code for the GetLoy widget.
87
     * @param string $transactionId Payment transaction identifier.
88
     * @param string $paymentMethod Payment method identifier (see {@see \Getloy\PaymentProviders}).
89
     * @param OrderDetails $order Order details.
90
     * @param PayeeDetails $payee Payee details.
91
     * @param string $callbackUrl URL to call from the GetLoy backend to notify the custom web
92
     *                            application of status updates for the payment transaction.
93
     * @param string $successUrl URL to redirect the user to when the payment completed successfully
94
     *                           (optional).
95
     * @param string $cancelUrl URL to redirect the user to when the payment gets cancelled or fails
96
     *                          (optional).
97
     * @param string $paymentMethodVariant Payment method variant name (optional).
98
     * @param bool $addPopupContainer Whether to add the HTML element that will contain the payment
99
     *                                popup (default is true).
100
     * @return string Widget HTML code.
101
     * @throws Exception if the provided transaction details are invalid.
102
     */
103
    public function widgetHtml(
104
        string $transactionId,
105
        string $paymentMethod,
106
        OrderDetails $order,
107
        PayeeDetails $payee,
108
        string $callbackUrl,
109
        string $successUrl = null,
110
        string $cancelUrl = null,
111
        string $paymentMethodVariant = null,
112
        bool $addPopupContainer = true
113
    ): string {
114
115
        $payload = $this->widgetPayload(
116
            $transactionId,
117
            $paymentMethod,
118
            $order,
119
            $payee,
120
            $callbackUrl,
121
            $paymentMethodVariant
122
        );
123
        $widgetOptions = [
124
            'payload' => $payload,
125
            'success_callback' => sprintf(
126
                "function(){window.location='%s';}",
127
                addcslashes($successUrl, "'")
128
            ),
129
            'cancel_callback' => sprintf(
130
                "function(){window.location='%s';}",
131
                addcslashes($cancelUrl, "'")
132
            ),
133
        ];
134
        return sprintf(
135
            "%s<script>\n%s\n</script>",
136
            $addPopupContainer ? '<div class="getloy"></div>' : '',
137
            $this->widgetCode($widgetOptions)
138
        );
139
    }
140
141
    /**
142
     * Generate payload for GetLoy widget.
143
     *
144
     * @param string $transactionId Payment transaction identifier.
145
     * @param string $paymentMethod Payment method identifier.
146
     * @param OrderDetails $order Order details.
147
     * @param PayeeDetails $payee Payee details.
148
     * @param string $callbackUrl URL to call from the GetLoy backend to notify the custom web
149
     *                            application of status updates for the payment transaction.
150
     * @param string $paymentMethodVariant Payment method variant name (optional).
151
     * @return string Widget payload (JSON string)
152
     */
153
    public function widgetPayload(
154
        string $transactionId,
155
        string $paymentMethod,
156
        OrderDetails $order,
157
        PayeeDetails $payee,
158
        string $callbackUrl,
159
        string $paymentMethodVariant = null
160
    ): array {
161
162
        $payload = [
163
            'tid' => $transactionId,
164
            'provider' => $paymentMethod,
165
            'request_origin' => $this->requestOrigin,
166
            'callback' => $callbackUrl,
167
            'merchant_hash' => $this->merchantHash(),
168
            'auth_hash' => $this->transactionHash($transactionId, $order),
169
            'test_mode' => $this->paymentProviders[$paymentMethod]->get('testMode'),
170
            'payee' => $payee->payloadConfig(),
171
            'order' => $order->payloadConfig(),
172
            'payment_provider' => $this->paymentProviders[$paymentMethod]->paymentProviderPayload(
173
                $transactionId,
174
                $order,
175
                $payee,
176
                $callbackUrl,
177
                $paymentMethodVariant
178
            ),
179
        ];
180
        if ($paymentMethodVariant) {
181
            $payload['provider_variant'] = $paymentMethodVariant;
182
        }
183
        return $payload;
184
    }
185
186
    /**
187
     * Parse and validate the body of a callback request.
188
     *
189
     * @param string $jsonCallback
190
     * @return CallbackDetails
191
     */
192
    public function parseCallback(string $jsonCallback): CallbackDetails
193
    {
194
        $callbackDetails = new CallbackDetails($this);
195
        $callbackDetails->parseCallback($jsonCallback);
196
        return $callbackDetails;
197
    }
198
199
    /**
200
     * Validate a callback request.
201
     *
202
     * @param array $callbackBody
203
     * @return CallbackDetails
204
     */
205
    public function validateCallback(array $callbackBody): CallbackDetails
206
    {
207
        $callbackDetails = new CallbackDetails($this);
208
        $callbackDetails->validateCallback($callbackBody);
209
        return $callbackDetails;
210
    }
211
212
    /**
213
     * Read callback body from php://input, parse and validate the  request.
214
     *
215
     * @return CallbackDetails
216
     */
217
    public function readCallbackBodyAndParse(): CallbackDetails
218
    {
219
        $callbackBody = file_get_contents('php://input');
220
        return $this->parseCallback($callbackBody);
221
    }
222
223
    /**
224
     * Compute the merchant hash.
225
     *
226
     * @return string Hash value (hex string).
227
     */
228
    protected function merchantHash(): string
229
    {
230
        return hash_hmac('sha512', $this->getloyToken, $this->getloyToken);
231
    }
232
233
    /**
234
     * Compute the transaction authentication hash.
235
     *
236
     * @param string $transactionId Payment transaction identifier.
237
     * @param OrderDetails $order Order details.
238
     * @return string Hash value (hex string).
239
     */
240
    protected function transactionHash(string $transactionId, OrderDetails $order): string
241
    {
242
        return hash_hmac(
243
            'sha512',
244
            sprintf(
245
                '%s%s%.2f',
246
                $this->getloyToken,
247
                $transactionId,
248
                $order->totalAmount()
249
            ),
250
            $this->getloyToken
251
        );
252
    }
253
}
254