16 private const MERCHANT_SESSION_GATEWAY =
"https://apple-pay-gateway.apple.com/paymentservices/paymentSession";
17 private const FILE_PREFIX =
"apple_pay_cert_";
19 private const HTTP_RESPONSE_CODE_OK = 200;
22 private $merchantIdentifier;
28 private $initiativeContext;
30 private $applePayCert;
40 public function __construct(
string $merchantIdentifier,
string $displayName,
string $domainName,
string $applePayCert)
42 $this->merchantIdentifier = $merchantIdentifier;
43 $this->displayName = $displayName;
44 $this->domainName = $domainName;
45 $this->applePayCert = $applePayCert;
53 $this->initiativeContext = $initiativeContext;
64 $requestParameters = [
65 "merchantIdentifier" => $this->merchantIdentifier,
66 "displayName" => $this->displayName,
67 "initiativeContext" => $this->domainName,
68 "initiative" =>
"web",
73 $result = $this->sendRequest(
$url, $requestParameters);
90 $requestParameters = [
91 "merchantIdentifier" => hash(
"sha256", $this->merchantIdentifier),
92 "displayName" => $this->displayName,
93 "domainName" => $this->domainName,
94 "initiative" =>
"messaging",
95 "initiativeContext" => $this->initiativeContext,
100 $result = $this->sendRequest(self::MERCHANT_SESSION_GATEWAY, $requestParameters);
120 $checkConfigResult = $this->checkConfig(
$config);
121 if (!$checkConfigResult->isSuccess())
123 $result->addErrors($checkConfigResult->getErrors());
128 if (!$messengerDataResult->isSuccess())
130 $result->addErrors($messengerDataResult->getErrors());
134 $result->setData($messengerDataResult->getData());
150 if (!$merchantSessionResult->isSuccess())
152 $result->addErrors($merchantSessionResult->getErrors());
161 "title" =>
$config[
"merchantDisplayName"],
162 "subtitle" => Loc::getMessage(
163 "SALE_APPLE_PAY_ORDER_SUBTITLE",
172 "title" => Loc::getMessage(
173 "SALE_APPLE_PAY_ORDER_SUBTITLE",
182 "requestIdentifier" => self::getUuid(),
183 "mspVersion" =>
"1.0",
185 "paymentRequest" => [
188 "label" => Loc::getMessage(
189 "SALE_APPLE_PAY_LINE_ITEM_ORDER",
194 "amount" => (string)$paymentSum,
199 "label" => Loc::getMessage(
"SALE_APPLE_PAY_LINE_ITEM_TOTAL"),
200 "amount" => (string)$paymentSum,
204 "merchantIdentifier" => $this->merchantIdentifier,
205 "supportedNetworks" =>
$config[
"supportedNetworks"],
206 "merchantCapabilities" =>
$config[
"merchantCapabilities"] ?? [
"supports3DS"],
208 "merchantName" =>
$config[
"merchantName"],
209 "countryCode" =>
$config[
"countryCode"],
210 "currencyCode" =>
$payment->getField(
"CURRENCY"),
211 "requiredBillingContactFields" =>
$config[
"requiredBillingContactFields"] ?? [],
212 "requiredShippingContactFields" =>
$config[
"requiredShippingContactFields"] ?? [],
214 "merchantSession" => $merchantSessionResult->getData(),
215 "endpoints" =>
$config[
"endpoints"]
220 "replyMessage" => $replyMessage,
221 "receivedMessage" => $receivedMessage,
232 private function checkConfig(
array $config): ServiceResult
236 if (empty(
$config[
"merchantDisplayName"]))
238 $result->addError(
new Main\Error(
"merchantDisplayName is empty",
"merchantDisplayName"));
241 if (empty(
$config[
"supportedNetworks"]))
243 $result->addError(
new Main\Error(
"supportedNetworks is empty",
"supportedNetworks"));
246 if (empty(
$config[
"merchantName"]))
248 $result->addError(
new Main\
Error(
"merchantName is empty",
"merchantName"));
251 if (empty(
$config[
"countryCode"]))
253 $result->addError(
new Main\
Error(
"countryCode is empty",
"countryCode"));
256 if (empty(
$config[
"endpoints"]))
258 $result->addError(
new Main\
Error(
"endpoints is empty",
"endpoints"));
278 $httpClient =
new Main\Web\HttpClient();
279 foreach ($this->getHeaders() as
$name => $value)
281 $httpClient->setHeader(
$name, $value);
284 $httpClient->setContextOptions($this->getContextOptions($this->applePayCert));
297 $errors = $httpClient->getError();
310 $httpStatus = $httpClient->getStatus();
311 if ($httpStatus !== self::HTTP_RESPONSE_CODE_OK)
318 "SALE_APPLE_PAY_HTTP_STATUS_MESSAGE",
320 "#HTTP_STATUS#" => $httpStatus,
321 "#STATUS_MESSAGE#" =>
$response[
"statusMessage"],
332 "SALE_APPLE_PAY_HTTP_STATUS_CODE",
334 "#HTTP_STATUS#" => $httpStatus,
351 private function getHeaders():
array
354 "Content-Type" =>
"application/json",
362 private function getContextOptions($applePayCert):
array
366 $applePayCertPath = $this->createTmpFile($applePayCert);
367 if ($applePayCertPath)
371 "local_cert" => $applePayCertPath,
372 "local_pk" => $applePayCertPath
385 private function createTmpFile(
$data): string
387 $filePath = \CTempFile::GetFileName(self::FILE_PREFIX.
randString());
389 if ($filePath && (
$data !==
null))
391 file_put_contents($filePath,
$data);
394 return $filePath ??
"";
404 return Main\Web\Json::encode(
$data, JSON_UNESCAPED_UNICODE);
411 private static function decode(
$data)
415 return Main\Web\Json::decode(
$data);
417 catch (Main\ArgumentException $exception)
426 private static function getUuid(): string
428 return sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
429 mt_rand(0, 0xffff), mt_rand(0, 0xffff),
431 mt_rand(0, 0x0fff) | 0x4000,
432 mt_rand(0, 0x3fff) | 0x8000,
433 mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
444 public static function isApplePaySystem(
array $paySystem): bool
452 isset($paySystem[
'ACTION_FILE'], $paySystem[
'PS_MODE'])
454 && $paySystem[
'PS_MODE'] === $className::PAYMENT_METHOD_APPLE_PAY