JezK
Edit File: coupon-apply.php
<?php /** * for coupon related API */ require_once __DIR__.'/../support/smart-coupons.php'; function applyCouponOnCart(WP_REST_Request $request) { try { global $woocommerce; $status = 400; $failure_reason = ""; $params = $request->get_params(); $logObj = []; $logObj["api"] = "applyCouponOnCart"; $logObj["params"] = $params; $validateInput = validateApplyCouponApi($params); if ($validateInput != null) { $response["failure_reason"] = $validateInput; $response["failure_code"] = "VALIDATION_ERROR"; $logObj["response"] = $response; rzpLogError(json_encode($logObj)); $rzp = new WC_Razorpay(); $trackObject = $rzp->newTrackPluginInstrumentation(); $properties = [ 'error' => $validateInput, 'log' => $logObj ]; $trackObject->rzpTrackDataLake('razorpay.1cc.apply.coupon.validation.error', $properties); return new WP_REST_Response($response, 400); } $couponCode = sanitize_text_field($params["code"]); $email = sanitize_text_field($params["email"]) ?? ""; $orderId = sanitize_text_field($params["order_id"]); // initializes the session initCustomerSessionAndCart(); if (is_plugin_active('wt-smart-coupons-for-woocommerce/wt-smart-coupon.php')) { // Set current user for smart coupon plugin if (empty($email) === false) { $user = get_user_by('email', $email); wp_set_current_user($user->id); } // Apply Smart Coupon if allowed for selected payment method (e.g., Razorpay) try { smartCouponPaymentRestriction($couponCode); } catch ( Throwable $e ) { rzpLogError('Smart Coupon restricted by payment method : ' . $e->getMessage()); } } // check for individual specific coupons // cart->apply does not enforce this $coupon = new WC_Coupon($couponCode); // check the enable coupon option if (get_option("woocommerce_enable_coupons") === "no") { $response["failure_reason"] = "Coupon feature disabled"; $response["failure_code"] = "INVALID_COUPON"; $logObj["response"] = $response; rzpLogError(json_encode($logObj)); $rzp = new WC_Razorpay(); $trackObject = $rzp->newTrackPluginInstrumentation(); $properties = [ 'error' => 'Coupon feature disabled', 'log' => $logObj ]; $trackObject->rzpTrackDataLake('razorpay.1cc.apply.coupon.invalid.coupon', $properties); return new WP_REST_Response($response, 400); } //check woo-discount-rule plugin disabling the coupons if (is_plugin_active('woo-discount-rules/woo-discount-rules.php')) { $discountOptions = get_option('woo-discount-config-v2', []); if (!empty($discountOptions)) { $isCouponEnabled = $discountOptions['disable_coupon_when_rule_applied']; if ($isCouponEnabled == 'disable_coupon') { $response["failure_reason"] = "Coupon feature disabled"; $response["failure_code"] = "INVALID_COUPON"; $logObj["response"] = $response; rzpLogError(json_encode($logObj)); return new WP_REST_Response($response, 400); } } } if (empty($coupon->get_email_restrictions()) === false) { if ($email == "") { $response["failure_reason"] = "User email is required"; $response["failure_code"] = "LOGIN_REQUIRED"; $logObj["response"] = $response; rzpLogError(json_encode($logObj)); $rzp = new WC_Razorpay(); $trackObject = $rzp->newTrackPluginInstrumentation(); $properties = [ 'error' => 'User email is required', 'log' => $logObj ]; $trackObject->rzpTrackDataLake('razorpay.1cc.apply.coupon.login.required', $properties); return new WP_REST_Response($response, 400); } elseif (in_array($email, $coupon->get_email_restrictions()) === false) { $response["failure_reason"] = "Coupon does not exist"; $response["failure_code"] = "INVALID_COUPON"; $logObj["response"] = $response; rzpLogError(json_encode($logObj)); $rzp = new WC_Razorpay(); $trackObject = $rzp->newTrackPluginInstrumentation(); $properties = [ 'error' => 'Coupon does not exist', 'log' => $logObj ]; $trackObject->rzpTrackDataLake('razorpay.1cc.apply.coupon.invalid.coupon', $properties); return new WP_REST_Response($response, 400); } } // Get coupon usage limit per user $userLimit = $coupon->get_usage_limit_per_user(); if (!empty($userLimit)) { $dataStore = $coupon->get_data_store(); $order = wc_get_order($orderId); $usageCount = $order->get_customer_id() ? $dataStore->get_usage_by_user_id($coupon, $order->get_customer_id()) : $dataStore->get_usage_by_email($coupon, $email); if (!empty($usageCount) && !empty($userLimit)) { // Calculate remaining $remainingCount = $userLimit - $usageCount; if ($remainingCount <= 0) { $response["failure_reason"] = "Coupon usage limit has been reached"; $response["failure_code"] = "REQUIREMENT_NOT_MET"; $logObj["response"] = $response; rzpLogError(json_encode($logObj)); $rzp = new WC_Razorpay(); $trackObject = $rzp->newTrackPluginInstrumentation(); $properties = [ 'error' => 'Coupon usage limit has been reached', 'log' => $logObj ]; $trackObject->rzpTrackDataLake('razorpay.1cc.apply.coupon.requirement.not.met', $properties); return new WP_REST_Response($response, 400); } } } // to clear any residual notices $temp = wc_print_notices(true); WC()->cart->empty_cart(); $cart1cc = create1ccCart($orderId); WC()->cart->remove_coupon($couponCode); if ($cart1cc) { $applyCoupon = WC()->cart->add_discount($couponCode); if ($applyCoupon === true) { $status = true; } else { $markup = wc_print_notices(true); $errorArray = explode("<li>", $markup); $errorMessage = preg_replace( "/\t|\n/", "", strip_tags(end($errorArray)) ); $failureReason = html_entity_decode($errorMessage); } } else { $invalidCartResponse = []; $invalidCartResponse["failure_reason"] = "Invalid merchant order id"; $invalidCartResponse["failure_code"] = "VALIDATION_ERROR"; $logObj["response"] = $invalidCartResponse; rzpLogError(json_encode($logObj)); $rzp = new WC_Razorpay(); $trackObject = $rzp->newTrackPluginInstrumentation(); $properties = [ 'error' => 'Invalid merchant order id', 'log' => $logObj ]; $trackObject->rzpTrackDataLake('razorpay.1cc.apply.coupon.validation.error', $properties); return new WP_REST_Response($invalidCartResponse, 400); } $newAmount = (WC()->cart->cart_contents_total + WC()->cart->tax_total) * 100; $discountAmount = (WC()->cart->get_cart_discount_tax_total() + WC()->cart->get_cart_discount_total()) * 100; $couponError = getApplyCouponErrorCodes($failureReason); $promotion = []; $promotion["code"] = $couponCode; $promotion["reference_id"] = $couponCode; $promotion["value"] = round($discountAmount ?? 0); $response["promotion"] = $promotion; if ($couponError["failure_reason"] === "") { $logObj["response"] = $response; rzpLogInfo(json_encode($logObj)); return new WP_REST_Response($response, 200); } else { $logObj["response"] = array_merge($response, $couponError); rzpLogError(json_encode($logObj)); $rzp = new WC_Razorpay(); $trackObject = $rzp->newTrackPluginInstrumentation(); $properties = [ 'error' => $validateInput, 'log' => $logObj ]; $trackObject->rzpTrackDataLake('razorpay.1cc.apply.coupon.error', $properties); return new WP_REST_Response($couponError, 400); } } catch (Throwable $e) { $rzp = new WC_Razorpay(); $trackObject = $rzp->newTrackPluginInstrumentation(); $properties = [ 'error' => $e->getMessage(), 'code' => $e->getCode(), 'file' => $e->getFile(), 'line' => $e->getLine() ]; $trackObject->rzpTrackDataLake('razorpay.1cc.apply.coupons.processing.failed', $properties); rzpLogError(json_encode($properties)); return new WP_REST_Response(['message' => "woocommerce server error : " . $e->getMessage()], 500); } } function getApplyCouponErrorCodes($failureMessage) { $result = []; $result["failure_code"] = "REQUIREMENT_NOT_MET"; if ($failureMessage === "" || is_null($failureMessage)) { $result["failure_reason"] = ""; $result["failure_code"] = ""; } elseif (stripos($failureMessage, "does not exist") !== false) { $result["failure_reason"] = "Coupon does not exist"; $result["failure_code"] = "INVALID_COUPON"; } elseif (stripos($failureMessage, "coupon has expired") !== false) { $result["failure_reason"] = "This coupon has expired"; } elseif (stripos($failureMessage, "minimum spend") !== false) { $result["failure_reason"] = "Cart is below the minimum amount"; } elseif (stripos($failureMessage, "maximum spend") !== false) { $result["failure_reason"] = "Cart is above maximum allowed amount"; } elseif ( stripos($failureMessage, "not applicable to selected products") !== false ) { $result["failure_reason"] = "Required product is missing"; } elseif ( stripos($failureMessage, "Coupon usage limit has been reached") !== false ) { $result["failure_reason"] = "Coupon usage limit has been reached"; } else { $result["failure_reason"] = "Coupon could not be applied"; $result["failure_code"] = "INVALID_COUPON"; } return $result; } function validateApplyCouponApi($param) { $failureReason = null; if (empty(sanitize_text_field($param["code"])) === true) { $failureReason = "Field code is required."; } elseif (empty(sanitize_text_field($param["order_id"])) === true) { $failureReason = "Field order id is required."; } return $failureReason; }