laipower/wp-content/plugins/easy-digital-downloads/includes/gateways/stripe/includes/card-actions.php

553 lines
14 KiB
PHP

<?php
/**
* Card actions.
*
* @package EDD_Stripe
* @since 2.7.0
*/
/**
* Process the card update actions from the manage card form.
*
* @since 2.6
* @return void
*/
function edd_stripe_process_card_update() {
$enabled = edd_stripe_existing_cards_enabled();
// Feature not enabled.
if ( ! $enabled ) {
wp_send_json_error(
array(
'message' => __( 'This feature is not available at this time.', 'easy-digital-downloads' ),
)
);
}
// Source can't be found.
$payment_method = isset( $_POST['payment_method'] ) ? sanitize_text_field( $_POST['payment_method'] ) : '';
if ( empty( $payment_method ) ) {
wp_send_json_error(
array(
'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
)
);
}
// Nonce failed.
if ( ! edds_verify( 'nonce', $payment_method . '_update' ) ) {
wp_send_json_error(
array(
'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
)
);
}
$stripe_customer_id = edds_get_stripe_customer_id( get_current_user_id() );
if ( empty( $stripe_customer_id ) ) {
wp_send_json_error(
array(
'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
)
);
}
try {
$card_args = array();
$card_fields = array(
'address_city',
'address_country',
'address_line1',
'address_line2',
'address_zip',
'address_state',
'exp_month',
'exp_year',
);
foreach ( $card_fields as $card_field ) {
$card_args[ $card_field ] = ( isset( $_POST[ $card_field ] ) && '' !== $_POST[ $card_field ] )
? sanitize_text_field( $_POST[ $card_field ] )
: null;
}
// Update a PaymentMethod.
if ( 'pm_' === substr( $payment_method, 0, 3 ) ) {
$address_args = array(
'city' => $card_args['address_city'],
'country' => $card_args['address_country'],
'line1' => $card_args['address_line1'],
'line2' => $card_args['address_line2'],
'postal_code' => $card_args['address_zip'],
'state' => $card_args['address_state'],
);
edds_api_request(
'PaymentMethod',
'update',
$payment_method,
array(
'billing_details' => array(
'address' => $address_args,
),
'card' => array(
'exp_month' => $card_args['exp_month'],
'exp_year' => $card_args['exp_year'],
),
)
);
// Update a legacy Card.
} else {
edds_api_request( 'Customer', 'updateSource', $stripe_customer_id, $payment_method, $card_args );
}
// Check if customer has default card.
$existing_cards = edd_stripe_get_existing_cards( get_current_user_id() );
$default_payment_method = edds_customer_get_default_payment_method( get_current_user_id(), $existing_cards );
// If there is no default card, make updated card default.
if ( null === $default_payment_method ) {
edds_customer_set_default_payment_method( $stripe_customer_id, current( $existing_cards )['source']->id );
}
wp_send_json_success(
array(
'message' => esc_html__( 'Card successfully updated.', 'easy-digital-downloads' ),
)
);
} catch ( \Exception $e ) {
wp_send_json_error(
array(
'message' => esc_html( $e->getMessage() ),
)
);
}
}
add_action( 'wp_ajax_edds_update_payment_method', 'edd_stripe_process_card_update' );
/**
* Process the set default card action from the manage card form.
*
* @since 2.6
* @return void
*/
function edd_stripe_process_card_default() {
$enabled = edd_stripe_existing_cards_enabled();
// Feature not enabled.
if ( ! $enabled ) {
wp_send_json_error(
array(
'message' => __( 'This feature is not available at this time.', 'easy-digital-downloads' ),
)
);
}
// Source can't be found.
$payment_method = isset( $_POST['payment_method'] ) ? sanitize_text_field( $_POST['payment_method'] ) : '';
if ( empty( $payment_method ) ) {
wp_send_json_error(
array(
'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
)
);
}
// Nonce failed.
if ( ! edds_verify( 'nonce', $payment_method . '_update' ) ) {
wp_send_json_error(
array(
'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
)
);
}
// Customer can't be found.
$stripe_customer_id = edds_get_stripe_customer_id( get_current_user_id() );
if ( empty( $stripe_customer_id ) ) {
wp_send_json_error(
array(
'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
)
);
}
try {
edds_customer_set_default_payment_method( $stripe_customer_id, $payment_method );
wp_send_json_success(
array(
'message' => esc_html__( 'Card successfully set as default.', 'easy-digital-downloads' ),
)
);
} catch ( \Exception $e ) {
wp_send_json_error(
array(
'message' => esc_html( $e->getMessage() ),
)
);
}
}
add_action( 'wp_ajax_edds_set_payment_method_default', 'edd_stripe_process_card_default' );
/**
* Process the delete card action from the manage card form.
*
* @since 2.6
* @return void
*/
function edd_stripe_process_card_delete() {
$enabled = edd_stripe_existing_cards_enabled();
// Feature not enabled.
if ( ! $enabled ) {
wp_send_json_error(
array(
'message' => __( 'This feature is not available at this time.', 'easy-digital-downloads' ),
)
);
}
// Source can't be found.
$payment_method = isset( $_POST['payment_method'] ) ? sanitize_text_field( $_POST['payment_method'] ) : '';
if ( empty( $payment_method ) ) {
wp_send_json_error(
array(
'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
)
);
}
// Nonce failed.
if ( ! edds_verify( 'nonce', $payment_method . '_update' ) ) {
wp_send_json_error(
array(
'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
)
);
}
// Customer can't be found.
$stripe_customer_id = edds_get_stripe_customer_id( get_current_user_id() );
if ( empty( $stripe_customer_id ) ) {
wp_send_json_error(
array(
'message' => __( 'Error updating card.', 'easy-digital-downloads' ),
)
);
}
// Removal is disabled for this card.
$should_remove = apply_filters(
'edd_stripe_should_remove_card',
array(
'remove' => true,
'message' => '',
),
$payment_method,
$stripe_customer_id
);
if ( ! $should_remove['remove'] ) {
wp_send_json_error(
array(
'message' => esc_html__( 'This feature is not available at this time.', 'easy-digital-downloads' ),
)
);
}
try {
// Detach a PaymentMethod.
if ( 'pm_' === substr( $payment_method, 0, 3 ) ) {
$payment_method = edds_api_request( 'PaymentMethod', 'retrieve', $payment_method );
$payment_method->detach();
// Delete a Card.
} else {
edds_api_request( 'Customer', 'deleteSource', $stripe_customer_id, $payment_method );
}
// Retrieve saved cards before checking for default.
$existing_cards = edd_stripe_get_existing_cards( get_current_user_id() );
$default_payment_method = edds_customer_get_default_payment_method( get_current_user_id(), $existing_cards );
// If there is no default card, make updated card default.
if ( null === $default_payment_method && ! empty( $existing_cards ) ) {
edds_customer_set_default_payment_method( $stripe_customer_id, current( $existing_cards )['source']->id );
}
wp_send_json_success(
array(
'message' => esc_html__( 'Card successfully removed.', 'easy-digital-downloads' ),
)
);
} catch ( \Exception $e ) {
wp_send_json_error(
array(
'message' => esc_html( $e->getMessage() ),
)
);
}
}
add_action( 'wp_ajax_edds_delete_payment_method', 'edd_stripe_process_card_delete' );
/**
* Handles adding a new PaymentMethod (via AJAX).
*
* @since 2.6
* @return void
*/
function edds_add_payment_method() {
$enabled = edd_stripe_existing_cards_enabled();
// Feature not enabled.
if ( ! $enabled ) {
wp_send_json_error(
array(
'message' => __( 'This feature is not available at this time.', 'easy-digital-downloads' ),
)
);
}
if ( edd_stripe()->rate_limiting->has_hit_card_error_limit() ) {
// Increase the card error count.
edd_stripe()->rate_limiting->increment_card_error_count();
wp_send_json_error(
array(
'message' => __( 'Unable to update your account at this time, please try again later', 'easy-digital-downloads' ),
)
);
}
// PaymentMethod can't be found.
$payment_method_id = isset( $_POST['payment_method_id'] ) ? sanitize_text_field( $_POST['payment_method_id'] ) : false;
if ( ! $payment_method_id ) {
wp_send_json_error(
array(
'message' => __( 'Missing card ID.', 'easy-digital-downloads' ),
)
);
}
// Nonce failed.
if ( ! edds_verify( 'nonce', 'edd-stripe-add-card' ) ) {
wp_send_json_error(
array(
'message' => __( 'Error adding card.', 'easy-digital-downloads' ),
)
);
}
$edd_customer = new \EDD_Customer( get_current_user_id(), true );
if ( 0 === $edd_customer->id ) {
wp_send_json_error(
array(
'message' => __(
'Unable to retrieve customer.',
'easy-digital-downloads'
),
)
);
}
$stripe_customer_id = edds_get_stripe_customer_id( get_current_user_id() );
$customer_name = '';
if ( ! empty( $edd_customer->name ) ) {
$customer_name = $edd_customer->name;
}
$stripe_customer = edds_get_stripe_customer(
$stripe_customer_id,
array(
'email' => $edd_customer->email,
'description' => $edd_customer->email,
'name' => $customer_name,
)
);
if ( false === $stripe_customer ) {
wp_send_json_error(
array(
'message' => __(
'Unable to create customer in Stripe.',
'easy-digital-downloads'
),
)
);
}
// Ensure the EDD Customer is has a link to the most up to date Stripe Customer ID.
$edd_customer->update_meta( edd_stripe_get_customer_key(), $stripe_customer->id );
try {
$payment_method = edds_api_request( 'PaymentMethod', 'retrieve', $payment_method_id );
$payment_method->attach(
array(
'customer' => $stripe_customer->id,
)
);
// Check if customer has default card.
$existing_cards = edd_stripe_get_existing_cards( get_current_user_id() );
$default_payment_method = edds_customer_get_default_payment_method( get_current_user_id(), $existing_cards );
// If there is no default card, make updated card default.
if ( null === $default_payment_method ) {
edds_customer_set_default_payment_method( $stripe_customer->id, current( $existing_cards )['source']->id );
}
wp_send_json_success(
array(
'message' => esc_html__( 'Card successfully added.', 'easy-digital-downloads' ),
)
);
} catch ( \Exception $e ) {
// Increase the card error count.
edd_stripe()->rate_limiting->increment_card_error_count();
wp_send_json_error(
array(
'message' => esc_html( $e->getMessage() ),
)
);
}
}
add_action( 'wp_ajax_edds_add_payment_method', 'edds_add_payment_method' );
/**
* Sets default payment method if none.
*
* @since 2.8
* @param string $stripe_customer_id Stripe Customer ID. Usually starts with cus_ .
* @param string $payment_method_id Stripe Payment ID. Usually starts with pm_ .
* @return \Stripe\Customer $customer Stripe Customer.
*/
function edds_customer_set_default_payment_method( $stripe_customer_id, $payment_method_id ) {
$customer = edds_api_request(
'Customer',
'update',
$stripe_customer_id,
array(
'invoice_settings' => array(
'default_payment_method' => $payment_method_id,
),
)
);
return $customer;
}
/**
* Checks if customer has default payment method.
*
* @since 2.8
* @param int $user_id WordPress user ID.
* @param array $payment_methods Array of payment methods for user, default = false will fetch payment methods.
* @return null|string Payment Method ID if found, else null
*/
function edds_customer_get_default_payment_method( $user_id, $payment_methods = false ) {
// Retrieve saved cards before checking for default.
if ( false === $payment_methods ) {
$payment_methods = edd_stripe_get_existing_cards( $user_id );
}
$default_payment_method = null;
if ( count( $payment_methods ) >= 1 ) {
// Loop through existing cards for default.
foreach ( $payment_methods as $card ) {
if ( true === $card['default'] ) {
$default_payment_method = $card['source']->id;
break;
}
}
}
return $default_payment_method;
}
/**
* Checks if customer Stripe Customer object exists.
*
* @since 2.8
* @param string $stripe_customer_id Stripe Customer ID. Usually starts with cus_ .
* @param array $customer_args {
* Arguments to create a Stripe Customer.
*
* @link https://stripe.com/docs/api/customers/create
* }
* @return \Stripe\Customer|false $customer Stripe Customer if found or false on error.
*/
function edds_get_stripe_customer( $stripe_customer_id, $customer_args ) {
$customer = false;
if ( ! empty( $stripe_customer_id ) ) {
try {
$customer = edds_api_request( 'Customer', 'retrieve', $stripe_customer_id );
if ( isset( $customer->deleted ) && $customer->deleted ) { // If customer was deleted in Stripe, try to create a new one.
$customer = edds_create_stripe_customer( $customer_args );
}
} catch ( \Stripe\Error\Base $e ) {
$error_code = $e->getStripeCode();
if ( 'resource_missing' === $error_code ) { // If Stripe returns an error of 'resource_missing', try to create a new Stripe Customer.
try {
$customer = edds_create_stripe_customer( $customer_args );
} catch ( \Exception $e ) {
// No further actions to take if something causes error.
}
}
}
} else {
try {
$customer = edds_create_stripe_customer( $customer_args );
} catch ( \Exception $e ) {
// No further actions to take if something causes error.
}
}
return $customer;
}
/**
* Creates a new Stripe Customer
*
* @since 2.8
* @param array $customer_args {
* Arguments to create a Stripe Customer.
*
* @link https://stripe.com/docs/api/customers/create
* }
* @return \Stripe\Customer|false $customer Stripe Customer if one is created or false on error.
*/
function edds_create_stripe_customer( $customer_args = array() ) {
/**
* Filters the arguments used to create a Customer in Stripe.
*
* @since unknown
*
* @param array $customer_args {
* Arguments to create a Stripe Customer.
*
* @link https://stripe.com/docs/api/customers/create
* }
* @param array $purchase_data {
* Cart purchase data if in the checkout context. Empty otherwise.
* }
*/
$customer_args = apply_filters( 'edds_create_customer_args', $customer_args, array() );
if ( empty( $customer_args['email'] ) || ! is_email( $customer_args['email'] ) ) {
return false;
}
if ( empty( $customer_args['description'] ) ) {
$customer_args['description'] = $customer_args['email'];
}
try {
$customer = edds_api_request( 'Customer', 'create', $customer_args );
} catch ( \Exception $e ) {
$customer = false;
}
return $customer;
}