First Commit

This commit is contained in:
2025-08-28 19:35:28 -07:00
commit 264e65006a
488 changed files with 155661 additions and 0 deletions

View File

@@ -0,0 +1,231 @@
<?php
if (!defined('ABSPATH')) {
exit;
}
class WPDD_PayPal_Payouts {
public static function init() {
// Schedule cron event for automatic payouts
if (!wp_next_scheduled('wpdd_process_automatic_payouts')) {
wp_schedule_event(time(), 'daily', 'wpdd_process_automatic_payouts');
}
add_action('wpdd_process_automatic_payouts', array(__CLASS__, 'process_automatic_payouts'));
}
public static function process_automatic_payouts() {
$threshold = floatval(get_option('wpdd_payout_threshold', 0));
if ($threshold <= 0) {
return;
}
$creators = WPDD_Creator::get_creators_with_balance();
foreach ($creators as $creator) {
if (floatval($creator->balance) >= $threshold && !empty($creator->paypal_email)) {
WPDD_Admin_Payouts::create_payout($creator->ID, 'automatic');
}
}
}
public static function process_payout($payout_id) {
global $wpdb;
// Get payout details
$payout = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}wpdd_payouts WHERE id = %d",
$payout_id
));
if (!$payout) {
return array('success' => false, 'error' => 'Payout not found');
}
// Get PayPal credentials
$mode = get_option('wpdd_paypal_mode', 'sandbox');
$client_id = get_option('wpdd_paypal_client_id');
$secret = get_option('wpdd_paypal_secret');
if (empty($client_id) || empty($secret)) {
return array('success' => false, 'error' => 'PayPal credentials not configured');
}
// Get access token
$token_result = self::get_access_token($client_id, $secret, $mode);
if (!$token_result['success']) {
return array('success' => false, 'error' => $token_result['error']);
}
$access_token = $token_result['token'];
// Create payout batch
$batch_result = self::create_payout_batch($payout, $access_token, $mode);
if ($batch_result['success']) {
return array(
'success' => true,
'transaction_id' => $batch_result['batch_id']
);
} else {
return array(
'success' => false,
'error' => $batch_result['error']
);
}
}
private static function get_access_token($client_id, $secret, $mode) {
$base_url = $mode === 'sandbox'
? 'https://api-m.sandbox.paypal.com'
: 'https://api-m.paypal.com';
$response = wp_remote_post(
$base_url . '/v1/oauth2/token',
array(
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($client_id . ':' . $secret),
'Content-Type' => 'application/x-www-form-urlencoded'
),
'body' => 'grant_type=client_credentials',
'timeout' => 30
)
);
if (is_wp_error($response)) {
return array('success' => false, 'error' => $response->get_error_message());
}
$body = json_decode(wp_remote_retrieve_body($response), true);
if (isset($body['access_token'])) {
return array('success' => true, 'token' => $body['access_token']);
} else {
$error = isset($body['error_description']) ? $body['error_description'] : 'Failed to get access token';
return array('success' => false, 'error' => $error);
}
}
private static function create_payout_batch($payout, $access_token, $mode) {
$base_url = $mode === 'sandbox'
? 'https://api-m.sandbox.paypal.com'
: 'https://api-m.paypal.com';
$batch_id = 'WPDD_' . $payout->id . '_' . time();
$payout_data = array(
'sender_batch_header' => array(
'sender_batch_id' => $batch_id,
'email_subject' => 'You have received a payout!',
'email_message' => 'You have received a payout from ' . get_bloginfo('name')
),
'items' => array(
array(
'recipient_type' => 'EMAIL',
'amount' => array(
'value' => number_format($payout->amount, 2, '.', ''),
'currency' => $payout->currency
),
'receiver' => $payout->paypal_email,
'note' => 'Payout for your sales on ' . get_bloginfo('name'),
'sender_item_id' => 'payout_' . $payout->id
)
)
);
$response = wp_remote_post(
$base_url . '/v1/payments/payouts',
array(
'headers' => array(
'Authorization' => 'Bearer ' . $access_token,
'Content-Type' => 'application/json'
),
'body' => json_encode($payout_data),
'timeout' => 30
)
);
if (is_wp_error($response)) {
return array('success' => false, 'error' => $response->get_error_message());
}
$response_code = wp_remote_retrieve_response_code($response);
$body = json_decode(wp_remote_retrieve_body($response), true);
if ($response_code === 201 && isset($body['batch_header']['payout_batch_id'])) {
return array(
'success' => true,
'batch_id' => $body['batch_header']['payout_batch_id']
);
} else {
$error = 'Failed to create payout batch';
if (isset($body['message'])) {
$error = $body['message'];
} elseif (isset($body['error_description'])) {
$error = $body['error_description'];
}
return array('success' => false, 'error' => $error);
}
}
public static function check_batch_status($batch_id, $mode = null) {
if (!$mode) {
$mode = get_option('wpdd_paypal_mode', 'sandbox');
}
$client_id = get_option('wpdd_paypal_client_id');
$secret = get_option('wpdd_paypal_secret');
if (empty($client_id) || empty($secret)) {
return array('success' => false, 'error' => 'PayPal credentials not configured');
}
// Get access token
$token_result = self::get_access_token($client_id, $secret, $mode);
if (!$token_result['success']) {
return array('success' => false, 'error' => $token_result['error']);
}
$access_token = $token_result['token'];
$base_url = $mode === 'sandbox'
? 'https://api-m.sandbox.paypal.com'
: 'https://api-m.paypal.com';
$response = wp_remote_get(
$base_url . '/v1/payments/payouts/' . $batch_id,
array(
'headers' => array(
'Authorization' => 'Bearer ' . $access_token,
'Content-Type' => 'application/json'
),
'timeout' => 30
)
);
if (is_wp_error($response)) {
return array('success' => false, 'error' => $response->get_error_message());
}
$body = json_decode(wp_remote_retrieve_body($response), true);
if (isset($body['batch_header'])) {
return array(
'success' => true,
'status' => $body['batch_header']['batch_status'],
'data' => $body
);
} else {
return array('success' => false, 'error' => 'Failed to get batch status');
}
}
public static function deactivate() {
wp_clear_scheduled_hook('wpdd_process_automatic_payouts');
}
}