Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PO-201 webhook cron for gravity forms #85

Merged
merged 6 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 85 additions & 9 deletions class-gf-razorpay.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ class GFRazorpay extends GFPaymentAddOn
const CUSTOMER_FIELDS_EMAIL = 'email';
const CUSTOMER_FIELDS_CONTACT = 'contact';

/**
* Order status for rzp_gf_webhook_triggers table
*/
const RZP_ORDER_CREATED = 0;
const RZP_ORDER_PROCESSED_BY_CALLBACK = 1;

// TODO: Check if all the variables below are needed

/**
Expand Down Expand Up @@ -313,6 +319,22 @@ public function callback()
$action['error'] = null;
}

// update order status in webhook table
global $wpdb;

require_once(ABSPATH . '/wp-admin/includes/upgrade.php');

$wpdb->update(
$wpdb->prefix . 'rzp_gf_webhook_triggers',
array(
'rzp_update_order_cron_status' => self::RZP_ORDER_PROCESSED_BY_CALLBACK
),
array(
'order_id' => $entryId,
'rzp_order_id' => $razorpayOrderId
)
);

return $action;
}

Expand Down Expand Up @@ -431,6 +453,26 @@ public function generate_razorpay_form($entry, $form)
$this->auto_enable_webhook();
}

// insert record in webhook table
global $wpdb;

require_once(ABSPATH . '/wp-admin/includes/upgrade.php');

$tableName = $wpdb->prefix . 'rzp_gf_webhook_triggers';
$webhookEvents = $wpdb->get_results("SELECT * FROM $tableName WHERE order_id=" . $entry['id'] . ";");
if (empty($webhookEvents) === true)
{
$wpdb->insert(
$tableName,
array(
'order_id' => $entry['id'],
'rzp_order_id' => $entry[self::RAZORPAY_ORDER_ID],
'rzp_webhook_data' => '[]',
'rzp_update_order_cron_status' => self::RZP_ORDER_CREATED
)
);
}

$feed = $this->get_payment_feed($entry, $form);

$customerFields = $this->get_customer_fields($form, $feed, $entry);
Expand Down Expand Up @@ -790,40 +832,74 @@ public function process_webhook()
return;
}

switch ($data['event'])
if (in_array($data['event'], $this->supportedWebhookEvents) === true)
{
case self::ORDER_PAID:
return $this->order_paid($data);
$webhookFilteredData = [
'gravity_forms_order_id' => $data['payload']['payment']['entity']['notes']['gravity_forms_order_id'],
'razorpay_payment_id' => $data['payload']['payment']['entity']['id'],
'amount' => $data['payload']['payment']['entity']['amount'],
'event' => $data['event']
];

default:
return;
global $wpdb;

require_once(ABSPATH . '/wp-admin/includes/upgrade.php');

$tableName = $wpdb->prefix . 'rzp_gf_webhook_triggers';

$webhookEvents = $wpdb->get_results("SELECT rzp_webhook_data FROM $tableName where order_id=" . $webhookFilteredData['gravity_forms_order_id'] . ";");

$rzpWebhookData = (array) json_decode($webhookEvents['rzp_webhook_data']);

$rzpWebhookData[] = $webhookFilteredData;

$wpdb->update(
$tableName,
array(
'rzp_webhook_data' => json_encode($rzpWebhookData),
'rzp_webhook_notified_at' => time()
),
array(
'order_id' => $webhookFilteredData['gravity_forms_order_id'],
'rzp_order_id' => $data['payload']['payment']['entity']['order_id']
)
);
}
else
{
$log = array(
'message' => "webhook event ". $data['event'] . " is not supported.",
);

error_log(json_encode($log));
}
}
}
}

/**
* [order_paid Consume 'order.paid' webhook payload for order processing]
* @param [array] $data [webhook payload]
* @return [type] [description]
*/
private function order_paid($data)
public function order_paid($data)
{
$entry_id = $data['payload']['payment']['entity']['notes']['gravity_forms_order_id'];
$entry_id = $data['gravity_forms_order_id'];

if(empty($entry_id) === false)
{
$entry = GFAPI::get_entry($entry_id);

if(is_array($entry) === true)
{
$razorpay_payment_id = $data['payload']['payment']['entity']['id'];
$razorpay_payment_id = $data['razorpay_payment_id'];

//check the payment status not set
if ((empty($entry['payment_status']) === true) or
(strtolower($entry['payment_status']) !== 'paid'))
{
//check for valid amount
$payment_amount = $data['payload']['payment']['entity']['amount'];
$payment_amount = $data['amount'];

$order_amount = (int) round(rgar($entry, 'payment_amount' ) * 100);

Expand Down
97 changes: 97 additions & 0 deletions razorpay.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@

add_action('admin_post_nopriv_gf_razorpay_webhook', "gf_razorpay_webhook_init", 10);
add_action('gform_loaded', array('GF_Razorpay_Bootstrap', 'load'), 5);
add_action('plugins_loaded', 'createRzpWebhookTables');
add_action('rzp_gf_webhook_exec_cron', 'execRzpWebhookEvents');

add_filter('cron_schedules','rzpCronSchedules');

class GF_Razorpay_Bootstrap
{
Expand Down Expand Up @@ -87,3 +91,96 @@ function gf_razorpay_webhook_init()
$gf_razorpay->process_webhook();
}

function createRzpWebhookTables()
{
$installedVersion = get_option('GF_RAZORPAY_VERSION');

if ($installedVersion !== GF_RAZORPAY_VERSION)
{
// create table to save webhook events
global $wpdb;

require_once(ABSPATH . '/wp-admin/includes/upgrade.php');

$charset_collate = $wpdb->get_charset_collate();

$sql = "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}rzp_gf_webhook_triggers` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`order_id` int(11) NOT NULL,
`rzp_order_id` varchar(25) NOT NULL,
`rzp_webhook_data` text,
`rzp_webhook_notified_at` varchar(30),
`rzp_update_order_cron_status` int(11) DEFAULT 0,
PRIMARY KEY (`id`)) $charset_collate;";

if (empty(dbDelta($sql)) === false)
{
update_option('GF_RAZORPAY_VERSION', GF_RAZORPAY_VERSION);
}

// create razorpay GF cron
createRzpCron('rzp_gf_webhook_exec_cron', time(), 'rzp_gf_webhook_cron_interval');
}
}

function rzpCronSchedules($schedules)
{
if (isset($schedules["rzp_gf_webhook_cron_interval"]) === false)
{
$schedules["rzp_gf_webhook_cron_interval"] = array(
'interval' => 5 * 60,
'display' => __('Every 5 minutes'));
}

return $schedules;
}

function createRzpCron($hookName, $startTime, $recurrence)
{
if (wp_next_scheduled($hookName) === false)
{
wp_schedule_event($startTime, $recurrence, $hookName);
}
}

function execRzpWebhookEvents()
{
global $wpdb;

require_once(ABSPATH . '/wp-admin/includes/upgrade.php');

$rzp_order_processed_by_webhook = 2;
$tableName = $wpdb->prefix . 'rzp_gf_webhook_triggers';

$webhookEvents = $wpdb->get_results("SELECT order_id, rzp_order_id, rzp_webhook_data FROM $tableName WHERE rzp_webhook_notified_at < " . (string)(time() - 300) ." AND rzp_update_order_cron_status=0;");

foreach ($webhookEvents as $row)
{
$events = json_decode($row->rzp_webhook_data);
foreach ($events as $event)
{
$event = (array) $event;
switch ($event['event'])
{
case 'order.paid':
$gf_razorpay = gf_razorpay();
$gf_razorpay->order_paid($event);

$wpdb->update(
$tableName,
array(
'rzp_update_order_cron_status' => $rzp_order_processed_by_webhook
),
array(
'order_id' => $row->order_id,
'rzp_order_id' => $row->rzp_order_id
)
);
return;

default:
return;
}
}
}
}