285 lines
8.9 KiB
PHP
285 lines
8.9 KiB
PHP
<?php
|
|
/**
|
|
* Apple Pay domain association
|
|
*
|
|
* @package checkout-plugins-stripe-woo
|
|
* @since 1.1.0
|
|
*/
|
|
|
|
namespace CPSW\Compatibility;
|
|
|
|
use CPSW\Inc\Traits\Get_Instance;
|
|
use CPSW\Gateway\Stripe\Stripe_Api;
|
|
use CPSW\Inc\Helper;
|
|
|
|
/**
|
|
* Apple Pay Domain Verification class
|
|
*/
|
|
class Apple_Pay {
|
|
|
|
use Get_Instance;
|
|
|
|
const APPLE_PAY_FILE = 'apple-developer-merchantid-domain-association';
|
|
const APPLE_PAY_DIR = '.well-known';
|
|
|
|
/**
|
|
* Domain verification flag
|
|
*
|
|
* @var bool
|
|
*/
|
|
public $domain_is_verfied;
|
|
|
|
/**
|
|
* Verified domain stored in database
|
|
*
|
|
* @var string
|
|
*/
|
|
public $verified_domain;
|
|
|
|
/**
|
|
* Current domain
|
|
*
|
|
* @var string
|
|
*/
|
|
public $domain;
|
|
|
|
/**
|
|
* Stores apple pay domain verification failure message.
|
|
*
|
|
* @var string
|
|
*/
|
|
private $failure_message;
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
public function __construct() {
|
|
add_action( 'init', [ $this, 'apple_pay_domain_association_rewrite_rule' ] );
|
|
add_action( 'admin_init', [ $this, 'is_domain_verified' ] );
|
|
add_filter( 'query_vars', [ $this, 'add_domain_association_query_var' ], 10, 1 );
|
|
add_action( 'parse_request', [ $this, 'parse_domain_association_request' ], 10, 1 );
|
|
|
|
$this->domain_is_verfied = get_option( 'cpsw_apple_pay_domain_is_verfied' );
|
|
$this->verified_domain = get_option( 'cpsw_apple_pay_verified_domain' );
|
|
$this->secret_key = Helper::get_setting( 'cpsw_secret_key' );
|
|
$this->failure_message = '';
|
|
$this->domain = isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( $_SERVER['HTTP_HOST'] ) : str_replace( array( 'https://', 'http://' ), '', get_site_url() );
|
|
}
|
|
|
|
/**
|
|
* Rewrite rules for apple pay domain association.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function apple_pay_domain_association_rewrite_rule() {
|
|
$regex = '^\\' . self::APPLE_PAY_DIR . '\/' . self::APPLE_PAY_FILE . '$';
|
|
$redirect = 'index.php?' . self::APPLE_PAY_FILE . '=1';
|
|
|
|
add_rewrite_rule( $regex, $redirect, 'top' );
|
|
}
|
|
|
|
/**
|
|
* Add domain association query var
|
|
*
|
|
* @param array $query_vars existing query vars.
|
|
* @return array
|
|
*/
|
|
public function add_domain_association_query_var( $query_vars ) {
|
|
$query_vars[] = self::APPLE_PAY_FILE;
|
|
return $query_vars;
|
|
}
|
|
|
|
/**
|
|
* Parse current domain should serve apple pay domain association file or not.
|
|
*
|
|
* @param object $wp query parameters.
|
|
* @return void
|
|
*/
|
|
public function parse_domain_association_request( $wp ) {
|
|
if (
|
|
self::APPLE_PAY_DIR . '/' . self::APPLE_PAY_FILE !== $wp->request ||
|
|
self::APPLE_PAY_FILE !== $wp->query_vars['attachment']
|
|
) {
|
|
return;
|
|
}
|
|
|
|
$path = CPSW_DIR . 'compatibility/' . self::APPLE_PAY_FILE;
|
|
header( 'Content-Type: text/plain;charset=utf-8' );
|
|
echo esc_html( @file_get_contents( $path ) ); // @codingStandardsIgnoreLine
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Checks if current domain is verified or not else verifys current domain.
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public function is_domain_verified() {
|
|
if ( ! empty( $this->verified_domain ) && $this->domain === $this->verified_domain && $this->domain_is_verfied ) {
|
|
return;
|
|
}
|
|
|
|
$settings = Helper::get_gateway_settings();
|
|
$this->express_checkout = $settings['express_checkout_enabled'];
|
|
if ( 'yes' !== $this->express_checkout || 'yes' !== $settings['enabled'] ) {
|
|
return;
|
|
}
|
|
|
|
// Generates admin notice in an admin scope if ssl not found, nonce verification not required.
|
|
if ( isset( $_GET['page'] ) && isset( $_GET['tab'] ) && isset( $_GET['section'] ) && 'wc-settings' === $_GET['page'] && 'checkout' === $_GET['tab'] && 'cpsw_express_checkout' === $_GET['section'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
if ( ! is_ssl() ) {
|
|
add_action( 'admin_notices', [ $this, 'no_ssl_notice' ] );
|
|
return;
|
|
}
|
|
|
|
// Required for apple pay integration.
|
|
flush_rewrite_rules(); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.flush_rewrite_rules_flush_rewrite_rules
|
|
|
|
$response = $this->move_file_to_apple_dir();
|
|
if ( ! $response['success'] ) {
|
|
$this->failure_message = $response['message'];
|
|
add_action( 'admin_notices', [ $this, 'apple_pay_verification_failed' ] );
|
|
return;
|
|
}
|
|
|
|
$this->verify_domain_for_apple_pay();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Moves domain association file to required directory
|
|
*
|
|
* @return array
|
|
*/
|
|
public function move_file_to_apple_dir() {
|
|
if ( $this->check_hosted_file() ) {
|
|
return [
|
|
'success' => true,
|
|
];
|
|
}
|
|
|
|
$well_known_dir = untrailingslashit( ABSPATH ) . '/' . self::APPLE_PAY_DIR;
|
|
$fullpath = $well_known_dir . '/' . self::APPLE_PAY_FILE;
|
|
|
|
if ( ! file_exists( $well_known_dir ) ) {
|
|
if ( ! @mkdir( $well_known_dir, 0755 ) ) { // @codingStandardsIgnoreLine
|
|
return [
|
|
'success' => false,
|
|
/* translators: 1 - 4 html entities */
|
|
'message' => sprintf( __( 'Unable to create domain association folder to domain root due to file permissions. Please create %1$1s.well-known%2$2s directory under domain root and place %3$3sdomain verification file%4$4s under it and refresh.', 'checkout-plugins-stripe-woo' ), '<code>', '</code>', '<a href="https://stripe.com/files/apple-pay/apple-developer-merchantid-domain-association" target="_blank">', '</a>' ),
|
|
];
|
|
}
|
|
}
|
|
|
|
if ( ! @copy( CPSW_DIR . 'compatibility/' . self::APPLE_PAY_FILE, $fullpath ) ) { // @codingStandardsIgnoreLine
|
|
return [
|
|
'success' => false,
|
|
'message' => __( 'Unable to copy domain association file to domain root.', 'checkout-plugins-stripe-woo' ),
|
|
];
|
|
}
|
|
|
|
return [
|
|
'success' => true,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Checks if hosted domain verification file is correct or not, updates if required.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function check_hosted_file() {
|
|
$new_contents = @file_get_contents( CPSW_DIR . 'compatibility/' . self::APPLE_PAY_FILE ); // @codingStandardsIgnoreLine
|
|
$fullpath = untrailingslashit( ABSPATH ) . '/' . self::APPLE_PAY_DIR . '/' . self::APPLE_PAY_FILE;
|
|
$local_contents = @file_get_contents( $fullpath ); // @codingStandardsIgnoreLine
|
|
$url = get_site_url() . '/' . self::APPLE_PAY_DIR . '/' . self::APPLE_PAY_FILE;
|
|
$response = @wp_remote_get( $url ); // @codingStandardsIgnoreLine
|
|
$remote_contents = @wp_remote_retrieve_body( $response ); // @codingStandardsIgnoreLine
|
|
|
|
return $local_contents === $new_contents || $remote_contents === $new_contents;
|
|
}
|
|
|
|
/**
|
|
* Automatic verification for apple pay using stripe api
|
|
*
|
|
* @return void
|
|
*/
|
|
public function verify_domain_for_apple_pay() {
|
|
|
|
if ( empty( $this->secret_key ) ) {
|
|
add_action( 'admin_notices', [ $this, 'no_live_secret_key' ] );
|
|
return;
|
|
}
|
|
|
|
add_filter( 'cpsw_get_secret_key', [ $this, 'get_live_secret_key' ], 10, 1 );
|
|
$stripe = new Stripe_Api();
|
|
|
|
$response = $stripe->apple_pay_domains(
|
|
'create',
|
|
[
|
|
[
|
|
'domain_name' => $this->domain,
|
|
],
|
|
]
|
|
);
|
|
|
|
$verification_response = $response['success'] ? $response['data'] : false;
|
|
|
|
if ( $verification_response ) {
|
|
update_option( 'cpsw_apple_pay_verified_domain', $this->domain );
|
|
update_option( 'cpsw_apple_pay_domain_is_verfied', true );
|
|
add_action( 'admin_notices', [ $this, 'apple_pay_verification_success' ] );
|
|
} else {
|
|
$this->failure_message = $response['message'];
|
|
delete_option( 'cpsw_apple_pay_domain_is_verfied' );
|
|
add_action( 'admin_notices', [ $this, 'apple_pay_verification_failed' ] );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generates admin notice if no live secret key is found
|
|
*
|
|
* @return void
|
|
*/
|
|
public function no_live_secret_key() {
|
|
echo wp_kses_post( '<div class="notice notice-error is-dismissible"><p>' . __( 'We cannot find live secret key in database, Live secret key is required for Apple Pay domain verification. ', 'checkout-plugins-stripe-woo' ) . '</p></div>' );
|
|
}
|
|
|
|
/**
|
|
* Generates admin notice for apple pay success
|
|
*
|
|
* @return void
|
|
*/
|
|
public function apple_pay_verification_success() {
|
|
echo wp_kses_post( '<div class="notice notice-success is-dismissible"><p>' . __( 'Apple Pay domain verification successful.', 'checkout-plugins-stripe-woo' ) . '</p></div>' );
|
|
}
|
|
|
|
/**
|
|
* Generates admin notice for SSL requirment for payment request Api
|
|
*
|
|
* @return void
|
|
*/
|
|
public function no_ssl_notice() {
|
|
echo wp_kses_post( '<div class="notice notice-error is-dismissible"><p>' . __( 'SSL is required for Express Pay Checkout.', 'checkout-plugins-stripe-woo' ) . '</p></div>' );
|
|
}
|
|
|
|
/**
|
|
* Generates admin notice for apple pay registration failure
|
|
*
|
|
* @return void
|
|
*/
|
|
public function apple_pay_verification_failed() {
|
|
/* translators: %1s - %3s HTML Entities, %4s Error Message */
|
|
echo wp_kses_post( '<div class="notice notice-warning is-dismissible"><p>' . sprintf( __( '%1$1sApple Pay domain verification failed! %2$2sReason%3$3s: %4$4s', 'checkout-plugins-stripe-woo' ), '<b>', '<br/>', '</b>', $this->failure_message ) . '</p></div>' );
|
|
}
|
|
|
|
/**
|
|
* Returns live secret key for apple pay Verification
|
|
*
|
|
* @param string $secret_key current secret key as per mode.
|
|
* @return string
|
|
*/
|
|
public function get_live_secret_key( $secret_key ) {
|
|
return $this->secret_key;
|
|
}
|
|
}
|