Cancel a Stripe subscription auto renewal after first Payment -Wordpress - php

I have used stripe plugin and gravity form for payment in my WordPress site. Subscription payment transaction is working. Now I want to cancel auto renewal after one payment. I have used this code in my functions.php. I have added the
my feed name $feed_names = array( 'Stripe Feed 1' ); and set the count if ( $count == 1 ) { but its not working. I cant understand how to solve this? I have not used any other code of gravity form in functions.php.
LINK
add_action( 'gform_post_add_subscription_payment', function ( $entry ) {
if ( rgar( $entry, 'payment_status' ) == 'Active' ) {
$feed = gf_stripe()->get_payment_feed( $entry );
$feed_name = rgars( $feed, 'meta/feedName' );
$feed_names = array( 'Stripe Feed 1' ); // update this line
if ( in_array( $feed_name, $feed_names ) ) {
global $wpdb;
$count = $wpdb->get_var( $wpdb->prepare( "SELECT count(id) FROM {$wpdb->prefix}gf_addon_payment_transaction WHERE lead_id=%d", $entry['id'] ) );
if ( $count == 1 ) { // update this line
$result = gf_stripe()->cancel( $entry, $feed );
gf_stripe()->log_debug( "gform_post_add_subscription_payment: Cancelling subscription (feed #{$feed['id']} - {$feed_name}) for entry #{$entry['id']}. Result: " . print_r( $result, 1 ) );
}
}
}
} );
Stripe Feeds Name

Yes, this code is OK but I don't know where is your issue. I have a suggestion which is you can check the table {$wpdb->prefix}gf_addon_payment_transaction has been added data successfully while Subscription going on if your data has been added successfully then this add-on hook will work otherwise not because the table is empty.
How you check the data?
It's very easy you can just open up your database's table & check data exists or not.
You can check your Stripe add-on log for seeing what's going on.
Could try the following third-party add-on
You can check these necessary links
Creating a Stripe Feed
logging-and-debugging
theme/plugin conflict test
Note:
When testing you'll need to wait a day before cancelling the subscription to give Stripe time to capture the subscription payment and send the webhook.
I think will help.

Related

Woocommerce & Opayo: Add a custom field to the data sent to the API

Very specific issue but, I've been dragged onto an issue with our companies Payment Gateway on our Wordpress / Woocommerce website where we are using the Opayo Plugin (For Opayo Direct).
The issue is:
When originally setup, there was no template / option selected for the Reference field on the data / object sent to the API
The guys originally doing the website then tried contacting the original developer of this now unsupported plugin to which they was sent some code to put into another plugin named PHP Injection the code was similar to below:
add_filter( 'opayo_direct_custom_field_vendordata', 'my_opayo_direct_custom_field_vendordata', 10, 2 );
function my_opayo_direct_custom_field_vendordata ( $vendordata, $order ) {
// Get Order ID
$order_id = $order->get_order_number();
$reference = "test_" . $order_id;
// Get the reference field - set '_reference_field' to the meta_key from your order
if( isset( get_post_meta( $order_id, '_reference_field', TRUE ) ) ) {
$vendordata = get_post_meta( $order_id , '_reference_field', TRUE );
//$vendordata['_reference_field'] = $reference; ### Commented as I'm unsure if this is correct
}
return $vendordata;
}
After doing numerous testing and small changes, still nothing seems to be showing up in the Reference field in Opayo itself?
Please tell me someone has encountered this situation before or knows what I might be missing, it's been a while since I've touched PHP
First you mot use $order->get_order_number()when trying to get order meta data but use $order->get_id() with get_post_meta() function instead.
Now you can also use the WC_Data method get_meta() to be used on $order object variable.
What you need to find out is the key slug that you need to use to incorporate that custom field value to the vendor data via opayo_direct_custom_field_vendordata filter hook.
Try the following (where I use 'reference' as key slug, to be replaced with the right slug):
add_filter( 'opayo_direct_custom_field_vendordata', 'my_opayo_direct_custom_field_vendordata', 10, 2 );
function my_opayo_direct_custom_field_vendordata ( $vendor_data, $order ) {
$reference = $order->get_meta('_reference_field');
if ( ! empty($reference) ) {
$vendor_data['reference'] = $reference;
}
return $vendor_data;
}
or using get_post_meta() function:
add_filter( 'opayo_direct_custom_field_vendordata', 'my_opayo_direct_custom_field_vendordata', 10, 2 );
function my_opayo_direct_custom_field_vendordata ( $vendor_data, $order ) {
$reference = get_post_meta($order->get_id(), '_reference_field', true);
if ( ! empty($reference) ) {
$vendor_data['reference'] = $reference;
}
return $vendor_data;
}
It could better work…
Alright, so, I contacted Opayo myself to see what the Mapping was for the Reference column on the Opayo website and what data that is sent to the API is mapped to that Reference column in the table.
Apparently the value sent to the API that corresponds to this is the VendorData (Not required, 200 Char limit, free-text)
So, to fix this, I had to:
Open the Plugin Editor on Wordpress
Select the woocommerce-gateway-sagepay-form Plugin
Navigate and select the woocommerce-gateway-sagepay-form/classes/direct/sagepay-direct-request-class.php file
I then scrolled to Line 335 inside of the $end array, I then added the field of VendorData as seen by the code below:
$end = array(
"CustomerEMail" => $order->get_billing_email(),
"ClientIPAddress" => $this->get_ipaddress(),
"AccountType" => $this->accounttype,
"ReferrerID" => $this->referrerid,
"Website" => site_url(),
"VendorData" => '#######',
"Crypt" => MD5( $this->open_salt . $order->get_order_key() . $this->close_salt ),
);
And then set the ####### to the Value I needed to send to Opayo to show in the Reference column in the payments table.
Then just to be sure it wasn't going to get pruned (Again, not touched PHP for a while, I went to (NOW) Line 378 and commented it out, see below:
// Customiseable fields
$end['TransType'] = apply_filters( 'opayo_direct_custom_field_transtype', '01', $order );
//$end['VendorData'] = apply_filters( 'opayo_direct_custom_field_vendordata', '', $order );
Saving this, then when an Order / Purchase was made, the Reference field on Opayo's website was populated with what I set the VendorData to.
Quick Note: The VendorData field is max of 200 characters and only Aa or 0-9, I had a couple of failed attempts when I was trying to have _ until I searched the error I received on this page:
https://www.opayo.co.uk/support/error-codes?keyword=3189
I hope that my issue and resolution helps someone in the future and sorry for anyone's time I wasted!

How can I store the values from a WPForm in WordPress to a MySQL database?

How can I store the values from a WPForm in WordPress to a MySQL database?When we use WPForms where I have to add PHP part to store data? Can we store form data to tables when we are using free version of WPForms without buying it?
If you are using WP Forms Lite you can't do this directly, either you'll need to upgrade to PRO version or build your own custom save actions.
If you decide to go with your own custom version, some details below on how to intersect form submission on WP Forms.
WPForms has some actions you can use to do you own custom actions after form submission:
wpforms_process_complete
do_action( 'wpforms_process_complete', $this->fields, $entry, $form_data, $entry_id );
By using on your own template or plugin the wordpress hook add_action for any of the events described, you are able to get form data and do the handling you need.
Reference for wordpress add_action can be seen on the official documentation.
https://developer.wordpress.org/reference/functions/add_action/
Did a quick snippet that will help you get started:
add_action("wpforms_process_complete", 'function_save_custom_form_data');
function function_save_custom_form_data($params) {
foreach($params as $idx=>$item) {
$field_name = $item['name'];
$fiel_value = $item['value'];
// Do whatever you need
}
return true;
}
Please let me know if you need any further details.
WPForms store all form data in two tables within the native WordPress database. They are:
wp_wpforms_entries: In this table, the field values for entries are stored.
wp_wpforms_entry_meta: This table contains meta information about your entries such as IDs associated and the date that entries were submitted.
After publishing the form, make sure to add a form entry, so we can access the entry from your WordPress dashboard. Additionally, in your form builder, go to Settings » General and make sure that entry storing in WordPress is not disabled.
Create custom tables for example wpforms_entries and wpforms_entry_meta in your database to store form data. Use the provided action hook wpforms_process_complete to store the form entries.
add_action( 'wpforms_process_complete', 'process_entry', 5, 4 );
function process_entry( $form_fields, $entry, $form_data, $entry_id ) {
global $wpdb;
$form_id = $form_data['id'];
$entry_data = array(
'form_id' => $form_id,
'status' => 'publish',
'referer' => $_SERVER['HTTP_REFERER'],
'date_created' => current_time( 'mysql' )
);
// Insert into wpforms_entries custom table.
$success = $wpdb->insert( $wpdb->prefix . 'wpforms_entries', $entry_data );
$entry_id = $wpdb->insert_id;
// Create meta data.
if ( $entry_id ) {
foreach ( $form_fields as $field ) {
$field = apply_filters( 'wpforms_process_entry_field', $field, $form_data, $entry_id );
if ( isset( $field['value'] ) && '' !== $field['value'] ) {
$field_value = is_array( $field['value'] ) ? serialize( $field['value'] ) : $field['value'];
$entry_metadata = array(
'entry_id' => $entry_id,
'meta_key' => $field['name'],
'meta_value' => $field_value,
);
// Insert entry meta.
$wpdb->insert( $wpdb->prefix . 'wpforms_entrymeta', $entry_metadata );
}
}
}
}
Refrence: https://github.com/sanzeeb3/entries-for-wpforms/blob/master/includes/functions-wpfe-core.php#L59
Alternatively, the plugin itself is available: https://wordpress.org/plugins/entries-for-wpforms/
Free version of WPForms does not save the entry details captured in form. Therefore, you will need to write custom code to save the values in your custom DB table and then display them.
Below hook of WPForms can be used for saving data being entered in WPForms
/*hook to save entries coming from WPforms into database*/
add_action( 'wpforms_process_entry_save', array( $this, 'ank_wpforms_save_entries' ), 10, 4 );
public function ank_wpforms_save_entries( $fields, $entry, $form_id, $form_data ) {
//no need to sanitize data coming from WPForms as it is being sanitized in WPForms plugin before this hook using
//wpforms_process_validate_{$field_type} in class-process.php
$data = array();
$data['form_id'] = $form_id;
$data['entry_details'] = $fields;
//additional sanity checks are also performed while json encoding in "add" before adding in database
ank_wpforms_entry()->get_class_instance( 'entry-db' )->add( $data );
}
Alternatively , You can use this free plugin to save entries coming from WPForms into wordpress database and then display them in Wordpress Dashboard - https://wordpress.org/plugins/add-entries-functionality-to-wpforms/

Woocommerce Subscription access from external php

I have a Wordpress website with Woocommerce and Woocommerce Subscription plugins.
I need to write some PHP script that will check if a user has active subscription status.
From the database, I would like to get information: user id, status (if it's active - if payment was made and the subscription was renewed), end date of subscription...
The problem is that I don't even know where subscription info is saved?
Can somebody write me a snippet of code, that includes a query that will give me a list of users that subscribed, with the necessary information mentioned earlier?
I will post an update with code later, for now, I just need help with query and guidance where to look in the database tables.
I think what you meant is you want to access the Wordpress/Woocommerce Subscriptions API from a PHP file within your Wordpress installation. To do this I think the following will help:
Create a folder in wp-content/plugins called woocommerce-subscriptions-status-checker
Create a file called woocommerce-subscriptions-status-checker.php inside the above new folder.
Add this code in the file:
/*
Plugin Name: Woocommerce Subscriptions Status Checker
Plugin URI: http://www.XXXXXX.com
Description: XXXXXXXXX
Author: XXXXXX
Version: 2.0
Author URI: http://www.XXXXX.com
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class WC_Subscriptions_Status_Checker {
function __construct() {
// Avoids the function firing if we are in wp-admin backend
if ( !is_admin() ) {
// Fires on every page load after WordPress, all plugins, and the theme are fully loaded and instantiated
add_action( 'wp-loaded', array( $this, 'check_current_user' ) );
}
}
function check_current_user() {
// Check if user is even logged in, if not exit
if ( !is_user_logged_in() ) return;
$current_user = wp_get_current_user(); // get current WP_User
$user_id = $current_user->ID; // get user id
$is_subscription = wcs_user_has_subscription( $user_id ); // check if user has subscription
if ( $is_subscription )
{
$subscriptions = wcs_get_users_subscriptions( $user_id ); // get array of all subscriptions
// Check if there is one subscription or multiple subscriptions per user
if ( count( $subscriptions ) > 1 ) {
// Example if you wanted to loop through all subscriptions, in the case of the user having multiple subscriptions
foreach ( $subscriptions as $sub_id => $subscription ) {
if ( $subscription->get_status() == 'active' ) {
// Do something
}
}
} else { // Only 1 subscription
$subscription = reset( $subscriptions ); // gets first and only value
if ( $subscription->get_status() == 'active' ) {
// Do something
}
}
}
}
}
new WC_Subscriptions_Status_Checker();
Visit the plugins section of wp-admin and Activate your new plugin.
Here is my solution (not saying that it's the best, but for me, it solved the problem that I had).
Code in function.php (WP child theme)
add_action('init','getWPuser');
function getWPuser(){
$current_user = wp_get_current_user();
return $current_user;
}
Custom website
Code in my custom site that needs information about the user.
require_once '../wp-load.php';
require_once '../wp-content/themes/h-code-child/functions.php';
require_once '../wp-includes/pluggable.php';
require_once '../wp-blog-header.php';
$current_user = getWPuser();
Saving user ID information.
$logged_user_id = $current_user->ID;
Checking on specific subscription if it's active.
$has_free = wcs_user_has_subscription( $logged_user_id, $product_id, 'active' );
You can try Woocommerce REST API.
https://docs.woocommerce.com/document/woocommerce-rest-api/
Basically, Woocommerce provide a restful API to access the data and interact with the ecommerce system outside of the traditional woocommerce workflow.

Link between Gravity Forms and Woocommerce APIs

I have a Woocommerce site, and I use Gravity Forms to further expand each order.
I am coding a management tool that consumes both APIs to make some statistics and other administration tools.
I can get a list of the Gravity Forms entries, and also a list of the orders. The problem I have is that I don't know how can I get the entry that is related to a particular order.
Is there a way to do this?
have you tried with the woocomerce history plugin or fetching the raw metadata out the item¿?
wc_get_order_item_meta($order_item_id, "_gravity_forms_history");
wc_get_order_item_meta($order_item_id, "_gravity_form_data");
keep in mind that this will require a new endpoint to be created is not put of the box.
The last time I worked with the WooCommerce Gravity Forms Product Addons (a year or so ago) it did not store the order ID in the entry (would have to happen after the entry is created and after the order is created), or the entry ID in the order. The latter probably makes more sense but both would require custom code.
Again, it's been some time since I worked with the add-on. I'd ping WC support and see if they any tips on implementing support for this.
This is where I found the link between WooCommerce and the gravity forms product addon:
In the database, find the order in the table your_table_prefix_posts, and grab its ID. I was filtering for the post_type "shop_order."
In the table your_table_prefix_woocommerce_order_items, find the ID just found and filter for "line_item" in the "order_item_type" column, and grab the "order_item_id."
Use that "order_item_id" to find the order's meta in the table your_table_prefix_woocommerce_order_itemmeta.
All of the order's gravity forms data is in there. It looks like there is no actual tie between what woo does and gravity, except that the form is filled out and it data is grabbed and stuck into your_table_prefix_woocommerce_order_itemmeta. I cannot find anything that ties a particular order to a particular gf entry, but you can get the data from Woo, and at least use that to search GF entries.
I was able to do this using Gravity Forms, Gravity Forms Product Addons, and Woocommerce using a three step process:
STEP 1: Get GF Entry ID/s as the entry is made and store it in a session. This happens before checkout is complete and sometimes before the user is logged in.
add_action( 'gform_after_submission', 'blb_get_lead_entry_id', 10, 2 );
function blb_get_lead_entry_id( $entry, $form ) {
$meta_value = $entry['id'];
//session array with all the entries because GF creates 2 entries each time for validation purposes apparently
if (!isset($_SESSION['entryclump'])) {
$_SESSION['entryclump'] = array();
}
$_SESSION['entryclump'][] = $meta_value;
//also an array with just the current entry which will end up be the later of the two entries added by GF
$_SESSION[ 'gf-entry-id' ] = $meta_value;
}
STEP 2: Include the entry you just gathered ($_SESSION[ 'gf-entry-id' ]) with the Cart Item Meta and then save it.
In this case, i am saving a field called "_gf_entry_ID" which will get added to the woocommerce_order_itemmeta table with the correct order_item_id and the later of the two GF entries as the meta_value.
//add cart item data
add_filter( 'woocommerce_add_cart_item_data', 'blb_add_gfentry_to_cart_data', 10, 3 );
function blb_add_gfentry_to_cart_data( $cartItemData, $productId, $variationId ) {
$entryid=$_SESSION[ 'gf-entry-id' ];
$cartItemData['GFentryID'] = $entryid;
return $cartItemData;
unset($_SESSION[ 'gf-entry-id' ]);
}
//add cart item data: session stuff
add_filter( 'woocommerce_get_cart_item_from_session', 'blb_cart_item_session', 10, 3 );
function blb_cart_item_session( $cartItemData, $cartItemSessionData, $cartItemKey ) {
if ( isset( $cartItemSessionData['GFentryID'] ) ) {
$cartItemData['GFentryID'] = $cartItemSessionData['GFentryID'];
}
return $cartItemData;
}
//save the data
add_action( 'woocommerce_add_order_item_meta', 'blb_save_gfentry', 10, 3 );
function blb_save_gfentry( $itemId, $values, $key ) {
if ( isset( $values['GFentryID'] ) ) {
wc_add_order_item_meta( $itemId, '_gf_entry_ID', $values['GFentryID'] );
}
}
STEP 3 (optional): Update the GF Form to reflect the correct created_by user ID. Now that checkout is complete and the user is logged in, we can do that.
function blb_woocommerce_thankyou( $order_id ) {
//Current User
$currentUserID = wp_get_current_user()->ID;
//GF Entry Array for Order
$order = new WC_Order( $order_id );
$items = $order->get_items();
$order_item_ids = array();
$gf_entry_ids = array();
foreach ( $items as $key=>$item ) {
$gf_entry_ids[] = $item['item_meta']['_gf_entry_ID'][0];
}
//First real quick clear all the entries in the entry clump (in case the user was already logged in)
//This is important because GF creates two forms for product add ons with Woocommerce and we only want one to show up in the list and edit plugin
$entryclump = $_SESSION[ 'entryclump' ];
foreach ( $entryclump as $entry ) {
global $wpdb;
$wpdb->update('wp_rg_lead', array('created_by' => null), array('id' => $entry));
}
//Update wp_rg_lead
if (($currentUserID!=0) && (isset($_SESSION[ 'entryclump' ])) ) {
foreach ( $gf_entry_ids as $gf_entry_id ) {
global $wpdb;
$wpdb->update('wp_rg_lead', array('created_by' => $currentUserID), array('id' => $gf_entry_id));
} //foreach
} //if
unset($_SESSION[ 'entryclump' ]);
};
add_action( 'woocommerce_thankyou', 'blb_woocommerce_thankyou', 10, 1 );

Wordpress Contact Form 7 Database Unique ID

I need to create a payment form with redirect to Chronopay payment gate on wordpress. I try to make it with CF7 plugin with database extension.
How can I do next things:
1. Add unique ID and payment status to CF7 database strings. (I have added 2 fields to database and tried to change them with hook on wpcf7_before_send_mail).
function order_set_id($f) {
global $wpdb;
global $table_prefix;
$submit_time = $f->submit_time;
$title = $f->title;
if ('Taxy pick up' == $title ) {
$sql = "SELECT MAX(order_id) as mid FROM `wp_cf7dbplugin_submits`";
$var = $wpdb->get_results($wpdb->prepare($sql));
$neworder_id = $var[0]->mid;
$wpdb->update( 'wp_cf7dbplugin_submits',
array( 'order_id' => 0, 'order_payment' => 0 ),
array( 'submit_time' => $submit_time ),
array( '%s', '%d' ),
array( '%d' )
);
}}
add_action( 'wpcf7_before_send_mail', 'order_set_id');
But it doesn't work.
I need to display a hidden form as payment invoice after submittin a form. How can I do it?
How can I block sending email messages in Contact Form 7?
In the nearly past I wanted something similar. Found this two methods:
http://runastartup.com/integrate-paypal-button-with-contact-form-in-wordpress/
http://www.gobdg.com/blog/code-library/donation-form-using-contact-form-7-paypal/
Idea is on hold for now, but asap I will have free time, will decide which method to use.
Good luck! :)

Categories