public function verifySignature(?string $signature = null): bool
	{
		// check merchantId and accountId from request
		if (
			$this->getRequestMerchantId() !== $this->getMerchantConfig()->merchantId
			|| $this->getRequestAccountId() !== $this->getMerchantConfig()->accountId
		) {
			throw new InvalidSignatureException();
		}

		if ($signature === null) {
			$signature = $this->signature;
		}

		// Compute the signature for specified arguments, and compare it to the specified signature.

		$out = [];
		$out[] = 'merchantId=' . $this->getRequestMerchantId();
		$out[] = 'accountId=' . $this->getRequestAccountId();
		foreach (array_merge(self::$REQUIRED_ARGS, self::$OPTIONAL_ARGS) as $property) {
			if ($this->{$property} !== null) {
				$value = $this->{$property};

				if (in_array($property, self::$FLOAT_ARGS, true)) {
					$value = number_format($value, 2, '.', '');
				} elseif (in_array($property, self::$BOOL_ARGS, true)) {
					$value = $value ? '1' : '0';
				}

				$out[] = sprintf('%s=%s', $property, $value);
			}
		}

		$out[] = 'password=' . $this->getMerchantConfig()->password;

		$sig = $this->hashFunction(implode('&', $out));

		if ($sig === $signature) {
			return true;
		}

		throw new InvalidSignatureException();
	}