Last active
May 28, 2025 02:25
-
-
Save shameemreza/29ec213e9baec25774711d89858d3124 to your computer and use it in GitHub Desktop.
Solution for WooCommerce Stripe iDEAL Refund
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Solution for WooCommerce Stripe iDEAL Refund | |
* | |
* This code adds a "Refund via iDEAL" button to WooCommerce orders paid with iDEAL, | |
* even when the Stripe gateway isn't properly registered. | |
*/ | |
add_action('woocommerce_order_item_add_action_buttons', function($order) { | |
if ($order->get_payment_method() !== 'stripe_ideal') { | |
return; | |
} | |
$amount = $order->get_remaining_refund_amount(); | |
if ($amount <= 0) { | |
return; | |
} | |
// Format the amount for display | |
$formatted_amount = strip_tags(wp_kses_post(wc_price($amount))); | |
// Create a nonce for security | |
$nonce = wp_create_nonce('ideal-refund'); | |
// Add the iDEAL refund button | |
?> | |
<button type="button" class="button button-primary ideal-refund-button" style="margin-left: 10px;"> | |
Refund <?php echo wc_price($amount); ?> via iDEAL | |
</button> | |
<!-- Custom modal dialog --> | |
<div id="ideal-refund-modal" style="display: none; position: fixed; z-index: 9999; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0,0,0,0.4);"> | |
<div style="background-color: #fefefe; margin: 15% auto; padding: 20px; border: 1px solid #888; width: 400px; border-radius: 4px; box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);"> | |
<h3 style="margin-top: 0;">Confirm iDEAL Refund</h3> | |
<p>Are you sure you want to refund <?php echo $formatted_amount; ?> via iDEAL?</p> | |
<div style="text-align: right; margin-top: 20px;"> | |
<button id="cancel-ideal-refund" class="button" style="margin-right: 10px;">Cancel</button> | |
<button id="confirm-ideal-refund" class="button button-primary">Confirm Refund</button> | |
</div> | |
</div> | |
</div> | |
<script type="text/javascript"> | |
jQuery(document).ready(function($) { | |
// Show the modal when the refund button is clicked | |
$('.ideal-refund-button').on('click', function(e) { | |
e.preventDefault(); | |
$('#ideal-refund-modal').show(); | |
}); | |
// Hide the modal when Cancel is clicked | |
$('#cancel-ideal-refund').on('click', function() { | |
$('#ideal-refund-modal').hide(); | |
}); | |
// Process the refund when Confirm is clicked | |
$('#confirm-ideal-refund').on('click', function() { | |
// Change button text and disable | |
$(this).prop('disabled', true).text('Processing...'); | |
$('#cancel-ideal-refund').prop('disabled', true); | |
// Process the refund | |
var data = { | |
action: 'process_ideal_refund', | |
order_id: <?php echo $order->get_id(); ?>, | |
amount: <?php echo $amount; ?>, | |
security: '<?php echo $nonce; ?>' | |
}; | |
$.post(ajaxurl, data, function(response) { | |
if (response.success) { | |
// Show success message and reload | |
$('#ideal-refund-modal').html( | |
'<div style="background-color: #fefefe; margin: 15% auto; padding: 20px; border: 1px solid #888; width: 400px; border-radius: 4px; box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);">' + | |
'<h3 style="margin-top: 0; color: #46b450;">Refund Successful</h3>' + | |
'<p>Refund of <?php echo $formatted_amount; ?> via iDEAL has been processed successfully.</p>' + | |
'<div style="text-align: right; margin-top: 20px;">' + | |
'<button id="close-ideal-refund" class="button button-primary">Close</button>' + | |
'</div>' + | |
'</div>' | |
); | |
$('#close-ideal-refund').on('click', function() { | |
window.location.reload(); | |
}); | |
} else { | |
// Show error message | |
$('#ideal-refund-modal').html( | |
'<div style="background-color: #fefefe; margin: 15% auto; padding: 20px; border: 1px solid #888; width: 400px; border-radius: 4px; box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);">' + | |
'<h3 style="margin-top: 0; color: #dc3232;">Refund Failed</h3>' + | |
'<p>' + response.data + '</p>' + | |
'<div style="text-align: right; margin-top: 20px;">' + | |
'<button id="close-ideal-refund" class="button button-primary">Close</button>' + | |
'</div>' + | |
'</div>' | |
); | |
$('#close-ideal-refund').on('click', function() { | |
$('#ideal-refund-modal').hide(); | |
}); | |
} | |
}); | |
}); | |
// Close modal if clicked outside | |
$(window).on('click', function(e) { | |
if ($(e.target).is('#ideal-refund-modal')) { | |
$('#ideal-refund-modal').hide(); | |
} | |
}); | |
}); | |
</script> | |
<?php | |
}, 20); | |
// Process the AJAX refund request | |
add_action('wp_ajax_process_ideal_refund', function() { | |
// Check security | |
if (!check_ajax_referer('ideal-refund', 'security', false)) { | |
wp_send_json_error('Security check failed'); | |
} | |
// Get order and amount | |
$order_id = isset($_POST['order_id']) ? intval($_POST['order_id']) : 0; | |
$amount = isset($_POST['amount']) ? floatval($_POST['amount']) : 0; | |
if (!$order_id || !$amount) { | |
wp_send_json_error('Invalid order or amount'); | |
} | |
$order = wc_get_order($order_id); | |
if (!$order) { | |
wp_send_json_error('Order not found'); | |
} | |
try { | |
// Process the refund | |
$refund = wc_create_refund([ | |
'amount' => $amount, | |
'reason' => 'Refund via iDEAL', | |
'order_id' => $order_id, | |
'refund_payment' => true | |
]); | |
if (is_wp_error($refund)) { | |
wp_send_json_error($refund->get_error_message()); | |
} | |
// Add a note | |
$order->add_order_note('Refund processed via iDEAL: ' . wc_price($amount)); | |
wp_send_json_success(); | |
} catch (Exception $e) { | |
wp_send_json_error($e->getMessage()); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment