php [专业网站] - 网站/博客列表中的自定义选项,以帮助进行PayPal快速网关续订测试

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php [专业网站] - 网站/博客列表中的自定义选项,以帮助进行PayPal快速网关续订测试相关的知识,希望对你有一定的参考价值。

<?php
/**
* Plugin Name: [Pro Sites] - Additional options on Sites Table
* Plugin URI: https://premium.wpmudev.org/
* Description: Adds more options on the Sites table
* Author: Panos Lyrakis @ WPMUDEV
* Author URI: https://premium.wpmudev.org/
* License: GPLv2 or later
*/
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

if ( ! class_exists( 'WPMUDEV_PS_Sites_Options' ) ) {
    
    class WPMUDEV_PS_Sites_Options {
        private static $_instance = null;
        
        public static function get_instance() {
            if( is_null( self::$_instance ) ){
                self::$_instance = new WPMUDEV_PS_Sites_Options();
            }
            return self::$_instance;
            
        }

        private function __construct() {

            add_filter( 'wpmu_blogs_columns', array( $this, 'add_head_column' ), 10 );
            add_action( 'manage_sites_custom_column', array( $this, 'add_column_field' ), 10, 2 );
            add_action( 'admin_footer', array( $this, 'footer_script' ), 10 );
            add_action( 'wp_ajax_wpmudev_ps_withdraw_blog', array( __CLASS__, 'force_withdraw_blog' ), 10 );
            add_action( 'wp_ajax_wpmudev_ps_reset_blog_expire', array( __CLASS__, 'reset_blog_expire_ajax' ), 10 );

            add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ), 10 );
            add_action( 'admin_head', array( $this, 'admin_head' ), 10 );

        }


        public function add_head_column( $columns ) {
            
            $first_array = array_splice( $columns, 0, 2 );
            $columns     = array_merge( $first_array, array( 'ps_options' => __( 'Custom Options', 'psts' ) ), $columns );
    
            return $columns;
        }


        public function add_column_field( $column, $blog_id ){

            if( 'ps_options' != $column ){
                return;
            }

            global $psts;

            echo '<div>' . $this->force_withdraw_blog_option( $blog_id ) . '</div>';
            echo '<div>' . $this->stripe_info( $blog_id ) . '</div>';
            echo '<div>' . $this->force_ipn_simulator_option( $blog_id ) . '</div>';
            echo '<div><code>' . date( 'd-m-Y H:i:s', $psts->get_expire( $blog_id ) ) . '</code></div>';
            if ( ! is_main_site( $blog_id ) && is_pro_site( $blog_id ) ){
                echo '<div class="datepicker-wrap">
                        <input type="text" class="datepicker" value="' . date( 'd-m-Y', $psts->get_expire( $blog_id ) ) . '" >
                        <button class="datechanger" data-blog-id="' . $blog_id . '" disabled>'. __( 'Change date' ) .'</button>
                        <input type="hidden" class="expire_time" value="' . date( 'H:i:s', $psts->get_expire( $blog_id ) ) . '" />
                    </div>';
            }

        }


        public function stripe_info( $blog_id ){

            if ( is_main_site( $blog_id ) || ! is_pro_site( $blog_id ) ) {
                return;
            }

            global $wpdb;

            $stripe_table = $wpdb->base_prefix . 'pro_sites_stripe_customers';

            $stripe_info = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$stripe_table} WHERE blog_id=%d", $blog_id ) );

            if( empty($stripe_info ) ){
                return '<div class="stripe-info"><small><code>No stripe info</code></small></div>';
            }

            $out = '<div class="stripe-info">';

                $out .= '<div class="stripe-info-created hidden">';
                    $out .= '<small>created: <code>'. time() .'</code></small>';
                $out .= '</div>';

                $out .= '<div class="stripe-info-blog-id hidden">';
                    $out .= '<small>blog_id: <code>'. $blog_id .'</code></small>';
                $out .= '</div>';

                $out .= '<div class="stripe-info-customer-id hidden">';
                    $out .= '<small>customer_id: <code>'. $stripe_info->customer_id .'</code></small>';
                $out .= '</div>';

                $out .= '<div class="stripe-info-subscription-id hidden">';
                    $out .= '<small>subscription_id: <code>'. $stripe_info->subscription_id .'</code></small>';
                $out .= '</div>';

                $out .= '<div class="stripe-info-start hidden">';
                    $out .= '<small>start (anything after): <code>'. strtotime( date() ) .'</code></small>';
                $out .= '</div>';

                $out .= '<div class="stripe-info-end hidden">';
                    $out .= '<small>end (anything after): <code>'. strtotime( date() . "+1 days" ) .'</code></small>';
                $out .= '</div>';

                $out .= '<div class="stripe-info-postman">';
                    $out .= '<small>Postman: 
                                <a href="#" class="stripe-to-postman button" 
                                    data-blog-id="' . $blog_id . '"
                                    data-created="' . time() . '"
                                    data-customer="' . $stripe_info->customer_id . '"
                                    data-subscription="' . $stripe_info->subscription_id . '"
                                    data-start="' . time() . '"
                                    data-end="' . strtotime( date() . "+1 days" ) . '"
                                    >
                                    Postman test
                                </a></small>';
                $out .= '</div>';

            $out .= '</div>';
            
            $stripe_fieldset = '<fieldset style="border: 1px solid #ddd; padding:2px;"><legend>Stripe</legend>' . $out . '</fieldset>';
            
            return $stripe_fieldset;
        }


        public function force_withdraw_blog_option( $blog_id ){

            $out = '';
            if ( ! is_main_site( $blog_id ) && is_pro_site( $blog_id ) ) {
                $out = '<a class="button wpmudev-ps-withdraw-blog-btn" data-blog-id="' . $blog_id . '">Withdraw</a>';
            }
            return $out;

        }


        public function force_ipn_simulator_option( $blog_id ){

            global $wpdb, $psts;

            $blog_info = $wpdb->get_row( "SELECT * FROM {$wpdb->base_prefix}pro_sites WHERE blog_ID = '$blog_id'" );

            $pref = 'psts';
            $level = $psts->get_level( $blog_id );
            if( 0 == $level ){
                $level = '[LEVEL]';
            }
            $period = $blog_info->term;
            $amount = $blog_info->amount;
            $timestamp = time();
            $activation_key = $blog_info->identifier;
            if( $activation_key == '' ){
                $blog_path = $wpdb->get_var( "SELECT path FROM {$wpdb->base_prefix}blogs WHERE blog_id={$blog_id}" );
                $activation_key = $wpdb->get_var( "SELECT activation_key FROM {$wpdb->base_prefix}signups WHERE path='{$blog_path}'" );
            }

            $simulator_custom_field = $pref . '_' . $blog_id . '_' . $level . '_' . $period . '_' . $amount . '_' . $timestamp . '_' . $activation_key;

            $simulator_custom_fieldset = '<fieldset style="border: 1px solid #ddd; padding:2px;"><legend>PayPal IPN</legend><small><code>' . $simulator_custom_field . '</code></small></fieldset>';
            return  $simulator_custom_fieldset;

        }

        public static function force_withdraw_blog(){

            check_ajax_referer( 'wpmudev-ps-withdraw-blog', 'security' );
            global $psts;
            $blog_id = (int)$_POST['blog_id'];
            
            $return = array(
                'success'       => false,
                'blog_id'       => $blog_id
            );

            if( ! is_wp_error( $psts->withdraw( $blog_id ) ) ){
                $return = array(
                    'success'       => true,
                    'blog_id'       => $blog_id
                );
            }

            wp_send_json($return);

        }


        public static function reset_blog_expire_ajax(){

            check_ajax_referer( 'wpmudev-ps-reset-blog-expire', 'security' );
            global $psts;
            $blog_id = (int)$_POST['blog_id'];
            $new_expire = strtotime( $_POST['new_expire'] );

            $return = array(
                'success'       => false,
                'blog_id'       => $blog_id
            );

            if( self::reset_blog_expire( $blog_id, $new_expire ) ){
                $return = array(
                    'success'       => true,
                    'blog_id'       => $blog_id
                );
                
                $psts->log_action( $blog_id, 'Blog was manually extended to ' . date( 'F j, Y H:i:s',  $new_expire ) . '. This was set with custom action' );

            }           

            wp_send_json($return);
        }


        public static function reset_blog_expire( $blog_id, $new_expire ){

            global $wpdb;

            $exists = false;
            if ( ! empty( $blog_id ) ) {
                $exists = $wpdb->get_var( $wpdb->prepare( "SELECT expire FROM {$wpdb->base_prefix}pro_sites WHERE blog_ID = %d", $blog_id ) );
            }

            if( ! $exists ){
                return false;
            }

            $wpdb->query( $wpdb->prepare( "
                UPDATE {$wpdb->base_prefix}pro_sites
                SET expire = %d
                WHERE blog_ID = %d",
                $new_expire,
                $blog_id
            ) );

            return true;            
        }


        public function admin_enqueue_scripts(){

            $screen = get_current_screen();
            
            if( 'sites-network' != $screen->id ){
                return;
            }

            wp_enqueue_script( 'jquery-ui-datepicker' );

            //For popup :
            wp_enqueue_script( 'jquery-ui-dialog' ); // jquery and jquery-ui should be dependencies, didn't check though...
            wp_enqueue_style( 'wp-jquery-ui-dialog' );

        }


        public function admin_head(){

            $screen = get_current_screen();
            
            if( 'sites-network' != $screen->id ){
                return;
            }

            ?>
            <style>

                .datepicker-wrap .datepicker{
                    max-width: 110px;
                }         

                .ui-widget {
                    font-family: "Helvetica Neue","Trebuchet MS",Tahoma,Verdana,Arial,sans-serif;
                    background: #fff;
                }

                .ui-datepicker,

                .ui-datepicker a,
                .ui-datepicker th,
                .ui-datepicker td{
                    padding: 10px !important;
                }

                .ui-datepicker {
                    padding: 0;    
                    -webkit-box-shadow: 0px 2px 14px 1px rgba(0,0,0,0.75);
                -moz-box-shadow: 0px 2px 14px 1px rgba(0,0,0,0.75);
                box-shadow: 0px 2px 14px 1px rgba(0,0,0,0.75);
                }

                .ui-datepicker-header {
                    border: none;
                    font-size: 80%;
                    -moz-border-radius: 4px 4px 0 0;
                    -webkit-border-radius: 4px 4px 0 0;
                    border-radius: 4px 4px 0 0; /* border radius */
                    -moz-background-clip: padding;
                    -webkit-background-clip: padding-box;
                    background-clip: padding-box; /* prevents bg color from leaking outside the border */
                    background-color: #e0e8ec; /* layer fill content */
                    -moz-box-shadow: 0 1px 0 rgba(255,255,255,.53), inset 0 -1px 0 rgba(0,0,0,.12); /* drop shadow and inner shadow */
                    -webkit-box-shadow: 0 1px 0 rgba(255,255,255,.53), inset 0 -1px 0 rgba(0,0,0,.12); /* drop shadow and inner shadow */
                    box-shadow: 0 1px 0 rgba(255,255,255,.53), inset 0 -1px 0 rgba(0,0,0,.12); /* drop shadow and inner shadow */
                    background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEwMCAxMDAiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iaGF0MCIgZ3JhZGllbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIHgxPSI1MCUiIHkxPSIxMDAlIiB4Mj0iNTAlIiB5Mj0iLTEuNDIxMDg1NDcxNTIwMmUtMTQlIj4KPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMCIgc3RvcC1vcGFjaXR5PSIwLjIxIi8+CjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIwLjIxIi8+CiAgIDwvbGluZWFyR3JhZGllbnQ+Cgo8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgZmlsbD0idXJsKCNoYXQwKSIgLz4KPC9zdmc+); /* gradient overlay */
                    background-image: -moz-linear-gradient(bottom, rgba(0,0,0,.21) 0%, rgba(255,255,255,.21) 100%); /* gradient overlay */
                    background-image: -o-linear-gradient(bottom, rgba(0,0,0,.21) 0%, rgba(255,255,255,.21) 100%); /* gradient overlay */
                    background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,.21) 0%, rgba(255,255,255,.21) 100%); /* gradient overlay */
                    background-image: linear-gradient(bottom, rgba(0,0,0,.21) 0%, rgba(255,255,255,.21) 100%); /* gradient overlay */
                    padding: 20px;
                    text-align: center;
                }

                .ui-datepicker-title {
                    color: #515d65; /* text color */
                    font-size: 13px;
                    font-weight: bold;
                    text-shadow: 0 1px 1px rgba(255,255,255,.8); /* drop shadow */

                }

                .ui-icon-circle-triangle-e {
                    background-image: url(images/ui-icons_454545_256x240.png);
                    background-position: -32px -16px;
                }

                .ui-icon-circle-triangle-w {
                    background-image: url(images/ui-icons_454545_256x240.png);
                    background-position: -96px -16px;
                }

                .ui-datepicker .ui-datepicker-prev,
                .ui-datepicker .ui-datepicker-next {
                    border-color: transparent;
                }

                .ui-state-default {
                    background: transparent;
                    border: none;
                    color: #2b2b2b;
                    font-family: "Myriad Pro";
                    font-weight: normal;
                    text-align: center;
                }

                .ui-datepicker-header .ui-state-hover {
                    background: #bdc5c9;
                }

                .ui-datepicker table {
                    margin: 0;
                }

                .ui-datepicker th {
                    color: #9da7af;
                    font-size: 12px;
                    font-weight: normal;
                    -moz-border-radius: 216px 0 0 0 / 0 0 0 0;
                    -webkit-border-radius: 216px 0 0 0 / 0 0 0 0;
                    border-radius: 216px 0 0 0 / 0 0 0 0;
                    -moz-background-clip: padding;
                    -webkit-background-clip: padding-box;
                    background-clip: padding-box;
                    background-color: rgba(0,0,0,.08);

                }

                .ui-datepicker td {
                    border-top: 1px solid #ddd;
                    border-right: 1px solid #ddd;
                    padding: 0;
                    -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.4);
                    -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.4);
                    box-shadow: inset 0 1px 0 rgba(255,255,255,.4);
                    background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEwMCAxMDAiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxsaW5lYXJHcmFkaWVudCBpZD0iaGF0MCIgZ3JhZGllbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIHgxPSI1MCUiIHkxPSIxMDAlIiB4Mj0iNTAlIiB5Mj0iLTEuNDIxMDg1NDcxNTIwMmUtMTQlIj4KPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMCIgc3RvcC1vcGFjaXR5PSIwLjA2Ii8+CjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIwLjA2Ii8+CiAgIDwvbGluZWFyR3JhZGllbnQ+Cgo8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgZmlsbD0idXJsKCNoYXQwKSIgLz4KPC9zdmc+);
                    background-image: -moz-linear-gradient(bottom, rgba(0,0,0,.06) 0%, rgba(255,255,255,.06) 100%);
                    background-image: -o-linear-gradient(bottom, rgba(0,0,0,.06) 0%, rgba(255,255,255,.06) 100%);
                    background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,.06) 0%, rgba(255,255,255,.06) 100%);
                    background-image: linear-gradient(bottom, rgba(0,0,0,.06) 0%, rgba(255,255,255,.06) 100%);

                }

                .ui-datepicker td:last-child {
                    border-right: none;
                }

                .ui-datepicker td span, 
                .ui-datepicker td a {
                    padding: .7em 0;
                    color: #6a747a;
                    font-size: 12px;
                    font-weight: bold;
                    font-family: Arial;
                }

                .ui-datepicker-calendar .ui-state-hover {
                    background-image: -moz-linear-gradient(bottom, rgba(0,0,0,.12) 0%, rgba(255,255,255,.06) 100%);
                    background-image: -o-linear-gradient(bottom, rgba(0,0,0,.12) 0%, rgba(255,255,255,.06) 100%);
                    background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,.12) 0%, rgba(255,255,255,.06) 100%);
                    background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,.12) 0%, rgba(255,255,255,.06) 100%);
                }

                td a.ui-state-active,
                td a.ui-state-active.ui-state-hover {
                    color: #fff;
                    background-color: #8ab8ed;
                    text-shadow: 0 1px 0 rgba(0,0,0,.26);
                    -moz-box-shadow: inset 0 4px 9px rgba(0,0,0,.24);
                    -webkit-box-shadow: inset 0 4px 9px rgba(0,0,0,.24);
                    box-shadow: inset 0 4px 9px rgba(0,0,0,.24);
                }

                .ui-datepicker td.ui-state-disabled span,
                .ui-datepicker td.ui-state-disabled a
                {
                    color: #ddd;
                }


            </style>
            <?php


        }
    
        
        public function footer_script(){

            $screen = get_current_screen();

            if( 'sites-network' != $screen->id ){
                return;
            }

            ?>
            <script type="text/javascript">
            (function($){
                $(document).ready(function(){
                    var ps_withdraw_btn = $( '.wpmudev-ps-withdraw-blog-btn' );
                    ps_withdraw_btn.on( 'click', function(e){

                        var $this = $(this);
                        $this.html( 'Withdrawing...' );
                        var blog_id = $(this).data( 'blog-id' );
                        var data = {
                            action: 'wpmudev_ps_withdraw_blog',
                            security: '<?php echo wp_create_nonce( "wpmudev-ps-withdraw-blog" ); ?>',
                            blog_id: blog_id
                        };
                        $.post(ajaxurl, data, function(response) {
                            if( response.success ){
                                $this.fadeOut( '300', function(){ $this.remove(); } );                                
                            }
                            else{
                                alert( 'Blog could not be withdrawn...' );
                            }

                            window.location.reload();
                        });
                    });

                    $( '.datepicker' ).on( 'change', function(){
                        var $this = $( this );
                        var new_date = $this.val();
                        $this.parent().find( '.datechanger' ).attr( 'disabled', false );
                    });

                    $( '.datechanger' ).on( 'click', function(){

                        $( '.datepicker-wrap' ).append( '<div>Please wait. Updating expiration date.</div>' );

                        var $this = $( this );
                        $this.attr( 'disabled', true );
                        var blog_id = $this.data( 'blog-id' );
                        var new_expire = $this.parent().find( '.datepicker' ).val();
                        var expire_time = $this.parent().find( '.expire_time' ).val();
                        new_expire += ' ' + expire_time;
                        

                        var data = {
                            action: 'wpmudev_ps_reset_blog_expire',
                            security: '<?php echo wp_create_nonce( "wpmudev-ps-reset-blog-expire" ); ?>',
                            blog_id: blog_id,
                            new_expire: new_expire
                        };
                        $.post(ajaxurl, data, function(response) {
                            if( response.success ){
                                $this.fadeOut( '300', function(){ $this.remove(); } );                                
                            }
                            else{
                                alert( 'Could not set new expiration date for blog...' );
                            }

                            window.location.reload();
                        });
                    });

                    $('.datepicker').datepicker({
                        dateFormat : 'dd-mm-yy',
                        minDate: 0
                    });


                    $('.stripe-to-postman').on( 'click', function(e){
                        e.preventDefault();

                        var $this = $( this );
                        var blog_id = $this.data( 'blog-id' );
                        var created = $this.data( 'created' );
                        var start = $this.data( 'start' );
                        var end = $this.data( 'end' );
                        var customer = $this.data( 'customer' );
                        var subscription = $this.data( 'subscription' );
                        var default_content = $( '#stripe-postman-default-content' ).html();
                        var new_content = default_content;

                        new_content = new_content.replace( '[%blog_id%]', blog_id );
                        new_content = new_content.replace( '[%created%]', created );
                        new_content = new_content.replace( '[%subscription%]', subscription );
                        new_content = new_content.replace( '[%customer%]', customer );
                        new_content = new_content.replace( '[%start%]', start );
                        new_content = new_content.replace( '[%end%]', end );

                        $('#stripe-postman-dialog .dialog-content').html( '<code>' + new_content + '</code>' )
                        $('#stripe-postman-dialog').dialog('open');
                    });


                    //Postman PopUp dialog
                    $('#stripe-postman-dialog').dialog({
                        title: 'Postman test',
                        dialogClass: 'wp-dialog',
                        autoOpen: false,
                        draggable: false,
                        width: 'auto',
                        modal: true,
                        resizable: false,
                        closeOnEscape: true,
                        position: {
                        my: "center",
                        at: "center",
                        of: window
                        },
                        open: function () {
                        // close dialog by clicking the overlay behind it
                        $('.ui-widget-overlay').bind('click', function(){
                            $('#stripe-postman-dialog').dialog('close');
                        })
                        },
                        create: function () {
                        // style fix for WordPress admin
                        $('.ui-dialog-titlebar-close').addClass('ui-button');
                        },
                    });

                    
                });
                
            })(jQuery);
            </script>


            <!-- The modal / dialog box, for Stripe postmane -->
            <div id="stripe-postman-dialog" class="hidden" style="min-width:600px;max-width:1000px">
            <h3>Please copy following into postman to test stripe succesfull payment</h3>
            <div class="dialog-content"></div>
            </div>

            <div id="stripe-postman-default-content" style="display:none">
            {
            "created": [%created%],
            "livemode": false,
            "id": "evt_00000000000000",
            "type": "invoice.payment_succeeded",
            "object": "event",
            "request": null,
            "pending_webhooks": 1,
            "api_version": "2017-08-15",
            "data": {
                "object": {
                "id": "in_00000000000000",
                "object": "invoice",
                "amount_due": 2000,
                "application_fee": null,
                "attempt_count": 1,
                "attempted": true,
                "billing": "charge_automatically",
                "charge": "_00000000000000",
                "closed": true,
                "currency": "usd",
                "customer": "[%customer%]",
                "date": 1463604240,
                "description": null,
                "discount": null,
                "ending_balance": 0,
                "forgiven": false,
                "lines": {
                    "data": [
                    {
                        "id": "sub_9lgdj4XYXu40PH",
                        "object": "line_item",
                        "amount": 4000,
                        "currency": "usd",
                        "description": null,
                        "discountable": true,
                        "livemode": true,
                        "metadata": {
                        "period": "1",
                        "level": "4",
                        "activation": "5f5dea9fd30af1ee",
                        "blog_id": "[%blog_id%]"
                        },
                        "period": {
                        "start": [%start%],
                        "end": [%end%]
                        },
                        "plan": {
                        "id": "ms-plan-4637-aZugfMmEub0xFkF7VLjuA",
                        "object": "plan",
                        "amount": 800,
                        "created": 1503821272,
                        "currency": "usd",
                        "interval": "day",
                        "interval_count": 30,
                        "livemode": false,
                        "metadata": {
                        },
                        "name": "Root",
                        "statement_descriptor": null,
                        "trial_period_days": null
                        },
                        "proration": false,
                        "quantity": 1,
                        "subscription": null,
                        "subscription_item": "si_19S9GBKvwjw7Q9S7tRdETFHQ",
                        "type": "subscription"
                    }
                    ],
                    "has_more": false,
                    "object": "list",
                    "url": "/v1/invoices/in_18CbWOKvwjw7Q9S7rk3NnjGT/lines"
                },
                "livemode": false,
                "metadata": {
                },
                "next_payment_attempt": null,
                "paid": true,
                "period_end": 1463604240,
                "period_start": 1463604240,
                "receipt_number": null,
                "starting_balance": 0,
                "statement_descriptor": null,
                "subscription": "[%subscription%]",
                "subtotal": 2000,
                "tax": null,
                "tax_percent": null,
                "total": 2000,
                "webhooks_delivered_at": 1463604240
                }
            }
            }
            </div>

<!-- This script should be enqueued properly in the footer -->
<script>
(function ($) {
    $( document ).ready(function(){
  // initalise the dialog
  
 

});
})(jQuery);
</script>
            <?php

        }
        

    }  

    add_action( 'plugins_loaded', function(){
        $GLOBALS['WPMUDEV_PS_Sites_Options'] = WPMUDEV_PS_Sites_Options::get_instance();
    }, 10 );

}

以上是关于php [专业网站] - 网站/博客列表中的自定义选项,以帮助进行PayPal快速网关续订测试的主要内容,如果未能解决你的问题,请参考以下文章

如何将 wordpress 博客与网站页眉和页脚设计集成到 php 网站博客页面?

在 php 网站上集成 IMAP

awesome-php中英文资源整理(同步更新)

php [专业网站] - 设置博客网关

基于php064个人网站博客系统

BlockChain 网站和相关博客列表