Commit inicial - WordPress Análisis de Precios Unitarios

- WordPress core y plugins
- Tema Twenty Twenty-Four configurado
- Plugin allow-unfiltered-html.php simplificado
- .gitignore configurado para excluir wp-config.php y uploads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-11-03 21:04:30 -06:00
commit a22573bf0b
24068 changed files with 4993111 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
<?php
/**
* Manual Payment Gateway
*
* @package Restrict Content Pro
* @subpackage Classes/Gateways/Manual
* @copyright Copyright (c) 2017, Pippin Williamson
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 2.1
*/
class RCP_Payment_Gateway_Manual extends RCP_Payment_Gateway {
/**
* Get things going
*
* @access public
* @since 2.1
* @return void
*/
public function init() {
$this->supports[] = 'one-time';
$this->supports[] = 'fees';
$this->supports[] = 'expiration-extension-on-renewals'; // @link https://github.com/restrictcontentpro/restrict-content-pro/issues/1259
}
/**
* Process registration
*
* @access public
* @since 2.1
* @return void
*/
public function process_signup() {
/**
* @var RCP_Payments $rcp_payments_db
*/
global $rcp_payments_db;
$member = new RCP_Member( $this->user_id );
/**
* Subscription activation is handled when the pending payment is manually updated to "Complete".
* @see rcp_complete_registration()
*/
// Update payment record with transaction ID.
$rcp_payments_db->update( $this->payment->id, array(
'payment_type' => 'manual',
'transaction_id' => $this->generate_transaction_id()
) );
do_action( 'rcp_process_manual_signup', $member, $this->payment->id, $this );
wp_redirect( $this->return_url ); exit;
}
}

View File

@@ -0,0 +1,569 @@
<?php
/**
* Payment Gateway Base Class
*
* You can extend this class to add support for a custom gateway.
* @link http://docs.restrictcontentpro.com/article/1695-payment-gateway-api
*
* @package Restrict Content Pro
* @subpackage Classes/Gateway
* @copyright Copyright (c) 2020, Sandhills Development, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 2.1
*/
class RCP_Payment_Gateway {
/**
* Array of features the gateway supports, including:
* one-time (one time payments)
* recurring (recurring payments)
* fees (setup fees)
* trial (free trials)
* ajax-payment (payment processing via ajax)
* card-updates (update billing card for subscriptions)
* off-site-subscription-creation (create subscriptions while the user is not on site)
*
* @var array
* @access public
*/
public $supports = array();
/**
* The customer's email address
*
* @var string
* @access public
*/
public $email;
/**
* The customer's user account ID
*
* @var int
* @access public
*/
public $user_id;
/**
* The customer's username
*
* @var string
* @access public
*/
public $user_name;
/**
* The selected currency code (i.e. "USD")
*
* @var string
* @access public
*/
public $currency;
/**
* Recurring subscription amount
* This excludes any one-time fees or one-time discounts.
*
* @var int|float
*/
public $amount;
/**
* Initial payment amount
* This is the amount to be billed for the first payment, including
* any one-time setup fees or one-time discounts.
*
* @var int|float
* @access public
*/
public $initial_amount;
/**
* Total discounts applied to the payment
*
* @var int|float
* @access public
*/
public $discount;
/**
* Subscription duration
*
* @var int
* @access public
*/
public $length;
/**
* Subscription unit: day, month, or year
*
* @var string
* @access public
*/
public $length_unit;
/**
* Signup fees to apply to the first payment
* (This number is included in $initial_amount)
*
* @var int|float
* @access public
*/
public $signup_fee;
/**
* Subscription key
*
* @var string
* @access public
*/
public $subscription_key;
/**
* Subscription ID number the customer is signing up for
*
* @var int
* @access public
*/
public $subscription_id;
/**
* Name of the subscription the customer is signing up for
*
* @var string
* @access public
*/
public $subscription_name;
/**
* Whether or not this registration is for a recurring subscription
*
* @var bool
* @access public
*/
public $auto_renew;
/**
* URL to redirect the customer to after a successful registration
*
* @var string
* @access public
*/
public $return_url;
/**
* Whether or not the site is in sandbox mode
*
* @var bool
* @access public
*/
public $test_mode;
/**
* Array of all subscription data that's been passed to the gateway
*
* @var array
* @access public
*/
public $subscription_data;
/**
* Webhook event ID (for example: the Stripe event ID)
* This may not always be populated
*
* @var string
* @access public
*/
public $webhook_event_id;
/**
* Payment object for this transaction. Going into the gateway it's been
* create with the status 'pending' and will need to be updated after
* a successful payment.
*
* @var object
* @access public
* @since 2.9
*/
public $payment;
/**
* Customer object for this user.
*
* @var RCP_Customer
* @access public
* @since 3.0
*/
public $customer;
/**
* Membership object for this payment.
*
* @var RCP_Membership
* @access public
* @since 3.0
*/
public $membership;
/**
* Start date of the subscription in MySQL format. It starts today by default (empty string).
*
* @var string
* @access public
*/
public $subscription_start_date;
/**
* Used for saving an error message that occurs during registration.
*
* @var string
* @access public
* @since 2.9
*/
public $error_message;
/**
* RCP_Payment_Gateway constructor.
*
* @param array $subscription_data Subscription data passed from rcp_process_registration()
*
* @access public
* @return void
*/
public function __construct( $subscription_data = array() ) {
$this->test_mode = rcp_is_sandbox();
$this->init();
if( ! empty( $subscription_data ) ) {
/**
* @var RCP_Payments $rcp_payments_db
*/
global $rcp_payments_db;
$this->email = $subscription_data['user_email'];
$this->user_id = $subscription_data['user_id'];
$this->user_name = $subscription_data['user_name'];
$this->currency = $subscription_data['currency'];
$this->amount = round( $subscription_data['recurring_price'], 2 );
$this->initial_amount = round( $subscription_data['initial_price'], 2 );
$this->discount = $subscription_data['discount'];
$this->discount_code = $subscription_data['discount_code'];
$this->length = $subscription_data['length'];
$this->length_unit = $subscription_data['length_unit'];
$this->signup_fee = $this->supports( 'fees' ) ? $subscription_data['fee'] : 0;
$this->subscription_key = $subscription_data['key'];
$this->subscription_id = $subscription_data['subscription_id'];
$this->subscription_name = $subscription_data['subscription_name'];
$this->auto_renew = $this->supports( 'recurring' ) ? $subscription_data['auto_renew'] : false;;
$this->return_url = $subscription_data['return_url'];
$this->subscription_data = $subscription_data;
$this->payment = $rcp_payments_db->get_payment( $subscription_data['payment_id'] );
$this->customer = $subscription_data['customer'];
$this->membership = rcp_get_membership( $subscription_data['membership_id'] );
$this->subscription_start_date = $subscription_data['subscription_start_date'];
if ( $this->is_trial() ) {
$this->initial_amount = 0;
}
rcp_log( sprintf( 'Registration for user #%d sent to gateway. Level ID: %d; Initial Amount: %.2f; Recurring Amount: %.2f; Auto Renew: %s; Trial: %s; Subscription Start: %s; Membership ID: %d', $this->user_id, $this->subscription_id, $this->initial_amount, $this->amount, var_export( $this->auto_renew, true ), var_export( $this->is_trial(), true ), $this->subscription_start_date, $this->membership->get_id() ) );
}
}
/**
* Initialize the gateway configuration
*
* This is used to populate the $supports property, setup any API keys, and set the API endpoint.
*
* @access public
* @return void
*/
public function init() {
/* Example:
$this->supports[] = 'one-time';
$this->supports[] = 'recurring';
$this->supports[] = 'fees';
$this->supports[] = 'trial';
global $rcp_options;
if ( $this->test_mode ) {
$this->api_endpoint = 'https://sandbox.gateway.com';
$this->api_key = $rcp_options['my_sandbox_api_key'];
} else {
$this->api_endpoint = 'https://live.gateway.com';
$this->api_key = $rcp_options['my_live_api_key'];
}
*/
}
/**
* Process signup via ajax
*
* Optionally, payment can be processed (in whole or in part) via ajax.
*
* If successful, return `true` or an array of field keys/values to add to the registration form as hidden fields.
*
* If failure, return `WP_Error`.
*
* @since 3.2
* @return true|array|WP_Error
*/
public function process_ajax_signup() {
return true;
}
/**
* Process registration
*
* This is where you process the actual payment. If non-recurring, you'll want to use
* the $this->initial_amount value. If recurring, you'll want to use $this->initial_amount
* for the first payment and $this->amount for the recurring amount.
*
* After a successful payment, redirect to $this->return_url.
*
* @access public
* @return void
*/
public function process_signup() {}
/**
* Process webhooks
*
* Listen for webhooks and take appropriate action to insert payments, renew the member's
* account, or cancel the membership.
*
* @access public
* @return void
*/
public function process_webhooks() {}
/**
* Use this space to enqueue any extra JavaScript files.
*
* @access public
* @return void
*/
public function scripts() {}
/**
* Load any extra fields on the registration form
*
* @access public
* @return string
*/
public function fields() {
/* Example for loading the credit card fields :
ob_start();
rcp_get_template_part( 'card-form' );
return ob_get_clean();
*/
}
/**
* Load fields for the Update Billing Card form
*
* @access public
* @since 3.3
* @return void
*/
public function update_card_fields() {
rcp_get_template_part( 'card-update-form-fields' );
}
/**
* Validate registration form fields
*
* @access public
* @return void
*/
public function validate_fields() {
/* Example :
if ( empty( $_POST['rcp_card_cvc'] ) ) {
rcp_errors()->add( 'missing_card_code', __( 'The security code you have entered is invalid', 'rcp' ), 'register' );
}
*/
}
/**
* Change the price of a membership's subscription in the gateway.
*
* `price-changes` needs to be declared as a supported feature.
*
* @param RCP_Membership $membership Membership object.
* @param float $new_price New price
*
* @return true|WP_Error True on success, WP_Error on failure.
*/
public function change_membership_subscription_price( $membership, $new_price ) {
/*
* Update the price of the subscription in the payment gateway.
* The membership record will automatically be updated with the new price if you return `TRUE`.
* Return a `WP_Error` object on failure.
*/
return new WP_Error( 'not_supported', __( 'Price changes not supported.', 'rcp' ) );
}
/**
* Create a subscription for a given membership object.
*
* `subscription-creation` needs to be declared as a supported feature.
*
* If successful, the membership record should updated accordingly:
* - Gateway customer ID set.
* - Gateway subscription ID set to new subscription.
*
* @param RCP_Membership $membership Membership object.
* @param bool $charge_now True if the customer should be charged immediately. False if the first payment should be
* the date of the membership expiration.
*
* @return string|WP_Error New subscription ID on success, WP_Error on failure.
*/
public function create_subscription_for_membership( $membership, $charge_now = false ) {
/*
* Create a new recurring subscription for the provided membership.
*
* If successful you need to do the following:
* - Set gateway_customer_id field, if not set already.
* - Set gateway_subscription_id to the new subscription ID value.
* - Return TRUE
*
* RCP will automatically set auto_renew on for the membership.
*
* If there's an error, return a WP_Error object.
*/
return new WP_Error( 'not_supported', __( 'Dynamic subscription creation not supported.', 'rcp' ) );
}
/**
* Change the next bill date for an existing membership.
*
* `renewal-date-changes` needs to be declared as a supported feature.
*
* @param RCP_Membership $membership Membership object.
* @param string $next_bill_date Desired next bill date in MySQL format.
*
* @since 3.2
* @return true|WP_Error True on success, WP_Error on failure.
*/
public function change_next_bill_date( $membership, $next_bill_date ) {
/*
* Use the $membership->get_gateway_subscription_id() to get the ID of the current subscription.
* Then update the next bill date to the value of $next_bill_date.
*
* Return TRUE on success, WP_Error on failure.
*/
return new WP_Error( 'not_supported', __( 'Next bill date changes not supported.', 'rcp' ) );
}
/**
* Check if the gateway supports a given feature
*
* @param string $item
*
* @access public
* @return bool
*/
public function supports( $item = '' ) {
return in_array( $item, $this->supports );
}
/**
* Generate a transaction ID
*
* Used in the manual payments gateway.
*
* @return string
*/
public function generate_transaction_id() {
$auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : '';
return strtolower( md5( $this->subscription_key . date( 'Y-m-d H:i:s' ) . $auth_key . uniqid( 'rcp', true ) ) );
}
/**
* Activate or renew the membership. If the membership has been billed `0` times then it is activated for the
* first time. Otherwise it is renewed.
*
* @param bool $recurring Whether or not it's a recurring subscription.
* @param string $status Status to set the member to, usually 'active'.
*
* @access public
* @return void
*/
public function renew_member( $recurring = false, $status = 'active' ) {
if ( 0 == $this->membership->get_times_billed() ) {
$this->membership->activate();
} else {
$this->membership->renew( $recurring, $status );
}
}
/**
* Add error to the registration form
*
* @param string $code Error code.
* @param string $message Error message to display.
*
* @access public
* @return void
*/
public function add_error( $code = '', $message = '' ) {
rcp_errors()->add( $code, $message, 'register' );
}
/**
* Determines if the subscription is eligible for a trial.
*
* @since 2.7
* @return bool True if the subscription is eligible for a trial, false if not.
*/
public function is_trial() {
return ! empty( $this->subscription_data['trial_eligible'] )
&& ! empty( $this->subscription_data['trial_duration'] )
&& ! empty( $this->subscription_data['trial_duration_unit'] )
;
}
/**
* Creates a new subscription at the gateway for the supplied membership
*
* This operation does not happen during
* registration and the customer may not even be on-site, which is why no card details are supplied or available.
* This method should only be implemented if the gateway supports `off-site-subscription-creation`
*
* @param RCP_Membership $membership
*
* @since 3.4
* @return true|WP_Error True on success, WP_Error object on failure.
*/
public function create_off_site_subscription( $membership ) {
return new WP_Error( 'not_supported', __( 'This feature is not supported by the chosen payment method.', 'rcp' ) );
}
}

View File

@@ -0,0 +1,226 @@
<?php
/**
* Payment Gateways Class
*
* @package Restrict Content Pro
* @subpackage Classes/Payment Gateways
* @copyright Copyright (c) 2017, Pippin Williamson
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 2.1
*/
class RCP_Payment_Gateways {
public $available_gateways;
public $enabled_gateways;
/**
* Get things going
*
* @since 2.1
*/
public function __construct() {
$this->available_gateways = $this->get_gateways();
$this->enabled_gateways = $this->get_enabled_gateways();
}
/**
* Retrieve a gateway by ID
*
* @since 2.1
* @return array|false
*/
public function get_gateway( $id = '' ) {
if( isset( $this->available_gateways[ $id ] ) ) {
return $this->available_gateways[ $id ];
}
return false;
}
/**
* Retrieve all registered gateways
*
* @since 2.1
* @return array
*/
private function get_gateways() {
$gateways = array(
'manual' => array(
'label' => __( 'Manual Payment', 'rcp' ),
'admin_label' => __( 'Manual Payment', 'rcp' ),
'class' => 'RCP_Payment_Gateway_Manual'
),
'stripe' => array(
'label' => __('Credit / Debit Card', 'rcp'),
'admin_label' => __('Stripe', 'rcp'),
'class' => 'RCP_Payment_Gateway_Stripe',
'test_card' => array(
'number' => '4242424242424242',
'cvc' => '123',
'zip' => '45814',
'link' => 'https://stripe.com/docs/testing#cards'
)
),
);
return apply_filters( 'rcp_payment_gateways', $gateways );
}
/**
* Retrieve all enabled gateways
*
* @since 2.1
* @return array
*/
private function get_enabled_gateways() {
global $rcp_options;
$enabled = array();
$saved = isset( $rcp_options['gateways'] ) ? array_map( 'trim', $rcp_options['gateways'] ) : array();
if ( ! empty( $saved ) && is_array( $saved ) && array_key_exists( 'stripe_checkout', $saved ) ) {
unset( $saved['stripe_checkout'] );
if ( ! in_array( 'stripe', $saved ) ) {
// Add normal Stripe if it's not already activated.
$saved['stripe'] = 1;
}
}
if( ! empty( $saved ) ) {
foreach( $this->available_gateways as $key => $gateway ) {
if( isset( $saved[ $key ] ) && $saved[ $key ] == 1 ) {
$enabled[ $key ] = $gateway;
}
}
}
/**
* TODO: If PayPay is activated as default then the settings should be actiavted before sending the result.
if( empty( $enabled ) ) {
$enabled[ 'paypal'] = __( 'PayPal', 'rcp' );
}
**/
return apply_filters( 'rcp_enabled_payment_gateways', $enabled, $this->available_gateways );
}
/**
* Determine if a gateway is enabled
*
* @param string $id ID of the gateway to check.
*
* @since 2.1
* @return bool
*/
public function is_gateway_enabled( $id = '' ) {
return isset( $this->enabled_gateways[ $id ] );
}
/**
* Load the fields for a gateway
*
* @since 2.1
* @return void
*/
public function load_fields() {
if( ! empty( $_POST['rcp_gateway'] ) ) {
$fields = $this->get_gateway_fields( $_POST['rcp_gateway'] );
if ( ! empty( $fields ) ) {
wp_send_json_success( array( 'success' => true, 'fields' => $fields ) );
} else {
wp_send_json_error( array( 'success' => false ) );
}
}
}
/**
* Returns the fields for a specific gateway.
*
* @param string $gateway Gateway slug.
*
* @return string|false
*/
public function get_gateway_fields( $gateway ) {
$gateway_name = sanitize_text_field( $gateway );
$gateway = $this->get_gateway( sanitize_text_field( $gateway ) );
$gateway_obj = false;
if( isset( $gateway['class'] ) ) {
$gateway_obj = new $gateway['class'];
}
if( ! is_object( $gateway_obj ) ) {
return false;
}
/**
* @var RCP_Payment_Gateway $gateway_obj
*/
$fields = $gateway_obj->fields();
// Add test card number.
$show_test_card = rcp_is_sandbox() && ! empty( $gateway['test_card']['number'] );
/**
* Filters whether or not the test card details should be shown.
*
* @param bool $show_test_card Whether or not the test card information should be shown.
* @param array $gateway Gateway details.
*/
$show_test_card = apply_filters( 'rcp_show_test_card_on_registration', $show_test_card, $gateway );
if ( $show_test_card ) {
ob_start();
?>
<div id="rcp-sandbox-gateway-test-cards">
<p><?php printf( __( '<strong>Test mode is enabled.</strong> You can use the following card details for %s test transactions:', 'rcp' ), $gateway['admin_label'] ); ?></p>
<ul>
<li><?php printf( __( 'Number: %s', 'rcp' ), $gateway['test_card']['number'] ); ?></li>
<?php if ( ! empty( $gateway['test_card']['cvc'] ) ) : ?>
<li><?php printf( __( 'CVC: %s', 'rcp' ), $gateway['test_card']['cvc'] ); ?></li>
<?php endif; ?>
<li><?php _e( 'Expiration: any future date', 'rcp' ); ?></li>
<?php if ( ! empty( $gateway['test_card']['zip'] ) ) : ?>
<li><?php printf( __( 'Zip: %s', 'rcp' ), $gateway['test_card']['zip'] ); ?></li>
<?php endif; ?>
</ul>
<?php if ( ! empty( $gateway['test_card']['link'] ) ) : ?>
<p><?php printf( __( 'For more test card numbers visit the <a href="%s" target="_blank">%s documentation page</a>.', 'rcp' ), esc_url( $gateway['test_card']['link'] ), $gateway['admin_label'] ); ?></p>
<?php endif; ?>
</div>
<?php
if( 'braintree' == $gateway_name ) {
do_action( 'rcp_braintree_additional_fields' );
}
$fields = ob_get_clean() . $fields;
}
return $fields;
}
}

View File

@@ -0,0 +1,418 @@
<?php
/**
* Gateway Actions
*
* @package Restrict Content Pro
* @subpackage Gateways/Actions
* @copyright Copyright (c) 2020, Restrict Content Pro
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
*/
/**
* Load webhook processor for all gateways
*
* @access public
* @since 2.1
* @return void
*/
function rcp_process_gateway_webooks() {
if ( ! apply_filters( 'rcp_process_gateway_webhooks', ! empty( $_GET['listener'] ) ) ) {
return;
}
$gateways = new RCP_Payment_Gateways;
foreach( $gateways->available_gateways as $key => $gateway ) {
$payment_gateway = rcp_get_gateway_class( $key );
if( $payment_gateway ) {
$payment_gateway->process_webhooks();
}
}
}
add_action( 'init', 'rcp_process_gateway_webooks', -99999 );
/**
* Process gateway confirmations.
*
* @access public
* @since 2.1
* @return void
*/
function rcp_process_gateway_confirmations() {
global $rcp_options;
if( empty( $rcp_options['registration_page'] ) ) {
return;
}
if( empty( $_GET['rcp-confirm'] ) ) {
return;
}
if( ! rcp_is_registration_page() ) {
return;
}
$gateways = new RCP_Payment_Gateways;
$gateway = sanitize_text_field( $_GET['rcp-confirm'] );
if( ! $gateways->is_gateway_enabled( $gateway ) ) {
return;
}
$payment_gateway = rcp_get_gateway_class( $gateway );
if( $payment_gateway && method_exists( $payment_gateway, 'process_confirmation' ) ) {
$payment_gateway->process_confirmation();
}
}
add_action( 'template_redirect', 'rcp_process_gateway_confirmations', -99999 );
/**
* Load gateway scripts on registration page
*
* @access public
* @since 2.1
* @return void
*/
function rcp_load_gateway_scripts() {
global $rcp_options;
$is_rcp_page = rcp_is_registration_page();
if ( ! $is_rcp_page ) {
// Check other known pages.
$pages = array( 'redirect', 'account_page', 'edit_profile', 'update_card' );
foreach ( $pages as $page_key ) {
if ( ! empty( $rcp_options[ $page_key ] ) && is_page( absint( $rcp_options[ $page_key ] ) ) ) {
$is_rcp_page = true;
break;
}
}
}
$load_scripts = $is_rcp_page || defined( 'RCP_LOAD_SCRIPTS_GLOBALLY' );
$gateways = new RCP_Payment_Gateways;
/*
* Unless the option is disabled, Stripe.js is loaded on all pages for advanced fraud functionality.
*/
$global_scripts = empty( $rcp_options['disable_sitewide_scripts'] ) ? array( 'stripe', 'stripe_checkout' ) : array();
foreach( $gateways->enabled_gateways as $key => $gateway ) {
$payment_gateway = rcp_get_gateway_class( $key );
if( $payment_gateway && ( $load_scripts || in_array( $key, $global_scripts ) ) ) {
$payment_gateway->scripts();
}
}
}
add_action( 'wp_enqueue_scripts', 'rcp_load_gateway_scripts', 100 );
/**
* Process an update card form request
*
* @uses rcp_member_can_update_billing_card()
*
* @access private
* @since 2.1
* @return void
*/
function rcp_process_update_card_form_post() {
if( ! is_user_logged_in() ) {
return;
}
if( is_admin() ) {
return;
}
if ( ! isset( $_POST['rcp_update_card_nonce'] ) || ! wp_verify_nonce( $_POST['rcp_update_card_nonce'], 'rcp-update-card-nonce' ) ) {
return;
}
$membership_id = isset( $_POST['rcp_membership_id'] ) ? absint( $_POST['rcp_membership_id'] ) : false;
if ( empty( $membership_id ) ) {
$customer = rcp_get_customer_by_user_id(); // current customer
$membership = ! empty( $customer ) ? rcp_get_customer_single_membership( $customer->get_id() ) : false;
} else {
$membership = rcp_get_membership( $membership_id );
}
if ( ! is_object( $membership ) || 0 == $membership->get_id() ) {
wp_die( __( 'Invalid membership.', 'rcp' ), __( 'Error', 'rcp' ), array( 'response' => 500 ) );
}
// Bail if this user isn't actually the customer associated with this membership.
if ( $membership->get_user_id() != get_current_user_id() ) {
wp_die( __( 'You do not have permission to perform this action.', 'rcp' ), __( 'Error', 'rcp' ), array( 'response' => 403 ) );
}
if( ! $membership->can_update_billing_card() ) {
wp_die( __( 'Your account does not support updating your billing card', 'rcp' ), __( 'Error', 'rcp' ), array( 'response' => 403 ) );
}
if ( has_action( 'rcp_update_billing_card' ) ) {
$member = new RCP_Member( get_current_user_id() );
if ( $member ) {
/**
* @deprecated 3.0 Use `rcp_update_membership_billing_card` instead.
*/
do_action( 'rcp_update_billing_card', $member->ID, $member );
}
}
/**
* Processes the billing card update. Individual gateways hook into here.
*
* @param RCP_Membership $membership
*
* @since 3.0
*/
do_action( 'rcp_update_membership_billing_card', $membership );
}
add_action( 'init', 'rcp_process_update_card_form_post' );
/**
* Log cancellation via webhook
*
* @param RCP_Member $member Member object.
* @param RCP_Payment_Gateway $gateway Gateway object.
*
* @since 2.9
* @return void
*/
function rcp_log_webhook_cancel( $member, $gateway ) {
rcp_log( sprintf( 'Membership cancelled via %s webhook for member ID #%d.', rcp_get_gateway_name_from_object( $gateway ), $member->ID ) );
}
add_action( 'rcp_webhook_cancel', 'rcp_log_webhook_cancel', 10, 2 );
/**
* Log new recurring payment profile created via webhook. This is when the
* subscription is initially created, it does not include renewals.
*
* @param RCP_Member $member Member object.
* @param RCP_Payment_Gateway $gateway Gateway object.
*
* @since 2.9
* @return void
*/
function rcp_log_webhook_recurring_payment_profile_created( $member, $gateway ) {
rcp_log( sprintf( 'New recurring payment profile created for member #%d in gateway %s.', $member->ID, rcp_get_gateway_name_from_object( $gateway ) ) );
}
add_action( 'rcp_webhook_recurring_payment_profile_created', 'rcp_log_webhook_recurring_payment_profile_created', 10, 2 );
/**
* Log error when duplicate payment is detected.
*
* @param string $payment_txn_id Payment transaction ID.
* @param RCP_Member $member Member object.
* @param RCP_Payment_Gateway $gateway Gateway object.
*
* @since 2.9
* @return void
*/
function rcp_log_duplicate_ipn_payment( $payment_txn_id, $member, $gateway ) {
rcp_log( sprintf( 'A duplicate payment was detected for user #%d. Check to make sure both payments weren\'t recorded. Transaction ID: %s', $member->ID, $payment_txn_id ) );
}
add_action( 'rcp_ipn_duplicate_payment', 'rcp_log_duplicate_ipn_payment', 10, 3 );
/**
* Log payment inserted via gateway. This can run on renewals and/or one-time payments.
*
* @param RCP_Member $member Member object.
* @param int $payment_id ID of the payment that was just inserted.
* @param RCP_Payment_Gateway $gateway Gateway object.
*
* @since 2.9
* @return void
*/
function rcp_log_gateway_payment_processed( $member, $payment_id, $gateway ) {
rcp_log( sprintf( 'Payment #%d completed for member #%d via %s gateway.', $payment_id, $member->ID, rcp_get_gateway_name_from_object( $gateway ) ) );
}
add_action( 'rcp_gateway_payment_processed', 'rcp_log_gateway_payment_processed', 10, 3 );
/**
* Update the membership's "recurring_amount" when a renewal payment is processed.
* This will correct any invalid recurring_amount values due to recurring discounts
* or level price changes.
*
* @param RCP_Member $member Member object.
* @param int $payment_id ID of the payment that was just inserted.
* @param RCP_Payment_Gateway $gateway Gateway object.
*
* @since 3.0.5
* @return void
*/
function rcp_update_membership_recurring_amount_on_renewal( $member, $payment_id, $gateway ) {
$payments = new RCP_Payments();
$payment = $payments->get_payment( $payment_id );
$membership = false;
if ( empty( $payment ) || empty( $payment->amount ) ) {
return;
}
if ( ! empty( $gateway->membership ) ) {
$membership = $gateway->membership;
} elseif ( ! empty( $payment->membership_id ) ) {
$membership = rcp_get_membership( $payment->membership_id );
}
if ( ! is_a( $membership, 'RCP_Membership' ) ) {
return;
}
if ( $payment->amount != $membership->get_recurring_amount() ) {
$membership->update( array(
'recurring_amount' => $payment->amount
) );
}
}
add_action( 'rcp_webhook_recurring_payment_processed', 'rcp_update_membership_recurring_amount_on_renewal', 10, 3 );
/**
* Change the price of a subscription.
*
* @param true|WP_Error $changed True if successfully changed, WP_Error if not.
* @param float $new_price The new price.
* @param string $gateway Gateway slug.
* @param RCP_Membership $membership Membership object.
*
* @since 3.5
* @return true|WP_Error True on success, WP_Error on failure.
*/
function rcp_gateway_process_change_subscription_price( $changed, $new_price, $gateway, $membership ) {
// Don't mess with a good thing.
if ( true === $changed ) {
return $changed;
}
rcp_log( sprintf( 'Changing subscription price in %s gateway for membership ID #%d. New price: %s.', $gateway, $membership->get_id(), rcp_currency_filter( $new_price ) ) );
// If gateway is empty, bail.
if ( empty( $gateway ) ) {
return new WP_Error( 'invalid_gateway', __( 'Invalid or unknown payment gateway.', 'rcp' ) );
}
$payment_gateway = rcp_get_gateway_class( $gateway );
if ( empty( $payment_gateway ) ) {
return new WP_Error( 'invalid_gateway_class', __( 'Invalid gateway class.', 'rcp' ) );
}
// Gateway doesn't support price changes.
if ( ! $payment_gateway->supports( 'price-changes' ) ) {
return new WP_Error( 'price_changes_not_supported', __( 'Payment gateway doesn\'t support price changes.', 'rcp' ) );
}
return $payment_gateway->change_membership_subscription_price( $membership, $new_price );
}
add_filter( 'rcp_membership_change_gateway_price', 'rcp_gateway_process_change_subscription_price', 10, 4 );
/**
* Process manual creation of a subscription
*
* This is done outside the registration form, such as when an admin is manually changing a membership's
* associated membership level. The old subscription is cancelled and a new one is created.
*
* For this to work, gateways must declare support for `subscription-creation`.
*
* @param true|WP_Error $created True if successfully created, WP_Error if not.
* @param bool $charge_now True to process the first payment now. False to wait until the membership's expiration date.
* @param string $gateway Gateway slug.
* @param RCP_Membership $membership Membership object.
*
* @since 3.5
* @return true|WP_Error True on success, WP_Error on failure.
*/
function rcp_gateway_process_manual_subscription_creation( $created, $charge_now, $gateway, $membership ) {
// Don't mess with a good thing.
if ( true === $created ) {
return $created;
}
// If gateway is empty, bail.
if ( empty( $gateway ) ) {
return new WP_Error( 'invalid_gateway', __( 'Invalid or unknown payment gateway.', 'rcp' ) );
}
$payment_gateway = rcp_get_gateway_class( $gateway );
if ( empty( $payment_gateway ) ) {
return new WP_Error( 'invalid_gateway_class', __( 'Invalid gateway class.', 'rcp' ) );
}
// Gateway doesn't support price changes.
if ( ! $payment_gateway->supports( 'subscription-creation' ) ) {
return new WP_Error( 'subscription_creation_not_supported', __( 'Payment gateway doesn\'t support dynamic subscription creation.', 'rcp' ) );
}
return $payment_gateway->create_subscription_for_membership( $membership, $charge_now );
}
add_filter( 'rcp_membership_created_gateway_subscription', 'rcp_gateway_process_manual_subscription_creation', 10, 4 );
/**
* Update the next bill date for a subscription
*
* We can't actually change this directly so we do something hacky by setting the "trial_end" date instead.
* This effectively changes the next bill date.
* @link https://stripe.com/docs/billing/subscriptions/billing-cycle#changing
*
* @param true|WP_Error $changed True if successfully changed, WP_Error if not.
* @param string $new_renewal_date New renewal date in MySQL format.
* @param string $gateway Payment gateway slug.
* @param RCP_Membership $membership Membership object.
*
* @return true|WP_Error True on success, WP_Error on failure.
* @throws Exception
*/
function rcp_stripe_update_subscription_bill_date( $changed, $new_renewal_date, $gateway, $membership ) {
// Don't mess with a good thing.
if ( true === $changed ) {
return $changed;
}
// If gateway is empty, bail.
if ( empty( $gateway ) ) {
return new WP_Error( 'invalid_gateway', __( 'Invalid or unknown payment gateway.', 'rcp' ) );
}
$payment_gateway = rcp_get_gateway_class( $gateway );
if ( empty( $payment_gateway ) ) {
return new WP_Error( 'invalid_gateway_class', __( 'Invalid gateway class.', 'rcp' ) );
}
// Gateway doesn't support next bill date changes.
if ( ! $payment_gateway->supports( 'renewal-date-changes' ) ) {
return new WP_Error( 'renewal_date_changes_not_supported', __( 'Payment gateway doesn\'t support renewal date changes.', 'rcp' ) );
}
return $payment_gateway->change_next_bill_date( $membership, $new_renewal_date );
}
add_filter( 'rcp_membership_change_next_bill_date', 'rcp_stripe_update_subscription_bill_date', 10, 4 );

View File

@@ -0,0 +1,573 @@
<?php
/**
* Gateway Functions
*
* @package Restrict Content Pro
* @subpackage Gateways/Functions
* @copyright Copyright (c) 2020, Restrict Content Pro
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
*/
/**
* Load additional gateway include files
*
* @uses rcp_get_payment_gateways()
*
* @access private
* @since 2.1
* @return void
*/
function rcp_load_gateway_files() {
foreach( rcp_get_payment_gateways() as $key => $gateway ) {
if( file_exists( RCP_PLUGIN_DIR . 'pro/includes/gateways/' . $key . '/functions.php' ) ) {
require_once RCP_PLUGIN_DIR . 'pro/includes/gateways/' . $key . '/functions.php';
} else if( file_exists( RCP_PLUGIN_DIR . 'core/includes/gateways/' . $key . '/functions.php' ) ) {
require_once RCP_PLUGIN_DIR . 'core/includes/gateways/' . $key . '/functions.php';
}
}
}
/**
* Get all available payment gateways
*
* @access private
* @return array
*/
function rcp_get_payment_gateways() {
$gateways = new RCP_Payment_Gateways;
return $gateways->available_gateways;
}
/**
* Get information about a payment gateway by its slug.
*
* For example, if you have the slug `paypal_express` and want to return the admin label of
* `PayPal Express`, you'd use this function like so:
*
* rcp_get_payment_gateway_details( 'paypal_express', 'admin_label' )
*
* @param string $slug Gateway slug to get details for.
* @param string $key Specific key to retrieve. Leave blank for array of all details, including:
* `label`, `admin_label`, `class`
*
* @since 3.0.4
* @return array|string
*/
function rcp_get_payment_gateway_details( $slug, $key = '' ) {
$gateways = rcp_get_payment_gateways();
$details = array();
if ( isset( $gateways[ $slug ] ) ) {
$details = $gateways[ $slug ];
}
if ( ! empty( $key ) && isset( $details[ $key ] ) ) {
return $details[ $key ];
} elseif ( ! empty( $key ) ) {
return '';
}
return $details;
}
/**
* Return list of active gateways
*
* @access private
* @return array
*/
function rcp_get_enabled_payment_gateways() {
$gateways = new RCP_Payment_Gateways;
foreach( $gateways->enabled_gateways as $key => $gateway ) {
if( is_array( $gateway ) ) {
$gateways->enabled_gateways[ $key ] = $gateway['label'];
}
}
return $gateways->enabled_gateways;
}
/**
* Determine if a gateway is enabled
*
* @param string $id ID of the gateway to check.
*
* @access public
* @return bool
*/
function rcp_is_gateway_enabled( $id = '' ) {
$gateways = new RCP_Payment_Gateways;
return $gateways->is_gateway_enabled( $id );
}
/**
* Send payment / subscription data to gateway
*
* @param string $gateway ID of the gateway.
* @param array $subscription_data Subscription data.
*
* @access private
* @return void
*/
function rcp_send_to_gateway( $gateway, $subscription_data ) {
if( has_action( 'rcp_gateway_' . $gateway ) ) {
do_action( 'rcp_gateway_' . $gateway, $subscription_data );
} else {
$gateways = new RCP_Payment_Gateways;
$gateway = $gateways->get_gateway( $gateway );
$gateway = new $gateway['class']( $subscription_data );
/**
* @var RCP_Payment_Gateway $gateway
*/
$gateway->process_signup();
}
}
/**
* Send payment / subscription data to gateway for ajax processing
*
* @param string $gateway Gatway slug.
* @param array $subscription_data Array of registration data.
*
* @since 3.2
* @return true|array|WP_Error
*/
function rcp_handle_gateway_ajax_processing( $gateway, $subscription_data ) {
if ( ! rcp_gateway_supports( $gateway, 'ajax-payment' ) ) {
return new WP_Error( 'ajax_unsupported', __( 'Ajax payment is not supported by this payment method.', 'rcp' ) );
}
$gateways = new RCP_Payment_Gateways;
$gateway = $gateways->get_gateway( $gateway );
$gateway = new $gateway['class']( $subscription_data );
/**
* @var RCP_Payment_Gateway $gateway
*/
return $gateway->process_ajax_signup();
}
/**
* Determines if a gateway supports a feature
*
* @param string $gateway ID of the gateway to check.
* @param string $item Feature to check support for.
*
* @access public
* @since 2.1
* @return bool
*/
function rcp_gateway_supports( $gateway = 'paypal', $item = 'recurring' ) {
$ret = true;
$gateways = new RCP_Payment_Gateways;
$gateway = $gateways->get_gateway( $gateway );
if( is_array( $gateway ) && isset( $gateway['class'] ) ) {
$gateway = new $gateway['class'];
$ret = $gateway->supports( sanitize_text_field( $item ) );
}
return $ret;
}
/**
* Get the `RCP_Payment_Gateway` class for a specific gateway.
*
* @param string $gateway_slug Payment gateway slug.
* @param array $args Arguments to pass to the class constructor.
*
* @since 3.3
* @return RCP_Payment_Gateway|false
*/
function rcp_get_gateway_class( $gateway_slug, $args = array() ) {
$class = false;
$gateways = new RCP_Payment_Gateways;
$gateway = $gateways->get_gateway( $gateway_slug );
if ( is_array( $gateway ) && isset( $gateway['class'] ) && class_exists( $gateway['class'] ) ) {
$class = new $gateway['class']( $args );
}
return $class;
}
/**
* Retrieve the full HTML link for the transaction ID on the merchant site
*
* @param object $payment Payment object
*
* @access public
* @since 2.6
* @return string HTML link, or just the transaction ID.
*/
function rcp_get_merchant_transaction_id_link( $payment ) {
global $rcp_options;
$url = '';
$link = $payment->transaction_id;
$test = rcp_is_sandbox();
if( ! empty( $payment->transaction_id ) ) {
$gateway = strtolower( $payment->gateway );
$type = strtolower( $payment->payment_type );
if ( empty( $gateway ) && ! empty( $type ) ) {
switch ( $type ) {
case 'web_accept' :
case 'paypal express one time' :
case 'recurring_payment' :
case 'subscr_payment' :
case 'recurring_payment_profile_created' :
$gateway = 'paypal';
break;
case 'credit card' :
case 'credit card one time' :
if ( false !== strpos( $payment->transaction_id, 'ch_' ) ) {
$gateway = 'stripe';
} elseif( false !== strpos( $payment->transaction_id, 'anet_' ) ) {
$gateway = 'authorizenet';
} elseif ( is_numeric( $payment->transaction_id ) ) {
$gateway = 'twocheckout';
}
break;
case 'braintree credit card one time' :
case 'braintree credit card initial payment' :
case 'braintree credit card' :
$gateway = 'braintree';
break;
}
}
switch( $gateway ) {
// PayPal
case 'paypal' :
case 'paypal_express' :
case 'paypal_pro' :
$mode = $test ? 'sandbox.' : '';
$url = 'https://www.' . $mode . 'paypal.com/webscr?cmd=_history-details-from-hub&id=' . $payment->transaction_id;
break;
// 2Checkout
case 'twocheckout' :
$mode = $test ? 'sandbox.' : '';
$url = 'https://' . $mode . '2checkout.com/sandbox/sales/detail?sale_id=' . $payment->transaction_id;
break;
// Stripe
case 'stripe' :
case 'stripe_checkout' :
$mode = $test ? 'test/' : '';
$dir = false !== strpos( $payment->transaction_id, 'sub_' ) ? 'subscriptions/' : 'payments/';
$url = 'https://dashboard.stripe.com/' . $mode . $dir . $payment->transaction_id;
break;
// Braintree
case 'braintree' :
$mode = $test ? 'sandbox.' : '';
$merchant_id = $test ? $rcp_options['braintree_sandbox_merchantId'] : $rcp_options['braintree_live_merchantId'];
$url = 'https://' . $mode . 'braintreegateway.com/merchants/' . $merchant_id . '/transactions/' . $payment->transaction_id;
break;
}
if( ! empty( $url ) ) {
$link = '<a href="' . esc_url( $url ) . '" class="rcp-payment-txn-id-link" target="_blank">' . $payment->transaction_id . '</a>';
}
}
return apply_filters( 'rcp_merchant_transaction_id_link', $link, $payment );
}
/**
* Returns the name of the gateway, given the class object
*
* @param RCP_Payment_Gateway $gateway Gateway object.
*
* @since 2.9
* @return string
*/
function rcp_get_gateway_name_from_object( $gateway ) {
$gateway_classes = wp_list_pluck( rcp_get_payment_gateways(), 'class' );
$gateway_name = array_search( get_class( $gateway ), $gateway_classes );
return ucwords( $gateway_name );
}
/**
* Return the direct URL to manage a customer profile in the gateway.
*
* @param string $gateway Gateway slug.
* @param int $customer_id ID of the customer profile in the payment gateway.
*
* @since 3.0.4
* @return string
*/
function rcp_get_gateway_customer_id_url( $gateway, $customer_id ) {
global $rcp_options;
$url = '';
$sandbox = rcp_is_sandbox();
if ( false !== strpos( $gateway, 'stripe' ) ) {
/**
* Stripe, Stripe Checkout, Stripe Elements (TK).
*/
$base_url = $sandbox ? 'https://dashboard.stripe.com/test/' : 'https://dashboard.stripe.com/';
$url = $base_url . 'customers/' . urlencode( $customer_id );
} elseif ( 'braintree' == $gateway ) {
/**
* Braintree
*/
$subdomain = $sandbox ? 'sandbox.' : '';
$merchant_id = '';
if ( $sandbox && ! empty( $rcp_options['braintree_sandbox_merchantId'] ) ) {
$merchant_id = $rcp_options['braintree_sandbox_merchantId'];
} elseif ( ! $sandbox && ! empty( $rcp_options['braintree_live_merchantId'] ) ) {
$merchant_id = $rcp_options['braintree_live_merchantId'];
}
if ( ! empty( $merchant_id ) ) {
$url = sprintf( 'https://%sbraintreegateway.com/merchants/%s/customers/%s', $subdomain, urlencode( $merchant_id ), urlencode( $customer_id ) );
}
}
/**
* Filters the customer profile URL.
*
* @param string $url URL to manage the customer profile in the gateway.
* @param string $gateway Payment gateway slug.
* @param string $customer_id ID of the customer in the gateway.
*
* @since 3.0.4
*/
return apply_filters( 'rcp_gateway_customer_id_url', $url, $gateway, $customer_id );
}
/**
* Return the direct URL to manage a subscription in the gateway.
*
* @param string $gateway Gateway slug.
* @param int $subscription_id ID of the subscription in the payment gateway.
*
* @since 3.0.4
* @return string
*/
function rcp_get_gateway_subscription_id_url( $gateway, $subscription_id ) {
global $rcp_options;
$url = '';
$sandbox = rcp_is_sandbox();
if ( false !== strpos( $gateway, 'stripe' ) ) {
/**
* Stripe, Stripe Checkout, Stripe Elements (TK).
*/
$base_url = $sandbox ? 'https://dashboard.stripe.com/test/' : 'https://dashboard.stripe.com/';
$url = $base_url . 'subscriptions/' . urlencode( $subscription_id );
} elseif( false !== strpos( $gateway, 'paypal' ) ) {
/**
* PayPal Standard, PayPal Express, PayPal Pro
*/
$base_url = $sandbox ? 'https://www.sandbox.paypal.com' : 'https://www.paypal.com';
$url = $base_url . '/cgi-bin/webscr?cmd=_profile-recurring-payments&encrypted_profile_id=' . urlencode( $subscription_id );
} elseif ( 'twocheckout' == $gateway ) {
/**
* 2Checkout
*/
if ( $sandbox ) {
$base_url = 'https://sandbox.2checkout.com/sandbox/sales/detail';
} else {
$base_url = 'https://2checkout.com/sales/detail';
}
$twocheckout_id = str_replace( '2co_', '', $subscription_id );
$url = add_query_arg( 'sale_id', urlencode( $twocheckout_id ), $base_url );
} elseif ( 'braintree' == $gateway ) {
/**
* Braintree
*/
$subdomain = $sandbox ? 'sandbox.' : '';
$merchant_id = '';
if ( $sandbox && ! empty( $rcp_options['braintree_sandbox_merchantId'] ) ) {
$merchant_id = $rcp_options['braintree_sandbox_merchantId'];
} elseif ( ! $sandbox && ! empty( $rcp_options['braintree_live_merchantId'] ) ) {
$merchant_id = $rcp_options['braintree_live_merchantId'];
}
if ( ! empty( $merchant_id ) ) {
$url = sprintf( 'https://%sbraintreegateway.com/merchants/%s/subscriptions/%s', $subdomain, urlencode( $merchant_id ), urlencode( $subscription_id ) );
}
}
/**
* Filters the subscription profile URL.
*
* @param string $url URL to manage the subscription in the gateway.
* @param string $gateway Payment gateway slug.
* @param string $subscription_id ID of the subscription in the gateway.
*
* @since 3.0.4
*/
return apply_filters( 'rcp_gateway_subscription_id_url', $url, $gateway, $subscription_id );
}
/**
* Get payment gateway slug from gateway customer/subscription IDs.
*
* @param array $args {
*
* @type string $gateway_customer_id Gateway customer ID.
* @type string $gateway_subscription_id Gateway subscription ID.
* }
*
* @since 3.1
* @return string|false Gateway slug on success, false if cannot be parsed.
*/
function rcp_get_gateway_slug_from_gateway_ids( $args ) {
$customer_id = ! empty( $args['gateway_customer_id'] ) ? $args['gateway_customer_id'] : '';
$subscription_id = ! empty( $args['gateway_subscription_id'] ) ? $args['gateway_subscription_id'] : '';
$enabled_gateways = rcp_get_enabled_payment_gateways();
// Check for Stripe.
if ( false !== strpos( $customer_id, 'cus_' ) || false !== strpos( $subscription_id, 'sub_' ) ) {
if ( array_key_exists( 'stripe', $enabled_gateways ) ) {
return 'stripe';
} elseif ( array_key_exists( 'stripe_checkout', $enabled_gateways ) ) {
return 'stripe_checkout';
}
return 'stripe';
}
// Check for 2Checkout.
if ( false !== strpos( $subscription_id, '2co_' ) ) {
return 'twocheckout';
}
// Check for Authorize.net.
if ( false !== strpos( $subscription_id, 'anet_' ) ) {
return 'authorizenet';
}
// Check for Braintree.
if ( false !== strpos( $customer_id, 'bt_' ) ) {
return 'braintree';
}
// Check for PayPal.
if ( false !== strpos( $subscription_id, 'I-' ) ) {
// Determine which PayPal gateway is activated.
if ( array_key_exists( 'paypal', $enabled_gateways ) ) {
return 'paypal';
} elseif ( array_key_exists( 'paypal_express', $enabled_gateways ) ) {
return 'paypal_express';
} elseif ( array_key_exists( 'paypal_express', $enabled_gateways ) ) {
return 'paypal_pro';
}
return 'paypal';
}
return false;
}
/**
* A list of webhooks that RCP process in the Stripe webhook call.
*
* @since 3.5.25
* @return array An array with the webhooks.
*/
function get_stripe_webhooks() : array {
return [
'customer.subscription.created',
'customer.subscription.deleted',
'charge.succeeded',
'charge.refunded',
'invoice.payment_succeeded',
'invoice.payment_failed',
];
}
/**
* Check if the given stripe webhook is handled by RCP.
*
* @since 3.5.25
* @param string $_webhook The webhook name.
* @return bool true|false If the webhook exits.
*/
function validate_stripe_webhook( string $_webhook ) : bool {
$valid_webhooks = get_stripe_webhooks();
if ( in_array( $_webhook, $valid_webhooks ) ) {
return true;
}
return false;
}

View File

@@ -0,0 +1 @@
<?php // Silence is golden.

View File

@@ -0,0 +1 @@
<?php // Silence is golden.

View File

@@ -0,0 +1 @@
<?php // Silence is golden.

View File

@@ -0,0 +1,283 @@
/* global rcpStripe, rcpStripeToggleElementErrors, rcp_stripe_script_options */
// Setup on page load.
( function() {
var container = document.getElementById( 'rcp-card-wrapper' );
if ( ! container ) {
return;
}
let $ = jQuery;
if ( ! document.getElementById( 'rcp-card-element' ) || ! document.getElementById( 'rcp-card-element-errors' ) ) {
container.innerHTML = '';
// Need to dynamically generate a container to hold errors under the card field.
var errorContainer = document.createElement( 'div' );
errorContainer.id = 'rcp-card-element-errors';
var cardContainer = document.createElement( 'div' );
cardContainer.id = 'rcp-card-element';
container.appendChild( cardContainer );
container.appendChild( errorContainer );
}
// Update element styles.
rcpStripeUpdateElementStyles( rcpStripe.elements.card, '.rcp_card_name' );
// Field is available, mount.
rcpStripe.elements.card.mount( '#rcp-card-element' );
// Handle errors.
rcpStripe.elements.card.addEventListener( 'change', rcpStripeToggleElementErrors );
// Show / hide new card fields.
let savedPaymentMethod = $( 'input[name="rcp_gateway_existing_payment_method"]' );
let newCardFields = $( '.rcp-gateway-new-card-fields' );
/**
* Listen for selected payment method changing.
*/
savedPaymentMethod.on( 'change', function() {
let value = $( 'input[name="rcp_gateway_existing_payment_method"]:checked' ).val();
if ( 'new' === value ) {
newCardFields.show();
} else {
newCardFields.hide();
}
} );
// Trigger change event so we can determine new vs saved card right off the bat.
savedPaymentMethod.trigger( 'change' );
/**
* Saved card management.
*/
var RCP_Stripe_Manage_Cards = {
/**
* Initialize
*/
init: function() {
$( '.rcp-gateway-saved-card-delete' ).on( 'click', 'a', RCP_Stripe_Manage_Cards.delete );
},
/**
* Delete a payment method
*/
delete: function( e ) {
e.preventDefault();
if ( ! confirm( rcp_stripe_script_options.confirm_delete_card ) ) {
return false;
}
let paymentMethod = $( this );
let errorWrap = $( '#rcp-card-element-errors' );
paymentMethod.data( 'text', paymentMethod.text() ).text( rcp_stripe_script_options.pleasewait );
errorWrap.empty();
$.ajax( {
type: 'post',
dataType: 'json',
url: rcp_stripe_script_options.ajaxurl,
data: {
action: 'rcp_stripe_delete_saved_payment_method',
payment_method_id: paymentMethod.data( 'id' ),
nonce: paymentMethod.data( 'nonce' )
},
xhrFields: {
withCredentials: true
},
success: function( response ) {
if ( response.success ) {
paymentMethod.parents( 'li' ).remove();
} else {
console.log( response );
errorWrap.append( '<div class="rcp_message error"><p class="rcp_error"><span>' + response.data + '</span></p></div>' );
paymentMethod.text( paymentMethod.data( 'text' ) );
}
}
} ).fail( function( response ) {
if ( window.console && window.console.log ) {
console.log( response );
}
} );
}
};
RCP_Stripe_Manage_Cards.init();
} )();
/**
* Attempt to generate a token when the form is submitted.
*
* @param {Event} e Form submission event.
*/
function rcpStripeSubmitBillingCardUpdate( e ) {
// Halt here.
e.preventDefault();
let cardHolderName = document.querySelector( '.rcp_card_name' ).value;
let submitButton = jQuery( '#rcp_submit' );
let form = jQuery( '#rcp_update_card_form' );
let paymentMethodID = jQuery( 'input[name="rcp_gateway_existing_payment_method"]:checked' ).val();
if ( 'new' === paymentMethodID ) {
paymentMethodID = false;
}
if ( ! paymentMethodID && '' === cardHolderName ) {
rcpStripeHandleCardUpdateError( rcp_stripe_script_options.enter_card_name );
return;
}
submitButton.prop( 'disabled', true );
form.block( {
message: rcp_stripe_script_options.pleasewait,
css: {
border: 'none',
padding: '15px',
backgroundColor: '#000',
'-webkit-border-radius': '10px',
'-moz-border-radius': '10px',
opacity: .5,
color: '#fff'
}
} );
/**
* Create a setup intent.
*/
jQuery.ajax( {
type: 'post',
dataType: 'json',
url: rcp_stripe_script_options.ajaxurl,
data: {
action: 'rcp_stripe_create_setup_intent_for_saved_card',
membership_id: jQuery( 'input[name="rcp_membership_id"]' ).val(),
payment_method_id: paymentMethodID ? paymentMethodID : 'new'
},
success: function ( response ) {
if ( response.success ) {
let args = {
payment_method: {
card: rcpStripe.elements.card,
billing_details: { name: cardHolderName }
}
};
if ( paymentMethodID ) {
args = {
payment_method: paymentMethodID
};
}
let handler = 'payment_intent' === response.data.payment_intent_object ? 'confirmCardPayment' : 'confirmCardSetup';
/*
* Payment Intent
* Handle a card payment.
*/
rcpStripeHandleIntent(
handler, response.data.payment_intent_client_secret, args
).then( function( result ) {
if ( result.error ) {
rcpStripeHandleCardUpdateError( result.error.message, result.error.code );
} else {
// Success
rcpStripeHandleCardUpdateSuccess( response );
}
} );
} else {
rcpStripeHandleCardUpdateError( response.data );
}
}
} );
}
/**
* Handles a Stripe payment / setup intent, dynamically factoring in:
* - Saved vs new payment method
* - Setup Intent vs Payment Intent
*
* @param {string} handler Stripe handler to call - either `handleCardPayment` or `confirmCardSetup`.
* @param {string} client_secret Client secret to pass into the function.
* @param {object} args Arguments to pass into the function. For a saved payment method this
* should contain the payment method ID. For a new payment method this
* might contain the billing card name.
*
* @since 3.3
* @return {Promise}
*/
function rcpStripeHandleIntent( handler, client_secret, args ) {
return rcpStripe.Stripe[ handler ]( client_secret, args );
}
/**
* Handle card update success
* - Add `stripe_payment_intent_id` hidden field.
* - Add `stripe_payment_intent_object` hidden field.
*
* @param {object} response Ajax response.
*
* @since 3.2
*/
function rcpStripeHandleCardUpdateSuccess( response ) {
let inputField = document.createElement( 'input' );
inputField.value = response.data.payment_intent_id;
inputField.type = 'hidden';
inputField.name = 'stripe_payment_intent_id';
form.appendChild( inputField );
let objectField = document.createElement( 'input' );
objectField.value = response.data.payment_intent_object;
objectField.type = 'hidden';
objectField.name = 'stripe_payment_intent_object';
form.appendChild( objectField );
// Re-submit form.
form.removeEventListener( 'submit', rcpStripeSubmitBillingCardUpdate );
form.submit();
}
/**
* Handle card update failures
* - Show error message.
* - Re-enable submit button.
*
* @param {string} message Error message to display.
* @param {string} code Optional. Error code.
*
* @since 3.2
*/
function rcpStripeHandleCardUpdateError( message, code = '' ) {
// Use localized error message if available.
if ( '' !== code && 'undefined' !== typeof rcpStripe.errors[code] ) {
message = rcpStripe.errors[code];
}
jQuery( '#rcp_update_card_form' ).unblock();
rcpStripeToggleElementErrors( {
error: {
message: message
}
} );
jQuery( '#rcp_submit' ).prop( 'disabled', false );
}
var form = document.getElementById( 'rcp_update_card_form' );
form.addEventListener( 'submit', rcpStripeSubmitBillingCardUpdate );

View File

@@ -0,0 +1,2 @@
!function(e){var t={};function r(n){if(t[n])return t[n].exports;var a=t[n]={i:n,l:!1,exports:{}};return e[n].call(a.exports,a,a.exports,r),a.l=!0,a.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)r.d(n,a,function(t){return e[t]}.bind(null,a));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=0)}([function(e,t){var r,n,a=document.getElementById("rcp-card-wrapper");if(a){let e=jQuery;document.getElementById("rcp-card-element")&&document.getElementById("rcp-card-element-errors")||(a.innerHTML="",(r=document.createElement("div")).id="rcp-card-element-errors",(n=document.createElement("div")).id="rcp-card-element",a.appendChild(n),a.appendChild(r)),rcpStripeUpdateElementStyles(rcpStripe.elements.card,".rcp_card_name"),rcpStripe.elements.card.mount("#rcp-card-element"),rcpStripe.elements.card.addEventListener("change",rcpStripeToggleElementErrors);let t=e('input[name="rcp_gateway_existing_payment_method"]'),c=e(".rcp-gateway-new-card-fields");t.on("change",(function(){"new"===e('input[name="rcp_gateway_existing_payment_method"]:checked').val()?c.show():c.hide()})),t.trigger("change");var i={init:function(){e(".rcp-gateway-saved-card-delete").on("click","a",i.delete)},delete:function(t){if(t.preventDefault(),!confirm(rcp_stripe_script_options.confirm_delete_card))return!1;let r=e(this),n=e("#rcp-card-element-errors");r.data("text",r.text()).text(rcp_stripe_script_options.pleasewait),n.empty(),e.ajax({type:"post",dataType:"json",url:rcp_stripe_script_options.ajaxurl,data:{action:"rcp_stripe_delete_saved_payment_method",payment_method_id:r.data("id"),nonce:r.data("nonce")},xhrFields:{withCredentials:!0},success:function(e){e.success?r.parents("li").remove():(console.log(e),n.append('<div class="rcp_message error"><p class="rcp_error"><span>'+e.data+"</span></p></div>"),r.text(r.data("text")))}}).fail((function(e){window.console&&window.console.log&&console.log(e)}))}};i.init()}function c(e,t=""){""!==t&&void 0!==rcpStripe.errors[t]&&(e=rcpStripe.errors[t]),jQuery("#rcp_update_card_form").unblock(),rcpStripeToggleElementErrors({error:{message:e}}),jQuery("#rcp_submit").prop("disabled",!1)}var p=document.getElementById("rcp_update_card_form");p.addEventListener("submit",(function e(t){t.preventDefault();let r=document.querySelector(".rcp_card_name").value,n=jQuery("#rcp_submit"),a=jQuery("#rcp_update_card_form"),i=jQuery('input[name="rcp_gateway_existing_payment_method"]:checked').val();(i="new"!==i&&i)||""!==r?(n.prop("disabled",!0),a.block({message:rcp_stripe_script_options.pleasewait,css:{border:"none",padding:"15px",backgroundColor:"#000","-webkit-border-radius":"10px","-moz-border-radius":"10px",opacity:.5,color:"#fff"}}),jQuery.ajax({type:"post",dataType:"json",url:rcp_stripe_script_options.ajaxurl,data:{action:"rcp_stripe_create_setup_intent_for_saved_card",membership_id:jQuery('input[name="rcp_membership_id"]').val(),payment_method_id:i||"new"},success:function(t){if(t.success){let d={payment_method:{card:rcpStripe.elements.card,billing_details:{name:r}}};i&&(d={payment_method:i});var n="payment_intent"===t.data.payment_intent_object?"confirmCardPayment":"confirmCardSetup";a=t.data.payment_intent_client_secret,o=d,rcpStripe.Stripe[n](a,o).then((function(r){if(r.error)c(r.error.message,r.error.code);else{r=t;let n=document.createElement("input"),a=(n.value=r.data.payment_intent_id,n.type="hidden",n.name="stripe_payment_intent_id",p.appendChild(n),document.createElement("input"));a.value=r.data.payment_intent_object,a.type="hidden",a.name="stripe_payment_intent_object",p.appendChild(a),p.removeEventListener("submit",e),p.submit()}}))}else c(t.data);var a,o}})):c(rcp_stripe_script_options.enter_card_name)}))}]);
//# sourceMappingURL=profile.min.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,330 @@
/* global rcpStripe, rcp_processing, rcp_script_options */
/**
* Unblock the form, hide loading symbols, and enable registration button.
*/
function rcpStripeEnableForm() {
jQuery( '#rcp_registration_form #rcp_submit' ).attr( 'disabled', false );
jQuery( '#rcp_ajax_loading' ).hide();
jQuery( '#rcp_registration_form' ).unblock();
jQuery( '#rcp_submit' ).val( rcp_script_options.register );
rcp_processing = false;
}
/**
* Handle a failed Stripe payment
*
* This does an ajax request to trigger `rcp_registration_failed`, which changes the payment
* status to `failed` and disables the pending membership.
*
* @param {int} payment_id
* @param {string} message
*
* @since 3.2
*/
function rcpStripeHandlePaymentFailure( payment_id, message ) {
let $ = jQuery;
$.ajax( {
type: 'post',
dataType: 'json',
url: rcp_script_options.ajaxurl,
data: {
action: 'rcp_stripe_handle_initial_payment_failure',
payment_id: payment_id,
message: message
},
success: function ( response ) { }
} );
}
/**
* Close the Stripe Checkout modal.
*
* @since 3.2
*/
function rcpStripeCloseCheckoutModal() {
// Don't allow closing if we're already processing the form.
if ( rcp_processing ) {
return;
}
let $ = jQuery;
let modalWrapper = $( '.rcp-modal-wrapper' );
let modalContainer = $( '.rcp-modal' );
modalWrapper.fadeOut( 250 );
modalContainer.hide();
if ( ! document.getElementById( 'rcp-card-element' ) ) {
return;
}
// Unmount Stripe Elements.
rcpStripe.elements.card.unmount( '#rcp-card-element' );
}
/**
* Handles a Stripe payment / setup intent, dynamically factoring in:
* - Saved vs new payment method
* - Setup Intent vs Payment Intent
*
* @param {string} handler Stripe handler to call - either `handleCardPayment` or `confirmCardSetup`.
* @param {string} client_secret Client secret to pass into the function.
* @param {object} args Arguments to pass into the function. For a saved payment method this
* should contain the payment method ID. For a new payment method this
* might contain the billing card name.
*
* @since 3.3
* @return {Promise}
*/
function rcpStripeHandleIntent( handler, client_secret, args ) {
return rcpStripe.Stripe[ handler ]( client_secret, args );
}
// Reliant on jQuery triggers, so setup jQuery.
jQuery( function( $ ) {
var RCP_Stripe_Registration = {
/**
* Whether or not a payment method has been filled out.
*/
hasPaymentMethod: false,
/**
* ID of the saved payment method, or `false` if using a new card.
*/
paymentMethodID: false,
/**
* Initialize all our events
*/
init: function() {
$( 'body' ).on( 'rcp_gateway_loaded', RCP_Stripe_Registration.mountElements );
$( '#rcp_submit' ).on( 'click', RCP_Stripe_Registration.maybeBlockSubmit );
$( 'body' ).on( 'rcp_registration_form_processed', RCP_Stripe_Registration.handlePayment );
$( 'body' ).on( 'click', '.rcp-stripe-register-submit-button', RCP_Stripe_Registration.launchModal );
},
/**
* Attempt to mount the Stripe Elements card when the gateway changes.
*
* @param e
* @param gateway
*/
mountElements: function ( e, gateway ) {
if ( ! document.getElementById( 'rcp-card-element' ) ) {
return;
}
// Update element styles.
rcpStripeUpdateElementStyles( rcpStripe.elements.card, '.rcp_card_name' );
// Field is available, mount.
rcpStripe.elements.card.mount( '#rcp-card-element' );
// Flag as having card details.
rcpStripe.elements.card.addEventListener( 'change', function ( event ) {
if ( event.complete ) {
RCP_Stripe_Registration.hasPaymentMethod = true;
}
} );
/**
* Listen for selected payment method changing.
*/
RCP_Stripe_Registration.setPaymentMethodID();
// Handle errors.
rcpStripe.elements.card.addEventListener( 'change', rcpStripeToggleElementErrors );
},
/**
* Set the current payment method ID and listen for changes.
*/
setPaymentMethodID: function() {
let savedPaymentMethod = $( 'input[name="rcp_gateway_existing_payment_method"]' );
savedPaymentMethod.on( 'change', function( e ) {
rcpStripeToggleElementErrors( e ); // clear errors
let value = $( 'input[name="rcp_gateway_existing_payment_method"]:checked' ).val();
$( '.rcp-gateway-saved-payment-method, .rcp-gateway-add-payment-method-wrap' ).removeClass( 'rcp-gateway-selected-payment-method' );
if ( 'new' === value ) {
$( '.rcp-gateway-new-card-fields' ).show();
$( '.rcp-gateway-add-payment-method-wrap' ).addClass( 'rcp-gateway-selected-payment-method' );
RCP_Stripe_Registration.paymentMethodID = false;
} else {
$( '.rcp-gateway-new-card-fields' ).hide();
$( this ).parents( '.rcp-gateway-saved-payment-method' ).addClass( 'rcp-gateway-selected-payment-method' );
RCP_Stripe_Registration.paymentMethodID = value;
}
} );
savedPaymentMethod.trigger( 'change' );
},
/**
* Block the form submission if Stripe is the selected gateway, payment is due, a new payment method is being
* entered, but no details have been provided.
*
* @param e
* @returns {boolean}
*/
maybeBlockSubmit: function ( e ) {
if ( 'stripe' === rcp_get_gateway().val() && document.getElementById( 'rcp-card-element' ) && ! RCP_Stripe_Registration.hasPaymentMethod && ! RCP_Stripe_Registration.paymentMethodID ) {
e.stopPropagation();
rcpStripeHandleError( rcp_script_options.enter_card_details );
return false;
}
},
/**
* After registration has been processed, handle card payments.
*
* @param event
* @param form
* @param response
*/
handlePayment: function ( event, form, response ) {
// Not on Stripe gateway, bail.
if ( response.gateway.slug !== 'stripe' ) {
return;
}
/*
* Bail if the amount due today is 0 AND:
* the recurring amount is 0, or auto renew is off
*/
if ( ! response.total && ( ! response.recurring_total || ! response.auto_renew ) ) {
return;
}
// 100% discount, bail.
if ( $( '.rcp_gateway_fields' ).hasClass( 'rcp_discounted_100' ) ) {
return;
}
// Trigger error if we don't have a client secret.
if ( ! response.gateway.data.stripe_client_secret ) {
rcpStripeHandleError( rcp_script_options.error_occurred );
rcpStripeHandlePaymentFailure( response.payment_id, rcp_script_options.error_occurred );
return;
}
let cardHolderName = $( '.card-name' ).val();
let handler = 'payment_intent' === response.gateway.data.stripe_intent_type ? 'confirmCardPayment' : 'confirmCardSetup';
let args = {
payment_method: {
card: rcpStripe.elements.card,
billing_details: { name: cardHolderName }
}
};
if ( RCP_Stripe_Registration.paymentMethodID ) {
args = {
payment_method: RCP_Stripe_Registration.paymentMethodID
};
}
/**
* Handle payment intent / setup intent.
*/
rcpStripeHandleIntent(
handler, response.gateway.data.stripe_client_secret, args
).then( function( paymentResult ) {
if ( paymentResult.error ) {
rcpStripeHandleError( paymentResult.error.message, paymentResult.error.code );
rcpStripeHandlePaymentFailure( response.payment_id, paymentResult.error.message );
} else {
rcp_submit_registration_form( form, response );
}
} );
},
/**
* Launch the [register_form_stripe] modal.
*
* @param e
*/
launchModal: function( e ) {
e.preventDefault();
let modalWrapper = $( '.rcp-modal-wrapper' );
let modalContainer = $( '.rcp-modal' );
let form = $( this ).parents( '.rcp-stripe-register' );
// Mount the Stripe Elements card.
if ( ! document.getElementById( 'rcp-card-element' ) ) {
return;
}
// Fade in wrapper.
modalWrapper.fadeIn( 250 );
// Field is available, mount.
rcpStripe.elements.card.mount( '#rcp-card-element' );
let registerButton = modalContainer.find( 'input.rcp-modal-submit' );
// Flag as having card details.
rcpStripe.elements.card.addEventListener( 'change', function ( event ) {
if ( event.complete ) {
RCP_Stripe_Registration.hasPaymentMethod = true;
}
} );
// Handle errors.
rcpStripe.elements.card.addEventListener( 'change', rcpStripeToggleElementErrors );
// Set up saved vs. new card.
RCP_Stripe_Registration.setPaymentMethodID();
// Set form content.
if ( form.data( 'name' ) ) {
$( '.rcp-modal-membership-name' ).text( form.data( 'name' ) ).show();
}
if ( form.data( 'description' ) ) {
$( '.rcp-modal-membership-description' ).text( form.data( 'description' ) ).show();
}
if ( form.data( 'panel-label' ) ) {
registerButton.val( form.data( 'panel-label' ) );
}
if ( form.data( 'level-id' ) ) {
modalContainer.find( '#rcp-stripe-checkout-level-id' ).val( form.data( 'level-id' ) );
}
// Fade in container.
modalContainer.fadeIn( 250 );
/**
* Close the modal on these three events...
*/
// If they click the close icon, close modal.
modalWrapper.find( '.rcp-modal-close' ).on( 'click', function() {
rcpStripeCloseCheckoutModal();
} );
// If they press "ESC" on the keyboard, close modal.
$( document ).on( 'keydown', function ( e ) {
if ( 27 === e.keyCode ) {
rcpStripeCloseCheckoutModal();
}
} );
// If they click outside the container, close modal.
$( document ).mouseup( function( e ) {
if ( ! modalContainer.is( e.target ) && modalContainer.has( e.target ).length === 0 ) {
rcpStripeCloseCheckoutModal();
}
} );
}
};
RCP_Stripe_Registration.init();
} );

View File

@@ -0,0 +1,2 @@
!function(e){var t={};function r(n){if(t[n])return t[n].exports;var a=t[n]={i:n,l:!1,exports:{}};return e[n].call(a.exports,a,a.exports,r),a.l=!0,a.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)r.d(n,a,function(t){return e[t]}.bind(null,a));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=0)}([function(e,t){function r(e,t){jQuery.ajax({type:"post",dataType:"json",url:rcp_script_options.ajaxurl,data:{action:"rcp_stripe_handle_initial_payment_failure",payment_id:e,message:t},success:function(e){}})}function n(){if(!rcp_processing){let e=jQuery,t=e(".rcp-modal-wrapper"),r=e(".rcp-modal");t.fadeOut(250),r.hide(),document.getElementById("rcp-card-element")&&rcpStripe.elements.card.unmount("#rcp-card-element")}}jQuery((function(e){var t={hasPaymentMethod:!1,paymentMethodID:!1,init:function(){e("body").on("rcp_gateway_loaded",t.mountElements),e("#rcp_submit").on("click",t.maybeBlockSubmit),e("body").on("rcp_registration_form_processed",t.handlePayment),e("body").on("click",".rcp-stripe-register-submit-button",t.launchModal)},mountElements:function(e,r){document.getElementById("rcp-card-element")&&(rcpStripeUpdateElementStyles(rcpStripe.elements.card,".rcp_card_name"),rcpStripe.elements.card.mount("#rcp-card-element"),rcpStripe.elements.card.addEventListener("change",(function(e){e.complete&&(t.hasPaymentMethod=!0)})),t.setPaymentMethodID(),rcpStripe.elements.card.addEventListener("change",rcpStripeToggleElementErrors))},setPaymentMethodID:function(){let r=e('input[name="rcp_gateway_existing_payment_method"]');r.on("change",(function(r){rcpStripeToggleElementErrors(r),r=e('input[name="rcp_gateway_existing_payment_method"]:checked').val(),e(".rcp-gateway-saved-payment-method, .rcp-gateway-add-payment-method-wrap").removeClass("rcp-gateway-selected-payment-method"),"new"===r?(e(".rcp-gateway-new-card-fields").show(),e(".rcp-gateway-add-payment-method-wrap").addClass("rcp-gateway-selected-payment-method"),t.paymentMethodID=!1):(e(".rcp-gateway-new-card-fields").hide(),e(this).parents(".rcp-gateway-saved-payment-method").addClass("rcp-gateway-selected-payment-method"),t.paymentMethodID=r)})),r.trigger("change")},maybeBlockSubmit:function(e){if("stripe"===rcp_get_gateway().val()&&document.getElementById("rcp-card-element")&&!t.hasPaymentMethod&&!t.paymentMethodID)return e.stopPropagation(),rcpStripeHandleError(rcp_script_options.enter_card_details),!1},handlePayment:function(n,a,c){if("stripe"===c.gateway.slug&&(c.total||c.recurring_total&&c.auto_renew)&&!e(".rcp_gateway_fields").hasClass("rcp_discounted_100")){if(!c.gateway.data.stripe_client_secret)return rcpStripeHandleError(rcp_script_options.error_occurred),void r(c.payment_id,rcp_script_options.error_occurred);var o,p=e(".card-name").val(),d="payment_intent"===c.gateway.data.stripe_intent_type?"confirmCardPayment":"confirmCardSetup";let n={payment_method:{card:rcpStripe.elements.card,billing_details:{name:p}}};t.paymentMethodID&&(n={payment_method:t.paymentMethodID}),p=c.gateway.data.stripe_client_secret,o=n,rcpStripe.Stripe[d](p,o).then((function(e){e.error?(rcpStripeHandleError(e.error.message,e.error.code),r(c.payment_id,e.error.message)):rcp_submit_registration_form(a,c)}))}},launchModal:function(r){r.preventDefault();let a=e(".rcp-modal-wrapper"),c=e(".rcp-modal"),o=e(this).parents(".rcp-stripe-register");if(document.getElementById("rcp-card-element")){a.fadeIn(250),rcpStripe.elements.card.mount("#rcp-card-element");let r=c.find("input.rcp-modal-submit");rcpStripe.elements.card.addEventListener("change",(function(e){e.complete&&(t.hasPaymentMethod=!0)})),rcpStripe.elements.card.addEventListener("change",rcpStripeToggleElementErrors),t.setPaymentMethodID(),o.data("name")&&e(".rcp-modal-membership-name").text(o.data("name")).show(),o.data("description")&&e(".rcp-modal-membership-description").text(o.data("description")).show(),o.data("panel-label")&&r.val(o.data("panel-label")),o.data("level-id")&&c.find("#rcp-stripe-checkout-level-id").val(o.data("level-id")),c.fadeIn(250),a.find(".rcp-modal-close").on("click",(function(){n()})),e(document).on("keydown",(function(e){27===e.keyCode&&n()})),e(document).mouseup((function(e){c.is(e.target)||0!==c.has(e.target).length||n()}))}}};t.init()}))}]);
//# sourceMappingURL=register.min.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,146 @@
// Get bootstrapped data from the page.
var rcpStripe = window.rcpStripe || {};
// Configure Stripe API.
rcpStripe.Stripe = Stripe( rcpStripe.keys.publishable );
// Setup Elements.
rcpStripe.Elements = rcpStripe.Stripe.elements();
rcpStripe.elements = {
card: rcpStripe.Elements.create( 'card', rcpStripe.elementsConfig ),
};
/**
*
* Handle form errors, given an error message.
*
* @param {string} message Error message.
* @param {string} code Optional. Error code.
*
* @since 3.2
*/
function rcpStripeHandleError( message, code ) {
// Use localized error message if available.
if ( 'undefined' !== typeof code && 'undefined' !== typeof rcpStripe.errors[code] ) {
message = rcpStripe.errors[code];
}
// If we're already on the registration form page or update billing card page, just show that error message.
if ( document.getElementById( 'rcp_registration_form' ) || document.getElementById( 'rcp_update_card_form' ) ) {
rcpStripeToggleElementErrors( {
error: {
message: message
}
} );
rcpStripeEnableForm();
} else if ( document.getElementById( 'rcp-stripe-confirm-form' ) ) {
// We're on the confirmation page - show an inline error.
jQuery( '#rcp-stripe-confirmation-loading' ).empty().append( rcpStripeGenerateNotice( message ) ).append( '<p><a href="' + document.referrer + '">' + rcp_script_options.click_try_again + '</a></p>' );
}
}
/**
* Generate a notice element.
*
* @param {string} message The notice text.
* @return {Element} HTML element containing errors.
*/
function rcpStripeGenerateNotice( message ) {
var span = document.createElement( 'span' );
span.innerText = message;
var notice = document.createElement( 'p' );
notice.classList.add( 'rcp_error' );
notice.appendChild( span );
var wrapper = document.createElement( 'div' );
wrapper.classList.add( 'rcp_message' );
wrapper.classList.add( 'error' );
wrapper.appendChild( notice );
return wrapper;
}
/**
* Show or hide errors based on input to the Card Element.
*
* @param {Event} event Change event on the Card Element.
*/
function rcpStripeToggleElementErrors( event ) {
var errorContainer = document.getElementById( 'rcp-card-element-errors' );
if ( null !== errorContainer ) {
errorContainer.innerHTML = '';
if ( event.error ) {
errorContainer.appendChild( rcpStripeGenerateNotice( event.error.message ) );
}
}
}
/**
* Copy styles from an existing element to the Stripe Card Element.
*
* @param cardElement Stripe card element.
* @param selector Selector to copy styles from.
*
* @since 3.3
*/
function rcpStripeUpdateElementStyles( cardElement, selector ) {
if ( undefined === typeof selector ) {
selector = '.rcp_card_name';
}
let inputField = document.querySelector( selector );
if ( null === inputField ) {
return;
}
// Bail if we already have custom styles.
if ( null !== rcpStripe.elementsConfig && rcpStripe.elementsConfig.style ) {
return;
}
let inputStyles = window.getComputedStyle( inputField );
let styleTag = document.createElement( 'style' );
styleTag.innerHTML = '.StripeElement {' +
'background-color:' + inputStyles.getPropertyValue( 'background-color' ) + ';' +
'border-top-color:' + inputStyles.getPropertyValue( 'border-top-color' ) + ';' +
'border-right-color:' + inputStyles.getPropertyValue( 'border-right-color' ) + ';' +
'border-bottom-color:' + inputStyles.getPropertyValue( 'border-bottom-color' ) + ';' +
'border-left-color:' + inputStyles.getPropertyValue( 'border-left-color' ) + ';' +
'border-top-width:' + inputStyles.getPropertyValue( 'border-top-width' ) + ';' +
'border-right-width:' + inputStyles.getPropertyValue( 'border-right-width' ) + ';' +
'border-bottom-width:' + inputStyles.getPropertyValue( 'border-bottom-width' ) + ';' +
'border-left-width:' + inputStyles.getPropertyValue( 'border-left-width' ) + ';' +
'border-top-style:' + inputStyles.getPropertyValue( 'border-top-style' ) + ';' +
'border-right-style:' + inputStyles.getPropertyValue( 'border-right-style' ) + ';' +
'border-bottom-style:' + inputStyles.getPropertyValue( 'border-bottom-style' ) + ';' +
'border-left-style:' + inputStyles.getPropertyValue( 'border-left-style' ) + ';' +
'border-top-left-radius:' + inputStyles.getPropertyValue( 'border-top-left-radius' ) + ';' +
'border-top-right-radius:' + inputStyles.getPropertyValue( 'border-top-right-radius' ) + ';' +
'border-bottom-left-radius:' + inputStyles.getPropertyValue( 'border-bottom-left-radius' ) + ';' +
'border-bottom-right-radius:' + inputStyles.getPropertyValue( 'border-bottom-right-radius' ) + ';' +
'padding-top:' + inputStyles.getPropertyValue( 'padding-top' ) + ';' +
'padding-right:' + inputStyles.getPropertyValue( 'padding-right' ) + ';' +
'padding-bottom:' + inputStyles.getPropertyValue( 'padding-bottom' ) + ';' +
'padding-left:' + inputStyles.getPropertyValue( 'padding-left' ) + ';' +
'}';
document.body.appendChild( styleTag );
cardElement.update( {
style: {
base: {
color: inputStyles.getPropertyValue( 'color' ),
fontFamily: inputStyles.getPropertyValue( 'font-family' ),
fontSize: inputStyles.getPropertyValue( 'font-size' ),
fontWeight: inputStyles.getPropertyValue( 'font-weight' ),
fontSmoothing: inputStyles.getPropertyValue( '-webkit-font-smoothing' )
}
}
} );
}

View File

@@ -0,0 +1 @@
var rcpStripe=window.rcpStripe||{};function rcpStripeHandleError(e,r){void 0!==typeof r&&void 0!==rcpStripe.errors[r]&&(e=rcpStripe.errors[r]),document.getElementById("rcp_registration_form")||document.getElementById("rcp_update_card_form")?(rcpStripeToggleElementErrors({error:{message:e}}),rcpStripeEnableForm()):document.getElementById("rcp-stripe-confirm-form")&&jQuery("#rcp-stripe-confirmation-loading").empty().append(rcpStripeGenerateNotice(e)).append('<p><a href="'+document.referrer+'">'+rcp_script_options.click_try_again+"</a></p>")}function rcpStripeGenerateNotice(e){var r=document.createElement("span");r.innerText=e;var t=document.createElement("p");t.classList.add("rcp_error"),t.appendChild(r);var o=document.createElement("div");return o.classList.add("rcp_message"),o.classList.add("error"),o.appendChild(t),o}function rcpStripeToggleElementErrors(e){var r=document.getElementById("rcp-card-element-errors");null!==r&&(r.innerHTML="",e.error&&r.appendChild(rcpStripeGenerateNotice(e.error.message)))}function rcpStripeUpdateElementStyles(e,r){void 0===typeof r&&(r=".rcp_card_name");let t=document.querySelector(r);if(null===t)return;if(null!==rcpStripe.elementsConfig&&rcpStripe.elementsConfig.style)return;let o=window.getComputedStyle(t),p=document.createElement("style");p.innerHTML=".StripeElement {background-color:"+o.getPropertyValue("background-color")+";border-top-color:"+o.getPropertyValue("border-top-color")+";border-right-color:"+o.getPropertyValue("border-right-color")+";border-bottom-color:"+o.getPropertyValue("border-bottom-color")+";border-left-color:"+o.getPropertyValue("border-left-color")+";border-top-width:"+o.getPropertyValue("border-top-width")+";border-right-width:"+o.getPropertyValue("border-right-width")+";border-bottom-width:"+o.getPropertyValue("border-bottom-width")+";border-left-width:"+o.getPropertyValue("border-left-width")+";border-top-style:"+o.getPropertyValue("border-top-style")+";border-right-style:"+o.getPropertyValue("border-right-style")+";border-bottom-style:"+o.getPropertyValue("border-bottom-style")+";border-left-style:"+o.getPropertyValue("border-left-style")+";border-top-left-radius:"+o.getPropertyValue("border-top-left-radius")+";border-top-right-radius:"+o.getPropertyValue("border-top-right-radius")+";border-bottom-left-radius:"+o.getPropertyValue("border-bottom-left-radius")+";border-bottom-right-radius:"+o.getPropertyValue("border-bottom-right-radius")+";padding-top:"+o.getPropertyValue("padding-top")+";padding-right:"+o.getPropertyValue("padding-right")+";padding-bottom:"+o.getPropertyValue("padding-bottom")+";padding-left:"+o.getPropertyValue("padding-left")+";}",document.body.appendChild(p),e.update({style:{base:{color:o.getPropertyValue("color"),fontFamily:o.getPropertyValue("font-family"),fontSize:o.getPropertyValue("font-size"),fontWeight:o.getPropertyValue("font-weight"),fontSmoothing:o.getPropertyValue("-webkit-font-smoothing")}}})}rcpStripe.Stripe=Stripe(rcpStripe.keys.publishable),rcpStripe.Elements=rcpStripe.Stripe.elements(),rcpStripe.elements={card:rcpStripe.Elements.create("card",rcpStripe.elementsConfig)};