I'm looking for some PHP logic code to process the payment for woocommerce order. My current logic is failling.
My scenario is customer places an online order on woocommerce enabled website by selecting braintree credit card payment method, enters credit card info and submits the order. The store receives the order until this stage, card payment is not authorized. Order may get changes as per their customers changes request or stores inability to process certain items from the order which is removed. Once order is finalized after changes, order is confirmed that is when I want to process the payment, capture the payment and settle it down. I have php code to process the payment, capture the payment amount and settle it down. But when I process the payment order is failing which I suspect due to lack of credit card information. How can I achieve the functionality?. I don't want to take customer to payment page and ask him or her to enter credit card info again.
NOTE: Woocommerce documentation states "Finally, you need to add payment code inside your process_payment( $order_id ) method. This takes the posted form data and attempts payment directly via the payment provider." (here the issue is how or where to find payment code?
Error message:Braintree (Credit Card) Payment Failed (Status code 91577, 81709, 81714, 81725, 81703: Merchant account does not support payment instrument., Expiration date is required., Credit card number is required., Credit card must include number, paymentMethodNonce, or venmoSdkPaymentMethodCode., Credit card type is not accepted by this merchant account.) Order status changed from On hold to Failed. (credit card info was entered during checkout)
Here is the code that actually failing
add_action( 'woocommerce_order_status_processing_to_on-hold', 'process_credit_card_authorize', 10, 2 );
function process_credit_card_authorize( $order_id, $order)
{
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
$result = $available_gateways[ 'braintree_credit_card' ]->process_payment( $order_id );
if ( $result['result'] == 'success' )
{
$result = apply_filters( 'woocommerce_payment_successful_result', $result, $order_id );
wp_redirect( $result['redirect'] );
exit;
}
}
Related
I am using the WooCommerce subscriptions plugin, in particular the woocommerce_subscription_payment_complete function.
I am using it like this:
add_action('woocommerce_subscription_payment_complete','subscription_created');
function subscription_created($subscription) {
echo 'Run when subscription payment is complete';
}
This works, but it also fires when a renewal payment completes. Does anybody know of a way to determine if the payment was for an initial subscription payment rather than a renewal?
You could use woocommerce_checkout_subscription_created, however the problem here is that it will fire before payment is processed - and I'm assuming you need to fire your even after payment has been successful.
One way to approach this is to set meta on the subscription post, that denotes whether your custom function has been run, and checking that meta with an if statement like this:
add_action('woocommerce_subscription_payment_complete','subscription_created');
function subscription_created($subscription) {
//check if meta exists/is not true
if (!get_post_meta($subscription->id, 'has_my_function_run', true)) {
//update meta to bool(true)
update_post_meta($subscription->id, 'has_my_function_run', true);
//run your function
echo 'Run when subscription payment is complete';
}
}
I am sure there is a better way to approach this though, so keep an eye out for other answers. It might be a good idea to look into hooking into woocommerce_order_status_processing, checking if it contains a subscription product, and then running your function, but that won't work if WooCommerce generates a new order for every subscription renewal.
I am using woocommerce plugin to checkout orders using paypal method. But issue is that when payment is done then orders status should moved to processing but it is still showing pending. So how to do that. I want order status should move automatically to processing once payment is done using paypal.
Insert this below code in your function.php. This code change order status pending to processing once payment is completed.
add_filter( 'woocommerce_payment_complete_order_status', 'custom_update_order_status', 10, 2 );
function custom_update_order_status( $order_status, $order_id ) {
return 'processing';
}
I am working on a project where a user would purchase a subscription and when they do we send data to another server using API calls. Once the server receives the necessary information it creates a serial number and sends it back to the woocommerce site.
This all works just fine, I am successful in sending data and retrieving serial numbers and synchronizing most things on the server.
I am stuck at when Woo Subscriptions renews their order I need to update information on the other server regarding the serial number. I think I would be fine if I could get access to the original order number.
The other issue I am running into is determining if the order is in fact a renewal order, I have a trivial flag set up that checks if "subscription_interval" is inside of the order->get_items, if not then its a renewal order. Something is just fishy about this whole thing.
Basically I need a way to find out if it is a renewal order and if it is give me the initial order number.
Looking at the order screen on the very bottom of the metaboxes (advanced) there is a metabox that shows "Related Subscription Orders" and even shows the initial order. How can I access this data?
Thanks in advance!
Ok, so I found WC_Subscriptions_Renewal_Order and ran a get_class_methods on it. I found is_renewal and get_parent_order_id, life is good again :)
Maybe this can help someone else looking for a way to find out the original order ID by the subscription ID.
function my_get_original_order_id_by_subscription_id( $sub_id ){
$sub_post = get_post( $sub_id );
if( $sub_post && is_object( $sub_post ) && isset( $sub_post->post_parent ) && absint( $sub_post->post_parent ) > 0 ){
return $sub_post->post_parent;
}
return false;
}
The solution is very simple. You need just to get the object post related to the subscription ID ($sub_id), and then the post_parent is the ID of the original order that you were looking for.
i was working in a wordpress registration plugin. i stucked in expiry of the user. actually i want to expire the member after one year of his/her registration. and i want to notify them via email before 1 month of their expiry. i am using add_action('init','my function name') to check how many of the user is going to expire after a month and also to send the mail. bt this action hook will run every time a user visits the site which will make my site too slow to load everytime a user will visit. so i want something dat will make this code run once in a day. e.g. when the first user visit the site this code will run and for the whole remaining day this code will not be invoke no matter how many user will visit the website.
Wordpress has a built-in function/API that just do exactly what you want - doing something every day/hour/any interval you specify.
http://codex.wordpress.org/Function_Reference/wp_schedule_event
Taken shamelessly from the above page
add_action( 'wp', 'prefix_setup_schedule' );
/**
* On an early action hook, check if the hook is scheduled - if not, schedule it.
*/
function prefix_setup_schedule() {
if ( ! wp_next_scheduled( 'prefix_daily_event' ) ) {
wp_schedule_event( time(), 'daily', 'prefix_daily_event');
}
}
add_action( 'prefix_daily_event', 'prefix_do_this_daily' );
/**
* On the scheduled action hook, run a function.
*/
function prefix_do_this_daily() {
// check every user and see if their account is expiring, if yes, send your email.
}
prefix_ is presumably to ensure there will be no collision with other plugins, so I suggest you to change this to something unique.
See http://wp.tutsplus.com/articles/insights-into-wp-cron-an-introduction-to-scheduling-tasks-in-wordpress/ if you want to know more.
I have a WooCommerce shop (running local) but I want to remove the payment gateways. The customer should be able to place an order without paying any cent, I will send them an invoice manually.
I can not really find where to disable this, it seems not to be standard in WooCommerce.
Have tried disabling all the payment gateways in the backend, but you have to leave one payment gateway enabled.
Thanks in advance!
Just add this line in functions.php in your theme:
add_filter('woocommerce_cart_needs_payment', '__return_false');
Leave 'Cash on Delivery' enabled, and it won't take a payment at the checkout. You can easily change the 'Cash on Delivery' titles and labels to something like 'No Payment Required' or similar.
Something that the other answers to this question haven't addressed is the fact that you need a way for the customer to eventually pay the invoice. Using Cash on Delivery (renamed to suit your needs) perfectly accomplishes not having the user actually pay at checkout, but the problem is that if Cash on Delivery was your only payment method, it will still be the only payment method when you send them the invoice.
I think in most cases you're going to want only cash on delivery during the cart checkout, and a different payment method (like Stripe) for the invoice payment method.
Here's the full workflow to create a deferred payment setup.
Like #crdunst mentions, you should use Cash on Delivery and rename
it to "Wait for Invoice" or something.
Enable all of the payment gateways that you ever want to use (in this example, we'll just use Cash on Delivery and Stripe. Cash on Delivery will be our "checkout" payment gateway, and Stripe will be our invoice payment gateway.
Use the following filter to turn on and off gateways based on whether or not you're on the order-pay endpoint (the page used for invoice payments).
/**
* Only show Cash on Delivery for checkout, and only Stripe for order-pay
*
* #param array $available_gateways an array of the enabled gateways
* #return array the processed array of enabled gateways
*/
function so1809762_set_gateways_by_context($available_gateways) {
global $woocommerce;
$endpoint = $woocommerce->query->get_current_endpoint();
if ($endpoint == 'order-pay') {
unset($available_gateways['cod']);
} else {
unset($available_gateways['stripe']);
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'so1809762_set_gateways_by_context');
Of course, if you're using a gateway other than stripe for the order-pay page, you'll want to make sure that you update unset($available_gateways['stripe']); to the proper array key.
After that, you should be good to go! Your site will now display different gateways based on whether or not you're on the invoice pay page!
Other option would be using BACS payment method, where you could explain the client that he will be invoiced later.
You can even add some info at the email that is sent when BACS is used.