diff --git a/.distignore b/.distignore new file mode 100644 index 0000000..4f087e8 --- /dev/null +++ b/.distignore @@ -0,0 +1,17 @@ +/.wordpress-org +/.git +/.github +/node_modules + +LICENSE +_config.yml +.distignore +.gitignore +CHANGELOG.md +composer.json +composer.lock +package.json +package-lock.json +phpcs.xml +README.md +todo \ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 2eefe4a..3d52d68 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -custom: https://www.paypal.me/iamsayan +custom: https://rzp.io/l/Bq3W5pr \ No newline at end of file diff --git a/banner.png b/.github/banner.png similarity index 100% rename from banner.png rename to .github/banner.png diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..a51ee35 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,35 @@ +name: Deploy to WordPress.org + +on: + release: + types: [published] + +jobs: + deploy: + name: New release + runs-on: ubuntu-latest + environment: wp.org plugin + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: WordPress Plugin Deploy + id: deploy + uses: 10up/action-wordpress-plugin-deploy@stable + with: + generate-zip: true + env: + SVN_USERNAME: ${{ secrets.SVN_USERNAME }} + SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }} + SLUG: rzp-woocommerce + + - name: Upload release asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ${{ steps.deploy.outputs.zip-path }} + asset_name: ${{ github.event.repository.name }}.zip + asset_content_type: application/zip diff --git a/.wordpress-org/banner-1544x500.png b/.wordpress-org/banner-1544x500.png new file mode 100644 index 0000000..d1c5aa1 Binary files /dev/null and b/.wordpress-org/banner-1544x500.png differ diff --git a/.wordpress-org/banner-772x250.png b/.wordpress-org/banner-772x250.png new file mode 100644 index 0000000..b338d63 Binary files /dev/null and b/.wordpress-org/banner-772x250.png differ diff --git a/.wordpress-org/icon-128x128.png b/.wordpress-org/icon-128x128.png new file mode 100644 index 0000000..a9ea56d Binary files /dev/null and b/.wordpress-org/icon-128x128.png differ diff --git a/.wordpress-org/icon-256x256.png b/.wordpress-org/icon-256x256.png new file mode 100644 index 0000000..9b7105b Binary files /dev/null and b/.wordpress-org/icon-256x256.png differ diff --git a/.wordpress-org/screenshot-1.png b/.wordpress-org/screenshot-1.png new file mode 100644 index 0000000..5cb8ead Binary files /dev/null and b/.wordpress-org/screenshot-1.png differ diff --git a/.wordpress-org/screenshot-2.png b/.wordpress-org/screenshot-2.png new file mode 100644 index 0000000..1759f08 Binary files /dev/null and b/.wordpress-org/screenshot-2.png differ diff --git a/.wordpress-org/screenshot-3.png b/.wordpress-org/screenshot-3.png new file mode 100644 index 0000000..87e257f Binary files /dev/null and b/.wordpress-org/screenshot-3.png differ diff --git a/.wordpress-org/screenshot-4.png b/.wordpress-org/screenshot-4.png new file mode 100644 index 0000000..766f846 Binary files /dev/null and b/.wordpress-org/screenshot-4.png differ diff --git a/.wordpress-org/screenshot-5.png b/.wordpress-org/screenshot-5.png new file mode 100644 index 0000000..c3b4292 Binary files /dev/null and b/.wordpress-org/screenshot-5.png differ diff --git a/.wordpress-org/screenshot-6.png b/.wordpress-org/screenshot-6.png new file mode 100644 index 0000000..6c395d9 Binary files /dev/null and b/.wordpress-org/screenshot-6.png differ diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c1c4ed..6b0ee58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,72 @@ # Changelog All notable changes to this project will be documented in this file. +## 1.1.6 +Release Date: July 15, 2022 + +* Improved: Code Quality. +* WordPress tested upto v6.0. +* WC Tested upto v6.7. + +## 1.1.5 +Release Date: July 25, 2021 + +* Improved: Localhost check. +* Support for old WC Version (2.0 to 3.1) +* WC Tested upto v5.5 and v5.6. + +## 1.1.4 +Release Date: June 16, 2021 + +* Added: Order Number instead of Order ID. +* WC Tested upto v5.4. + +## 1.1.3 +Release Date: May 23, 2021 + +* Added: Auto Enable Webhook on plugin settings save. +* Fixed: Bug related to new API. + +## 1.1.2 +Release Date: January 11, 2021 + +* Added: Option to switch between Standard and Legacy Payment Links API. If your Razorpay Account was created on or after 1 September 2020 and Legacy API is not working for you, please use Standrard API. Legacy API will be officially deprecated by Razorpay on 31st March, 2021. + +## 1.1.1 +Release Date: December 14, 2020 + +* WordPress tested upto v5.6. +* WC Tested upto v4.8. + +## 1.1.0 +Release Date: November 7, 2020 + +* Fixed: Partial refund from Razorpay Dashbaord causing multiple refund events. +* WC Tested upto v4.6. + +## 1.0.9 +Release Date: August 15, 2020 + +* Fixed: Webhook Issue. +* WC Tested upto v4.4. + +## 1.0.8 +Release Date: July 24, 2020 + +* Fixed: Redirection issue due to recent Razorpay API Chnages. + +## 1.0.7 +Release Date: July 20, 2020 + +* WC Tested upto v4.3. + +## 1.0.6 +Release Date: June 9, 2020 + +* Tweak: Cart will not be cleared if payment is not actually made. +* Fixed: Redirection issue. +* WC Tested upto v4.2.0 + ## 1.0.5 Release Date: May 24, 2020 diff --git a/README.md b/README.md index 0340594..31f5ac2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -![alt text](https://github.com/iamsayan/rzp-woocommerce/raw/master/banner.png "Plugin Banner") +![Razorpay Payment Links for WooCommerce](.github/banner.png "Plugin Banner") -# Razorpay Gateway for WooCommerce +# Razorpay Payment Links for WooCommerce This is the Un-Official Razorpay Payment Gateway plugin for WooCommerce. Allows you to accept Credit Cards, Debit Cards, Netbanking, Wallets, and UPI Payments with the WooCommerce plugin. @@ -8,7 +8,7 @@ This is the Un-Official Razorpay Payment Gateway plugin for WooCommerce. Allows ## Description -### Razorpay Gateway for WooCommerce +### Razorpay Payment Links for WooCommerce This is the Un-Official Razorpay Payment Gateway plugin for WooCommerce. Allows you to accept Credit Cards, Debit Cards, Netbanking, Wallets, and UPI Payments with the WooCommerce plugin. @@ -32,7 +32,7 @@ It uses a Razorpay's Payment Link API integration, allowing the customer to pay * Detailed Payment process Log via WooCommerce Logger. * Lots of filters available to customize the output. -Like Razorpay Gateway for WooCommerce plugin? Consider leaving a [5 star review](https://wordpress.org/support/plugin/rzp-woocommerce/reviews/?rate=5#new-post). +Like Razorpay Payment Links for WooCommerce plugin? Consider leaving a [5 star review](https://wordpress.org/support/plugin/rzp-woocommerce/reviews/?rate=5#new-post). ### Compatibility @@ -49,13 +49,13 @@ Like Razorpay Gateway for WooCommerce plugin? Consider leaving a [5 star review] ### From within WordPress 1. Visit 'Plugins > Add New'. -1. Search for 'Razorpay Gateway for WooCommerce'. -1. Activate Razorpay Gateway for WooCommerce from your Plugins page. +1. Search for 'Razorpay Payment Links for WooCommerce'. +1. Activate Razorpay Payment Links for WooCommerce from your Plugins page. 1. Go to "after activation" below. ### Manually 1. Upload the `rzp-woocommerce` folder to the `/wp-content/plugins/` directory. -1. Activate Razorpay Gateway for WooCommerce plugin through the 'Plugins' menu in WordPress. +1. Activate Razorpay Payment Links for WooCommerce plugin through the 'Plugins' menu in WordPress. 1. Go to "after activation" below. ### After activation @@ -72,6 +72,22 @@ Yes. You can access this from 'WooCommerce > Settings > Payments > Razorpay Paym Go to 'WooCommerce > Settings > Payments > Razorpay Payment Gateway', enable/disable options as per your need and save your changes. +#### How to use webhook? What webhooks are supported? = + +Go to Razorpay 'Dashboard > Settings > Webhooks'. Enter the URL from plugin settings page and create and copy webhook secret key and paste it to plugin settings and save changes. By Default this plugin supports only these two Webhooks: "payment.authorized" and "refund.created". If you want more webhooks supported, please feel free to contact me at hello@sayandatta.in or https://www.sayandatta.in/contact/ as it needs custom developmet. + +#### How to send automatic payment reminder to customer, if customer does not make payment after initiating the payment procedure? = + +It needs custom developement. Please contact me at hello@sayandatta.in or https://sayandatta.in/contact/. + +#### I want to use Razorpay Web Integration like Automatic Checkout/Manual Checkout (On site Checkout - No Redirection) with webhooks? = + +It needs custom developement. Please contact me at hello@sayandatta.in or https://sayandatta.in/contact/. + +#### I want to customize the look of the default Razorpay Gateway like colors/text etc. How can I get this? = + +It needs custom developement. Please contact me at hello@sayandatta.in or https://sayandatta.in/contact/. + #### Is this plugin compatible with any themes? Yes, this plugin is compatible with any theme. diff --git a/includes/notice.php b/includes/notice.php index 9c81736..5ba62c6 100644 --- a/includes/notice.php +++ b/includes/notice.php @@ -3,7 +3,7 @@ /** * The admin-facing functionality of the plugin. * - * @package Razorpay Gateway for WooCommerce + * @package Razorpay Payment Links for WooCommerce * @subpackage Includes * @author Sayan Datta * @license http://www.gnu.org/licenses/ GNU General Public License @@ -13,52 +13,93 @@ add_action( 'admin_init', 'rzpwc_dismiss_rating_admin_notice' ); function rzpwc_rating_admin_notice() { - // Show notice after 360 hours (15 days) from installed time. - if ( rzpwc_plugin_get_installed_time() > strtotime( '-360 hours' ) - || '1' === get_option( 'rzpwc_plugin_dismiss_rating_notice' ) - || ! current_user_can( 'manage_options' ) - || apply_filters( 'rzpwc_plugin_hide_sticky_notice', false ) ) { + if ( ! current_user_can( 'manage_options' ) ) { return; } - $dismiss = wp_nonce_url( add_query_arg( 'rzpwc_rating_notice_action', 'dismiss_rating_true' ), 'rzpwc_dismiss_rating_true' ); - $no_thanks = wp_nonce_url( add_query_arg( 'rzpwc_rating_notice_action', 'no_thanks_rating_true' ), 'rzpwc_no_thanks_rating_true' ); ?> - -
-

5-star rating on WordPress? Just to help me spread the word and boost my motivation.', 'rzp-woocommerce' ); ?>

-

  -  | - -

- strtotime( '-10 days' ) + || '1' === get_option( 'rzpwc_plugin_dismiss_rating_notice' ) + || apply_filters( 'rzpwc/hide_sticky_rating_notice', false ) ) { + $show_rating = false; + } + + if ( $show_rating ) { + $dismiss = wp_nonce_url( add_query_arg( 'rzpwc_notice_action', 'dismiss_rating' ), 'rzpwc_notice_nonce' ); + $no_thanks = wp_nonce_url( add_query_arg( 'rzpwc_notice_action', 'no_thanks_rating' ), 'rzpwc_notice_nonce' ); ?> + +
+

5-star rating on WordPress? Just to help us spread the word and boost my motivation.', 'rzp-woocommerce' ); ?>

+

  +  | +

+
+ strtotime( '-240 hours' ) + || '1' === get_option( 'rzpwc_plugin_dismiss_donate_notice' ) + || apply_filters( 'rzpwc/hide_sticky_donate_notice', false ) ) { + $show_donate = false; + } + + if ( $show_donate ) { + $dismiss = wp_nonce_url( add_query_arg( 'rzpwc_notice_action', 'dismiss_donate' ), 'rzpwc_notice_nonce' ); + $no_thanks = wp_nonce_url( add_query_arg( 'rzpwc_notice_action', 'no_thanks_donate' ), 'rzpwc_notice_nonce' ); ?> + +
+

+

  +  | +

+
+ strtotime( '-360 hours' ) ) { - return; - } + // Check for Rating Notice + if ( get_option( 'rzpwc_plugin_no_thanks_rating_notice' ) === '1' + && get_option( 'rzpwc_plugin_dismissed_time' ) <= strtotime( '-14 days' ) ) { delete_option( 'rzpwc_plugin_dismiss_rating_notice' ); delete_option( 'rzpwc_plugin_no_thanks_rating_notice' ); } - if ( ! isset( $_GET['rzpwc_rating_notice_action'] ) ) { + // Check for Donate Notice + if ( get_option( 'rzpwc_plugin_no_thanks_donate_notice' ) === '1' + && get_option( 'rzpwc_plugin_dismissed_time_donate' ) <= strtotime( '-15 days' ) ) { + delete_option( 'rzpwc_plugin_dismiss_donate_notice' ); + delete_option( 'rzpwc_plugin_no_thanks_donate_notice' ); + } + + if ( ! isset( $_REQUEST['rzpwc_notice_action'] ) || empty( $_REQUEST['rzpwc_notice_action'] ) ) { return; } - if ( 'dismiss_rating_true' === $_GET['rzpwc_rating_notice_action'] ) { - check_admin_referer( 'rzpwc_dismiss_rating_true' ); - update_option( 'rzpwc_plugin_dismiss_rating_notice', '1' ); + check_admin_referer( 'rzpwc_notice_nonce' ); + + $notice = sanitize_text_field( $_REQUEST['rzpwc_notice_action'] ); + $notice = explode( '_', $notice ); + $notice_type = end( $notice ); + array_pop( $notice ); + $notice_action = join( '_', $notice ); + + if ( 'dismiss' === $notice_action ) { + update_option( 'rzpwc_plugin_dismiss_' . $notice_type . '_notice', '1' ); } - if ( 'no_thanks_rating_true' === $_GET['rzpwc_rating_notice_action'] ) { - check_admin_referer( 'rzpwc_no_thanks_rating_true' ); - update_option( 'rzpwc_plugin_no_thanks_rating_notice', '1' ); - update_option( 'rzpwc_plugin_dismiss_rating_notice', '1' ); - update_option( 'rzpwc_plugin_dismissed_time', time() ); + if ( 'no_thanks' === $notice_action ) { + update_option( 'rzpwc_plugin_no_thanks_' . $notice_type . '_notice', '1' ); + update_option( 'rzpwc_plugin_dismiss_' . $notice_type . '_notice', '1' ); + if ( 'donate' === $notice_type ) { + update_option( 'rzpwc_plugin_dismissed_time_donate', time() ); + } else { + update_option( 'rzpwc_plugin_dismissed_time', time() ); + } } - wp_redirect( remove_query_arg( 'rzpwc_rating_notice_action' ) ); + wp_redirect( remove_query_arg( [ 'rzpwc_notice_action', '_wpnonce' ] ) ); exit; } diff --git a/includes/payment.php b/includes/payment.php index b99511e..5becf74 100644 --- a/includes/payment.php +++ b/includes/payment.php @@ -2,7 +2,7 @@ /** * The admin-facing functionality of the plugin. * - * @package Razorpay Gateway for WooCommerce + * @package Razorpay Payment Links for WooCommerce * @subpackage Includes * @author Sayan Datta * @license http://www.gnu.org/licenses/ GNU General Public License @@ -13,6 +13,7 @@ function rzpwc_payment_add_gateway_class( $gateways ) { $gateways[] = 'WC_RZP_Woo_Gateway'; // class name + return $gateways; } @@ -68,11 +69,12 @@ public function __construct() { $this->title = $this->get_option( 'title' ); $this->description = $this->get_option( 'description' ); $this->thank_you = $this->get_option( 'thank_you' ); + $this->api_type = $this->get_option( 'api_type', 'legacy' ); $this->testmode = 'yes' === $this->get_option( 'testmode' ); $this->key_id = $this->testmode ? $this->get_option( 'test_key_id' ) : $this->get_option( 'key_id' ); $this->key_secret = $this->testmode ? $this->get_option( 'test_key_secret' ) : $this->get_option( 'key_secret' ); $this->webhook_enabled = $this->get_option( 'webhook_enabled' ); - $this->webhook_secret = $this->testmode ? $this->get_option( 'test_webhook_secret' ) : $this->get_option( 'webhook_secret' ); + $this->webhook_secret = $this->get_option( 'webhook_secret' ); $this->sms_notification = $this->get_option( 'sms_notification' ); $this->email_notification = $this->get_option( 'email_notification' ); $this->reminder = $this->get_option( 'reminder' ); @@ -88,10 +90,23 @@ public function __construct() { $this->description .= ' ' . sprintf( __( 'TESTING MODE ENABLED. You can use Razorpay testing accounts only. See the Razorpay Testing Guide for more details.', 'rzp-woocommerce' ), 'https://razorpay.com/docs/payment-gateway/test-card-details/' ); $this->description = trim( $this->description ); } - - // This action hook saves the settings - add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); + $this->api_mode = 'invoice'; + $this->ref = 'receipt'; + $this->status = 'issued'; + if ( $this->api_type === 'standard' ) { + $this->api_mode = 'payment_link'; + $this->ref = 'reference_id'; + $this->status = 'created'; + } + + // This action hook saves the settings + if ( version_compare( WOOCOMMERCE_VERSION, '2.0.0', '>=' ) ) { + add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); + } else { + add_action( 'woocommerce_update_options_payment_gateways', array( $this, 'process_admin_options' ) ); + } + // verify payment from redirection add_action( 'woocommerce_api_rzp-payment', array( $this, 'capture_payment' ) ); @@ -139,7 +154,10 @@ public static function log( $message, $level = 'info' ) { */ public function process_admin_options() { $saved = parent::process_admin_options(); - + + // auto enable webhook + $this->auto_enable_webhook(); + // Maybe clear logs. if ( 'yes' !== $this->get_option( 'debug_mode', 'no' ) ) { if ( empty( self::$log ) ) { @@ -180,7 +198,9 @@ public function admin_options() { ?>

- : here.', 'rzp-woocommerce' ), 'https://razorpay.com/docs/international-payments/#supported-currencies' ); ?> + : here.', 'rzp-woocommerce' ), 'https://razorpay.com/docs/international-payments/#supported-currencies' ); ?>

form_fields = array( - 'enabled' => array( + 'enabled' => array( 'title' => __( 'Enable/Disable:', 'rzp-woocommerce' ), - 'label' => __( 'Enable Razorpay Gateway', 'rzp-woocommerce' ), + 'label' => __( 'Enable Razorpay Payment Gateway', 'rzp-woocommerce' ), 'type' => 'checkbox', 'description' => __( 'Enable Razorpay Payment Gateway for this website.', 'rzp-woocommerce' ), 'default' => 'yes', - 'desc_tip' => true, + 'desc_tip' => false, ), - 'title' => array( + 'title' => array( 'title' => __( 'Title:', 'rzp-woocommerce' ), 'type' => 'text', 'description' => __( 'This controls the title which the user sees during checkout.', 'rzp-woocommerce' ), 'default' => __( 'Pay with Razorpay', 'rzp-woocommerce' ), - 'desc_tip' => true, + 'desc_tip' => false, ), - 'description' => array( + 'description' => array( 'title' => __( 'Description:', 'rzp-woocommerce' ), 'type' => 'textarea', 'description' => __( 'This controls the description which the user sees during checkout.', 'rzp-woocommerce' ), - 'desc_tip' => true, + 'desc_tip' => false, 'default' => __( 'Pay securely by Credit or Debit card or Internet Banking or UPI or QR Code or Wallets through Razorpay.', 'rzp-woocommerce' ), ), - 'thank_you' => array( + 'thank_you' => array( 'title' => __( 'Thank You Message:', 'rzp-woocommerce' ), 'type' => 'textarea', 'description' => __( 'This displays a message to customer after a successful payment is made.', 'rzp-woocommerce' ), - 'desc_tip' => true, - 'default' => __( 'Thank you for your payment. Your transaction has been completed, and your order has been successfully placed. Please check you Email inbox for details. You can view your bank account to view transaction details.', 'rzp-woocommerce' ), + 'desc_tip' => false, + 'default' => __( 'Thank you for shopping with us. Your account has been charged and your transaction is successful. We will be processing your order soon.', 'rzp-woocommerce' ), ), - 'api_details' => array( + 'api_details' => array( 'title' => __( 'API Credentials', 'rzp-woocommerce' ), 'type' => 'title', 'description' => '', ), - 'key_id' => array( + 'api_type' => array( + 'title' => __( 'Razorpay API Type:', 'rzp-woocommerce' ), + 'type' => 'select', + 'description' => __( 'Select the Razorpay API Type from here. Legacy API will be officially deprecated by Razorpay on March 31, 2021.', 'rzp-woocommerce' ), + 'desc_tip' => false, + 'default' => 'legacy', + 'options' => array( + 'standard' => __( 'Standard API', 'rzp-woocommerce' ), + 'legacy' => __( 'Legacy API', 'rzp-woocommerce' ), + ), + ), + 'key_id' => array( 'title' => __( 'Live Client API Key:', 'rzp-woocommerce' ), 'type' => 'text', 'description' => __( 'The key Id can be generated from "API Keys" section of Razorpay Dashboard. Use live key for live mode.', 'rzp-woocommerce' ), - 'desc_tip' => true, + 'desc_tip' => false, ), - 'key_secret' => array( + 'key_secret' => array( 'title' => __( 'Live Client Secret Key:', 'rzp-woocommerce' ), 'type' => 'password', 'description' => __( 'The key secret can be generated from "API Keys" section of Razorpay Dashboard. Use live secret for live mode.', 'rzp-woocommerce' ), - 'desc_tip' => true, + 'desc_tip' => false, ), - 'testmode' => array( + 'testmode' => array( 'title' => __( 'Test Mode:', 'rzp-woocommerce' ), 'label' => __( 'Enable Test Mode', 'rzp-woocommerce' ), 'type' => 'checkbox', 'description' => __( 'Run the Razorpay Payment Gateway in test mode.', 'rzp-woocommerce' ), 'default' => 'yes', - 'desc_tip' => true, + 'desc_tip' => false, ), - 'test_key_id' => array( + 'test_key_id' => array( 'title' => __( 'Test Client API Key:', 'rzp-woocommerce' ), 'type' => 'text', 'description' => __( 'The key Id can be generated from "API Keys" section of Razorpay Dashboard. Use test key for test mode.', 'rzp-woocommerce' ), - 'desc_tip' => true, + 'desc_tip' => false, ), - 'test_key_secret' => array( + 'test_key_secret' => array( 'title' => __( 'Test Client Secret Key:', 'rzp-woocommerce' ), 'type' => 'password', 'description' => __( 'The key secret can be generated from "API Keys" section of Razorpay Dashboard. Use test secret for test mode.', 'rzp-woocommerce' ), - 'desc_tip' => true, + 'desc_tip' => false, ), - 'webhook_details' => array( + 'webhook_details' => array( 'title' => __( 'Razorpay Webhook', 'rzp-woocommerce' ), 'type' => 'title', - 'description' => sprintf( __( 'Webhook URL: %1$sOnly "%2$s" and "%3$s" action events supported.' ), '' . get_home_url() . '/wc-api/rzp-webhook/
', 'payment.authorized', 'refund.created' ), + 'description' => sprintf( __( 'Webhook URL: %1$sOnly "%2$s" and "%3$s" action events are supported.', 'rzp-woocommerce' ), '' . get_home_url() . '/wc-api/rzp-webhook/
', 'payment.authorized', 'refund.created' ), ), - 'webhook_enabled' => array( + 'webhook_enabled' => array( 'title' => __( 'Razorpay Webhook:', 'rzp-woocommerce' ), 'label' => __( 'Enable Razorpay Webhook', 'rzp-woocommerce' ), 'type' => 'checkbox', 'description' => __( 'Use the above webhook URL in Razorpaay "Settings > Webhooks".', 'rzp-woocommerce' ), 'default' => 'no', - 'desc_tip' => true, + 'desc_tip' => false, ), - 'webhook_secret' => array( - 'title' => __( 'Live Webhook Secret Key:', 'rzp-woocommerce' ), + 'webhook_secret' => array( + 'title' => __( 'Webhook Secret Key:', 'rzp-woocommerce' ), 'type' => 'password', 'description' => __( 'The webhook secret can be generated from "Webhooks" section of Razorpay Dashboard.', 'rzp-woocommerce' ), - 'desc_tip' => true, + 'desc_tip' => false, ), - 'test_webhook_secret' => array( - 'title' => __( 'Test Webhook Secret Key:', 'rzp-woocommerce' ), - 'type' => 'password', - 'description' => __( 'The webhook secret can be generated from "Webhooks" section of Razorpay Dashboard of test account.', 'rzp-woocommerce' ), - 'desc_tip' => true, - ), - 'configure' => array( + 'configure' => array( 'title' => __( 'Razorpay Settings', 'rzp-woocommerce' ), 'type' => 'title', 'description' => '', ), - 'sms_notification' => array( + 'sms_notification' => array( 'title' => __( 'SMS Notification:', 'rzp-woocommerce' ), 'label' => __( 'Enable/Disable', 'rzp-woocommerce' ), 'type' => 'checkbox', 'description' => __( 'Enable this option to send payment links to your customer\'s Mobile Number as a SMS.', 'rzp-woocommerce' ), 'default' => 'no', - 'desc_tip' => true, + 'desc_tip' => false, ), 'email_notification' => array( 'title' => __( 'Email Notification:', 'rzp-woocommerce' ), @@ -303,47 +328,47 @@ public function init_form_fields() { 'type' => 'checkbox', 'description' => __( 'Enable this option to send payment links to your customer\'s Email Address as a Email.', 'rzp-woocommerce' ), 'default' => 'no', - 'desc_tip' => true, + 'desc_tip' => false, ), - 'reminder' => array( + 'reminder' => array( 'title' => __( 'Payment Reminder:', 'rzp-woocommerce' ), 'label' => __( 'Enable/Disable', 'rzp-woocommerce' ), 'type' => 'checkbox', 'description' => __( 'Enable this option to send payment reminder alerts to your customers if they do not completed their payment yet. It only works when you will enable Payment Reminder from your Razorpay Account.', 'rzp-woocommerce' ), 'default' => 'no', - 'desc_tip' => true, + 'desc_tip' => false, ), - 'link_expire' => array( + 'link_expire' => array( 'title' => __( 'Payment Link Auto Expire:', 'rzp-woocommerce' ), 'label' => __( 'Enable/Disable', 'rzp-woocommerce' ), 'type' => 'checkbox', 'description' => __( 'Enable this option to auto expire payment links depending on hold stock duration. It will work only when Stock Management is enabled in WooCommerce Settings.', 'rzp-woocommerce' ), 'default' => 'no', - 'desc_tip' => true, + 'desc_tip' => false, ), - 'gateway_fee' => array( + 'gateway_fee' => array( 'title' => __( 'Payment Gateway Fees:', 'rzp-woocommerce' ), - 'label' => __( 'Collect Razorpay Gateway Fees from Customer', 'rzp-woocommerce' ), + 'label' => __( 'Collect Gateway Fees from Customer', 'rzp-woocommerce' ), 'type' => 'checkbox', 'description' => __( 'Enable this option to collect the Razorpay Gateway Fee from your customers for the payments they make. Gateway fees will be automatically excluded if a refund is made from WordPress dashboard.', 'rzp-woocommerce' ), 'default' => 'no', - 'desc_tip' => true, + 'desc_tip' => false, ), - 'instant_refund' => array( + 'instant_refund' => array( 'title' => __( 'Instant Refund:', 'rzp-woocommerce' ), 'label' => __( 'Enable/Disable', 'rzp-woocommerce' ), 'type' => 'checkbox', - 'description' => __( 'Enable this option to refund instantly. It will only work if Instant Refund is enabled on your account.', 'rzp-woocommerce' ), + 'description' => __( 'Enable this option to refund instantly. It will only work if Instant Refund is enabled on your Razorpay account.', 'rzp-woocommerce' ), 'default' => 'no', - 'desc_tip' => true, + 'desc_tip' => false, ), - 'debug_mode' => array( + 'debug_mode' => array( 'title' => __( 'Debug Mode:', 'rzp-woocommerce' ), 'label' => __( 'Enable/Disable', 'rzp-woocommerce' ), 'type' => 'checkbox', 'description' => __( 'Enable this option to view the detailed communication between the Gateway API and WooCommerce in a WooCommerce log file.', 'rzp-woocommerce' ), 'default' => 'no', - 'desc_tip' => true, + 'desc_tip' => false, ), ); @@ -354,134 +379,122 @@ public function init_form_fields() { */ public function process_payment( $order_id ) { $this->log( "Creating Razorpay Payment Link for Order ID: $order_id" ); + // we need it to get any order details $order = wc_get_order( $order_id ); + // get order meta + $pay_url = $order->get_meta( '_rzp_payment_url', true ); + if ( ! empty( $pay_url ) ) { + // add details to log + $this->log( 'Payment Link already exists: ' . esc_url( $pay_url ) ); + // Redirect to the the payment page + return array( + 'result' => 'success', + 'redirect' => apply_filters( 'rzpwc_payment_init_redirect', esc_url( $pay_url ), $order ), + ); + } + $amount = $order->get_total(); if ( $this->gateway_fee === 'yes' ) { $amount = apply_filters( 'rzpwc_charge_custom_tax_amount', ( $amount / 97.64 ) * 100, $amount, $order ); } - // api url - $api_endpoint = 'https://api.razorpay.com/v1/invoices/'; - - /* - * Array with parameters for API interaction + /** + * Array with parameters for API interaction */ $args = array( - 'type' => 'link', - 'view_less' => 1, - 'amount' => round( $amount * 100 ), - 'currency' => $order->get_currency(), - 'description' => apply_filters( 'rzpwc_payment_init_description', __( 'Order ID: ', 'rzp-woocommerce' ) ) . $order_id, - 'receipt' => substr( $order->get_order_key(), 0, 40 ), - 'customer' => array( - 'name' => html_entity_decode( $order->get_formatted_billing_full_name(), ENT_QUOTES, 'UTF-8' ), - 'email' => $order->get_billing_email(), - 'contact' => substr( $order->get_billing_phone(), -10 ) - ), + 'type' => 'link', + 'view_less' => 1, + 'amount' => (int) round( $amount * 100 ), + 'currency' => $this->get_wc_order_currency( $order ), + 'description' => 'Order ID: ' . $order->get_order_number(), + $this->ref => substr( $order->get_order_key(), 0, 40 ), + 'customer' => $this->get_wc_customer_info( $order ), 'reminder_enable' => ( $this->reminder === 'yes' ) ? true : false, - 'sms_notify' => ( $this->sms_notification === 'yes' ) ? 1 : 0, - 'email_notify' => ( $this->email_notification === 'yes' ) ? 1 : 0, - 'notes' => array( - 'full_name' => html_entity_decode( $order->get_formatted_billing_full_name(), ENT_QUOTES, 'UTF-8' ), - 'email' => $order->get_billing_email(), - 'contact' => substr( $order->get_billing_phone(), -10 ), - 'woocommerce_order_id' => $order_id - ), - 'callback_url' => get_home_url().'/wc-api/rzp-payment/?order_id='.$order_id, + 'sms_notify' => ( $this->sms_notification === 'yes' ) ? 1 : 0, + 'email_notify' => ( $this->email_notification === 'yes' ) ? 1 : 0, + 'notes' => array_merge( $this->get_wc_customer_info( $order ), array( + 'woocommerce_order_id' => $order_id, + 'woocommerce_order_number' => $order->get_order_number(), + ) ), + 'callback_url' => trailingslashit( get_home_url( null, 'wc-api/rzp-payment' ) ), 'callback_method' => 'get', ); + if ( 'standard' === $this->api_type ) { + unset( $args['type'] ); + unset( $args['view_less'] ); + unset( $args['sms_notify'] ); + unset( $args['email_notify'] ); + + $args['notify']['sms'] = ( $this->sms_notification === 'yes' ) ? true : false; + $args['notify']['email'] = ( $this->email_notification === 'yes' ) ? true : false; + $args['upi_link'] = false; + } + $held_duration = apply_filters( 'rzpwc_payment_link_expire_duration', get_option( 'woocommerce_hold_stock_minutes' ) ); if ( $this->link_expire === 'yes' && 'yes' === get_option( 'woocommerce_manage_stock' ) && $held_duration >= 1 ) { $args['expire_by'] = time() + ( absint( $held_duration ) * 60 ); } - $args = apply_filters( 'rzpwc_payment_init_payload', $args, $order ); + $args = apply_filters( 'rzpwc_payment_init_payload', $args, $order, $this->testmode ); $this->log( 'Data sent for creating Payment Link: ' . wc_print_r( $args, true ) ); - // get order meta - $pay_url = $order->get_meta( '_rzp_payment_url', true ); + do_action( 'rzpwc_after_payment_init', $order_id, $order ); - if ( empty( $pay_url ) ) { + // make api request + $response = $this->api_data( $this->api_mode . 's/', wp_json_encode( $args ) ); + + // check is not error + if ( is_wp_error( $response ) ) { + // log + $this->log( 'Payment Link Generation Failed: ' . $response->get_error_message(), 'error' ); + + // add error notice + wc_add_notice( __( 'Error Occured! Please change API Type form plugin settings or contact with Site Administrator to resolve this issue.', 'rzp-woocommerce' ), 'error' ); + return; - $this->log( "Key ID: $this->key_id | Key Secret: $this->key_secret" ); + } else { + // get data + $body = json_decode( wp_remote_retrieve_body( $response ), true ); + + $this->log( 'Razorpay response on creating Payment Link: ' . wc_print_r( $body, true ) ); - $auth = base64_encode( $this->key_id . ':' . $this->key_secret ); - - /* - * Build API interaction - */ - $response = wp_remote_post( $api_endpoint, array( - 'body' => json_encode( $args ), - 'headers' => array( - 'Content-Type' => 'application/json', - 'Authorization' => "Basic $auth", - ) ) - ); - - if ( is_wp_error( $response ) ) { + // check the json response from Razorpay payment processor + if ( isset( $body['status'] ) && $this->status === $body['status'] ) { + // we received the payment init request + $order->update_status( apply_filters( 'rzpwc_order_status_on_payment_init', 'pending' ) ); - $this->log( 'Payment Link Generation Failed: ' . $response->get_error_message(), 'error' ); - - // add error notice - wc_add_notice( __( 'Error Occured! Please contact with Site Administrator to resolve this issue.', 'rzp-woocommerce' ), 'error' ); - return; + // update post metas + update_post_meta( $order->get_id(), '_rzp_invoice_id', esc_attr( $body['id'] ) ); + update_post_meta( $order->get_id(), '_rzp_payment_url', esc_url( $body['short_url'] ) ); - } else { - - $body = json_decode( wp_remote_retrieve_body( $response ), true ); + // add some order notes + $order->add_order_note( __( 'Payment is Pending against this order. URL: ', 'rzp-woocommerce' ) . esc_url( $body['short_url'] ), false ); - $this->log( 'Response from server on creating Payment Link: ' . wc_print_r( $body, true ) ); - - // check the json response from Razorpay payment processor - if ( isset( $body['status'] ) && $body['status'] === 'issued' ) { - - // we received the payment init request - $order->update_status( apply_filters( 'rzpwc_order_status_on_payment_init', 'pending' ) ); - - update_post_meta( $order->get_id(), '_rzp_receipt_id', esc_attr( $body['receipt'] ) ); - update_post_meta( $order->get_id(), '_rzp_order_id', esc_attr( $body['order_id'] ) ); - update_post_meta( $order->get_id(), '_rzp_invoice_id', esc_attr( $body['id'] ) ); - update_post_meta( $order->get_id(), '_rzp_payment_url', esc_url( $body['short_url'] ) ); - - // add some order notes - $order->add_order_note( __( 'Payment is Pending against this order. URL: ', 'rzp-woocommerce' ) . esc_url( $body['short_url'] ), false ); - + if ( apply_filters( 'rzpwc_payment_empty_cart', false ) ) { // Empty cart WC()->cart->empty_cart(); - - // Redirect to the the payment page - return array( - 'result' => 'success', - 'redirect' => apply_filters( 'rzpwc_payment_init_redirect', esc_url( $body['short_url'] ), $order ) - ); - - } elseif ( isset( $body['error'] ) ) { - - $this->log( __( 'Error Occured: ', 'rzp-woocommerce' ) . esc_attr( $body['error']['code'] ) . ' : ' . esc_attr( $body['error']['description'] ) ); - - // add order note - $order->add_order_note( esc_attr( $body['error']['code'] ) . ' : ' . esc_attr( $body['error']['description'] ), false ); - - // add error notice - wc_add_notice( __( 'Connection Error Occured! Please try again.', 'rzp-woocommerce' ), 'error' ); - return; - } - - } - } else { - // add details to log - $this->log( 'Payment Link already exists: ' . esc_url( $pay_url ) ); - // Redirect to the the payment page - return array( - 'result' => 'success', - 'redirect' => apply_filters( 'rzpwc_payment_init_redirect', esc_url( $pay_url ) ) - ); + // Redirect to the the payment page + return array( + 'result' => 'success', + 'redirect' => apply_filters( 'rzpwc_payment_init_redirect', esc_url( $body['short_url'] ), $order ), + ); + } elseif ( isset( $body['error'] ) ) { + // log + $this->log( __( 'Error Occured: ', 'rzp-woocommerce' ) . esc_attr( $body['error']['code'] ) . ' : ' . esc_attr( $body['error']['description'] ) ); + + // add order note + $order->add_order_note( esc_attr( $body['error']['code'] ) . ' : ' . esc_attr( $body['error']['description'] ), false ); + + // add error notice + wc_add_notice( __( 'Connection Error Occured! Please try again.', 'rzp-woocommerce' ), 'error' ); + return; + } } } @@ -500,7 +513,7 @@ public function can_refund_order( $order ) { $has_api_creds = $this->get_option( 'key_id' ) && $this->get_option( 'key_secret' ); } - return $order && $order->get_transaction_id() && ! $order->get_meta( '_rzp_refund_id', true ) && $has_api_creds; + return $order && $order->get_transaction_id() && $has_api_creds; } /** @@ -523,13 +536,15 @@ public function process_refund( $order_id, $amount = null, $reason = '' ) { // get order meta $payment_id = $order->get_transaction_id(); - + $refund_ids = maybe_unserialize( $order->get_meta( '_rzp_refund_ids', true ) ); + if ( empty( $refund_ids ) ) $refund_ids = array(); + // build array $args = array(); // amount if ( ! is_null( $amount ) ) { - $args['amount'] = round( $amount * 100 ); + $args['amount'] = (int) round( $amount * 100 ); } $args['speed'] = ( $this->instant_refund === 'yes' ) ? 'optimum' : 'normal'; @@ -537,30 +552,18 @@ public function process_refund( $order_id, $amount = null, $reason = '' ) { // add notes to array $args['notes']['comment'] = ! empty( $reason ) ? $reason : __( 'No reason specified!', 'rzp-woocommerce' ); $args['notes']['woocommerce_order_id'] = $order->get_id(); + $args['notes']['woocommerce_order_number'] = $order->get_order_number(); + $args['notes']['refund_from_website'] = true; + $args['notes']['source'] = 'woocommerce'; $args = apply_filters( 'rzpwc_payment_refund_payload', $args, $order ); $this->log( 'Data sent for Refund: ' . wc_print_r( $args, true ) ); - // api url - $api_endpoint = 'https://api.razorpay.com/v1/payments/'.$payment_id.'/refund'; - - $this->log( "Key ID: $this->key_id | Key Secret: $this->key_secret" ); - - $auth = base64_encode( $this->key_id . ':' . $this->key_secret ); - - /* - * Build API interaction - */ - $response = wp_remote_post( $api_endpoint, array( - 'body' => json_encode( $args ), - 'headers' => array( - 'Content-Type' => 'application/json', - 'Authorization' => "Basic $auth", - ) ) - ); + // make api request + $response = $this->api_data( 'payments/' . $payment_id . '/refund', wp_json_encode( $args ) ); - if( is_wp_error( $response ) ) { + if ( is_wp_error( $response ) ) { $this->log( 'Refund Capture Failed: ' . $response->get_error_message(), 'error' ); /* translators: %s: Razorpay gateway error message */ @@ -575,10 +578,14 @@ public function process_refund( $order_id, $amount = null, $reason = '' ) { // check the json response from Razorpay payment processor if ( isset( $body['entity'] ) && $body['entity'] === 'refund' ) { + $refund_ids[] = esc_attr( $body['id'] ); + // add order note - $order->add_order_note( sprintf( __( 'Amount Refunded. Rs. %1$s
Refund ID: %2$s
Reason: %3$s' ), esc_attr( round( $body['amount'] / 100 ) ), esc_attr( $body['id'] ), esc_attr( $body['notes']['comment'] ) ), false ); + $order->add_order_note( sprintf( __( 'Amount Refunded. Rs. %1$s
Refund ID: %2$s
Reason: %3$s', 'rzp-woocommerce' ), esc_attr( round( $body['amount'] / 100 ) ), esc_attr( $body['id'] ), esc_attr( $body['notes']['comment'] ) ), false ); + // store refund id to meta update_post_meta( $order->get_id(), '_rzp_refund_id', esc_attr( $body['id'] ) ); + update_post_meta( $order->get_id(), '_rzp_refund_ids', maybe_serialize( $refund_ids ) ); delete_post_meta( $order->get_id(), '_rzp_payment_url' ); return true; @@ -598,75 +605,82 @@ public function process_refund( $order_id, $amount = null, $reason = '' ) { */ public function capture_payment() { // check server request method - if ( 'GET' !== $_SERVER['REQUEST_METHOD'] ) { + if ( empty( $_SERVER['REQUEST_METHOD'] ) || 'GET' !== $_SERVER['REQUEST_METHOD'] ) { // create redirect wp_safe_redirect( home_url() ); exit; } // check GET veriables - if( ! isset( $_GET['order_id'], $_GET['razorpay_payment_id'], $_GET['razorpay_invoice_id'], $_GET['razorpay_invoice_receipt'], $_GET['razorpay_invoice_status'], $_GET['razorpay_signature'] ) ) { + if ( ! isset( $_GET['razorpay_payment_id'], $_GET[ 'razorpay_' . $this->api_mode . '_id' ], $_GET[ 'razorpay_' . $this->api_mode . '_' . $this->ref ], $_GET[ 'razorpay_' . $this->api_mode . '_status' ], $_GET['razorpay_signature'] ) ) { $this->log( 'Missing the nessesary GET variables.' ); // create redirect wp_safe_redirect( home_url() ); exit; } + $ref = sanitize_text_field( wp_unslash( $_GET[ 'razorpay_' . $this->api_mode . '_' . $this->ref ] ) ); + $id = sanitize_text_field( wp_unslash( $_GET[ 'razorpay_' . $this->api_mode . '_id' ] ) ); + $status = sanitize_text_field( wp_unslash( $_GET[ 'razorpay_' . $this->api_mode . '_status' ] ) ); + $payment_id = sanitize_text_field( wp_unslash( $_GET['razorpay_payment_id'] ) ); + $signature = sanitize_text_field( wp_unslash( $_GET['razorpay_signature'] ) ); + + // get wc order id + $order_id = wc_get_order_id_by_order_key( $ref ); + // generate order - $order = wc_get_order( $_GET['order_id'] ); + $order = wc_get_order( $order_id ); // check if it an order if ( ! is_a( $order, 'WC_Order' ) ) { $title = __( 'Order can\'t be found against this payment. If the money deducted from your account, please contact with Site Administrator for further action. Thanks for your understanding.', 'rzp-woocommerce' ); - wp_die( $title, get_bloginfo( 'name' ) ); + wp_die( esc_html( $title ), esc_html( get_bloginfo( 'name' ) ) ); exit; } // load get data - $signature_payload = esc_attr( $_GET['razorpay_invoice_id'] ) . '|' . esc_attr( $_GET['razorpay_invoice_receipt'] ) . '|' . esc_attr( $_GET['razorpay_invoice_status'] ) . '|' . esc_attr( $_GET['razorpay_payment_id'] ); + //$signature_payload = esc_attr( $_GET[ 'razorpay_'.$this->api_mode.'_id' ] ) . '|' . esc_attr( $_GET[ 'razorpay_'.$this->api_mode.'_'.$this->ref ] ) . '|' . esc_attr( $_GET[ 'razorpay_'.$this->api_mode.'_status' ] ) . '|' . esc_attr( $_GET['razorpay_payment_id'] ); + + $signature_payload = join( '|', compact( 'id', 'ref', 'status', 'payment_id' ) ); $this->log( "Payload: $signature_payload" ); // generate hash $expected_signature = hash_hmac( 'sha256', $signature_payload, $this->key_secret ); - $this->log( "Original Signature: " . esc_attr( $_GET['razorpay_signature'] ) ); + $this->log( "Original Signature: " . $signature ); $this->log( "Generated Signature: $expected_signature" ); // match signatures - if( hash_equals( $expected_signature, esc_attr( $_GET['razorpay_signature'] ) ) ) { + if ( hash_equals( $expected_signature, $signature ) ) { $this->log( 'Original and Generated Signature matched.' ); - // check order info - if ( $this->id === $order->get_payment_method() && $order->needs_payment() === true ) { + // check order info + if ( $this->id === $order->get_payment_method() && true === $order->needs_payment() ) { // update the payment reference - $order->payment_complete( esc_attr( $_GET['razorpay_payment_id'] ) ); + $order->payment_complete( $payment_id ); // reduce stock wc_reduce_stock_levels( $order->get_id() ); // add some order notes - $order->add_order_note( __( 'Payment is Successful against this order.
Transaction ID: ', 'rzp-woocommerce' ) . esc_attr( $_GET['razorpay_payment_id'] ), false ); + $order->add_order_note( __( 'Payment is Successful against this order.
Transaction ID: ', 'rzp-woocommerce' ) . $payment_id, false ); // remove old payment link delete_post_meta( $order->get_id(), '_rzp_payment_url' ); $this->log( 'Order marked as paid successfully. Redirecting...' ); } - wp_safe_redirect( apply_filters( 'rzpwc_payment_success_redirect', $this->get_return_url( $order ), $order ) ); - exit; } else { $this->log( 'Original and Generated Signature mismatched. Transaction verfication failed!' ); // update the order status $order->update_status( 'failed' ); - - $title = apply_filters( 'rzpwc_payment_signature_verify_failed_text', __( 'Signature Verification Failed. If the money debited from your account, please Contact with Site Administrator for further action.', 'rzp-woocommerce' ) ); - - wp_die( $title, get_bloginfo( 'name' ) ); - exit; } + // create redirect + wp_safe_redirect( apply_filters( 'rzpwc_after_payment_redirect', $this->get_return_url( $order ), $order ) ); + exit; } /** @@ -681,27 +695,12 @@ public function cancel_payment_link( $order_id ) { // get order meta $inv_id = $order->get_meta( '_rzp_invoice_id', true ); $pay_url = $order->get_meta( '_rzp_payment_url', true ); - $refund_id = $order->get_meta( '_rzp_refund_id', true ); - if( 'yes' === $this->enabled && ( ( $this->id !== $order->get_payment_method() && $order->has_status( 'processing' ) ) || $order->has_status( 'cancelled' ) ) && ! empty( $pay_url ) && ! empty( $inv_id ) ) { - // api url - $api_endpoint = 'https://api.razorpay.com/v1/invoices/'.$inv_id.'/cancel'; - - $this->log( "Key ID: $this->key_id | Key Secret: $this->key_secret" ); - - $auth = base64_encode( $this->key_id . ':' . $this->key_secret ); - - /* - * Build API interaction - */ - $response = wp_remote_post( $api_endpoint, array( - 'headers' => array( - 'Content-Type' => 'application/json', - 'Authorization' => "Basic $auth", - ) ) - ); + if ( 'yes' === $this->enabled && ( ( $this->id !== $order->get_payment_method() && $order->has_status( 'processing' ) ) || $order->has_status( 'cancelled' ) ) && ! empty( $pay_url ) && ! empty( $inv_id ) ) { + // make api request + $response = $this->api_data( $this->api_mode . 's/' . $inv_id . '/cancel' ); - if( is_wp_error( $response ) ) { + if ( is_wp_error( $response ) ) { $this->log( 'Link Cancellation Failed: ' . $response->get_error_message(), 'error' ); @@ -765,24 +764,18 @@ public function custom_checkout_url( $url, $order ) { } /** - * Process webhook payloads. - */ - public function process_webhook() { - // check server request method - if ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) { - // create redirect - wp_safe_redirect( home_url() ); - exit; - } - + * Process webhook payloads. + */ + public function process_webhook() { + // Catch php input. $post = file_get_contents( 'php://input' ); $data = json_decode( $post, true ); if ( json_last_error() !== 0 ) { return; } - if ( $this->webhook_enabled === 'yes' && ! empty( $this->webhook_secret ) && ! empty( $data['event'] ) ) { - if ( isset( $_SERVER['HTTP_X_RAZORPAY_SIGNATURE'] ) ) { + if ( 'yes' === $this->webhook_enabled && ! empty( $this->webhook_secret ) && ! empty( $data['event'] ) ) { + if ( ! empty( $_SERVER['HTTP_X_RAZORPAY_SIGNATURE'] ) ) { // generate hash $expected_signature = hash_hmac( 'sha256', $post, $this->webhook_secret ); // check signatures @@ -804,28 +797,28 @@ public function process_webhook() { } /** - * Process order update. - * - * @param array $data - */ + * Process order update. + * + * @param array $data + */ private function webhook_update_order( $data ) { // get payloads - $razorpayPaymentId = $data['payload']['payment']['entity']['id']; - $razorpayStatus = $data['payload']['payment']['entity']['status']; - $orderId = $data['payload']['payment']['entity']['notes']['woocommerce_order_id']; - $order = wc_get_order( $orderId ); + $rzp_payment_id = $data['payload']['payment']['entity']['id']; + $rzp_status = $data['payload']['payment']['entity']['status']; + $wc_order_id = $data['payload']['payment']['entity']['notes']['woocommerce_order_id']; + $order = wc_get_order( absint( $wc_order_id ) ); // check if it an order if ( is_a( $order, 'WC_Order' ) ) { - if ( ! empty( $razorpayStatus ) && $razorpayStatus === 'authorized' && $order->needs_payment() === true ) { + if ( ! empty( $rzp_status ) && $rzp_status === 'authorized' && $order->needs_payment() === true ) { // update the payment reference - $order->payment_complete( esc_attr( $razorpayPaymentId ) ); + $order->payment_complete( sanitize_text_field( $rzp_payment_id ) ); // reduce stock wc_reduce_stock_levels( $order->get_id() ); // add some order notes - $order->add_order_note( __( 'Payment is Successful against this order.
Transaction ID: ', 'rzp-woocommerce' ) . esc_attr( $razorpayPaymentId ), false ); + $order->add_order_note( __( 'Payment is Successful against this order.
Transaction ID: ', 'rzp-woocommerce' ) . sanitize_text_field( $rzp_payment_id ), false ); } } } @@ -837,35 +830,39 @@ private function webhook_update_order( $data ) { */ private function webhook_refund_order( $data ) { // get payloads - $refundId = $data['payload']['refund']['entity']['id']; - $razorpayPaymentId = $data['payload']['refund']['entity']['payment_id']; - $refund_amount = round( ( $data['payload']['refund']['entity']['amount'] / 100 ), 2 ); + $rzp_refund_id = $data['payload']['refund']['entity']['id']; + $rzp_payment_id = $data['payload']['refund']['entity']['payment_id']; + $refund_amount = (int) round( ( $data['payload']['refund']['entity']['amount'] / 100 ), 2 ); $refund_reason = $data['payload']['refund']['entity']['notes']['comment']; - - if ( isset( $data['payload']['refund']['entity']['notes']['woocommerce_order_id'] ) ) { - $orderId = $data['payload']['refund']['entity']['notes']['woocommerce_order_id']; - } else { - $orderId = $this->get_wc_order_id( $razorpayPaymentId ); - } - - $order = wc_get_order( $orderId ); - + + $wc_order_id = $data['payload']['payment']['entity']['notes']['woocommerce_order_id']; + $order = wc_get_order( absint( $wc_order_id ) ); + $refund_ids = maybe_unserialize( $order->get_meta( '_rzp_refund_ids', true ) ); + if ( empty( $refund_ids ) ) $refund_ids = array(); + // check if it an order - if( is_a( $order, 'WC_Order' ) ) { + if ( is_a( $order, 'WC_Order' ) ) { // If it is already marked as unpaid, ignore the event - if ( $order->needs_payment() === false && ! $order->has_status( 'refunded' ) ) { + if ( $order->needs_payment() === false && ! $order->has_status( 'refunded' ) && ! in_array( $rzp_refund_id, $refund_ids ) ) { + $refund_ids[] = esc_attr( $rzp_refund_id ); + + // create refund wc_create_refund( array( 'amount' => $refund_amount, 'reason' => $refund_reason, 'order_id' => $order->get_id(), + 'refund_id' => $rzp_refund_id, 'line_items' => array(), 'refund_payment' => false, - 'restock_items' => true + 'restock_items' => true, ) ); + // add some order notes - $order->add_order_note( __( 'Order amount is refunded.
Refund ID: ', 'rzp-woocommerce' ) . esc_attr( $refundId ), false ); + $order->add_order_note( sprintf( __( 'Order amount is refunded.
Refund ID: %s', 'rzp-woocommerce' ), esc_attr( $rzp_refund_id ) ), false ); + // store refund id to meta - update_post_meta( $order->get_id(), '_rzp_refund_id', esc_attr( $refundId ) ); + update_post_meta( $order->get_id(), '_rzp_refund_id', esc_attr( $rzp_refund_id ) ); + update_post_meta( $order->get_id(), '_rzp_refund_ids', maybe_serialize( $refund_ids ) ); } } @@ -873,39 +870,175 @@ private function webhook_refund_order( $data ) { exit; } + public function auto_enable_webhook() { + $webhook_exist = false; + $webhook_url = esc_url( get_home_url( null, '/wc-api/rzp-webhook/' ) ); + $webhook_enabled = $this->get_option( 'webhook_enabled' ); + $webhook_secret = $this->get_option( 'webhook_secret' ); + $webhook_events = array( + 'payment.authorized' => true, + 'refund.created' => true, + ); + + if ( 'no' === $this->webhook_enabled ) { + return; + } + + $domain = wp_parse_url( $webhook_url ); + $domain_ip = gethostbyname( $domain['host'] ); + if ( ! filter_var( $domain_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) { + $this->update_option( 'webhook_enabled', 'no' ); ?> +
+

+
+ +
+

+
+ $webhook_url, + 'active' => false, + ); + } else { + $data = array( + 'url' => $webhook_url, + 'active' => true, + 'events' => $webhook_events, + 'secret' => $webhook_secret, + ); + } + + $webhook = $this->webhook_data( 'GET', 'webhooks/' ); + if ( $webhook ) { + foreach ( $webhook['items'] as $key => $value ) { + if ( $value['url'] === $webhook_url ) { + $webhook_exist = true; + $webhook_id = $value['id']; + } + } + } + + if ( $webhook_exist ) { + $this->webhook_data( 'PUT', 'webhooks/' . $webhook_id, wp_json_encode( $data ) ); + } else { + $this->webhook_data( 'POST', 'webhooks/', wp_json_encode( $data ) ); + } + } + /** - * Get WC Order ID. - * - * @param string $payment_id - */ - private function get_wc_order_id( $payment_id ) { + * Alter Webhook Data using API. + * + * @param string $method cURL Method + * @param string $url API URL + * @param string $data Body Data + */ + private function webhook_data( $method, $url, $data = null ) { + // make api request + $response = $this->api_data( $url, $data, $method ); + + if ( is_wp_error( $response ) ) { + $this->log( 'Webhook Action Failed: ' . $response->get_error_message(), 'error' ); + + return false; + + } else { + $body = json_decode( wp_remote_retrieve_body( $response ), true ); + + return $body; + } + } + + /** + * Interact with Razorpay API. + * + * @param string $url API URL + * @param string $data Body Data + * @param string $method cURL Method + */ + private function api_data( $url, $data = null, $method = 'POST' ) { // api url - $api_endpoint = 'https://api.razorpay.com/v1/payments/'.$payment_id; + $api_endpoint = 'https://api.razorpay.com/v1/' . $url; + + $this->log( "Key ID: $this->key_id | Key Secret: $this->key_secret" ); + $auth = base64_encode( $this->key_id . ':' . $this->key_secret ); + if ( ! is_null( $data ) && is_array( $data ) ) { + $data = wp_json_encode( $data ); + } + /* * Build API interaction - */ - $response = wp_remote_get( $api_endpoint, array( + */ + $response = wp_remote_request( $api_endpoint, array( + 'body' => $data, + 'method' => $method, 'headers' => array( - 'Content-Type' => 'application/json', - 'Authorization' => "Basic $auth", - ) ) + 'Content-Type' => 'application/json', + 'Authorization' => "Basic $auth", + ), + ) ); - - if( is_wp_error( $response ) ) { - return; + + return $response; + } + + /** + * Get Cutomer Info. + * + * @param string $order WC_Order Object + */ + private function get_wc_customer_info( $order ) { + if ( version_compare( WOOCOMMERCE_VERSION, '2.7.0', '>=' ) ) { + $args = array( + 'name' => html_entity_decode( $order->get_formatted_billing_full_name(), ENT_QUOTES, 'UTF-8' ), + 'email' => $order->get_billing_email(), + 'contact' => ( $this->api_type === 'standard' ) ? '+91' . substr( $order->get_billing_phone(), -10 ) : substr( $order->get_billing_phone(), -10 ), + ); + } else { + $args = array( + 'name' => $order->billing_first_name . ' ' . $order->billing_last_name, + 'email' => $order->billing_email, + 'contact' => $order->billing_phone, + ); } - - $body = json_decode( wp_remote_retrieve_body( $response ), true ); - - $orderId = $body['notes']['woocommerce_order_id']; - - if ( ! empty( $orderId ) ) { - return $orderId; + + return $args; + } + + /** + * Get WC Order Key + * + * @param WC_Order $order + * @return string Order Key + */ + private function get_wc_order_key( $order ) { + if ( version_compare( WOOCOMMERCE_VERSION, '3.0.0', '>=' ) ) { + return $order->get_order_key(); } - - return false; + + return $order->order_key; + } + + /** + * @param WC_Order $order + * @return string Currency + */ + private function get_wc_order_currency( $order ) { + if ( version_compare( WOOCOMMERCE_VERSION, '2.7.0', '>=' ) ) { + return $order->get_currency(); + } + + return $order->get_order_currency(); } } } \ No newline at end of file diff --git a/languages/rzp-woocommerce.pot b/languages/rzp-woocommerce.pot index 1bf5ec1..b225dd0 100644 --- a/languages/rzp-woocommerce.pot +++ b/languages/rzp-woocommerce.pot @@ -1,447 +1,395 @@ -#, fuzzy +# Copyright (C) 2022 Sayan Datta +# This file is distributed under the GPLv3. msgid "" msgstr "" -"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -"Project-Id-Version: Razorpay Gateway for WooCommerce\n" -"POT-Creation-Date: 2020-05-24 12:09+0530\n" -"PO-Revision-Date: 2020-01-25 23:09+0530\n" -"Last-Translator: \n" -"Language-Team: Sayan Datta \n" +"Project-Id-Version: Razorpay Payment Links for WooCommerce 1.1.6\n" +"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/rzp-woocommerce\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.2\n" -"X-Poedit-Basepath: ..\n" -"X-Poedit-Flags-xgettext: --add-comments=translators:\n" -"X-Poedit-WPHeader: rzp-woocommerce.php\n" -"X-Poedit-SourceCharset: UTF-8\n" -"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;" -"esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;" -"_nx_noop:3c,1,2;__ngettext_noop:1,2\n" -"X-Poedit-SearchPath-0: .\n" -"X-Poedit-SearchPathExcluded-0: *.js\n" - -#: includes/notice.php:28 -msgid "" -"Hey, I noticed you've been using Razorpay Gateway for WooCommerce for more " -"than 1 week – that’s awesome! Could you please do me a BIG favor and give it " -"a 5-star rating on WordPress? Just to help me spread the " -"word and boost my motivation." +"POT-Creation-Date: 2022-07-15T04:47:17+00:00\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"X-Generator: WP-CLI 2.5.0\n" +"X-Domain: rzp-woocommerce\n" + +#. Plugin Name of the plugin +msgid "Razorpay Payment Links for WooCommerce" +msgstr "" + +#. Plugin URI of the plugin +msgid "https://wordpress.org/plugins/rzp-woocommerce/" +msgstr "" + +#. Description of the plugin +msgid "The easiest and most secure solution to collect payments with WooCommerce. Allow customers to securely pay via Razorpay (Credit/Debit Cards, NetBanking, UPI, Wallets, QR Code)." +msgstr "" + +#. Author of the plugin +msgid "Sayan Datta" +msgstr "" + +#. Author URI of the plugin +msgid "https://sayandatta.in" msgstr "" -#: includes/notice.php:29 +#: includes/notice.php:33 msgid "Ok, you deserve it" msgstr "" -#: includes/notice.php:30 +#: includes/notice.php:34 msgid "I already did" msgstr "" -#: includes/notice.php:31 +#: includes/notice.php:35 +#: includes/notice.php:55 msgid "Nope, maybe later" msgstr "" -#: includes/payment.php:53 -msgid "Razorpay Payment Gateway" +#: includes/notice.php:53 +msgid "Donate Now" +msgstr "" + +#: includes/notice.php:54 +msgid "I already donated" msgstr "" #: includes/payment.php:54 -msgid "" -"Allow customers to securely pay via Razorpay Payment Links using Credit/" -"Debit Cards, NetBanking, UPI, Wallets, QR Codes." +msgid "Razorpay Payment Gateway" msgstr "" #: includes/payment.php:55 +msgid "Allow customers to securely pay via Razorpay Payment Links using Credit/Debit Cards, NetBanking, UPI, Wallets, QR Codes." +msgstr "" + +#: includes/payment.php:56 msgid "Proceed to Payment" msgstr "" -#: includes/payment.php:86 +#: includes/payment.php:88 msgid "(Test Mode)" msgstr "" #. translators: %s: Link to Razorpay testing guide page -#: includes/payment.php:88 -#, php-format -msgid "" -"TESTING MODE ENABLED. You can use Razorpay testing accounts only. See the Razorpay Testing Guide for more details." +#: includes/payment.php:90 +msgid "TESTING MODE ENABLED. You can use Razorpay testing accounts only. See the Razorpay Testing Guide for more details." msgstr "" -#: includes/payment.php:183 +#: includes/payment.php:201 msgid "Gateway disabled" msgstr "" -#: includes/payment.php:183 -#, php-format -msgid "" -"Razorpay does not support your store currency. Please check the supported " -"currency list from here." +#. translators: %s: Link to Razorpay currency page +#: includes/payment.php:203 +msgid "Razorpay does not support your store currency. Please check the supported currency list from here." msgstr "" -#: includes/payment.php:197 +#: includes/payment.php:217 msgid "Enable/Disable:" msgstr "" -#: includes/payment.php:198 -msgid "Enable Razorpay Gateway" +#: includes/payment.php:218 +msgid "Enable Razorpay Payment Gateway" msgstr "" -#: includes/payment.php:200 +#: includes/payment.php:220 msgid "Enable Razorpay Payment Gateway for this website." msgstr "" -#: includes/payment.php:205 +#: includes/payment.php:225 msgid "Title:" msgstr "" -#: includes/payment.php:207 +#: includes/payment.php:227 msgid "This controls the title which the user sees during checkout." msgstr "" -#: includes/payment.php:208 +#: includes/payment.php:228 msgid "Pay with Razorpay" msgstr "" -#: includes/payment.php:212 +#: includes/payment.php:232 msgid "Description:" msgstr "" -#: includes/payment.php:214 +#: includes/payment.php:234 msgid "This controls the description which the user sees during checkout." msgstr "" -#: includes/payment.php:216 -msgid "" -"Pay securely by Credit or Debit card or Internet Banking or UPI or QR Code " -"or Wallets through Razorpay." +#: includes/payment.php:236 +msgid "Pay securely by Credit or Debit card or Internet Banking or UPI or QR Code or Wallets through Razorpay." msgstr "" -#: includes/payment.php:219 +#: includes/payment.php:239 msgid "Thank You Message:" msgstr "" -#: includes/payment.php:221 +#: includes/payment.php:241 msgid "This displays a message to customer after a successful payment is made." msgstr "" -#: includes/payment.php:223 -msgid "" -"Thank you for your payment. Your transaction has been completed, and your " -"order has been successfully placed. Please check you Email inbox for " -"details. You can view your bank account to view transaction details." +#: includes/payment.php:243 +msgid "Thank you for shopping with us. Your account has been charged and your transaction is successful. We will be processing your order soon." msgstr "" -#: includes/payment.php:226 +#: includes/payment.php:246 msgid "API Credentials" msgstr "" -#: includes/payment.php:231 +#: includes/payment.php:251 +msgid "Razorpay API Type:" +msgstr "" + +#: includes/payment.php:253 +msgid "Select the Razorpay API Type from here. Legacy API will be officially deprecated by Razorpay on March 31, 2021." +msgstr "" + +#: includes/payment.php:257 +msgid "Standard API" +msgstr "" + +#: includes/payment.php:258 +msgid "Legacy API" +msgstr "" + +#: includes/payment.php:262 msgid "Live Client API Key:" msgstr "" -#: includes/payment.php:233 -msgid "" -"The key Id can be generated from \"API Keys\" section of Razorpay Dashboard. " -"Use live key for live mode." +#: includes/payment.php:264 +msgid "The key Id can be generated from \"API Keys\" section of Razorpay Dashboard. Use live key for live mode." msgstr "" -#: includes/payment.php:237 +#: includes/payment.php:268 msgid "Live Client Secret Key:" msgstr "" -#: includes/payment.php:239 -msgid "" -"The key secret can be generated from \"API Keys\" section of Razorpay " -"Dashboard. Use live secret for live mode." +#: includes/payment.php:270 +msgid "The key secret can be generated from \"API Keys\" section of Razorpay Dashboard. Use live secret for live mode." msgstr "" -#: includes/payment.php:243 +#: includes/payment.php:274 msgid "Test Mode:" msgstr "" -#: includes/payment.php:244 +#: includes/payment.php:275 msgid "Enable Test Mode" msgstr "" -#: includes/payment.php:246 +#: includes/payment.php:277 msgid "Run the Razorpay Payment Gateway in test mode." msgstr "" -#: includes/payment.php:251 +#: includes/payment.php:282 msgid "Test Client API Key:" msgstr "" -#: includes/payment.php:253 -msgid "" -"The key Id can be generated from \"API Keys\" section of Razorpay Dashboard. " -"Use test key for test mode." +#: includes/payment.php:284 +msgid "The key Id can be generated from \"API Keys\" section of Razorpay Dashboard. Use test key for test mode." msgstr "" -#: includes/payment.php:257 +#: includes/payment.php:288 msgid "Test Client Secret Key:" msgstr "" -#: includes/payment.php:259 -msgid "" -"The key secret can be generated from \"API Keys\" section of Razorpay " -"Dashboard. Use test secret for test mode." +#: includes/payment.php:290 +msgid "The key secret can be generated from \"API Keys\" section of Razorpay Dashboard. Use test secret for test mode." msgstr "" -#: includes/payment.php:263 +#: includes/payment.php:294 msgid "Razorpay Webhook" msgstr "" -#: includes/payment.php:265 -#, php-format -msgid "Webhook URL: %1$sOnly \"%2$s\" and \"%3$s\" action events supported." +#: includes/payment.php:296 +msgid "Webhook URL: %1$sOnly \"%2$s\" and \"%3$s\" action events are supported." msgstr "" -#: includes/payment.php:268 +#: includes/payment.php:299 msgid "Razorpay Webhook:" msgstr "" -#: includes/payment.php:269 +#: includes/payment.php:300 msgid "Enable Razorpay Webhook" msgstr "" -#: includes/payment.php:271 +#: includes/payment.php:302 msgid "Use the above webhook URL in Razorpaay \"Settings > Webhooks\"." msgstr "" -#: includes/payment.php:276 -msgid "Live Webhook Secret Key:" -msgstr "" - -#: includes/payment.php:278 -msgid "" -"The webhook secret can be generated from \"Webhooks\" section of Razorpay " -"Dashboard." +#: includes/payment.php:307 +msgid "Webhook Secret Key:" msgstr "" -#: includes/payment.php:282 -msgid "Test Webhook Secret Key:" -msgstr "" - -#: includes/payment.php:284 -msgid "" -"The webhook secret can be generated from \"Webhooks\" section of Razorpay " -"Dashboard of test account." +#: includes/payment.php:309 +msgid "The webhook secret can be generated from \"Webhooks\" section of Razorpay Dashboard." msgstr "" -#: includes/payment.php:288 +#: includes/payment.php:313 msgid "Razorpay Settings" msgstr "" -#: includes/payment.php:293 +#: includes/payment.php:318 msgid "SMS Notification:" msgstr "" -#: includes/payment.php:294 includes/payment.php:302 includes/payment.php:310 -#: includes/payment.php:318 includes/payment.php:334 includes/payment.php:342 +#: includes/payment.php:319 +#: includes/payment.php:327 +#: includes/payment.php:335 +#: includes/payment.php:343 +#: includes/payment.php:359 +#: includes/payment.php:367 msgid "Enable/Disable" msgstr "" -#: includes/payment.php:296 -msgid "" -"Enable this option to send payment links to your customer's Mobile Number as " -"a SMS." +#: includes/payment.php:321 +msgid "Enable this option to send payment links to your customer's Mobile Number as a SMS." msgstr "" -#: includes/payment.php:301 +#: includes/payment.php:326 msgid "Email Notification:" msgstr "" -#: includes/payment.php:304 -msgid "" -"Enable this option to send payment links to your customer's Email Address as " -"a Email." +#: includes/payment.php:329 +msgid "Enable this option to send payment links to your customer's Email Address as a Email." msgstr "" -#: includes/payment.php:309 +#: includes/payment.php:334 msgid "Payment Reminder:" msgstr "" -#: includes/payment.php:312 -msgid "" -"Enable this option to send payment reminder alerts to your customers if they " -"do not completed their payment yet. It only works when you will enable " -"Payment Reminder from your Razorpay Account." +#: includes/payment.php:337 +msgid "Enable this option to send payment reminder alerts to your customers if they do not completed their payment yet. It only works when you will enable Payment Reminder from your Razorpay Account." msgstr "" -#: includes/payment.php:317 +#: includes/payment.php:342 msgid "Payment Link Auto Expire:" msgstr "" -#: includes/payment.php:320 -msgid "" -"Enable this option to auto expire payment links depending on hold stock " -"duration. It will work only when Stock Management is enabled in WooCommerce " -"Settings." +#: includes/payment.php:345 +msgid "Enable this option to auto expire payment links depending on hold stock duration. It will work only when Stock Management is enabled in WooCommerce Settings." msgstr "" -#: includes/payment.php:325 +#: includes/payment.php:350 msgid "Payment Gateway Fees:" msgstr "" -#: includes/payment.php:326 -msgid "Collect Razorpay Gateway Fees from Customer" +#: includes/payment.php:351 +msgid "Collect Gateway Fees from Customer" msgstr "" -#: includes/payment.php:328 -msgid "" -"Enable this option to collect the Razorpay Gateway Fee from your customers " -"for the payments they make. Gateway fees will be automatically excluded if a " -"refund is made from WordPress dashboard." +#: includes/payment.php:353 +msgid "Enable this option to collect the Razorpay Gateway Fee from your customers for the payments they make. Gateway fees will be automatically excluded if a refund is made from WordPress dashboard." msgstr "" -#: includes/payment.php:333 +#: includes/payment.php:358 msgid "Instant Refund:" msgstr "" -#: includes/payment.php:336 -msgid "" -"Enable this option to refund instantly. It will only work if Instant Refund " -"is enabled on your account." +#: includes/payment.php:361 +msgid "Enable this option to refund instantly. It will only work if Instant Refund is enabled on your Razorpay account." msgstr "" -#: includes/payment.php:341 +#: includes/payment.php:366 msgid "Debug Mode:" msgstr "" -#: includes/payment.php:344 -msgid "" -"Enable this option to view the detailed communication between the Gateway " -"API and WooCommerce in a WooCommerce log file." -msgstr "" - -#: includes/payment.php:376 -msgid "Order ID: " +#: includes/payment.php:369 +msgid "Enable this option to view the detailed communication between the Gateway API and WooCommerce in a WooCommerce log file." msgstr "" -#: includes/payment.php:430 -msgid "" -"Error Occured! Please contact with Site Administrator to resolve this issue." +#: includes/payment.php:456 +msgid "Error Occured! Please change API Type form plugin settings or contact with Site Administrator to resolve this issue." msgstr "" -#: includes/payment.php:451 +#: includes/payment.php:475 msgid "Payment is Pending against this order. URL: " msgstr "" -#: includes/payment.php:464 +#: includes/payment.php:489 msgid "Error Occured: " msgstr "" -#: includes/payment.php:470 +#: includes/payment.php:495 msgid "Connection Error Occured! Please try again." msgstr "" -#: includes/payment.php:521 +#: includes/payment.php:534 msgid "Refund can't be initiated. Please check your plugin settings." msgstr "" -#: includes/payment.php:538 +#: includes/payment.php:553 msgid "No reason specified!" msgstr "" #. translators: %s: Razorpay gateway error message -#: includes/payment.php:567 -#, php-format +#: includes/payment.php:570 msgid "Refund could not be captured: %s" msgstr "" -#: includes/payment.php:579 -#, php-format +#: includes/payment.php:584 msgid "Amount Refunded. Rs. %1$s
Refund ID: %2$s
Reason: %3$s" msgstr "" -#: includes/payment.php:587 +#: includes/payment.php:594 msgid "Refund Error Occured: " msgstr "" -#: includes/payment.php:620 -msgid "" -"Order can't be found against this payment. If the money deducted from your " -"account, please contact with Site Administrator for further action. Thanks " -"for your understanding." +#: includes/payment.php:636 +msgid "Order can't be found against this payment. If the money deducted from your account, please contact with Site Administrator for further action. Thanks for your understanding." msgstr "" -#: includes/payment.php:650 includes/payment.php:828 +#: includes/payment.php:668 +#: includes/payment.php:821 msgid "Payment is Successful against this order.
Transaction ID: " msgstr "" -#: includes/payment.php:665 -msgid "" -"Signature Verification Failed. If the money debited from your account, " -"please Contact with Site Administrator for further action." -msgstr "" - #. translators: %s: Razorpay gateway error message -#: includes/payment.php:709 -#, php-format +#: includes/payment.php:708 msgid "Link Cancellation could not be captured: %s" msgstr "" -#: includes/payment.php:721 +#: includes/payment.php:720 msgid "Invoice Link Cancelled." msgstr "" -#: includes/payment.php:727 +#: includes/payment.php:726 msgid "Link Cancellation falied: " msgstr "" -#: includes/payment.php:866 -msgid "Order amount is refunded.
Refund ID: " -msgstr "" - -#: rzp-woocommerce.php:92 -msgid "Settings" -msgstr "" - -#: rzp-woocommerce.php:104 -msgid "Support" -msgstr "" - -#: rzp-woocommerce.php:105 -msgid "FAQ" +#: includes/payment.php:861 +msgid "Order amount is refunded.
Refund ID: %s" msgstr "" -#: rzp-woocommerce.php:106 -msgid "Donate" +#: includes/payment.php:892 +msgid "Could not enable webhook for localhost." msgstr "" -#: rzp-woocommerce.php:117 -msgid "" -"Your version of PHP is below the minimum version of PHP required by Razorpay " -"Payment Links for WooCommerce plugin. Please contact your host and request " -"that your version be upgraded to 5.6 or later." +#: includes/payment.php:900 +msgid "Please enter the webhook secret." msgstr "" -#: rzp-woocommerce.php:123 -#, php-format -msgid "" -"Thanks for installing %1$s v%2$s plugin. Click here to " -"configure plugin settings." +#: rzp-woocommerce.php:94 +msgid "Settings" msgstr "" -#. Plugin Name of the plugin/theme -msgid "Razorpay Payment Links for WooCommerce" +#: rzp-woocommerce.php:108 +msgid "Support" msgstr "" -#. Plugin URI of the plugin/theme -msgid "https://wordpress.org/plugins/rzp-woocommerce/" +#: rzp-woocommerce.php:109 +msgid "FAQ" msgstr "" -#. Description of the plugin/theme -msgid "" -"The easiest and most secure solution to collect payments with WooCommerce. " -"Allow customers to securely pay via Razorpay (Credit/Debit Cards, " -"NetBanking, UPI, Wallets, QR Code)." +#: rzp-woocommerce.php:110 +msgid "Donate" msgstr "" -#. Author of the plugin/theme -msgid "Sayan Datta" +#: rzp-woocommerce.php:124 +msgid "Your version of PHP is below the minimum version of PHP required by Razorpay Payment Links for WooCommerce plugin. Please contact your host and request that your version be upgraded to 5.6 or later." msgstr "" -#. Author URI of the plugin/theme -msgid "https://www.sayandatta.in" +#. translators: %s: Plugin Details. 1. Plugin Name, 2. Plugin Version, 3. Plugin Settings +#: rzp-woocommerce.php:132 +msgid "Thanks for installing %1$s v%2$s plugin. Click here to configure plugin settings." msgstr "" diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..429d3f5 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,98 @@ + + + PHPCS dev PHP_CodeSniffer ruleset. + + . + + + .js + .css + */css/* + */languages/* + */icon/* + */js/* + + + + + + + + + + + + + + + + + + + + index.php + + + + + + + + + + + + + + + + + + + + + + + + + + + + inc/**/abstract-*.php + tests/* + src/* + + + + . + + + + + tests/e2e-tests/ + + + + tests/ + + + + languages/ + i18n/ + src/ + + + + . + + + + + + + + \ No newline at end of file diff --git a/readme.txt b/readme.txt index b0b7132..f2f7576 100644 --- a/readme.txt +++ b/readme.txt @@ -1,15 +1,15 @@ === Razorpay Payment Links for WooCommerce === Contributors: infosatech -Tags: razorpay, qrcode, upi, woocommerce, PaywithRazorpay +Tags: razorpay, qrcode, upi, woocommerce, debit card, credit card Requires at least: 4.6 -Tested up to: 5.4 -Stable tag: 1.0.5 +Tested up to: 6.0 +Stable tag: 1.1.6 Requires PHP: 5.6 -Donate link: https://www.paypal.me/iamsayan +Donate link: https://rzp.io/l/Bq3W5pr License: GPLv3 License URI: http://www.gnu.org/licenses/gpl.html -🔥 The easiest and most secure solution to collect payments with WooCommerce. Allow customers to securely pay via Razorpay (Credit/Debit Cards, NetBanking, UPI, Wallets, QR Code). +The easiest and most secure solution to collect payments with WooCommerce. Allow customers to securely pay via Razorpay (Credit/Debit Cards, NetBanking, UPI, Wallets, QR Code). == Description == @@ -69,9 +69,21 @@ Yes. You can access this from 'WooCommerce > Settings > Payments > Razorpay Paym Go to 'WooCommerce > Settings > Payments > Razorpay Payment Gateway', enable/disable options as per your need and save changes. -= How to use webhook? = += How to use webhook? What webhooks are supported? = -Go to Razorpay 'Dashboard > Settings > Webhooks'. Enter the URL from plugin settings page and create and copy webhook secret key and paste it to plugin settings and save changes. +Go to Razorpay 'Dashboard > Settings > Webhooks'. Enter the URL from plugin settings page and create and copy webhook secret key and paste it to plugin settings and save changes. By Default this plugin supports only these two Webhooks: "payment.authorized" and "refund.created". If you want more webhooks supported, please feel free to contact me at hello@sayandatta.in or https://www.sayandatta.in/contact/ as it needs custom developmet. + += How to send automatic payment reminder to customer, if customer does not make payment after initiating the payment procedure? = + +It needs custom developement. Please contact me at hello@sayandatta.in or https://sayandatta.in/contact/. + += I want to use Razorpay Web Integration like Automatic Checkout/Manual Checkout (On site Checkout - No Redirection) with webhooks? = + +It needs custom developement. Please contact me at hello@sayandatta.in or https://sayandatta.in/contact/. + += I want to customize the look of the default Razorpay Gateway like colors/text etc. How can I get this? = + +It needs custom developement. Please contact me at hello@sayandatta.in or https://sayandatta.in/contact/. = Is this plugin compatible with any themes? = @@ -94,6 +106,72 @@ Post detailed information about the issue in the [support forum](https://wordpre If you like Razorpay Payment Links for WooCommerce, please take a moment to [give a 5-star rating](https://wordpress.org/support/plugin/rzp-woocommerce/reviews/?rate=5#new-post). It helps to keep development and support going strong. Thank you! += 1.1.6 = +Release Date: July 15, 2022 + +* Improved: Code Quality. +* WordPress tested upto v6.0. +* WC Tested upto v6.7. + += 1.1.5 = +Release Date: July 25, 2021 + +* Improved: Localhost check. +* Support for old WC Version (2.0 to 3.1) +* WC Tested upto v5.5 and v5.6. + += 1.1.4 = +Release Date: June 16, 2021 + +* Added: Order Number instead of Order ID. +* WC Tested upto v5.4. + += 1.1.3 = +Release Date: May 23, 2021 + +* Added: Auto Enable Webhook on plugin settings save. +* Fixed: Bug related to new API. + += 1.1.2 = +Release Date: January 11, 2021 + +* Added: Option to switch between Standard and Legacy Payment Links API. If your Razorpay Account was created on or after 1 September 2020 and Legacy API is not working for you, please use Standrard API. Legacy API will be officially deprecated by Razorpay on 31st March, 2021. + += 1.1.1 = +Release Date: December 14, 2020 + +* WordPress tested upto v5.6. +* WC Tested upto v4.8. + += 1.1.0 = +Release Date: November 7, 2020 + +* Fixed: Partial refund from Razorpay Dashbaord causing multiple refund events. +* WC Tested upto v4.6. + += 1.0.9 = +Release Date: August 15, 2020 + +* Fixed: Webhook Issue. +* WC Tested upto v4.4. + += 1.0.8 = +Release Date: July 24, 2020 + +* Fixed: Redirection issue due to recent Razorpay API Chnages. + += 1.0.7 = +Release Date: July 20, 2020 + +* WC Tested upto v4.3. + += 1.0.6 = +Release Date: June 9, 2020 + +* Tweak: Cart will not be cleared if payment is not actually made. +* Fixed: Redirection issue. +* WC Tested upto v4.2.0 + = 1.0.5 = Release Date: May 24, 2020 diff --git a/rzp-woocommerce.php b/rzp-woocommerce.php index 87189c8..62bf7e5 100644 --- a/rzp-woocommerce.php +++ b/rzp-woocommerce.php @@ -3,14 +3,14 @@ * Plugin Name: Razorpay Payment Links for WooCommerce * Plugin URI: https://wordpress.org/plugins/rzp-woocommerce/ * Description: The easiest and most secure solution to collect payments with WooCommerce. Allow customers to securely pay via Razorpay (Credit/Debit Cards, NetBanking, UPI, Wallets, QR Code). - * Version: 1.0.5 + * Version: 1.1.6 * Author: Sayan Datta - * Author URI: https://www.sayandatta.in + * Author URI: https://sayandatta.in * License: GPLv3 * Text Domain: rzp-woocommerce * Domain Path: /languages - * WC requires at least: 3.1 - * WC tested up to: 4.1 + * WC requires at least: 2.0 + * WC tested up to: 6.7 * * Razorpay Payment Links for WooCommerce is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,12 +39,12 @@ } $consts = array( - 'RZPWC_WOO_PLUGIN_VERSION' => '1.0.5', // plugin version - 'RZPWC_WOO_PLUGIN_BASENAME' => plugin_basename( __FILE__ ), - 'RZPWC_WOO_PLUGIN_DIR' => plugin_dir_url( __FILE__ ) + 'RZPWC_WOO_PLUGIN_VERSION' => '1.1.6', // plugin version + 'RZPWC_WOO_PLUGIN_BASENAME' => plugin_basename( __FILE__ ), + 'RZPWC_WOO_PLUGIN_DIR' => plugin_dir_url( __FILE__ ), ); -foreach( $consts as $const => $value ) { +foreach ( $consts as $const => $value ) { if ( ! defined( $const ) ) { define( $const, $value ); } @@ -59,7 +59,7 @@ * @since 1.0.0 */ function rzpwc_plugin_load_textdomain() { - load_plugin_textdomain( 'rzp-woocommerce', false, dirname( RZPWC_WOO_PLUGIN_BASENAME ) . '/languages/' ); + load_plugin_textdomain( 'rzp-woocommerce', false, dirname( RZPWC_WOO_PLUGIN_BASENAME ) . '/languages' ); } // register activation hook @@ -69,7 +69,8 @@ function rzpwc_plugin_activation() { if ( ! current_user_can( 'activate_plugins' ) ) { return; } - set_transient( 'rzpwc-admin-notice-on-activation', true, 5 ); + + set_transient( 'rzpwc-admin-notice-on-activation', true ); } // register deactivation hook @@ -79,6 +80,7 @@ function rzpwc_plugin_deactivation() { if ( ! current_user_can( 'activate_plugins' ) ) { return; } + delete_option( 'rzpwc_plugin_dismiss_rating_notice' ); delete_option( 'rzpwc_plugin_no_thanks_rating_notice' ); delete_option( 'rzpwc_plugin_installed_time' ); @@ -89,8 +91,9 @@ function rzpwc_plugin_deactivation() { function rzpwc_add_action_links( $links ) { $rzpwclinks = array( - '' . __( 'Settings', 'rzp-woocommerce' ) . '', + '' . esc_html__( 'Settings', 'rzp-woocommerce' ) . '', ); + return array_merge( $rzpwclinks, $links ); } @@ -99,12 +102,16 @@ function rzpwc_add_action_links( $links ) { function rzpwc_plugin_meta_links( $links, $file ) { $plugin = RZPWC_WOO_PLUGIN_BASENAME; - if ( $file == $plugin ) // only for this plugin + if ( $file === $plugin ) { // only for this plugin return array_merge( $links, - array( '' . __( 'Support', 'rzp-woocommerce' ) . '' ), - array( '' . __( 'FAQ', 'rzp-woocommerce' ) . '' ), - array( '' . __( 'Donate', 'rzp-woocommerce' ) . '' ) + array( + '' . esc_html__( 'Support', 'rzp-woocommerce' ) . '', + '' . esc_html__( 'FAQ', 'rzp-woocommerce' ) . '', + '' . esc_html__( 'Donate', 'rzp-woocommerce' ) . '', + ) ); + } + return $links; } @@ -113,14 +120,16 @@ function rzpwc_plugin_meta_links( $links, $file ) { function rzpwc_new_plugin_install_notice() { // Show a warning to sites running PHP < 5.6 - if( version_compare( PHP_VERSION, '5.6', '<' ) ) { - echo '

' . __( 'Your version of PHP is below the minimum version of PHP required by Razorpay Payment Links for WooCommerce plugin. Please contact your host and request that your version be upgraded to 5.6 or later.', 'rzp-woocommerce' ) . '

'; + if ( version_compare( PHP_VERSION, '5.6', '<' ) ) { + echo '

' . esc_html__( 'Your version of PHP is below the minimum version of PHP required by Razorpay Payment Links for WooCommerce plugin. Please contact your host and request that your version be upgraded to 5.6 or later.', 'rzp-woocommerce' ) . '

'; } // Check transient, if available display notice - if( get_transient( 'rzpwc-admin-notice-on-activation' ) ) { ?> + if ( get_transient( 'rzpwc-admin-notice-on-activation' ) ) { ?>
-

here to configure plugin settings.', 'rzp-woocommerce' ), 'Razorpay Payment Links for WooCommerce', RZPWC_WOO_PLUGIN_VERSION, admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=wc-razorpay' ) ); ?>

+

here to configure plugin settings.', 'rzp-woocommerce' ), 'Razorpay Payment Links for WooCommerce', esc_html( RZPWC_WOO_PLUGIN_VERSION ), esc_url( admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=wc-razorpay' ) ) ); ?>