如何通过使用 MemberPress 的 WordPress 网站的 API 批量更新 Stripe 订阅价格?

问题描述 投票:0回答:1

我有一个带有 MemberPress 插件的 WordPress 网站,我的订阅已连接到 Stripe 进行付款。不幸的是,MemberPress 没有内置选项来批量更新订阅价格,而且 Stripe 的仪表板似乎也没有提供本地方法来执行此操作。

我需要将 Stripe 中的大约 5,000 个活跃订阅更新为新价格。我编写了一个在 Stripe 测试模式下成功运行的 PHP 脚本,但我不确定以下内容:

  1. 我的脚本可以在单页执行中通过 WordPress 和 PHP 处理更新 5,000 个订阅吗?服务器性能或超时有哪些风险和潜在问题?
  2. 在 WordPress/MemberPress 中手动更新会员价格以反映 Stripe 的新价格是否安全且合适,或者是否有更好的方法来保持两个平台同步?

您能看一下我的代码并提供任何反馈或建议吗?我们将非常感谢您的帮助!

这是带有注释的脚本:

<?php
/*
This script is designed to update all Stripe subscriptions tied to a **specific price ID**.
It retrieves all subscriptions that are linked to an old price and updates them to a new price,
but only if both prices belong to the same product.
The update process is triggered by a URL parameter in the WordPress admin interface.

Steps:
1. Retrieve all subscriptions associated with the old price ID.
2. Verify that the old and new prices belong to the same product.
3. If they do, update those subscriptions to the new price.
4. Trigger the update via a URL parameter in the admin area.

*/

// Function to get the product ID for a specific price ID
function get_product_id_for_price($price_id, $api_key) {
    // Prepare cURL request to retrieve the price details
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://api.stripe.com/v1/prices/$price_id");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($ch, CURLOPT_USERPWD, $api_key . ":");

    // Execute the cURL request
    $response = curl_exec($ch);
    curl_close($ch);

    // Decode the response to get the price details
    $price_details = json_decode($response, true);

    // Return the product ID if the price exists, otherwise return null
    return isset($price_details['product']) ? $price_details['product'] : null;
}

// Function to get all subscriptions for a specific price ID
// This retrieves all subscriptions tied to a given price, supporting pagination if needed.
function get_all_subscriptions_for_price($price_id, $api_key) {
    $subscriptions = [];
    $has_more = true;
    $starting_after = null;

    // Loop through all pages of subscriptions until all are retrieved
    while ($has_more) {
        // Build the request URL, and include pagination if necessary
        $ch = curl_init();
        $url = "https://api.stripe.com/v1/subscriptions?price=$price_id&limit=100";

        if ($starting_after) {
            $url .= "&starting_after=$starting_after";
        }

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        curl_setopt($ch, CURLOPT_USERPWD, $api_key . ":");

        // Execute the API request and store the result
        $response = curl_exec($ch);
        curl_close($ch);

        // Decode the JSON response into an array
        $result = json_decode($response, true);

        // If subscriptions are found, merge them with the existing list
        if (isset($result['data'])) {
            $subscriptions = array_merge($subscriptions, $result['data']);
            $has_more = $result['has_more'];
            $starting_after = end($result['data'])['id'];
        } else {
            // No more pages of subscriptions
            $has_more = false;
        }
    }

    return $subscriptions;
}

// Function to update all retrieved subscriptions to a new price
// This function takes an array of subscriptions and updates them to a new price ID.
function update_subscriptions_with_new_price($subscriptions, $new_price_id, $api_key) {
    foreach ($subscriptions as $subscription) {
        $subscription_id = $subscription['id'];
        $subscription_item_id = $subscription['items']['data'][0]['id'];

        // Prepare cURL request to update the subscription with the new price
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, "https://api.stripe.com/v1/subscriptions/$subscription_id");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        curl_setopt($ch, CURLOPT_USERPWD, $api_key . ":");
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
            'items[0][id]' => $subscription_item_id,
            'items[0][price]' => $new_price_id,
        ]));

        // Execute the cURL request
        $response = curl_exec($ch);
        curl_close($ch);

        // Decode the response and check for any errors
        $update_result = json_decode($response, true);
        if (isset($update_result['error'])) {
            echo "Error updating subscription ID $subscription_id: " . $update_result['error']['message'];
        } else {
            echo "Subscription ID $subscription_id updated successfully.\n";
        }
    }
}

// Function to update subscriptions for a specific price ID
// This retrieves all subscriptions linked to the old price and updates them to a new price if both prices belong to the same product.
function update_specific_subscriptions_for_price($product_id, $old_price_id, $new_price_id) {
    // Your Stripe secret API key to authenticate API requests
    $api_key = 'sk_test_xxxxxxxxxxxx';  // Stripe secret key

    // Step 1: Get the product IDs for the old and new prices
    $old_price_product_id = get_product_id_for_price($old_price_id, $api_key);
    $new_price_product_id = get_product_id_for_price($new_price_id, $api_key);

    // Step 2: Check if both prices belong to the specified product
    if ($old_price_product_id === $product_id && $new_price_product_id === $product_id) {
        echo "Both prices belong to the specified product. Proceeding with subscription updates.\n";

        // Step 3: Get all subscriptions tied to the old price ID
        $subscriptions = get_all_subscriptions_for_price($old_price_id, $api_key);

        // Step 4: If there are subscriptions, update them to the new price ID
        if (!empty($subscriptions)) {
            update_subscriptions_with_new_price($subscriptions, $new_price_id, $api_key);
        } else {
            echo "No subscriptions found for Price ID: $old_price_id\n";
        }
    } else {
        // Prices do not belong to the same product or specified product, do not proceed
        echo "Error: One or both of the price IDs do not belong to the specified product. No updates will be made.\n";
    }
}

// Example usage: Admin function to trigger subscription updates via a URL parameter
add_action('admin_init', function() {
    // The Product ID that both prices must belong to
    $product_id = 'prod_xxxxxxxxx';  // The actual product ID

    // The old Price ID that you want to update
    $old_price_id = 'price_xxxxxxxxx';    // The actual old price ID from Stripe

    // The new Price ID to which subscriptions should be updated
    $new_price_id = 'price_xxxxxxxxxx';    // The new price ID
    
    

    // Check if the update process is triggered by the URL parameter
    if (isset($_GET['trigger_subscription_update']) && $_GET['trigger_subscription_update'] === 'true') {
        // Run the function to update subscriptions tied to the old price ID
        update_specific_subscriptions_for_price($product_id, $old_price_id, $new_price_id);
    }
});
?>

php curl stripe-payments memberpress
1个回答
0
投票

目前公共 API 中没有批量订阅更新功能,因此按照您编写的脚本编写的脚本是实现此功能的方法。

虽然我没有详细审查您的代码,但这种方法在大多数情况下应该有效。需要记住的是 API 速率限制,并确保您的请求速度保持在这些限制以下(也为您的正常操作留出空间)并优雅地处理任何 429 响应以重试。

© www.soinside.com 2019 - 2024. All rights reserved.