1175 lines
36 KiB
PHP
1175 lines
36 KiB
PHP
<?php
|
|
namespace PayWithAmazon;
|
|
|
|
/**
|
|
* Amazon Payments Gateway
|
|
*
|
|
* @package EDD
|
|
* @subpackage Gateways
|
|
* @copyright Copyright (c) 2015, Pippin's Pages, LLC
|
|
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
|
* @since 2.4
|
|
*/
|
|
|
|
// Exit if accessed directly
|
|
defined( 'ABSPATH' ) || exit;
|
|
|
|
final class EDD_Amazon_Payments {
|
|
|
|
private static $instance;
|
|
public $gateway_id = 'amazon';
|
|
public $client = null;
|
|
public $redirect_uri = null;
|
|
public $checkout_uri = null;
|
|
public $signin_redirect = null;
|
|
public $reference_id = null;
|
|
public $doing_ipn = false;
|
|
public $is_setup = null;
|
|
|
|
/**
|
|
* Get things going
|
|
*
|
|
* @access private
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
private function __construct() {
|
|
|
|
$this->reference_id = ! empty( $_REQUEST['amazon_reference_id'] )
|
|
? sanitize_text_field( $_REQUEST['amazon_reference_id'] )
|
|
: '';
|
|
|
|
// Run this separate so we can ditch as early as possible
|
|
$this->register();
|
|
|
|
if ( ! edd_is_gateway_active( $this->gateway_id ) ) {
|
|
return;
|
|
}
|
|
|
|
$this->config();
|
|
$this->includes();
|
|
$this->setup_client();
|
|
$this->filters();
|
|
$this->actions();
|
|
}
|
|
|
|
/**
|
|
* Retrieve current instance
|
|
*
|
|
* @access private
|
|
* @since 2.4
|
|
* @return EDD_Amazon_Payments instance
|
|
*/
|
|
public static function getInstance() {
|
|
if ( ! isset( self::$instance ) && ! ( self::$instance instanceof EDD_Amazon_Payments ) ) {
|
|
self::$instance = new EDD_Amazon_Payments;
|
|
}
|
|
|
|
return self::$instance;
|
|
}
|
|
|
|
/**
|
|
* Register the payment gateway
|
|
*
|
|
* @access private
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
private function register() {
|
|
add_filter( 'edd_payment_gateways', array( $this, 'register_gateway' ), 1, 1 );
|
|
}
|
|
|
|
/**
|
|
* Setup constant configuration for file paths
|
|
*
|
|
* @access private
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
private function config() {
|
|
if ( ! defined( 'EDD_AMAZON_CLASS_DIR' ) ) {
|
|
$path = trailingslashit( plugin_dir_path( EDD_PLUGIN_FILE ) ) . 'includes/gateways/libs/amazon';
|
|
define( 'EDD_AMAZON_CLASS_DIR', trailingslashit( $path ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Method to check if all the required settings have been filled out, allowing us to not output information without it.
|
|
*
|
|
* @since 2.7
|
|
* @return bool
|
|
*/
|
|
public function is_setup() {
|
|
if ( null !== $this->is_setup ) {
|
|
return $this->is_setup;
|
|
}
|
|
|
|
$required_items = array( 'merchant_id', 'client_id', 'access_key', 'secret_key' );
|
|
|
|
$current_values = array(
|
|
'merchant_id' => edd_get_option( 'amazon_seller_id', '' ),
|
|
'client_id' => edd_get_option( 'amazon_client_id', '' ),
|
|
'access_key' => edd_get_option( 'amazon_mws_access_key', '' ),
|
|
'secret_key' => edd_get_option( 'amazon_mws_secret_key', '' ),
|
|
);
|
|
|
|
$this->is_setup = true;
|
|
|
|
foreach ( $required_items as $key ) {
|
|
if ( empty( $current_values[ $key ] ) ) {
|
|
$this->is_setup = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return $this->is_setup;
|
|
}
|
|
|
|
/**
|
|
* Load additional files
|
|
*
|
|
* @access private
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
private function includes() {
|
|
require_once EDD_AMAZON_CLASS_DIR . 'Client.php'; // Requires the other files itself
|
|
require_once EDD_AMAZON_CLASS_DIR . 'IpnHandler.php';
|
|
}
|
|
|
|
/**
|
|
* Add filters
|
|
*
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
private function filters() {
|
|
|
|
add_filter( 'edd_accepted_payment_icons', array( $this, 'register_payment_icon' ), 10, 1 );
|
|
add_filter( 'edd_show_gateways', array( $this, 'maybe_hide_gateway_select' ) );
|
|
|
|
// Since the Amazon Gateway loads scripts on page, it needs the scripts to load in the header.
|
|
add_filter( 'edd_load_scripts_in_footer', '__return_false' );
|
|
|
|
if ( is_admin() ) {
|
|
add_filter( 'edd_settings_sections_gateways', array( $this, 'register_gateway_section' ), 1, 1 );
|
|
add_filter( 'edd_settings_gateways', array( $this, 'register_gateway_settings' ), 1, 1 );
|
|
add_filter( 'edd_payment_details_transaction_id-' . $this->gateway_id, array( $this, 'link_transaction_id' ), 10, 2 );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add actions
|
|
*
|
|
* @access private
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
private function actions() {
|
|
add_action( 'wp_enqueue_scripts', array( $this, 'print_client' ), 10 );
|
|
add_action( 'wp_enqueue_scripts', array( $this, 'load_scripts' ), 11 );
|
|
add_action( 'edd_pre_process_purchase', array( $this, 'check_config' ), 1 );
|
|
add_action( 'init', array( $this, 'capture_oauth' ), 9 );
|
|
add_action( 'init', array( $this, 'signin_redirect' ) );
|
|
add_action( 'edd_purchase_form_before_register_login', array( $this, 'login_form' ) );
|
|
add_action( 'edd_checkout_error_check', array( $this, 'checkout_errors' ), 10, 2 );
|
|
add_action( 'edd_gateway_amazon', array( $this, 'process_purchase' ) );
|
|
add_action( 'wp_ajax_edd_amazon_get_address', array( $this, 'ajax_get_address' ) );
|
|
add_action( 'wp_ajax_nopriv_edd_amazon_get_address', array( $this, 'ajax_get_address' ) );
|
|
add_action( 'edd_pre_process_purchase', array( $this, 'disable_address_requirement' ), 99999 );
|
|
add_action( 'init', array( $this, 'process_ipn' ) );
|
|
|
|
if ( empty( $this->reference_id ) ) {
|
|
return;
|
|
}
|
|
|
|
add_action( 'edd_amazon_cc_form', array( $this, 'wallet_form' ) );
|
|
}
|
|
|
|
/**
|
|
* Show an error message on checkout if Amazon is enabled but not setup.
|
|
*
|
|
* @since 2.7
|
|
*/
|
|
public function check_config() {
|
|
$is_enabled = edd_is_gateway_active( $this->gateway_id );
|
|
if ( ( ! $is_enabled || false === $this->is_setup() ) && 'amazon' == edd_get_chosen_gateway() ) {
|
|
edd_set_error( 'amazon_gateway_not_configured', __( 'There is an error with the Amazon Payments configuration.', 'easy-digital-downloads' ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieve the client object
|
|
*
|
|
* @access private
|
|
* @since 2.4
|
|
* @return PayWithAmazon\Client
|
|
*/
|
|
private function get_client() {
|
|
|
|
if ( ! $this->is_setup() ) {
|
|
return false;
|
|
}
|
|
|
|
if ( ! is_null( $this->client ) ) {
|
|
return $this->client;
|
|
}
|
|
|
|
$this->setup_client();
|
|
|
|
return $this->client;
|
|
}
|
|
|
|
/**
|
|
* Setup the client object
|
|
*
|
|
* @access private
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
private function setup_client() {
|
|
|
|
if ( ! $this->is_setup() ) {
|
|
return;
|
|
}
|
|
|
|
$region = edd_get_shop_country();
|
|
|
|
if ( 'GB' === $region ) {
|
|
$region = 'UK';
|
|
}
|
|
|
|
$config = array(
|
|
'merchant_id' => edd_get_option( 'amazon_seller_id', '' ),
|
|
'client_id' => edd_get_option( 'amazon_client_id', '' ),
|
|
'access_key' => edd_get_option( 'amazon_mws_access_key', '' ),
|
|
'secret_key' => edd_get_option( 'amazon_mws_secret_key', '' ),
|
|
'region' => $region,
|
|
'sandbox' => edd_is_test_mode(),
|
|
);
|
|
|
|
$config = apply_filters( 'edd_amazon_client_config', $config );
|
|
|
|
$this->client = new Client( $config );
|
|
}
|
|
|
|
/**
|
|
* Register the gateway
|
|
*
|
|
* @since 2.4
|
|
* @param $gateways array
|
|
* @return array
|
|
*/
|
|
public function register_gateway( $gateways ) {
|
|
|
|
$default_amazon_info = array(
|
|
$this->gateway_id => array(
|
|
'admin_label' => __( 'Amazon', 'easy-digital-downloads' ),
|
|
'checkout_label' => __( 'Amazon', 'easy-digital-downloads' ),
|
|
'supports' => array(),
|
|
'icons' => array( 'amazon' ),
|
|
),
|
|
);
|
|
|
|
$default_amazon_info = apply_filters( 'edd_register_amazon_gateway', $default_amazon_info );
|
|
$gateways = array_merge( $gateways, $default_amazon_info );
|
|
|
|
return $gateways;
|
|
}
|
|
|
|
/**
|
|
* Register the payment icon
|
|
*
|
|
* @since 2.4
|
|
* @param array $payment_icons Array of payment icons
|
|
* @return array The array of icons with Amazon Added
|
|
*/
|
|
public function register_payment_icon( $payment_icons ) {
|
|
$payment_icons['amazon'] = 'Amazon';
|
|
|
|
return $payment_icons;
|
|
}
|
|
|
|
/**
|
|
* Hides payment gateway select options after return from Amazon
|
|
*
|
|
* @since 2.7.6
|
|
* @param bool $show Should gateway select be shown
|
|
* @return bool
|
|
*/
|
|
public function maybe_hide_gateway_select( $show ) {
|
|
|
|
if ( ! empty( $_REQUEST['payment-mode'] ) && 'amazon' == $_REQUEST['payment-mode'] && ! empty( $_REQUEST['amazon_reference_id'] ) && ! empty( $_REQUEST['state'] ) && 'authorized' == $_REQUEST['state'] ) {
|
|
$show = false;
|
|
}
|
|
|
|
return $show;
|
|
}
|
|
|
|
/**
|
|
* Register the payment gateways setting section
|
|
*
|
|
* @since 2.5
|
|
* @param array $gateway_sections Array of sections for the gateways tab
|
|
* @return array Added Amazon Payments into sub-sections
|
|
*/
|
|
public function register_gateway_section( $gateway_sections ) {
|
|
$gateway_sections['amazon'] = __( 'Amazon Payments', 'easy-digital-downloads' );
|
|
|
|
return $gateway_sections;
|
|
}
|
|
|
|
/**
|
|
* Register the gateway settings
|
|
*
|
|
* @since 2.4
|
|
* @param $gateway_settings array
|
|
* @return array
|
|
*/
|
|
public function register_gateway_settings( $gateway_settings ) {
|
|
$default_amazon_settings = array(
|
|
'amazon_register' => array(
|
|
'id' => 'amazon_register',
|
|
'name' => __( 'Register with Amazon', 'easy-digital-downloads' ),
|
|
'desc' => '<p><a href="' . esc_url( $this->get_registration_url() ) . '" class="button" target="_blank">' .
|
|
__( 'Connect Easy Digital Downloads to Amazon', 'easy-digital-downloads' ) .
|
|
'</a></p>' .
|
|
'<p class="description">' .
|
|
__( 'Once registration is complete, enter your API credentials below.', 'easy-digital-downloads' ) .
|
|
'</p>',
|
|
'type' => 'descriptive_text',
|
|
),
|
|
'amazon_seller_id' => array(
|
|
'id' => 'amazon_seller_id',
|
|
'name' => __( 'Seller ID', 'easy-digital-downloads' ),
|
|
'desc' => __( 'Found in the Integration settings. Also called a Merchant ID', 'easy-digital-downloads' ),
|
|
'type' => 'text',
|
|
'size' => 'regular',
|
|
),
|
|
'amazon_mws_access_key' => array(
|
|
'id' => 'amazon_mws_access_key',
|
|
'name' => __( 'MWS Access Key', 'easy-digital-downloads' ),
|
|
'desc' => __( 'Found on Seller Central in the MWS Keys section', 'easy-digital-downloads' ),
|
|
'type' => 'text',
|
|
'size' => 'regular',
|
|
),
|
|
'amazon_mws_secret_key' => array(
|
|
'id' => 'amazon_mws_secret_key',
|
|
'name' => __( 'MWS Secret Key', 'easy-digital-downloads' ),
|
|
'desc' => __( 'Found on Seller Central in the MWS Keys section', 'easy-digital-downloads' ),
|
|
'type' => 'text',
|
|
'size' => 'regular',
|
|
),
|
|
'amazon_client_id' => array(
|
|
'id' => 'amazon_client_id',
|
|
'name' => __( 'Client ID', 'easy-digital-downloads' ),
|
|
'desc' => __( 'The Amazon Client ID. Should look like `amzn1.application-oa2...`', 'easy-digital-downloads' ),
|
|
'type' => 'text',
|
|
'size' => 'regular',
|
|
),
|
|
'amazon_mws_callback_url' => array(
|
|
'id' => 'amazon_callback_url',
|
|
'name' => __( 'Amazon MWS Callback URL', 'easy-digital-downloads' ),
|
|
'desc' => __( 'The Return URL to provide in your MWS Application. Enter this under your Login and Pay → Web Settings', 'easy-digital-downloads' ),
|
|
'type' => 'text',
|
|
'size' => 'large',
|
|
'std' => $this->get_amazon_authenticate_redirect(),
|
|
'faux' => true,
|
|
),
|
|
'amazon_mws_ipn_url' => array(
|
|
'id' => 'amazon_ipn_url',
|
|
'name' => __( 'Amazon Merchant IPN URL', 'easy-digital-downloads' ),
|
|
'desc' => sprintf( __( 'The IPN URL to provide in your MWS account. Enter this under your <a href="%s">Integration Settings</a>', 'easy-digital-downloads' ), 'https://sellercentral.amazon.com/gp/pyop/seller/account/settings/user-settings-edit.html' ),
|
|
'type' => 'text',
|
|
'size' => 'large',
|
|
'std' => $this->get_amazon_ipn_url(),
|
|
'faux' => true,
|
|
),
|
|
);
|
|
|
|
$default_amazon_settings = apply_filters( 'edd_default_amazon_settings', $default_amazon_settings );
|
|
$gateway_settings['amazon'] = $default_amazon_settings;
|
|
|
|
return $gateway_settings;
|
|
}
|
|
|
|
/**
|
|
* Load javascript files and localized variables
|
|
*
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
public function load_scripts() {
|
|
|
|
if ( ! $this->is_setup() ) {
|
|
return;
|
|
}
|
|
|
|
if ( ! edd_is_checkout() ) {
|
|
return;
|
|
}
|
|
|
|
$test_mode = edd_is_test_mode();
|
|
$seller_id = edd_get_option( 'amazon_seller_id', '' );
|
|
$client_id = edd_get_option( 'amazon_client_id', '' );
|
|
|
|
$default_amazon_scope = array(
|
|
'profile',
|
|
'postal_code',
|
|
'payments:widget',
|
|
);
|
|
|
|
if ( edd_use_taxes() ) {
|
|
$default_amazon_scope[] = 'payments:shipping_address';
|
|
}
|
|
|
|
$default_amazon_button_settings = array(
|
|
'type' => 'PwA',
|
|
'color' => 'Gold',
|
|
'size' => 'medium',
|
|
'scope' => implode( ' ', $default_amazon_scope ),
|
|
'popup' => true,
|
|
);
|
|
|
|
$amazon_button_settings = apply_filters( 'edd_amazon_button_settings', $default_amazon_button_settings );
|
|
$base_url = '';
|
|
$sandbox = $test_mode ? 'sandbox/' : '';
|
|
|
|
switch ( edd_get_shop_country() ) {
|
|
case 'GB':
|
|
$base_url = 'https://static-eu.payments-amazon.com/OffAmazonPayments/uk/' . $sandbox . 'lpa/';
|
|
break;
|
|
case 'DE':
|
|
$base_url = 'https://static-eu.payments-amazon.com/OffAmazonPayments/de/' . $sandbox. 'lpa/';
|
|
break;
|
|
default:
|
|
$base_url = 'https://static-na.payments-amazon.com/OffAmazonPayments/us/' . $sandbox;
|
|
break;
|
|
}
|
|
|
|
if ( ! empty( $base_url ) ) {
|
|
$url = $base_url . 'js/Widgets.js?sellerId=' . $seller_id;
|
|
|
|
wp_enqueue_script( 'edd-amazon-widgets', $url, array( 'jquery' ), null, false );
|
|
wp_localize_script( 'edd-amazon-widgets', 'edd_amazon', apply_filters( 'edd_amazon_checkout_vars', array(
|
|
'sellerId' => $seller_id,
|
|
'clientId' => $client_id,
|
|
'referenceID' => $this->reference_id,
|
|
'buttonType' => $amazon_button_settings['type'],
|
|
'buttonColor' => $amazon_button_settings['color'],
|
|
'buttonSize' => $amazon_button_settings['size'],
|
|
'scope' => $amazon_button_settings['scope'],
|
|
'popup' => $amazon_button_settings['popup'],
|
|
'checkoutUri' => $this->get_amazon_checkout_uri(),
|
|
'redirectUri' => $this->get_amazon_authenticate_redirect(),
|
|
'signinUri' => $this->get_amazon_signin_redirect(),
|
|
) ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Print client ID in header
|
|
*
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
public function print_client() {
|
|
|
|
if ( ! $this->is_setup() ) {
|
|
return false;
|
|
}
|
|
|
|
if ( ! edd_is_checkout() ) {
|
|
return;
|
|
}
|
|
?>
|
|
<script>
|
|
window.onAmazonLoginReady = function() {
|
|
amazon.Login.setClientId(<?php echo json_encode( edd_get_option( 'amazon_client_id', '' ) ); ?>);
|
|
};
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Capture authentication after returning from Amazon
|
|
*
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
public function capture_oauth() {
|
|
|
|
if ( ! isset( $_GET['edd-listener'] ) || $_GET['edd-listener'] !== 'amazon' ) {
|
|
return;
|
|
}
|
|
|
|
if ( ! isset( $_GET['state'] ) || $_GET['state'] !== 'return_auth' ) {
|
|
return;
|
|
}
|
|
|
|
if ( empty( $_GET['access_token'] ) || false === strpos( $_GET['access_token'], 'Atza' ) ) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$profile = $this->client->getUserInfo( $_GET['access_token'] );
|
|
|
|
EDD()->session->set( 'amazon_access_token', $_GET['access_token'] );
|
|
EDD()->session->set( 'amazon_profile', $profile );
|
|
} catch( Exception $e ) {
|
|
wp_die( print_r( $e, true ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set customer details after authentication
|
|
*
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
public function signin_redirect() {
|
|
|
|
if ( ! isset( $_GET['edd-listener'] ) || $_GET['edd-listener'] !== 'amazon' ) {
|
|
return;
|
|
}
|
|
|
|
if ( ! isset( $_GET['state'] ) || $_GET['state'] !== 'signed-in' ) {
|
|
return;
|
|
}
|
|
|
|
$profile = EDD()->session->get( 'amazon_profile' );
|
|
$reference = $_GET['amazon_reference_id'];
|
|
|
|
if ( ! is_user_logged_in() ) {
|
|
$user = get_user_by( 'email', $profile['email'] );
|
|
|
|
if ( $user ) {
|
|
edd_log_user_in( $user->ID, $user->user_login, '' );
|
|
|
|
$customer = array(
|
|
'first_name' => $user->first_name,
|
|
'last_name' => $user->last_name,
|
|
'email' => $user->user_email
|
|
);
|
|
|
|
} else {
|
|
$names = explode( ' ', $profile['name'], 2 );
|
|
|
|
$customer = array(
|
|
'first_name' => $names[0],
|
|
'last_name' => isset( $names[1] ) ? $names[1] : '',
|
|
'email' => $profile['email']
|
|
);
|
|
|
|
// Create a customer account if registration is not disabled
|
|
if ( 'none' !== edd_get_option( 'show_register_form' ) ) {
|
|
$args = array(
|
|
'user_email' => $profile['email'],
|
|
'user_login' => $profile['email'],
|
|
'display_name' => $profile['name'],
|
|
'first_name' => $customer['first_name'],
|
|
'last_name' => $customer['last_name'],
|
|
'user_pass' => wp_generate_password( 20 ),
|
|
);
|
|
|
|
$user_id = wp_insert_user( $args );
|
|
|
|
edd_log_user_in( $user_id, $args['user_login'], $args['user_pass'] );
|
|
}
|
|
}
|
|
|
|
EDD()->session->set( 'customer', $customer );
|
|
}
|
|
|
|
edd_redirect( edd_get_checkout_uri( array( 'payment-mode' => 'amazon', 'state' => 'authorized', 'amazon_reference_id' => urlencode( $reference ) ) ) );
|
|
}
|
|
|
|
/**
|
|
* Display the log in button
|
|
*
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
public function login_form() {
|
|
|
|
if ( ! $this->is_setup() ) {
|
|
return false;
|
|
}
|
|
|
|
if ( empty( $this->reference_id ) && 'amazon' == edd_get_chosen_gateway() ) :
|
|
|
|
remove_all_actions( 'edd_purchase_form_after_cc_form' );
|
|
remove_all_actions( 'edd_purchase_form_after_user_info' );
|
|
remove_all_actions( 'edd_purchase_form_register_fields' );
|
|
remove_all_actions( 'edd_purchase_form_login_fields' );
|
|
remove_all_actions( 'edd_register_fields_before' );
|
|
remove_all_actions( 'edd_cc_form' );
|
|
remove_all_actions( 'edd_checkout_form_top' );
|
|
|
|
ob_start(); ?>
|
|
<fieldset id="edd-amazon-login-fields" class="edd-amazon-fields">
|
|
|
|
<div id="edd-amazon-pay-button"></div>
|
|
<script type="text/javascript">
|
|
var authRequest;
|
|
OffAmazonPayments.Button('edd-amazon-pay-button', edd_amazon.sellerId, {
|
|
type: edd_amazon.buttonType,
|
|
color: edd_amazon.buttonColor,
|
|
size: edd_amazon.buttonSize,
|
|
|
|
authorization: function() {
|
|
|
|
loginOptions = {
|
|
scope: edd_amazon.scope,
|
|
popup: edd_amazon.popup
|
|
};
|
|
|
|
authRequest = amazon.Login.authorize( loginOptions, edd_amazon.redirectUri );
|
|
|
|
},
|
|
onSignIn: function( orderReference ) {
|
|
amazonOrderReferenceId = orderReference.getAmazonOrderReferenceId();
|
|
window.location = edd_amazon.signinUri + '&amazon_reference_id=' + amazonOrderReferenceId;
|
|
}, onError: function(error) {
|
|
jQuery('#edd_purchase_submit').prepend( '<div class="edd_errors"><p class="edd_error" id="edd_error_"' + error.getErrorCode() + '>' + error.getErrorMessage() + '</p></div>' );
|
|
}
|
|
});
|
|
</script>
|
|
|
|
</fieldset>
|
|
|
|
<?php
|
|
|
|
echo ob_get_clean();
|
|
|
|
endif;
|
|
}
|
|
|
|
/**
|
|
* Display the wallet and address forms
|
|
*
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
public function wallet_form() {
|
|
|
|
if ( ! $this->is_setup() ) {
|
|
return false;
|
|
}
|
|
|
|
$profile = EDD()->session->get( 'amazon_profile' );
|
|
remove_action( 'edd_purchase_form_after_cc_form', 'edd_checkout_tax_fields', 999 );
|
|
ob_start(); ?>
|
|
|
|
<fieldset id="edd_cc_fields" class="edd-amazon-fields">
|
|
<p class="edd-amazon-profile-wrapper">
|
|
<?php _e( 'Currently logged into Amazon as', 'easy-digital-downloads' ); ?>: <span class="edd-amazon-profile-name"><?php echo $profile['name']; ?></span>
|
|
<span class="edd-amazon-logout">(<a id="Logout"><?php _e( 'Logout', 'easy-digital-downloads' ); ?></a>)</span>
|
|
</p>
|
|
<?php if ( edd_use_taxes() ) : ?>
|
|
<div id="edd-amazon-address-box"></div>
|
|
<?php endif; ?>
|
|
<div id="edd-amazon-wallet-box"></div>
|
|
<script>
|
|
var edd_global_vars;
|
|
if ( '1' == edd_global_vars.taxes_enabled ) {
|
|
new OffAmazonPayments.Widgets.AddressBook({
|
|
sellerId: edd_amazon.sellerId,
|
|
amazonOrderReferenceId: edd_amazon.referenceID,
|
|
onOrderReferenceCreate: function(orderReference) {
|
|
orderReference.getAmazonOrderReferenceId();
|
|
},
|
|
onAddressSelect: function(orderReference) {
|
|
jQuery.ajax({
|
|
type: "POST",
|
|
data: {
|
|
action : 'edd_amazon_get_address',
|
|
reference_id : edd_amazon.referenceID
|
|
},
|
|
dataType: "json",
|
|
url: edd_global_vars.ajaxurl,
|
|
xhrFields: {
|
|
withCredentials: true
|
|
},
|
|
success: function (response) {
|
|
jQuery('#card_city').val( response.City );
|
|
jQuery('#card_address').val( response.AddressLine1 );
|
|
jQuery('#card_address_2').val( response.AddressLine2 );
|
|
jQuery('#card_zip').val( response.PostalCode );
|
|
jQuery('#billing_country').val( response.CountryCode );
|
|
jQuery('#card_state').val( response.StateOrRegion ).trigger( 'change' );
|
|
}
|
|
}).fail(function (response) {
|
|
if ( window.console && window.console.log ) {
|
|
console.log( response );
|
|
}
|
|
}).done(function (response) {
|
|
|
|
});
|
|
},
|
|
design: {
|
|
designMode: 'responsive'
|
|
},
|
|
onError: function(error) {
|
|
jQuery('#edd-amazon-address-box').hide();
|
|
jQuery('#edd_purchase_submit').prepend( '<div class="edd_errors"><p class="edd_error" id="edd_error_"' + error.getErrorCode() + '>' + error.getErrorMessage() + '</p></div>' );
|
|
}
|
|
}).bind("edd-amazon-address-box");
|
|
|
|
new OffAmazonPayments.Widgets.Wallet({
|
|
sellerId: edd_amazon.sellerId,
|
|
amazonOrderReferenceId: edd_amazon.referenceID,
|
|
design: {
|
|
designMode: 'responsive'
|
|
},
|
|
onPaymentSelect: function(orderReference) {
|
|
// Display your custom complete purchase button
|
|
},
|
|
onError: function(error) {
|
|
jQuery('#edd_purchase_submit').prepend( '<div class="edd_errors"><p class="edd_error" id="edd_error_"' + error.getErrorCode() + '>' + error.getErrorMessage() + '</p></div>' );
|
|
}
|
|
}).bind("edd-amazon-wallet-box");
|
|
|
|
} else {
|
|
|
|
new OffAmazonPayments.Widgets.Wallet({
|
|
sellerId: edd_amazon.sellerId,
|
|
design: {
|
|
designMode: 'responsive'
|
|
},
|
|
onOrderReferenceCreate: function(orderReference) {
|
|
jQuery( '#edd_amazon_reference_id' ).val( orderReference.getAmazonOrderReferenceId() );
|
|
},
|
|
onPaymentSelect: function(orderReference) {
|
|
// Display your custom complete purchase button
|
|
},
|
|
onError: function(error) {
|
|
jQuery('#edd_purchase_submit').prepend( '<div class="edd_errors"><p class="edd_error" id="edd_error_"' + error.getErrorCode() + '>' + error.getErrorMessage() + '</p></div>' );
|
|
}
|
|
}).bind("edd-amazon-wallet-box");
|
|
|
|
}
|
|
</script>
|
|
|
|
<div id="edd_cc_address">
|
|
<input type="hidden" name="edd_amazon_reference_id" id="edd_amazon_reference_id" value="<?php echo esc_attr( $this->reference_id ); ?>"/>
|
|
<input type="hidden" name="card_city" class="card_city" id="card_city" value=""/>
|
|
<input type="hidden" name="card_address" class="card_address" id="card_address" value=""/>
|
|
<input type="hidden" name="card_address_2" class="card_address_2" id="card_address_2" value=""/>
|
|
<input type="hidden" name="card_zip" class="card_zip" id="card_zip" value=""/>
|
|
<input type="hidden" name="card_state" class="card_state" id="card_state" value=""/>
|
|
<input type="hidden" name="billing_country" class="billing_country" id="billing_country" value=""/>
|
|
</div>
|
|
</fieldset>
|
|
|
|
<?php
|
|
echo ob_get_clean();
|
|
}
|
|
|
|
/**
|
|
* Retrieve the billing address via ajax
|
|
*
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
public function ajax_get_address() {
|
|
|
|
if ( ! $this->is_setup() ) {
|
|
return false;
|
|
}
|
|
|
|
if ( empty( $_POST['reference_id'] ) ) {
|
|
die( '-2' );
|
|
}
|
|
|
|
$request = $this->client->getOrderReferenceDetails( array(
|
|
'merchant_id' => edd_get_option( 'amazon_seller_id', '' ),
|
|
'amazon_order_reference_id' => $_POST['reference_id'],
|
|
'address_consent_token' => EDD()->session->get( 'amazon_access_token' )
|
|
) );
|
|
|
|
$address = array();
|
|
$data = new ResponseParser( $request->response );
|
|
$data = $data->toArray();
|
|
|
|
if ( isset( $data['GetOrderReferenceDetailsResult']['OrderReferenceDetails']['Destination']['PhysicalDestination'] ) ) {
|
|
|
|
$address = $data['GetOrderReferenceDetailsResult']['OrderReferenceDetails']['Destination']['PhysicalDestination'];
|
|
$address = wp_parse_args( $address, array( 'City', 'CountryCode', 'StateOrRegion', 'PostalCode', 'AddressLine1', 'AddressLine2' ) );
|
|
|
|
}
|
|
|
|
echo json_encode( $address ); exit;
|
|
}
|
|
|
|
/**
|
|
* Check for errors during checkout
|
|
*
|
|
* @since 2.4
|
|
* @param $valid_data Customer / product data from checkout
|
|
* @param $post_data $_POST
|
|
* @return void
|
|
*/
|
|
public function checkout_errors( $valid_data, $post_data ) {
|
|
|
|
// should validate that we have a reference ID here, perhaps even fire the API call here
|
|
if ( empty( $post_data['edd_amazon_reference_id'] ) ) {
|
|
edd_set_error( 'missing_reference_id', __( 'Missing Reference ID, please try again.', 'easy-digital-downloads' ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Process the purchase and create the charge in Amazon
|
|
*
|
|
* @since 2.4
|
|
* @param $purchase_data array Cart details
|
|
* @return void
|
|
*/
|
|
public function process_purchase( $purchase_data ) {
|
|
|
|
if ( empty( $purchase_data['post_data']['edd_amazon_reference_id'] ) ) {
|
|
edd_set_error( 'missing_reference_id', __( 'Missing Reference ID, please try again.', 'easy-digital-downloads' ) );
|
|
}
|
|
|
|
$errors = edd_get_errors();
|
|
if ( ! empty( $errors ) ) {
|
|
edd_send_back_to_checkout( '?payment-mode=amazon' );
|
|
}
|
|
|
|
$args = apply_filters( 'edd_amazon_charge_args', array(
|
|
'merchant_id' => edd_get_option( 'amazon_seller_id', '' ),
|
|
'amazon_reference_id' => $purchase_data['post_data']['edd_amazon_reference_id'],
|
|
'authorization_reference_id' => $purchase_data['purchase_key'],
|
|
'charge_amount' => $purchase_data['price'],
|
|
'currency_code' => edd_get_currency(),
|
|
'charge_note' => html_entity_decode( edd_get_purchase_summary( $purchase_data, false ) ),
|
|
'charge_order_id' => $purchase_data['purchase_key'],
|
|
'store_name' => remove_accents( wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ) ),
|
|
'transaction_timeout' => 0
|
|
), $purchase_data );
|
|
|
|
$args['platform_id'] = 'A3JST9YM1SX7LB';
|
|
|
|
$charge = $this->client->charge( $args );
|
|
|
|
if ( 200 == $charge->response['Status'] ) {
|
|
$charge = new ResponseParser( $charge->response );
|
|
$charge = $charge->toArray();
|
|
|
|
$status = $charge['AuthorizeResult']['AuthorizationDetails']['AuthorizationStatus']['State'];
|
|
|
|
if ( 'Declined' === $status ) {
|
|
|
|
$reason = $charge['AuthorizeResult']['AuthorizationDetails']['AuthorizationStatus']['ReasonCode'];
|
|
edd_set_error( 'payment_declined', sprintf( __( 'Your payment could not be authorized, please try a different payment method. Reason: %s', 'easy-digital-downloads' ), $reason ) );
|
|
edd_send_back_to_checkout( '?payment-mode=amazon&amazon_reference_id=' . $purchase_data['post_data']['edd_amazon_reference_id'] );
|
|
}
|
|
|
|
// Setup payment data to be recorded
|
|
$payment_data = array(
|
|
'price' => $purchase_data['price'],
|
|
'date' => $purchase_data['date'],
|
|
'user_email' => $purchase_data['user_email'],
|
|
'purchase_key' => $purchase_data['purchase_key'],
|
|
'currency' => edd_get_currency(),
|
|
'downloads' => $purchase_data['downloads'],
|
|
'user_info' => $purchase_data['user_info'],
|
|
'cart_details' => $purchase_data['cart_details'],
|
|
'gateway' => $this->gateway_id,
|
|
'status' => 'pending',
|
|
);
|
|
|
|
$payment_id = edd_insert_payment( $payment_data );
|
|
|
|
$authorization_id = $charge['AuthorizeResult']['AuthorizationDetails']['AmazonAuthorizationId'];
|
|
$capture_id = str_replace( '-A', '-C', $authorization_id );
|
|
$reference_id = sanitize_text_field( $_POST['edd_amazon_reference_id'] );
|
|
|
|
// Confirm the capture was completed
|
|
$capture = $this->client->getCaptureDetails( array(
|
|
'merchant_id' => edd_get_option( 'amazon_seller_id', '' ),
|
|
'amazon_capture_id' => $capture_id
|
|
) );
|
|
|
|
$capture = new ResponseParser( $capture->response );
|
|
$capture = $capture->toArray();
|
|
|
|
edd_update_payment_meta( $payment_id, '_edd_amazon_authorization_id', $authorization_id );
|
|
edd_update_payment_meta( $payment_id, '_edd_amazon_capture_id', $capture_id );
|
|
|
|
edd_set_payment_transaction_id( $payment_id, $reference_id, $purchase_data['price'] );
|
|
|
|
edd_update_payment_status( $payment_id, 'complete' );
|
|
|
|
// Empty the shopping cart
|
|
edd_empty_cart();
|
|
edd_send_to_success_page();
|
|
|
|
// Set an error
|
|
} else {
|
|
edd_set_error( 'amazon_error',sprintf( __( 'There was an issue processing your payment. Amazon error: %s', 'easy-digital-downloads' ), print_r( $charge, true ) ) );
|
|
edd_send_back_to_checkout( '?payment-mode=amazon&amazon_reference_id=' . $purchase_data['post_data']['edd_amazon_reference_id'] );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieve the checkout URL for Amazon after authentication is complete
|
|
*
|
|
* @since 2.4
|
|
* @return string
|
|
*/
|
|
private function get_amazon_checkout_uri() {
|
|
if ( is_null( $this->checkout_uri ) ) {
|
|
$this->checkout_uri = esc_url_raw( add_query_arg( array( 'payment-mode' => 'amazon' ), edd_get_checkout_uri() ) );
|
|
}
|
|
|
|
return $this->checkout_uri;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the return URL for Amazon after authentication on Amazon is complete
|
|
*
|
|
* @since 2.4
|
|
* @return string
|
|
*/
|
|
private function get_amazon_authenticate_redirect() {
|
|
if ( is_null( $this->redirect_uri ) ) {
|
|
$this->redirect_uri = esc_url_raw( add_query_arg( array( 'edd-listener' => 'amazon', 'state' => 'return_auth' ), edd_get_checkout_uri() ) );
|
|
}
|
|
|
|
return $this->redirect_uri;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the URL to send customers too once sign-in is complete
|
|
*
|
|
* @since 2.4
|
|
* @return string
|
|
*/
|
|
private function get_amazon_signin_redirect() {
|
|
if ( is_null( $this->signin_redirect ) ) {
|
|
$this->signin_redirect = esc_url_raw( add_query_arg( array( 'edd-listener' => 'amazon', 'state' => 'signed-in' ), home_url() ) );
|
|
}
|
|
|
|
return $this->signin_redirect;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the IPN URL for Amazon
|
|
*
|
|
* @since 2.4
|
|
* @return string
|
|
*/
|
|
private function get_amazon_ipn_url() {
|
|
return esc_url_raw( add_query_arg( array( 'edd-listener' => 'amazon' ), home_url( 'index.php' ) ) );
|
|
}
|
|
|
|
/**
|
|
* Removes the requirement for entering the billing address
|
|
*
|
|
* Address is pulled directly from Amazon
|
|
*
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
public function disable_address_requirement() {
|
|
if ( ! empty( $_POST['edd-gateway'] ) && $this->gateway_id == $_REQUEST['edd-gateway'] ) {
|
|
add_filter( 'edd_require_billing_address', '__return_false', 9999 );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Given a transaction ID, generate a link to the Amazon transaction ID details
|
|
*
|
|
* @since 2.4
|
|
* @param string $transaction_id The Transaction ID
|
|
* @param int $payment_id The payment ID for this transaction
|
|
* @return string A link to the PayPal transaction details
|
|
*/
|
|
public function link_transaction_id( $transaction_id, $payment_id ) {
|
|
$base_url = 'https://sellercentral.amazon.com/hz/me/pmd/payment-details?orderReferenceId=';
|
|
$transaction_url = '<a href="' . esc_url( $base_url . $transaction_id ) . '" target="_blank">' . esc_html( $transaction_id ) . '</a>';
|
|
|
|
return apply_filters( 'edd_' . $this->gateway_id . '_link_payment_details_transaction_id', $transaction_url );
|
|
}
|
|
|
|
/**
|
|
* Process IPN messages from Amazon
|
|
*
|
|
* @since 2.4
|
|
* @return void
|
|
*/
|
|
public function process_ipn() {
|
|
|
|
if ( ! isset( $_GET['edd-listener'] ) || $_GET['edd-listener'] !== 'amazon' ) {
|
|
return;
|
|
}
|
|
|
|
if ( isset( $_GET['state'] ) ) {
|
|
return;
|
|
}
|
|
|
|
// Get the IPN headers and Message body
|
|
$headers = getallheaders();
|
|
$body = file_get_contents( 'php://input' );
|
|
|
|
$this->doing_ipn = true;
|
|
|
|
try {
|
|
$ipn = new IpnHandler( $headers, $body );
|
|
$data = $ipn->toArray();
|
|
$seller_id = $data['SellerId'];
|
|
|
|
if ( $seller_id != edd_get_option( 'amazon_seller_id', '' ) ) {
|
|
wp_die( __( 'Invalid Amazon seller ID', 'easy-digital-downloads' ), __( 'IPN Error', 'easy-digital-downloads' ), array( 'response' => 401 ) );
|
|
}
|
|
|
|
switch( $data['NotificationType'] ) {
|
|
case 'OrderReferenceNotification' :
|
|
break;
|
|
|
|
case 'PaymentAuthorize' :
|
|
break;
|
|
|
|
case 'PaymentCapture' :
|
|
$key = $data['CaptureDetails']['CaptureReferenceId'];
|
|
$status = $data['CaptureDetails']['CaptureStatus']['State'];
|
|
|
|
if ( 'Declined' === $status ) {
|
|
$payment_id = edd_get_purchase_id_by_key( $key );
|
|
|
|
edd_update_payment_status( $payment_id, 'failed' );
|
|
|
|
edd_insert_payment_note( $payment_id, __( 'Capture declined in Amazon', 'easy-digital-downloads' ) );
|
|
}
|
|
|
|
break;
|
|
|
|
case 'PaymentRefund' :
|
|
$trans_id = substr( $data['RefundDetails']['AmazonRefundId'], 0, 19 );
|
|
$status = $data['RefundDetails']['RefundStatus']['State'];
|
|
|
|
if ( 'Completed' === $status ) {
|
|
$payment_id = edd_get_purchase_id_by_transaction_id( $trans_id );
|
|
|
|
edd_update_payment_status( $payment_id, 'refunded' );
|
|
|
|
edd_insert_payment_note( $payment_id, sprintf( __( 'Refund completed in Amazon. Refund ID: %s', 'easy-digital-downloads' ), $data['RefundDetails']['AmazonRefundId'] ) );
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
} catch( Exception $e ) {
|
|
wp_die( $e->getErrorMessage(), __( 'IPN Error', 'easy-digital-downloads' ), array( 'response' => 401 ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Detect a refund action from EDD
|
|
*
|
|
* @deprecated 3.0 Due to issues with Amazon, refunds must be processed at the gateway.
|
|
* @since 2.4
|
|
* @param $payment_id int The ID number of the payment being refunded
|
|
* @param $new_status string The new status assigned to the payment
|
|
* @param $old_status string The previous status of the payment
|
|
* @return void
|
|
*/
|
|
public function process_refund( $payment_id, $new_status, $old_status ) {
|
|
_edd_deprecated_function( __METHOD__, '3.0' );
|
|
|
|
if ( 'complete' !== $old_status && 'revoked' !== $old_status ) {
|
|
return;
|
|
}
|
|
|
|
if ( 'refunded' !== $new_status ) {
|
|
return;
|
|
}
|
|
|
|
if ( ! empty( $this->doing_ipn ) ) {
|
|
return;
|
|
}
|
|
|
|
if ( 'amazon' !== edd_get_payment_gateway( $payment_id ) ) {
|
|
return;
|
|
}
|
|
|
|
$this->refund( $payment_id );
|
|
|
|
}
|
|
|
|
/**
|
|
* Refund a charge in Amazon
|
|
*
|
|
* @since 2.4
|
|
* @param $payment_id int The ID number of the payment being refunded
|
|
* @return string
|
|
*/
|
|
private function refund( $payment_id = 0 ) {
|
|
|
|
$refund = $this->client->refund( array(
|
|
'merchant_id' => edd_get_option( 'amazon_seller_id', '' ),
|
|
'amazon_capture_id' => edd_get_payment_meta( $payment_id, '_edd_amazon_capture_id', true ),
|
|
'refund_reference_id' => md5( edd_get_payment_key( $payment_id ) . '-refund' ),
|
|
'refund_amount' => edd_get_payment_amount( $payment_id ),
|
|
'currency_code' => edd_get_payment_currency_code( $payment_id ),
|
|
) );
|
|
|
|
if ( 200 == $refund->response['Status'] ) {
|
|
$refund = new ResponseParser( $refund->response );
|
|
$refund = $refund->toArray();
|
|
|
|
$reference_id = $refund['RefundResult']['RefundDetails']['RefundReferenceId'];
|
|
$status = $refund['RefundResult']['RefundDetails']['RefundStatus']['State'];
|
|
|
|
switch( $status ) {
|
|
case 'Declined' :
|
|
$note = __( 'Refund declined in Amazon. Refund ID: %s', 'easy-digital-downloads' );
|
|
break;
|
|
|
|
case 'Completed' :
|
|
$refund_id = $refund['RefundResult']['RefundDetails']['AmazonRefundId'];
|
|
$note = sprintf( __( 'Refund completed in Amazon. Refund ID: %s', 'easy-digital-downloads' ), $refund_id );
|
|
break;
|
|
|
|
case 'Pending' :
|
|
$note = sprintf( __( 'Refund initiated in Amazon. Reference ID: %s', 'easy-digital-downloads' ), $reference_id );
|
|
break;
|
|
}
|
|
edd_insert_payment_note( $payment_id, $note );
|
|
|
|
} else {
|
|
edd_insert_payment_note( $payment_id, __( 'Refund request failed in Amazon.', 'easy-digital-downloads' ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieve the URL for connecting Amazon account to EDD
|
|
*
|
|
* @since 2.4
|
|
* @since 2.9.8 - Updated registration URL per Amazon Reps
|
|
* @return string
|
|
*/
|
|
private function get_registration_url() {
|
|
|
|
switch ( edd_get_shop_country() ) {
|
|
case 'GB':
|
|
$base_url = 'https://payments.amazon.co.uk/preregistration/lpa';
|
|
break;
|
|
case 'DE':
|
|
$base_url = 'https://payments.amazon.de/preregistration/lpa';
|
|
break;
|
|
default:
|
|
$base_url = 'https://sellercentral.amazon.com/hz/me/sp/signup';
|
|
break;
|
|
}
|
|
|
|
$query_args = array(
|
|
'registration_source' => 'SPPD',
|
|
'spId' => 'A3JST9YM1SX7LB',
|
|
);
|
|
|
|
return add_query_arg( $query_args, $base_url );
|
|
}
|
|
}
|