Razorpay for WooCommerce - Version 4.0.0

Version Description

  • Added support for CartBounty plugin in magic checkout.
  • Added debug log config on native checkout flow.
Download this release

Release Info

Developer razorpay
Plugin Icon 128x128 Razorpay for WooCommerce
Version 4.0.0
Comparing to
See all releases

Code changes from version 3.9.4 to 4.0.0

includes/api/api.php CHANGED
@@ -200,14 +200,7 @@ function addMagicCheckoutSettingFields(&$defaultFormFields)
200
  'description' => "To track orders using Facebook Pixel",
201
  'label' => __('Activate Magic Checkout Facebook Analytics'),
202
  'default' => 'no',
203
- ),
204
- 'enable_1cc_debug_mode' => array(
205
- 'title' => __('Activate debug mode'),
206
- 'type' => 'checkbox',
207
- 'description' => 'When debug mode is active, API logs and errors are collected and stored in your Woocommerce dashboard. It is recommended to keep this activated.',
208
- 'label' => __('Enable debug mode for Magic Checkout'),
209
- 'default' => 'yes',
210
- ),
211
  );
212
 
213
  $defaultFormFields = array_merge($defaultFormFields, $magicCheckoutConfigFields);
200
  'description' => "To track orders using Facebook Pixel",
201
  'label' => __('Activate Magic Checkout Facebook Analytics'),
202
  'default' => 'no',
203
+ )
 
 
 
 
 
 
 
204
  );
205
 
206
  $defaultFormFields = array_merge($defaultFormFields, $magicCheckoutConfigFields);
includes/api/order.php CHANGED
@@ -84,9 +84,8 @@ function createWcOrder(WP_REST_Request $request)
84
  return new WP_REST_Response($response, $statusCode);
85
  }
86
 
87
- $cartHash = WC()->cart->get_cart_hash();
88
-
89
- $orderIdFromHash = $woocommerce->session->get(RZP_1CC_CART_HASH . $cartHash);
90
 
91
  if ($orderIdFromHash == null) {
92
  $checkout = WC()->checkout();
@@ -100,7 +99,6 @@ function createWcOrder(WP_REST_Request $request)
100
  } else {
101
  $existingOrder = wc_get_order($orderIdFromHash);
102
  $existingOrder->calculate_totals();
103
-
104
  if ($existingOrder->needs_payment() == false) {
105
  $woocommerce->session->__unset(RZP_1CC_CART_HASH . $cartHash);
106
  $checkout = WC()->checkout();
@@ -112,8 +110,7 @@ function createWcOrder(WP_REST_Request $request)
112
  //Keep order in draft status untill customer info available
113
  updateOrderStatus($orderId, 'draft');
114
  } else {
115
- $orderId = $woocommerce->session->get(RZP_1CC_CART_HASH . $cartHash);
116
-
117
  //To get the applied coupon details from cart object.
118
  $coupons = WC()->cart->get_coupons();
119
  $couponCode = !empty($coupons) ? array_key_first($coupons) : null;
@@ -242,6 +239,7 @@ function createWcOrder(WP_REST_Request $request)
242
 
243
  $woocommerce->session->set(RZP_1CC_CART_HASH . $cartHash, $orderId);
244
  set_transient(RZP_1CC_CART_HASH . $orderId, $cartHash, 3600);
 
245
  set_transient($razorpay::SESSION_KEY, $orderId, 3600);
246
 
247
  $logObj['response'] = $response;
84
  return new WP_REST_Response($response, $statusCode);
85
  }
86
 
87
+ $cartHash = WC()->cart->get_cart_hash();
88
+ $orderIdFromHash = get_transient(RZP_1CC_CART_HASH . $cartHash);
 
89
 
90
  if ($orderIdFromHash == null) {
91
  $checkout = WC()->checkout();
99
  } else {
100
  $existingOrder = wc_get_order($orderIdFromHash);
101
  $existingOrder->calculate_totals();
 
102
  if ($existingOrder->needs_payment() == false) {
103
  $woocommerce->session->__unset(RZP_1CC_CART_HASH . $cartHash);
104
  $checkout = WC()->checkout();
110
  //Keep order in draft status untill customer info available
111
  updateOrderStatus($orderId, 'draft');
112
  } else {
113
+ $orderId = $orderIdFromHash;
 
114
  //To get the applied coupon details from cart object.
115
  $coupons = WC()->cart->get_coupons();
116
  $couponCode = !empty($coupons) ? array_key_first($coupons) : null;
239
 
240
  $woocommerce->session->set(RZP_1CC_CART_HASH . $cartHash, $orderId);
241
  set_transient(RZP_1CC_CART_HASH . $orderId, $cartHash, 3600);
242
+ set_transient(RZP_1CC_CART_HASH . $cartHash, $orderId, 3600);
243
  set_transient($razorpay::SESSION_KEY, $orderId, 3600);
244
 
245
  $logObj['response'] = $response;
includes/api/save-abandonment-data.php CHANGED
@@ -3,6 +3,8 @@
3
  * For abandon cart recovery related API
4
  */
5
 
 
 
6
  function saveCartAbandonmentData(WP_REST_Request $request)
7
  {
8
  global $woocommerce;
@@ -31,7 +33,6 @@ function saveCartAbandonmentData(WP_REST_Request $request)
31
 
32
  return new WP_REST_Response($response, $statusCode);
33
  }
34
-
35
  if (isset($razorpayData['receipt'])) {
36
  $wcOrderId = $razorpayData['receipt'];
37
 
@@ -63,6 +64,14 @@ function saveCartAbandonmentData(WP_REST_Request $request)
63
  return new WP_REST_Response($result['response'], $result['status_code']);
64
  }
65
 
 
 
 
 
 
 
 
 
66
  if (is_plugin_active('klaviyo/klaviyo.php') && empty($razorpayData['customer_details']['email']) == false) {
67
  WC()->cart->empty_cart();
68
  $cart1cc = create1ccCart($wcOrderId);
@@ -131,9 +140,8 @@ function saveWooAbandonmentCartLiteData($razorpayData, $wcOrderId)
131
  $billingLastName = " ";
132
  $billingZipcode = $razorpayData['customer_details']['billing_address']['zipcode'] ?? '';
133
  $shippingZipcode = $razorpayData['customer_details']['shipping_address']['zipcode'] ?? '';
134
-
135
- $shippingCharges = $razorpayData['shipping_fee'] / 100;
136
- $email = $razorpayData['customer_details']['email'];
137
 
138
  // Insert record in abandoned cart table for the guest user.
139
  $userId = saveGuestUserDetails($billingFirstName, $billingLastName, $email, $billingZipcode, $shippingZipcode, $shippingCharges);
3
  * For abandon cart recovery related API
4
  */
5
 
6
+ require_once __DIR__ . '/../support/cartbounty.php';
7
+
8
  function saveCartAbandonmentData(WP_REST_Request $request)
9
  {
10
  global $woocommerce;
33
 
34
  return new WP_REST_Response($response, $statusCode);
35
  }
 
36
  if (isset($razorpayData['receipt'])) {
37
  $wcOrderId = $razorpayData['receipt'];
38
 
64
  return new WP_REST_Response($result['response'], $result['status_code']);
65
  }
66
 
67
+ //Check CartBounty plugin is activated or not
68
+ if (is_plugin_active('woo-save-abandoned-carts/cartbounty-abandoned-carts.php') && (empty($razorpayData['customer_details']['email']) == false || empty($customerEmail) == false)) {
69
+
70
+ $result = saveCartBountyData($razorpayData); //save abandonment data
71
+
72
+ return new WP_REST_Response($result['response'], $result['status_code']);
73
+ }
74
+
75
  if (is_plugin_active('klaviyo/klaviyo.php') && empty($razorpayData['customer_details']['email']) == false) {
76
  WC()->cart->empty_cart();
77
  $cart1cc = create1ccCart($wcOrderId);
140
  $billingLastName = " ";
141
  $billingZipcode = $razorpayData['customer_details']['billing_address']['zipcode'] ?? '';
142
  $shippingZipcode = $razorpayData['customer_details']['shipping_address']['zipcode'] ?? '';
143
+ $shippingCharges = $razorpayData['shipping_fee'] / 100;
144
+ $email = $razorpayData['customer_details']['email'];
 
145
 
146
  // Insert record in abandoned cart table for the guest user.
147
  $userId = saveGuestUserDetails($billingFirstName, $billingLastName, $email, $billingZipcode, $shippingZipcode, $shippingCharges);
includes/razorpay-webhook.php CHANGED
@@ -102,20 +102,17 @@ class RZP_Webhook
102
  //
103
  // If the webhook secret isn't set on wordpress, return
104
  //
105
- if (empty($razorpayWebhookSecret) === true ) {
106
- $razorpayWebhookSecret = get_option('rzp_webhook_secret');
107
- if (empty($razorpayWebhookSecret) === false){
108
  $this->razorpay->update_option('webhook_secret', $razorpayWebhookSecret);
109
- }
110
- else
111
- {
112
  rzpLogInfo("Woocommerce orderId: $orderId webhook process exited due to secret not available");
113
 
114
  return;
115
- }
116
  }
117
-
118
-
119
  try
120
  {
121
  $this->api->utility->verifyWebhookSignature($post,
@@ -240,23 +237,21 @@ class RZP_Webhook
240
 
241
  rzpLogInfo("Woocommerce orderId: $orderId webhook process intitiated for payment authorized event");
242
 
243
- if(!empty($orderId))
244
- {
245
- $order = $this->checkIsObject($orderId);
246
  }
247
 
248
- $orderStatus = $order->get_status();
249
  rzpLogInfo("Woocommerce orderId: $orderId order status: $orderStatus");
250
 
251
  // If it is already marked as paid, ignore the event
252
  if ($orderStatus != 'draft' && $order->needs_payment() === false) {
253
- rzpLogInfo("Woocommerce orderId: $orderId webhook process exited with need payment status :". $order->needs_payment());
254
 
255
  return;
256
  }
257
 
258
- if($orderStatus == 'draft')
259
- {
260
  updateOrderStatus($orderId, 'wc-pending');
261
  }
262
 
@@ -326,7 +321,7 @@ class RZP_Webhook
326
  return;
327
  }
328
 
329
- if (isset($data['payload']['payment']['entity']['method']) != 'cod' ) {
330
  return;
331
  }
332
 
@@ -337,23 +332,21 @@ class RZP_Webhook
337
 
338
  rzpLogInfo("Woocommerce orderId: $orderId webhook process intitiated for COD method payment pending event");
339
 
340
- if(!empty($orderId))
341
- {
342
- $order = $this->checkIsObject($orderId);
343
  }
344
 
345
- $orderStatus = $order->get_status();
346
  rzpLogInfo("Woocommerce orderId: $orderId order status: $orderStatus");
347
 
348
  // If it is already marked as paid, ignore the event
349
  if ($orderStatus != 'draft' && $order->needs_payment() === false) {
350
- rzpLogInfo("Woocommerce orderId: $orderId webhook process exited with need payment status :". $order->needs_payment());
351
 
352
  return;
353
  }
354
 
355
- if($orderStatus == 'draft')
356
- {
357
  updateOrderStatus($orderId, 'wc-pending');
358
  }
359
 
@@ -392,9 +385,8 @@ class RZP_Webhook
392
  //
393
  $orderId = $data['payload']['payment']['entity']['notes']['woocommerce_order_number'];
394
 
395
- if(!empty($orderId))
396
- {
397
- $order = $this->checkIsObject($orderId);
398
  }
399
  // If it is already marked as paid, ignore the event
400
  if ($order->needs_payment() === false) {
@@ -531,9 +523,8 @@ class RZP_Webhook
531
  //
532
  $orderId = $payment['notes']['woocommerce_order_number'];
533
 
534
- if(!empty($orderId))
535
- {
536
- $order = $this->checkIsObject($orderId);
537
  }
538
 
539
  // If it is already marked as unpaid, ignore the event
@@ -596,12 +587,9 @@ class RZP_Webhook
596
  public function checkIsObject($orderId)
597
  {
598
  $order = wc_get_order($orderId);
599
- if(is_object($order))
600
- {
601
  return wc_get_order($orderId);
602
- }
603
- else
604
- {
605
  rzpLogInfo("Woocommerce order Object does not exist");
606
  exit();
607
  }
102
  //
103
  // If the webhook secret isn't set on wordpress, return
104
  //
105
+ if (empty($razorpayWebhookSecret) === true) {
106
+ $razorpayWebhookSecret = get_option('rzp_webhook_secret');
107
+ if (empty($razorpayWebhookSecret) === false) {
108
  $this->razorpay->update_option('webhook_secret', $razorpayWebhookSecret);
109
+ } else {
 
 
110
  rzpLogInfo("Woocommerce orderId: $orderId webhook process exited due to secret not available");
111
 
112
  return;
113
+ }
114
  }
115
+
 
116
  try
117
  {
118
  $this->api->utility->verifyWebhookSignature($post,
237
 
238
  rzpLogInfo("Woocommerce orderId: $orderId webhook process intitiated for payment authorized event");
239
 
240
+ if (!empty($orderId)) {
241
+ $order = $this->checkIsObject($orderId);
 
242
  }
243
 
244
+ $orderStatus = $order->get_status();
245
  rzpLogInfo("Woocommerce orderId: $orderId order status: $orderStatus");
246
 
247
  // If it is already marked as paid, ignore the event
248
  if ($orderStatus != 'draft' && $order->needs_payment() === false) {
249
+ rzpLogInfo("Woocommerce orderId: $orderId webhook process exited with need payment status :" . $order->needs_payment());
250
 
251
  return;
252
  }
253
 
254
+ if ($orderStatus == 'draft') {
 
255
  updateOrderStatus($orderId, 'wc-pending');
256
  }
257
 
321
  return;
322
  }
323
 
324
+ if (isset($data['payload']['payment']['entity']['method']) != 'cod') {
325
  return;
326
  }
327
 
332
 
333
  rzpLogInfo("Woocommerce orderId: $orderId webhook process intitiated for COD method payment pending event");
334
 
335
+ if (!empty($orderId)) {
336
+ $order = $this->checkIsObject($orderId);
 
337
  }
338
 
339
+ $orderStatus = $order->get_status();
340
  rzpLogInfo("Woocommerce orderId: $orderId order status: $orderStatus");
341
 
342
  // If it is already marked as paid, ignore the event
343
  if ($orderStatus != 'draft' && $order->needs_payment() === false) {
344
+ rzpLogInfo("Woocommerce orderId: $orderId webhook process exited with need payment status :" . $order->needs_payment());
345
 
346
  return;
347
  }
348
 
349
+ if ($orderStatus == 'draft') {
 
350
  updateOrderStatus($orderId, 'wc-pending');
351
  }
352
 
385
  //
386
  $orderId = $data['payload']['payment']['entity']['notes']['woocommerce_order_number'];
387
 
388
+ if (!empty($orderId)) {
389
+ $order = $this->checkIsObject($orderId);
 
390
  }
391
  // If it is already marked as paid, ignore the event
392
  if ($order->needs_payment() === false) {
523
  //
524
  $orderId = $payment['notes']['woocommerce_order_number'];
525
 
526
+ if (!empty($orderId)) {
527
+ $order = $this->checkIsObject($orderId);
 
528
  }
529
 
530
  // If it is already marked as unpaid, ignore the event
587
  public function checkIsObject($orderId)
588
  {
589
  $order = wc_get_order($orderId);
590
+ if (is_object($order)) {
 
591
  return wc_get_order($orderId);
592
+ } else {
 
 
593
  rzpLogInfo("Woocommerce order Object does not exist");
594
  exit();
595
  }
includes/support/cartbounty.php ADDED
@@ -0,0 +1,312 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ //Save cart abandonment data for CartBounty plugin
3
+ function saveCartBountyData($razorpayData)
4
+ {
5
+ global $wpdb;
6
+ $products = WC()->cart->get_cart();
7
+ $ghost = false;
8
+ $name = $razorpayData['customer_details']['billing_address']['name'] ?? '';
9
+ $surname = " ";
10
+ $email = $razorpayData['customer_details']['email'];
11
+ $phone = $razorpayData['customer_details']['contact'];
12
+ $cartTable = $wpdb->prefix . "cartbounty";
13
+ $cart = readCartCB($razorpayData['receipt']);
14
+ $cartbountyPublic = new CartBounty_Public(CARTBOUNTY_PLUGIN_NAME_SLUG, CARTBOUNTY_VERSION_NUMBER);
15
+ $cartbountyAdmin = new CartBounty_Admin(CARTBOUNTY_PLUGIN_NAME_SLUG, CARTBOUNTY_VERSION_NUMBER);
16
+
17
+ $location = array(
18
+ 'country' => $razorpayData['customer_details']['shipping_address']['country'] ?? '',
19
+ 'city' => $razorpayData['customer_details']['shipping_address']['city'] ?? '',
20
+ 'postcode' => $razorpayData['customer_details']['shipping_address']['zipcode'] ?? '',
21
+ );
22
+
23
+ $otherFields = array(
24
+ 'cartbounty_billing_company' => '',
25
+ 'cartbounty_billing_address_1' => $razorpayData['customer_details']['billing_address']['line1'] ?? '',
26
+ 'cartbounty_billing_address_2' => $razorpayData['customer_details']['billing_address']['line2'] ?? '',
27
+ 'cartbounty_billing_state' => $razorpayData['customer_details']['billing_address']['state'] ?? '',
28
+ 'cartbounty_shipping_first_name' => $razorpayData['customer_details']['billing_address']['name'] ?? '',
29
+ 'cartbounty_shipping_last_name' => '',
30
+ 'cartbounty_shipping_company' => '',
31
+ 'cartbounty_shipping_country' => $razorpayData['customer_details']['shipping_address']['country'] ?? '',
32
+ 'cartbounty_shipping_address_1' => $razorpayData['customer_details']['shipping_address']['line1'] ?? '',
33
+ 'cartbounty_shipping_address_2' => $razorpayData['customer_details']['shipping_address']['line2'] ?? '',
34
+ 'cartbounty_shipping_city' => $razorpayData['customer_details']['shipping_address']['city'] ?? '',
35
+ 'cartbounty_shipping_state' => $razorpayData['customer_details']['shipping_address']['state'] ?? '',
36
+ 'cartbounty_shipping_postcode' => $razorpayData['customer_details']['shipping_address']['zipcode'] ?? '',
37
+ 'cartbounty_order_comments' => '',
38
+ 'cartbounty_create_account' => '',
39
+ 'cartbounty_ship_elsewhere' => '',
40
+ );
41
+
42
+ $userData = array(
43
+ 'name' => $name,
44
+ 'surname' => $surname,
45
+ 'email' => $email,
46
+ 'phone' => $phone,
47
+ 'location' => $location,
48
+ 'other_fields' => $otherFields,
49
+ );
50
+
51
+ $sessionID = getSessionID($razorpayData['receipt']);
52
+
53
+ if ($cartbountyPublic->cart_saved($sessionID) == false) {
54
+ //If cart is not saved
55
+ $wpdb->query(
56
+ $wpdb->prepare(
57
+ "INSERT INTO $cartTable
58
+ ( name, surname, email, phone, location, cart_contents, cart_total, currency, time, session_id, other_fields)
59
+ VALUES ( %s, %s, %s, %s, %s, %s, %0.2f, %s, %s, %s, %s)",
60
+ array(
61
+ 'name' => sanitize_text_field($userData['name']),
62
+ 'surname' => sanitize_text_field($userData['surname']),
63
+ 'email' => sanitize_email($userData['email']),
64
+ 'phone' => filter_var($userData['phone'], FILTER_SANITIZE_NUMBER_INT),
65
+ 'location' => sanitize_text_field(serialize($userData['location'])),
66
+ 'products' => serialize($cart['product_array']),
67
+ 'total' => sanitize_text_field($cart['cart_total']),
68
+ 'currency' => sanitize_text_field($cart['cart_currency']),
69
+ 'time' => sanitize_text_field($cart['current_time']),
70
+ 'session_id' => sanitize_text_field($cart['session_id']),
71
+ 'other_fields' => sanitize_text_field(serialize($userData['other_fields'])),
72
+ )
73
+ )
74
+ );
75
+
76
+ $cartbountyPublic->increase_recoverable_cart_count();
77
+ $cartbountyPublic->set_cartbounty_session($sessionID);
78
+ }
79
+ $updatedRows = $wpdb->query(
80
+ $wpdb->prepare(
81
+ "UPDATE $cartTable
82
+ SET name = %s,
83
+ surname = %s,
84
+ email = %s,
85
+ phone = %s,
86
+ location = %s,
87
+ other_fields = '$otherFields'
88
+ WHERE session_id = %s and type=0",
89
+ sanitize_text_field($userData['name']),
90
+ sanitize_text_field($userData['surname']),
91
+ sanitize_email($userData['email']),
92
+ filter_var($userData['phone'], FILTER_SANITIZE_NUMBER_INT),
93
+ sanitize_text_field(serialize($userData['location'])),
94
+ $sessionID
95
+ )
96
+ );
97
+
98
+ deleteDuplicateCarts($sessionID, $updatedRows, $cartTable);
99
+ $cartbountyPublic->set_cartbounty_session($sessionID);
100
+ $response['status'] = true;
101
+ $response['message'] = 'Data successfully inserted for CartBounty plugin';
102
+ $statusCode = 200;
103
+
104
+ update_post_meta($sessionID, 'FromEmail', "Y");
105
+ WC()->session->set('cartbounty_from_link', true);
106
+
107
+ $result['response'] = $response;
108
+ $result['status_code'] = $statusCode;
109
+ return $result;
110
+ }
111
+
112
+ //Delete Duplicate carts CartBounty plugin
113
+ function deleteDuplicateCarts($sessionID, $duplicateCount, $cartTable)
114
+ {
115
+ global $wpdb;
116
+ $cartbountyAdmin = new CartBounty_Admin(CARTBOUNTY_PLUGIN_NAME_SLUG, CARTBOUNTY_VERSION_NUMBER);
117
+ if ($duplicateCount) {
118
+ //If we have updated at least one row
119
+ if ($duplicateCount > 1) { //Checking if we have updated more than a single row to know if there were duplicates
120
+ $whereSentence = $cartbountyAdmin->get_where_sentence('ghost');
121
+ //First delete all duplicate ghost carts
122
+ $deletedDuplicateGhostCarts = $wpdb->query(
123
+ $wpdb->prepare(
124
+ "DELETE FROM $cartTable
125
+ WHERE session_id = %s
126
+ $whereSentence",
127
+ $sessionID
128
+ )
129
+ );
130
+
131
+ $limit = $duplicateCount - $deletedDuplicateGhostCarts - 1;
132
+ if ($limit < 1) {
133
+ $limit = 0;
134
+ }
135
+
136
+ $wpdb->query( //Leaving one cart remaining that can be identified
137
+ $wpdb->prepare(
138
+ "DELETE FROM $cartTable
139
+ WHERE session_id = %s AND
140
+ type != %d
141
+ ORDER BY id DESC
142
+ LIMIT %d",
143
+ $sessionID,
144
+ 1,
145
+ $limit
146
+ )
147
+ );
148
+ }
149
+ }
150
+ }
151
+
152
+ function getSessionID($orderID)
153
+ {
154
+ $sessionID = WC()->session->get_customer_id();
155
+ $order = wc_get_order($orderID);
156
+ $userID = $order->get_user_id();
157
+
158
+ if ($userID != 0 or $userID != null) {
159
+ //Used to check whether user is logged in
160
+ $sessionID = $userID;
161
+ } else {
162
+ $sessionID = WC()->session->get('cartbounty_session_id');
163
+ if (empty($sessionID)) { //If session value does not exist - set one now
164
+ $sessionID = WC()->session->get_customer_id(); //Retrieving customer ID from WooCommerce sessions variable
165
+ }
166
+ if (WC()->session->get('cartbounty_from_link') && WC()->session->get('cartbounty_session_id')) {
167
+ $sessionID = WC()->session->get('cartbounty_session_id');
168
+ }
169
+ }
170
+ return $sessionID;
171
+ }
172
+
173
+ function handleCBRecoveredOrder($orderID)
174
+ {
175
+ global $wpdb;
176
+
177
+ if (!isset($orderID)) {
178
+ //Exit if Order ID is not present
179
+ return;
180
+ }
181
+
182
+ $cartbountyPublic = new CartBounty_Public(CARTBOUNTY_PLUGIN_NAME_SLUG, CARTBOUNTY_VERSION_NUMBER);
183
+ $cartbountyAdmin = new CartBounty_Admin(CARTBOUNTY_PLUGIN_NAME_SLUG, CARTBOUNTY_VERSION_NUMBER);
184
+
185
+ $cartbountyPublic->update_logged_customer_id(); //In case a user chooses to create an account during checkout process, the session id changes to a new one so we must update it
186
+
187
+ $cartTable = $wpdb->prefix . CARTBOUNTY_TABLE_NAME;
188
+
189
+ if (WC()->session) {
190
+ //If session exists
191
+ $cart = readCartCB($orderID);
192
+ $type = $cartbountyAdmin->get_cart_type('ordered'); //Default type describing an order has been placed
193
+ $sessionID = getSessionID($orderID);
194
+ $fromEmail = get_post_meta(getSessionID($orderID), 'FromEmail', true);
195
+
196
+ if ($sessionID != null) {
197
+ if ($fromEmail === "Y") {
198
+ //If the user has arrived from CartBounty link
199
+ $type = $cartbountyAdmin->get_cart_type('recovered');
200
+ update_post_meta($sessionID, 'FromEmail', "N");
201
+ }
202
+ $cartbountyAdmin->update_cart_type($sessionID, $type); //Update cart type to recovered
203
+
204
+ }
205
+ }
206
+ clearCartData($orderID, $cartTable); //Clearing abandoned cart after it has been synced
207
+
208
+ }
209
+
210
+ //CartBounty admin function to clearCartData
211
+ function clearCartData($wcOrderId, $cartTable)
212
+ {
213
+ //If a new Order is added from the WooCommerce admin panel, we must check if WooCommerce session is set. Otherwise we would get a Fatal error.
214
+ if (!isset(WC()->session)) {
215
+ return;
216
+ }
217
+
218
+ global $wpdb;
219
+ $cart = readCartCB($wcOrderId);
220
+
221
+ if (!isset($cart['session_id'])) {
222
+ return;
223
+ }
224
+
225
+ //Cleaning Cart data
226
+ $update_result = $wpdb->query(
227
+ $wpdb->prepare(
228
+ "UPDATE $cartTable
229
+ SET cart_contents = '',
230
+ cart_total = %d,
231
+ currency = %s,
232
+ time = %s
233
+ WHERE session_id = %s AND
234
+ type = %d",
235
+ 0,
236
+ sanitize_text_field($cart['cart_currency']),
237
+ sanitize_text_field($cart['current_time']),
238
+ $cart['session_id'],
239
+ 0
240
+ )
241
+ );
242
+ }
243
+
244
+ //CartBounty plugin function for retrieving the cart data
245
+ function readCartCB($wcOrderId)
246
+ {
247
+ WC()->cart->empty_cart();
248
+ $cart1cc = create1ccCart($wcOrderId);
249
+ $cart = WC()->cart;
250
+
251
+ if (!WC()->cart) {
252
+ //Exit if Woocommerce cart has not been initialized
253
+ return;
254
+ }
255
+
256
+ $cartTotal = WC()->cart->total; //Retrieving cart total value and currency
257
+ $cartCurrency = get_woocommerce_currency();
258
+ $currentTime = current_time('mysql', false); //Retrieving current time
259
+ $sessionID = getSessionID($wcOrderId);
260
+ //Retrieving cart
261
+ $products = WC()->cart->get_cart_contents();
262
+ $productArray = array();
263
+
264
+ foreach ($products as $key => $product) {
265
+ $item = wc_get_product($product['data']->get_id());
266
+ $productTitle = $item->get_title();
267
+ $productQuantity = $product['quantity'];
268
+ $productVariationPrice = '';
269
+ $productTax = '';
270
+
271
+ if (isset($product['line_total'])) {
272
+ $productVariationPrice = $product['line_total'];
273
+ }
274
+
275
+ if (isset($product['line_tax'])) {
276
+ //If we have taxes, add them to the price
277
+ $productTax = $product['line_tax'];
278
+ }
279
+
280
+ // Handling product variations
281
+ if ($product['variation_id']) {
282
+ //If user has chosen a variation
283
+ $singleVariation = new WC_Product_Variation($product['variation_id']);
284
+
285
+ //Handling variable product title output with attributes
286
+ $productAttributes = attribute_slug_to_title($singleVariation->get_variation_attributes());
287
+ $productVariationID = $product['variation_id'];
288
+ } else {
289
+ $productAttributes = false;
290
+ $productVariationID = '';
291
+ }
292
+
293
+ $productData = array(
294
+ 'product_title' => $productTitle . $productAttributes,
295
+ 'quantity' => $productQuantity,
296
+ 'product_id' => $product['product_id'],
297
+ 'product_variation_id' => $productVariationID,
298
+ 'product_variation_price' => $productVariationPrice,
299
+ 'product_tax' => $productTax,
300
+ );
301
+
302
+ $productArray[] = $productData;
303
+ }
304
+
305
+ return $resultsArray = array(
306
+ 'cart_total' => $cartTotal,
307
+ 'cart_currency' => $cartCurrency,
308
+ 'current_time' => $currentTime,
309
+ 'session_id' => $sessionID,
310
+ 'product_array' => $productArray,
311
+ );
312
+ }
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: razorpay
3
  Tags: razorpay, payments, india, woocommerce, ecommerce
4
  Requires at least: 3.9.2
5
- Tested up to: 5.9
6
- Stable tag: 3.9.4
7
  Requires PHP: 5.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -41,6 +41,10 @@ This is compatible with WooCommerce>=2.4, including the new 3.0 release. It has
41
 
42
  == Changelog ==
43
 
 
 
 
 
44
  = 3.9.4 =
45
  * Added delay of 5 minutes to webhook process.
46
 
2
  Contributors: razorpay
3
  Tags: razorpay, payments, india, woocommerce, ecommerce
4
  Requires at least: 3.9.2
5
+ Tested up to: 6.0.1
6
+ Stable tag: 4.0.0
7
  Requires PHP: 5.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
41
 
42
  == Changelog ==
43
 
44
+ = 4.0.0 =
45
+ * Added support for CartBounty plugin in magic checkout.
46
+ * Added debug log config on native checkout flow.
47
+
48
  = 3.9.4 =
49
  * Added delay of 5 minutes to webhook process.
50
 
woo-razorpay.php CHANGED
@@ -3,10 +3,10 @@
3
  * Plugin Name: Razorpay for WooCommerce
4
  * Plugin URI: https://razorpay.com
5
  * Description: Razorpay Payment Gateway Integration for WooCommerce
6
- * Version: 3.9.4
7
- * Stable tag: 3.9.4
8
  * Author: Team Razorpay
9
- * WC tested up to: 6.4.1
10
  * Author URI: https://razorpay.com
11
  */
12
 
@@ -23,6 +23,7 @@ require_once __DIR__ .'/includes/razorpay-route-actions.php';
23
  require_once __DIR__.'/includes/api/api.php';
24
  require_once __DIR__.'/includes/utils.php';
25
  require_once __DIR__.'/includes/state-map.php';
 
26
 
27
  use Razorpay\Api\Api;
28
  use Razorpay\Api\Errors;
@@ -81,6 +82,7 @@ function woocommerce_razorpay_init()
81
  'payment_action',
82
  'order_success_message',
83
  'route_enable',
 
84
  );
85
 
86
  public $form_fields = array();
@@ -187,7 +189,6 @@ function woocommerce_razorpay_init()
187
  'enable_1cc',
188
  'enable_1cc_mandatory_login',
189
  'enable_1cc_test_mode',
190
- 'enable_1cc_debug_mode',
191
  'enable_1cc_pdp_checkout',
192
  'enable_1cc_mini_cart_checkout',
193
  'enable_1cc_ga_analytics',
@@ -286,6 +287,13 @@ function woocommerce_razorpay_init()
286
  'description' => __('Message to be displayed after a successful order', $this->id),
287
  'default' => __(STATIC::DEFAULT_SUCCESS_MESSAGE, $this->id),
288
  ),
 
 
 
 
 
 
 
289
  );
290
 
291
  do_action_ref_array( 'setup_extra_setting_fields', array( &$defaultFormFields ) );
@@ -1073,7 +1081,7 @@ EOT;
1073
  rzpLogInfo("Set transient with key " . self::SESSION_KEY . " params order_id $order_id");
1074
 
1075
  $orderKey = $this->getOrderKey($order);
1076
-
1077
  if (version_compare(WOOCOMMERCE_VERSION, '2.1', '>='))
1078
  {
1079
  return array(
@@ -1327,7 +1335,7 @@ EOT;
1327
  {
1328
  $message = 'An error occured. Please contact administrator for assistance';
1329
  }
1330
- rzpLogInfo("returning $getErrorMessage");
1331
  return $message;
1332
  }
1333
 
@@ -1342,7 +1350,7 @@ EOT;
1342
 
1343
  $orderId = $order->get_order_number();
1344
 
1345
- rzpLogInfo("updateOrder orderId: $orderId , errorMessage: $errorMessage, razorpayPaymentId: $razorpayPaymentId , success: $success");
1346
 
1347
  if ($success === true)
1348
  {
@@ -1383,6 +1391,10 @@ EOT;
1383
  {
1384
  $order->payment_complete($razorpayPaymentId);
1385
  }
 
 
 
 
1386
 
1387
  $order->add_order_note("Razorpay payment successful <br/>Razorpay Id: $razorpayPaymentId");
1388
 
@@ -1570,7 +1582,7 @@ EOT;
1570
  }
1571
  else
1572
  {
1573
- $item->set_method_title($shippingData[0]['name']);
1574
  }
1575
 
1576
  // set an non existing Shipping method rate ID will mark the order as completed instead of processing status
@@ -1946,7 +1958,6 @@ function enqueueScriptsFor1cc()
1946
 
1947
  wp_register_script('1cc_razorpay_checkout', RZP_CHECKOUTJS_URL, null, null);
1948
  wp_enqueue_script('1cc_razorpay_checkout');
1949
-
1950
  wp_register_style(RZP_1CC_CSS_SCRIPT, plugin_dir_url(__FILE__) . 'public/css/1cc-product-checkout.css', null, null);
1951
  wp_enqueue_style(RZP_1CC_CSS_SCRIPT);
1952
 
@@ -2073,3 +2084,13 @@ if(is1ccEnabled())
2073
  add_action('woocommerce_cart_updated', 'enqueueScriptsFor1cc', 10);
2074
  add_filter('woocommerce_order_needs_shipping_address', '__return_true');
2075
  }
 
 
 
 
 
 
 
 
 
 
3
  * Plugin Name: Razorpay for WooCommerce
4
  * Plugin URI: https://razorpay.com
5
  * Description: Razorpay Payment Gateway Integration for WooCommerce
6
+ * Version: 4.0.0
7
+ * Stable tag: 4.0.0
8
  * Author: Team Razorpay
9
+ * WC tested up to: 6.7.0
10
  * Author URI: https://razorpay.com
11
  */
12
 
23
  require_once __DIR__.'/includes/api/api.php';
24
  require_once __DIR__.'/includes/utils.php';
25
  require_once __DIR__.'/includes/state-map.php';
26
+ require_once __DIR__.'/includes/support/cartbounty.php';
27
 
28
  use Razorpay\Api\Api;
29
  use Razorpay\Api\Errors;
82
  'payment_action',
83
  'order_success_message',
84
  'route_enable',
85
+ 'enable_1cc_debug_mode',
86
  );
87
 
88
  public $form_fields = array();
189
  'enable_1cc',
190
  'enable_1cc_mandatory_login',
191
  'enable_1cc_test_mode',
 
192
  'enable_1cc_pdp_checkout',
193
  'enable_1cc_mini_cart_checkout',
194
  'enable_1cc_ga_analytics',
287
  'description' => __('Message to be displayed after a successful order', $this->id),
288
  'default' => __(STATIC::DEFAULT_SUCCESS_MESSAGE, $this->id),
289
  ),
290
+ 'enable_1cc_debug_mode' => array( //Added this config for both native and 1cc merchants
291
+ 'title' => __('Activate debug mode'),
292
+ 'type' => 'checkbox',
293
+ 'description' => 'When debug mode is active, API logs and errors are collected and stored in your Woocommerce dashboard. It is recommended to keep this activated.',
294
+ 'label' => __('Enable debug mode'),
295
+ 'default' => 'yes',
296
+ ),
297
  );
298
 
299
  do_action_ref_array( 'setup_extra_setting_fields', array( &$defaultFormFields ) );
1081
  rzpLogInfo("Set transient with key " . self::SESSION_KEY . " params order_id $order_id");
1082
 
1083
  $orderKey = $this->getOrderKey($order);
1084
+
1085
  if (version_compare(WOOCOMMERCE_VERSION, '2.1', '>='))
1086
  {
1087
  return array(
1335
  {
1336
  $message = 'An error occured. Please contact administrator for assistance';
1337
  }
1338
+ rzpLogInfo("returning $message");
1339
  return $message;
1340
  }
1341
 
1350
 
1351
  $orderId = $order->get_order_number();
1352
 
1353
+ rzpLogInfo("updateOrder orderId: $orderId , razorpayPaymentId: $razorpayPaymentId , success: $success");
1354
 
1355
  if ($success === true)
1356
  {
1391
  {
1392
  $order->payment_complete($razorpayPaymentId);
1393
  }
1394
+
1395
+ if(is_plugin_active('woo-save-abandoned-carts/cartbounty-abandoned-carts.php')){
1396
+ handleCBRecoveredOrder($orderId);
1397
+ }
1398
 
1399
  $order->add_order_note("Razorpay payment successful <br/>Razorpay Id: $razorpayPaymentId");
1400
 
1582
  }
1583
  else
1584
  {
1585
+ $item->set_method_title($shippingData??[0]['name']);
1586
  }
1587
 
1588
  // set an non existing Shipping method rate ID will mark the order as completed instead of processing status
1958
 
1959
  wp_register_script('1cc_razorpay_checkout', RZP_CHECKOUTJS_URL, null, null);
1960
  wp_enqueue_script('1cc_razorpay_checkout');
 
1961
  wp_register_style(RZP_1CC_CSS_SCRIPT, plugin_dir_url(__FILE__) . 'public/css/1cc-product-checkout.css', null, null);
1962
  wp_enqueue_style(RZP_1CC_CSS_SCRIPT);
1963
 
2084
  add_action('woocommerce_cart_updated', 'enqueueScriptsFor1cc', 10);
2085
  add_filter('woocommerce_order_needs_shipping_address', '__return_true');
2086
  }
2087
+
2088
+ //Changes Recovery link URL to Magic cart URL to avoid redirection to checkout page
2089
+ function cartbounty_alter_automation_button( $button ){
2090
+ return str_replace("cartbounty=","cartbounty=magic_",$button);
2091
+ }
2092
+
2093
+ if(is_plugin_active('woo-save-abandoned-carts/cartbounty-abandoned-carts.php')){
2094
+ add_filter( 'cartbounty_automation_button_html', 'cartbounty_alter_automation_button' );
2095
+ }
2096
+