admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpdd_payouts'),
'confirm_payout' => __('Are you sure you want to process this payout?', 'wp-digital-download'),
'confirm_bulk' => __('Are you sure you want to process all selected payouts?', 'wp-digital-download')
));
}
public static function render_page() {
global $wpdb;
// Get filter parameters
$status_filter = isset($_GET['status']) ? sanitize_text_field($_GET['status']) : 'pending';
$creator_filter = isset($_GET['creator']) ? intval($_GET['creator']) : 0;
// Get creators with balance
$creators = WPDD_Creator::get_creators_with_balance();
$currency = get_option('wpdd_currency', 'USD');
$threshold = floatval(get_option('wpdd_payout_threshold', 0));
// Get payout requests (requested status)
$payout_requests = $wpdb->get_results(
"SELECT p.*, u.display_name, u.user_email
FROM {$wpdb->prefix}wpdd_payouts p
INNER JOIN {$wpdb->users} u ON p.creator_id = u.ID
WHERE p.status = 'requested'
ORDER BY p.created_at ASC"
);
// Get payout history
$query = "SELECT p.*, u.display_name, u.user_email
FROM {$wpdb->prefix}wpdd_payouts p
INNER JOIN {$wpdb->users} u ON p.creator_id = u.ID
WHERE 1=1";
if ($status_filter && $status_filter !== 'all') {
$query .= $wpdb->prepare(" AND p.status = %s", $status_filter);
}
if ($creator_filter) {
$query .= $wpdb->prepare(" AND p.creator_id = %d", $creator_filter);
}
$query .= " ORDER BY p.created_at DESC LIMIT 100";
$payouts = $wpdb->get_results($query);
?>
()
|
|
|
|
|
display_name); ?>
user_email); ?>
|
amount, $request->currency); ?> |
paypal_email); ?> |
created_at))); ?> |
|
|
|
|
|
|
|
|
|
processed_by ? get_userdata($payout->processed_by) : null;
?>
created_at))); ?>
processed_at) : ?>
processed_at))); ?>
|
display_name); ?>
user_email); ?>
|
amount, $payout->currency); ?> |
paypal_email); ?> |
transaction_id ?: '-'); ?>
notes) : ?>
notes); ?>
|
status) {
case 'completed':
$status_class = 'notice-success';
break;
case 'failed':
$status_class = 'notice-error';
break;
case 'pending':
$status_class = 'notice-warning';
break;
}
?>
status)); ?>
|
payout_method)); ?> |
display_name); ?>
payout_method === 'automatic' ? __('System', 'wp-digital-download') : '-'; ?>
|
0) {
$creators = WPDD_Creator::get_creators_with_balance();
foreach ($creators as $creator) {
if (floatval($creator->balance) >= $threshold && !empty($creator->paypal_email)) {
self::create_payout($creator->ID);
}
}
}
} else {
// Process selected creators
$creator_ids = isset($_POST['creator_ids']) ? array_map('intval', $_POST['creator_ids']) : array();
foreach ($creator_ids as $creator_id) {
self::create_payout($creator_id);
}
}
wp_redirect(admin_url('edit.php?post_type=wpdd_product&page=wpdd-payouts&message=success'));
exit;
}
public static function create_payout($creator_id, $method = 'manual') {
global $wpdb;
$balance = WPDD_Creator::get_creator_balance($creator_id);
$paypal_email = get_user_meta($creator_id, 'wpdd_paypal_email', true);
if ($balance <= 0 || empty($paypal_email)) {
return false;
}
$currency = get_option('wpdd_currency', 'USD');
$current_user_id = get_current_user_id();
// Create payout record
$wpdb->insert(
$wpdb->prefix . 'wpdd_payouts',
array(
'creator_id' => $creator_id,
'amount' => $balance,
'currency' => $currency,
'paypal_email' => $paypal_email,
'status' => 'pending',
'payout_method' => $method,
'processed_by' => $current_user_id,
'created_at' => current_time('mysql')
),
array('%d', '%f', '%s', '%s', '%s', '%s', '%d', '%s')
);
$payout_id = $wpdb->insert_id;
// Try to process via PayPal API
$result = WPDD_PayPal_Payouts::process_payout($payout_id);
if ($result['success']) {
// Update payout status
$wpdb->update(
$wpdb->prefix . 'wpdd_payouts',
array(
'status' => 'completed',
'transaction_id' => $result['transaction_id'],
'processed_at' => current_time('mysql')
),
array('id' => $payout_id),
array('%s', '%s', '%s'),
array('%d')
);
// Reset creator balance
update_user_meta($creator_id, 'wpdd_creator_balance', 0);
return true;
} else {
// Update with error
$wpdb->update(
$wpdb->prefix . 'wpdd_payouts',
array(
'status' => 'failed',
'notes' => $result['error']
),
array('id' => $payout_id),
array('%s', '%s'),
array('%d')
);
return false;
}
}
public static function process_payout_request() {
if (!current_user_can('manage_options')) {
wp_die(__('You do not have permission to perform this action.', 'wp-digital-download'));
}
$payout_id = isset($_POST['payout_id']) ? intval($_POST['payout_id']) : 0;
if (!$payout_id || !wp_verify_nonce($_POST['wpdd_nonce'], 'wpdd_process_payout_request_' . $payout_id)) {
wp_redirect(admin_url('edit.php?post_type=wpdd_product&page=wpdd-payouts&message=error'));
exit;
}
global $wpdb;
// Get the payout request
$payout = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}wpdd_payouts WHERE id = %d AND status = 'requested'",
$payout_id
));
if (!$payout) {
wp_redirect(admin_url('edit.php?post_type=wpdd_product&page=wpdd-payouts&message=error'));
exit;
}
// Process via PayPal API
$result = WPDD_PayPal_Payouts::process_payout($payout_id);
if ($result['success']) {
// Update payout status
$wpdb->update(
$wpdb->prefix . 'wpdd_payouts',
array(
'status' => 'completed',
'transaction_id' => $result['transaction_id'],
'processed_by' => get_current_user_id(),
'processed_at' => current_time('mysql')
),
array('id' => $payout_id),
array('%s', '%s', '%d', '%s'),
array('%d')
);
wp_redirect(admin_url('edit.php?post_type=wpdd_product&page=wpdd-payouts&message=success'));
} else {
// Update with error
$wpdb->update(
$wpdb->prefix . 'wpdd_payouts',
array(
'status' => 'failed',
'notes' => $result['error']
),
array('id' => $payout_id),
array('%s', '%s'),
array('%d')
);
wp_redirect(admin_url('edit.php?post_type=wpdd_product&page=wpdd-payouts&message=error'));
}
exit;
}
public static function reject_payout_request() {
if (!current_user_can('manage_options')) {
wp_die(__('You do not have permission to perform this action.', 'wp-digital-download'));
}
$payout_id = isset($_POST['payout_id']) ? intval($_POST['payout_id']) : 0;
if (!$payout_id || !wp_verify_nonce($_POST['wpdd_nonce'], 'wpdd_reject_payout_request_' . $payout_id)) {
wp_redirect(admin_url('edit.php?post_type=wpdd_product&page=wpdd-payouts&message=error'));
exit;
}
global $wpdb;
// Get the payout request
$payout = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}wpdd_payouts WHERE id = %d AND status = 'requested'",
$payout_id
));
if (!$payout) {
wp_redirect(admin_url('edit.php?post_type=wpdd_product&page=wpdd-payouts&message=error'));
exit;
}
// Update status to failed/rejected
$wpdb->update(
$wpdb->prefix . 'wpdd_payouts',
array(
'status' => 'failed',
'notes' => 'Request rejected by administrator',
'processed_by' => get_current_user_id(),
'processed_at' => current_time('mysql')
),
array('id' => $payout_id),
array('%s', '%s', '%d', '%s'),
array('%d')
);
// Restore balance to creator
update_user_meta($payout->creator_id, 'wpdd_creator_balance', $payout->amount);
wp_redirect(admin_url('edit.php?post_type=wpdd_product&page=wpdd-payouts&message=success'));
exit;
}
public static function process_manual_payout() {
if (!current_user_can('manage_options') ||
!wp_verify_nonce($_POST['wpdd_nonce'], 'wpdd_manual_payout')) {
wp_die(__('Security check failed', 'wp-digital-download'));
}
$creator_id = intval($_POST['creator_id']);
$amount = floatval($_POST['payout_amount']);
$reason = sanitize_textarea_field($_POST['payout_reason']);
if (!$creator_id || $amount <= 0) {
wp_redirect(add_query_arg('message', 'error', wp_get_referer()));
exit;
}
$creator = get_userdata($creator_id);
if (!$creator || !in_array('wpdd_creator', $creator->roles)) {
wp_redirect(add_query_arg('message', 'error', wp_get_referer()));
exit;
}
$paypal_email = get_user_meta($creator_id, 'wpdd_paypal_email', true);
if (empty($paypal_email)) {
wp_redirect(add_query_arg('message', 'error', wp_get_referer()));
exit;
}
global $wpdb;
// Create the payout record
$result = $wpdb->insert(
$wpdb->prefix . 'wpdd_payouts',
array(
'creator_id' => $creator_id,
'amount' => $amount,
'currency' => get_option('wpdd_currency', 'USD'),
'paypal_email' => $paypal_email,
'status' => 'pending',
'payout_method' => 'manual',
'notes' => $reason,
'created_at' => current_time('mysql'),
'processed_by' => get_current_user_id()
),
array('%d', '%f', '%s', '%s', '%s', '%s', '%s', '%s', '%d')
);
if (!$result) {
wp_redirect(add_query_arg('message', 'error', wp_get_referer()));
exit;
}
$payout_id = $wpdb->insert_id;
// Try to process via PayPal
if (class_exists('WPDD_PayPal_Payouts')) {
$paypal_result = WPDD_PayPal_Payouts::process_payout($payout_id);
if (!$paypal_result) {
// Update status to failed
$wpdb->update(
$wpdb->prefix . 'wpdd_payouts',
array('status' => 'failed'),
array('id' => $payout_id),
array('%s'),
array('%d')
);
}
}
wp_redirect(add_query_arg('message', 'success', wp_get_referer()));
exit;
}
public static function adjust_creator_balance() {
if (!current_user_can('manage_options') ||
!wp_verify_nonce($_POST['wpdd_nonce'], 'wpdd_adjust_balance')) {
wp_die(__('Security check failed', 'wp-digital-download'));
}
$creator_id = intval($_POST['creator_id']);
$adjustment_type = sanitize_text_field($_POST['adjustment_type']);
$amount = floatval($_POST['adjustment_amount']);
$reason = sanitize_textarea_field($_POST['adjustment_reason']);
if (!$creator_id || $amount <= 0 || !in_array($adjustment_type, array('add', 'subtract'))) {
wp_redirect(add_query_arg('message', 'error', wp_get_referer()));
exit;
}
$creator = get_userdata($creator_id);
if (!$creator || !in_array('wpdd_creator', $creator->roles)) {
wp_redirect(add_query_arg('message', 'error', wp_get_referer()));
exit;
}
// Get current balance
$current_balance = floatval(get_user_meta($creator_id, 'wpdd_balance', true));
// Calculate new balance
if ($adjustment_type === 'add') {
$new_balance = $current_balance + $amount;
} else {
$new_balance = max(0, $current_balance - $amount); // Don't allow negative balance
}
// Update the balance
update_user_meta($creator_id, 'wpdd_balance', $new_balance);
// Create a record of this adjustment
global $wpdb;
$wpdb->insert(
$wpdb->prefix . 'wpdd_balance_adjustments',
array(
'creator_id' => $creator_id,
'adjustment_type' => $adjustment_type,
'amount' => $amount,
'previous_balance' => $current_balance,
'new_balance' => $new_balance,
'reason' => $reason,
'adjusted_by' => get_current_user_id(),
'created_at' => current_time('mysql')
),
array('%d', '%s', '%f', '%f', '%f', '%s', '%d', '%s')
);
wp_redirect(add_query_arg('message', 'balance_adjusted', wp_get_referer()));
exit;
}
}