$label )
$default_exchange[ $type ] = 1;
parent::__construct( array(
'id' => 'stripe',
'label' => 'Stripe',
'defaults' => array(
'mode' => 'test',
'live_public' => '',
'live_secret' => '',
'test_public' => '',
'test_secret' => '',
'currency' => 'USD',
'exchange' => $default_exchange,
'box_logo' => '',
'box_title' => '',
'box_desc' => '',
'box_button' => '',
'description' => '',
'card_statement' => '',
'populate_email' => 1,
'require_billing' => 1,
'allow_rememberme' => 0
)
), $gateway_prefs );
add_action( 'mycred_pre_process_buycred', array( $this, 'change_stripe_button_call' ), 10 );
add_action( 'mycred_front_enqueue', array( $this, 'register_scripts' ), 10 );
add_action( 'wp_footer', array( $this, 'wp_footer' ) );
add_action( 'mycred_front_enqueue_footer', array( $this, 'enqueue_footer' ) );
add_action( 'admin_init', array( $this, 'register_admin_assets' ) );
if ( $this->prefs['mode'] == 'test' ) {
$this->sandbox_mode = true;
}
$this->visitors_allowed = apply_filters( 'mycred_stripe_visitors_allowed', false, $this );
add_filter( 'mycred_buycred_populate_transaction', array( $this, 'mycred_buycred_populate_transaction' ), 10, 2 );
}
/**
* Filter's Callback
* @since 2.2.6
* @version 1.0
*/
public function mycred_buycred_populate_transaction( $populate_transaction, $id ) {
if( $id == 'stripe' )
$populate_transaction = true;
return $populate_transaction;
}
/**
* Register Scripts
* @since 2.0
* @version 1.0
*/
public function mycred_hook_js() {
$public_key = ( $this->prefs['mode'] == 'test' ) ? $this->prefs['test_public'] : $this->prefs['live_public'];
?>
visitors_allowed && ! is_user_logged_in() ) return;
$email_address = '';
if ( ! $this->visitors_allowed && $this->prefs['populate_email'] === 1 ) {
$user = wp_get_current_user();
$email_address = $user->user_email;
}
wp_register_style( 'mycred-stripe-checkout-css', plugins_url( 'assets/css/stripe-frontend-styles.css', MYCRED_STRIPE ) );
wp_enqueue_script( 'mycred-stripe-js', 'https://js.stripe.com/v3', array(), 'v3' );
wp_register_script( 'mycred-stripe-checkout', plugins_url( 'assets/js/stripe.js', MYCRED_STRIPE ), array( 'jquery', 'mycred-stripe-js' ), MYCRED_STRIPE_VERSION );
wp_localize_script(
'mycred-stripe-checkout',
'buyCREDStripe',
apply_filters( 'mycred_buycred_stripe_js', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'stripekey' => ( ( $this->prefs['mode'] == 'test' ) ? $this->prefs['test_public'] : $this->prefs['live_public'] ),
'remember' => ( ( $this->prefs['allow_rememberme'] === 1 ) ? 'yes' : 'no' ),
'billing' => ( ( $this->prefs['require_billing'] === 1 ) ? 'yes' : 'no' ),
'panellabel' => $this->prefs['box_button'],
'currency' => strtolower( $this->prefs['currency'] ),
'useremail' => $email_address,
'newbuytoken' => wp_create_nonce( 'buycred-stripe-new-purchase' )
), $this )
);
}
public function register_admin_assets() {
wp_register_script( 'mycred-stripe-admin', plugins_url( 'assets/js/mycred-stripe-admin.js', MYCRED_STRIPE ), array( 'jquery' ), MYCRED_STRIPE_VERSION );
}
/**
* check stripe request
* Insert payment cover.
* @since 2.0
* @version 1.0
*/
public function change_stripe_button_call(){
if ( isset( $_REQUEST["mycred_buy"] ) ) {
if( $_REQUEST['mycred_buy'] == "stripe" ) {
add_filter( 'mycred_buycred_checkout_button', array( $this, 'change_stripe_button' ) );
}
}
}
/**
* Replace stripe button
* Insert payment cover.
* @since 2.0
* @version 1.0
*/
public function change_stripe_button(){
return do_shortcode( '[mycred_stripe_buy amount=' . sanitize_text_field( $_REQUEST["amount"] ) . ']Continue[/mycred_stripe_buy]' );
}
/**
* WP Footer
* Insert mycred_stripe_buy modal.
* @since 2.0
* @version 1.0
*/
public function wp_footer() {
if ( ! $this->visitors_allowed && ! is_user_logged_in() ) return;
if ( isset( $this->buycred_stripe_sale['atts'] ) && isset( $this->buycred_stripe_sale['content'] ) ) {
$cache_key = 'mycred_stripe_purchase_form';
$already_exist = wp_cache_get( $cache_key );
if ( false === $already_exist ) {
wp_cache_set( $cache_key, true );
$this->buycred_stripe_sale['atts']['classes'] = '';
echo '
';
echo $this->purchase_form( $this->buycred_stripe_sale['atts'], $this->buycred_stripe_sale['content'] );
echo '
';
}
}
}
/**
* Process Purchase
* @since 1.0
* @version 2.0
*/
public function process() { }
/**
* AJAX Buy Handler
* @since 1.8
* @version 1.0
*/
public function ajax_buy() {
$atts = array( 'amount' => sanitize_text_field( $_REQUEST['amount'] ) );
if ( isset( $_REQUEST['er_random'] ) ) {
$atts['e_rate'] = mycred_decode_values( sanitize_text_field( $_REQUEST['er_random'] ) );
}
if ( isset( $_REQUEST['ctype'] ) ) {
$atts['ctype'] = sanitize_text_field( $_REQUEST['ctype'] );
}
if ( isset( $_REQUEST['gift_to'] ) ) {
$atts['to'] = absint( $_REQUEST['gift_to'] );
}
$response = $this->purchase_form( $atts, 'Checkout' );
$response .= '';
$response .= '';
$this->send_json( $response );
}
/**
* Full page Checkout
* @param $gateway_prefs
* @since 2.2.6
* @verison 1.0
*/
public function checkout_page_body() {
echo wp_kses_post( $this->checkout_header() );
echo wp_kses_post( $this->checkout_logo( false ) );
echo wp_kses_post( $this->checkout_order() );
$atts = array( 'amount' => $this->amount );
if ( isset( $_REQUEST['er_random'] ) ) {
$atts['e_rate'] = mycred_decode_values( sanitize_text_field( $_REQUEST['er_random'] ) );
}
if ( isset( $_REQUEST['ctype'] ) ) {
$atts['ctype'] = sanitize_text_field( $_REQUEST['ctype'] );
}
if ( isset( $_REQUEST['gift_to'] ) ) {
$atts['to'] = absint( $_REQUEST['gift_to'] );
}
echo $this->purchase_form( $atts, 'Checkout' );
echo wp_kses_post( $this->checkout_cancel() );
?>
visitors_allowed )
add_action( 'wp_ajax_nopriv_buycred-new-purchase', array( $this, 'ajax_new_purchase' ) );
if ( is_user_logged_in() )
add_action( 'wp_ajax_buycred-new-purchase', array( $this, 'ajax_new_purchase' ) );
}
/**
* Buy Handler
* @since 1.0
* @version 2.0
*/
public function buy() {
wp_die( 'Stripe payments not allowed via the buyCRED Checkout page.
' );
}
/**
* @since 2.3
* @version 1.0
*/
public function purchase_form( $atts, $content = '' ) {
extract( shortcode_atts( array(
'logo' => $this->prefs['box_logo'],
'title' => $this->prefs['box_title'],
'desc' => $this->prefs['box_desc'],
'label' => $this->prefs['box_button'],
'amount' => 0,
'to' => 'current',
'ctype' => 'mycred_default',
'id' => '',
'classes' => '',
'e_rate' => ''
), $atts ) );
if ( ! $this->visitors_allowed && ! is_user_logged_in() ) return;
wp_enqueue_script( 'mycred-stripe-checkout' );
wp_enqueue_style( 'mycred-stripe-checkout-css' );
$user_id = get_current_user_id();
// Make sure the type we added exists
if ( function_exists( 'mycred_point_type_exists' ) && ! mycred_point_type_exists( $ctype ) )
$ctype = 'mycred_default';
// Make sure the type we added is enabled to be used with buyCRED
if ( is_array( $this->core->core['buy_creds']['types'] ) && ! in_array( $ctype, $this->core->core['buy_creds']['types'] ) )
return 'Invalid point type';
// Setup myCRED to use our selected point type
if ( $ctype != 'mycred_default' )
$mycred = mycred( $ctype );
else
$mycred = $this->core;
// Check if the current user is excluded from using this point type
if ( ! $this->visitors_allowed && $mycred->exclude_user( $user_id ) ) return;
if ( $to === 'current' )
$to = $user_id;
if ( $to != $user_id && $mycred->exclude_user( $user_id ) )
return 'Recipient is excluded from using this type.';
// Remove HTML tags from fields that do not support them
$label = strip_tags( $label );
// The button must have classes
if ( $classes == '' )
$classes = 'btn btn-primary btn-lg';
// Get the cost
$cost = 0;
if ( ! empty( $e_rate ) )
$cost = $this->get_cost( $amount, $ctype, false, $e_rate );
else
$cost = $this->get_cost( $amount, $ctype );
$this->cost = $cost;
$label = str_replace( '{{amount}}', number_format( $cost, 2, '.', '' ), $label );
// Stripe requires costs to be set in cents
$cost = number_format( $cost * 100, 0, '.', '' );
$sensitive_data = array(
'e_rate' => empty( $e_rate ) ? 0 : $e_rate,
'ctype' => $ctype,
'to' => $to
);
$encrypted_data = mycred_encode_values( serialize( $sensitive_data ) );
if ( $id != '' )
$id = ' id="' . $id . '"';
// Lets construct a button
ob_start();
$user_info = get_userdata( $user_id );
$user_email = $user_info->user_email;
?>
$this->prefs['box_logo'],
'title' => $this->prefs['box_title'],
'desc' => $this->prefs['box_desc'],
'label' => $this->prefs['box_button'],
'amount' => 0,
'to' => 'current',
'ctype' => 'mycred_default',
'classes' => 'btn btn-primary btn-lg',
'id' => '',
'e_rate' => ''
), $atts );
if ( ! $this->visitors_allowed && ! is_user_logged_in() ) return;
$user_id = get_current_user_id();
// Make sure the type we added exists
if ( function_exists( 'mycred_point_type_exists' ) && ! mycred_point_type_exists( $atts['ctype'] ) )
$atts['ctype'] = 'mycred_default';
// Make sure the type we added is enabled to be used with buyCRED
if ( is_array( $this->core->core['buy_creds']['types'] ) && ! in_array( $atts['ctype'], $this->core->core['buy_creds']['types'] ) )
return 'Invalid point type';
// Setup myCRED to use our selected point type
if ( $atts['ctype'] != 'mycred_default' )
$mycred = mycred( $atts['ctype'] );
else
$mycred = $this->core;
// Check if the current user is excluded from using this point type
if ( ! $this->visitors_allowed && $mycred->exclude_user( $user_id ) ) return;
if ( $atts['to'] === 'current' )
$atts['to'] = $user_id;
if ( $atts['to'] != $user_id && $mycred->exclude_user( $atts['to'] ) )
return 'Recipient is excluded from using this type.';
// The button must have classes
if ( $atts['classes'] == '' )
$atts['classes'] = 'btn btn-primary btn-lg';
// Add trigger class
$atts['classes'] .= ' mycred-stripe-buy-modal';
// Remove HTML tags from fields that do not support them
$title = strip_tags( $atts['title'] );
$desc = strip_tags( $atts['desc'] );
$label = strip_tags( $atts['label'] );
// Get the cost
$cost = 0;
if ( ! empty( $atts['e_rate'] ) )
$cost = $this->get_cost( $atts['amount'], $atts['ctype'], false, $atts['e_rate'] );
else
$cost = $this->get_cost( $atts['amount'], $atts['ctype'] );
$label = str_replace( '{{amount}}', number_format( $cost, 2, '.', '' ), $label );
// Stripe requires costs to be set in cents
$cost = number_format( $cost * 100, 0, '.', '' );
$sensitive_data = array(
'e_rate' => empty( $atts['e_rate'] ) ? 0 : $atts['e_rate'],
'ctype' => $atts['ctype'],
'to' => $atts['to']
);
$encrypted_data = mycred_encode_values( serialize( $sensitive_data ) );
$this->buycred_stripe_sale = array(
'atts' => $atts,
'content' => $content
);
ob_start();
?>
get_cost( $points, $point_type, false, $decoded_data['e_rate'] );
else
$cost = $this->get_cost( $points, $point_type );
$raw_cost = $cost;
$cost = number_format( $cost * 100, 0, '.', '' );
if ( $cost != $points_cost )
wp_send_json_error( __( 'Invalid amount paid', 'mycred_stripe' ) . '. - Error 1' );
// Make sure we are buying an allowed point type
if ( ( function_exists( 'mycred_point_type_exists' ) && ! mycred_point_type_exists( $point_type ) ) || is_array( $this->core->core['buy_creds']['types'] ) && ! in_array( $point_type, $this->core->core['buy_creds']['types'] ) )
wp_send_json_error( __( 'Invalid point type purchase', 'mycred_stripe' ) . '. - Error 2' );
if ( $point_type != 'mycred_default' )
$mycred = mycred( $point_type );
else
$mycred = $this->core;
// Make sure we have not just been excluded
if ( ! $this->visitors_allowed && $mycred->exclude_user( $user_id ) )
wp_send_json_error( __( 'Purchase declined', 'mycred_stripe' ) . '. - Error 3' );
// All is well - Charge Card
$failed = false;
$intent = null;
mycred_connect_stripe( $this->prefs );
try {
if ( isset( $_POST["payment_method_id"] ) ) {
$customer_data = array(
'name' => sanitize_text_field( $_POST['name'] )
);
if ( ! empty( $_POST['email'] ) ) {
$customer_data['email'] = sanitize_text_field( $_POST['email'] );
}
$customer = \Stripe\Customer::create( $customer_data );
# Create the PaymentIntent first step
$intent = \Stripe\PaymentIntent::create([
'payment_method' => $_POST["payment_method_id"],
'amount' => $cost,
'currency' => strtolower( $this->prefs['currency'] ),
'description' => $mycred->template_tags_amount($this->prefs['description'],$points),
'confirmation_method' => 'manual',
'confirm' => true,
'customer' => $customer->id,
'return_url' => home_url('/')
]);
if ( $intent->status == 'succeeded' )
$this->mycred_succeeded_process( $intent, $point_type, $points, $recipient, $user_id, $raw_cost );
}
if ( isset( $_POST["payment_intent_id"] ) ) {
# complete the PaymentIntent secound step
$intent = \Stripe\PaymentIntent::retrieve( $_POST["payment_intent_id"] );
$intent->confirm();
}
# Note that if your API version is before 2019-02-11, 'requires_action'
# appears as 'requires_source_action'.
if ( $intent->status == 'requires_action' ) {
# Tell the client to handle the action
echo json_encode([
'requires_action' => true,
'payment_intent_client_secret' => $intent->client_secret
]);
}
else if ( $intent->status == 'succeeded' ) {
# The payment didn’t need any additional actions and completed!
# Handle post-payment fulfillment
$this->mycred_succeeded_process( $intent, $point_type, $points, $recipient, $user_id, $raw_cost );
}
else {
# Invalid status
http_response_code( 500 );
echo json_encode( ['error' => $intent->status] );
}
}
catch ( \Stripe\Exception\ApiErrorException $e ) {
# Display error on client
$failed = true;
echo json_encode([
'error' => $e->getMessage()
]);
}
die;
}
public function mycred_succeeded_process( $intent, $ctype, $points, $recipient, $user_id, $raw_cost ) {
$pending_payment = buycred_get_pending_payment( array(
'public_id' => '',
'point_type' => $ctype,
'amount' => $points,
'cost' => $raw_cost,
'currency' => $this->prefs['currency'],
'buyer_id' => $user_id,
'recipient_id' => $recipient,
'gateway_id' => $this->id,
'transaction_id' => ''
) );
$payout = $this->complete_payment( $pending_payment, $intent->id );
if ( $payout === false ) {
$failed = false;
$message = sprintf( _x( 'Could not deposit %s into your account.', 'Point type name', 'mycred_stripe' ), $mycred->plural() );
$message .= ' %s';
try {
$refund = \Stripe\Refund::create([
"charge" => $intent->id
]);
//$refund = \Stripe\Refund::create( array( 'charge' => $intent->id ) );
}
catch ( \Stripe\Error\RateLimit $e ) {
$failed = true;
$error = 'Too many requests. Please try again later.';
}
catch ( \Stripe\Error\InvalidRequest $e ) {
$failed = true;
$error = 'Invalid Stripe request. Please contact support.';
}
catch ( \Stripe\Error\Authentication $e ) {
$failed = true;
$error = 'Invalid Stripe account request. Please contact support.';
}
catch ( \Stripe\Error\ApiConnection $e ) {
$failed = true;
$error = 'Could not contact Stripe. Please try again later.';
}
catch ( Exception $e ) {
$failed = true;
$body = $e->getJsonBody();
$error = $body['error']['message'];
}
// Outch, for some reason our refund was declined. Need to inform admin
if ( $failed === true ) {
$this->inform_admin_of_error( 'refunds', $error, $user_id, $intent, $ctype );
wp_send_json_error( sprintf( $message, sprintf( __( 'Please contact support as a refund could not be executed. Please provide them with the following transaction ID: %s', 'mycred_stripe' ), $charge->id ) ) );
}
// Refunded charge
wp_send_json_error( sprintf( $message, __( 'Your payment has been refunded.', 'mycred_stripe' ) ) );
}
// Construct success message for user
$message = apply_filters( 'mycred_stripe_purchase_success', __( 'Purchase completed.', 'mycred_stripe' ), $pending_payment, $this );
$redirect = false;
if ( isset( $this->core->buy_creds ) && $this->core->buy_creds['thankyou']['use'] == 'page' && ! empty( $this->core->buy_creds['thankyou']['page'] ) )
$redirect = get_permalink( $this->core->buy_creds['thankyou']['page'] );
elseif ( isset( $this->core->buy_creds ) && $this->core->buy_creds['thankyou']['custom'] != '' )
$redirect = get_bloginfo( 'url' ) . '/' . $this->core->buy_creds['thankyou']['custom'];
wp_send_json_success( array( 'message' => $message, 'redirect' => apply_filters( 'mycred_stripe_purchase_redirect', $redirect, $pending_payment, $this ) ) );
}
/**
* Preferences
* @since 1.0
* @version 2.0
*/
public function preferences( $buy_creds = NULL ) {
wp_enqueue_script( 'mycred-stripe-admin' );
add_filter( 'mycred_dropdown_currencies', array( $this, 'stripe_currencies' ) );
$prefs = $this->prefs;
?>
Setup
currencies_dropdown( 'currency', 'mycred-gateway-stripe-currency' ); ?>
exchange_rate_setup( 'USD' ); ?>
$rate ) {
if ( $rate != 1 && in_array( substr( $rate, 0, 1 ), array( '.', ',' ) ) )
$data['exchange'][ $type ] = (float) '0' . $rate;
}
}
$data['exchange'] = $data['exchange'];
$data['description'] = sanitize_text_field( $data['description'] );
$data['card_statement'] = sanitize_text_field( $data['card_statement'] );
$data['box_logo'] = sanitize_text_field( $data['box_logo'] );
$data['box_title'] = sanitize_text_field( $data['box_title'] );
$data['box_desc'] = sanitize_text_field( $data['box_desc'] );
$data['box_button'] = sanitize_text_field( $data['box_button'] );
$data['populate_email'] = ( ( array_key_exists( 'populate_email', $data ) ) ? absint( $data['populate_email'] ) : 0 );
$data['require_billing'] = ( ( array_key_exists( 'require_billing', $data ) ) ? absint( $data['require_billing'] ) : 0 );
$data['allow_rememberme'] = ( ( array_key_exists( 'allow_rememberme', $data ) ) ? absint( $data['allow_rememberme'] ) : 0 );
return $data;
}
/**
* Adjust Available Currencies
* @since 1.0
* @version 1.1
*/
public function stripe_currencies() {
return array(
'USD' => __( 'US Dollar', 'mycred_stripe' ),
'CAD' => __( 'Canadian Dollar', 'mycred_stripe' ),
'GBP' => __( 'British Pound Sterling', 'mycred_stripe' ),
'EUR' => __( 'Euro', 'mycred_stripe' ),
'DKK' => __( 'Danish Krone', 'mycred_stripe' ),
'NOK' => __( 'Norwegian Krone', 'mycred_stripe' ),
'SEK' => __( 'Swedish Krona', 'mycred_stripe' ),
'CHF' => __( 'Swiss Franc', 'mycred_stripe' ),
'SEK' => __( 'Swedish Krona', 'mycred_stripe' ),
'AUD' => __( 'Australian Dollar', 'mycred_stripe' ),
'JPY' => __( 'Japanese Yen', 'mycred_stripe' ),
'MXN' => __( 'Mexican Peso', 'mycred_stripe' ),
'SGD' => __( 'Singapore Dollar', 'mycred_stripe' )
);
}
protected function inform_admin_of_error( $instance = '', $error_message = '', $user = NULL, $object = NULL, $type = 'mycred_default' ) {
if ( $instance == 'refunds' ) {
$subject = 'buyCRED Stripe - Refund Error';
$message = 'The buyCRED Stripe add-on has failed to refund a users payment as %plural% could not be deposited into their account after they made a payment. The user has been informed to contact you regarding this.' . "\n\n";
$message .= 'The charge ID that needs to be refunded is: %charge_id%.' . "\n\n";
$message .= 'Error given by Stripe when the refund failed: %error%';
$message = str_replace( '%charge_id%', $object->id, $message );
$message = str_replace( '%error%', $error_message, $message );
if ( $point_type != 'mycred_default' )
$mycred = mycred( $point_type );
else
$mycred = $this->core;
$message = $mycred->template_tags_general( $mycred );
}
if ( apply_filters( 'mycred_stripe_admin_error', true, $error_message, $user, $object, $type ) === true )
wp_mail( get_option( 'admin_email' ), $subject, $message );
}
}
endif;
?>