Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add Locale Support #26

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
644 changes: 351 additions & 293 deletions hyperswitch-checkout.php

Large diffs are not rendered by default.

68 changes: 68 additions & 0 deletions i18n-setup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php
// Place this file in your plugin root directory

function scan_php_files($dir) {
$result = array();
$scan = scandir($dir);

foreach ($scan as $file) {
if ($file === '.' || $file === '..') continue;

$path = $dir . DIRECTORY_SEPARATOR . $file;

if (is_dir($path)) {
$result = array_merge($result, scan_php_files($path));
} else if (pathinfo($path, PATHINFO_EXTENSION) === 'php') {
$result[] = $path;
}
}

return $result;
}

function check_translation_functions($files) {
$patterns = array(
'/__\s*\(\s*[\'"](.*?)[\'"],\s*[\'"]?([a-zA-Z0-9-_]+)?[\'"]?\s*\)/', // __() function
'/_e\s*\(\s*[\'"](.*?)[\'"],\s*[\'"]?([a-zA-Z0-9-_]+)?[\'"]?\s*\)/', // _e() function
'/esc_html__\s*\(\s*[\'"](.*?)[\'"],\s*[\'"]?([a-zA-Z0-9-_]+)?[\'"]?\s*\)/', // esc_html__() function
'/esc_attr__\s*\(\s*[\'"](.*?)[\'"],\s*[\'"]?([a-zA-Z0-9-_]+)?[\'"]?\s*\)/', // esc_attr__() function
'/esc_html_e\s*\(\s*[\'"](.*?)[\'"],\s*[\'"]?([a-zA-Z0-9-_]+)?[\'"]?\s*\)/', // esc_html_e() function
'/esc_attr_e\s*\(\s*[\'"](.*?)[\'"],\s*[\'"]?([a-zA-Z0-9-_]+)?[\'"]?\s*\)/' // esc_attr_e() function
);

$missing_domain = array();

foreach ($files as $file) {
$content = file_get_contents($file);
foreach ($patterns as $pattern) {
preg_match_all($pattern, $content, $matches);

if (!empty($matches[0])) {
foreach ($matches[0] as $key => $match) {
if (empty($matches[2][$key]) || $matches[2][$key] !== 'hyperswitch') {
$missing_domain[] = array(
'file' => $file,
'string' => $match
);
}
}
}
}
}

return $missing_domain;
}

// Scan files
$files = scan_php_files(__DIR__);
$missing = check_translation_functions($files);

if (!empty($missing)) {
echo "Found translation functions missing 'hyperswitch' text domain:\n\n";
foreach ($missing as $item) {
echo "File: {$item['file']}\n";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't it be better to log the results to a file, or at least printing the output in a more structured format (JSON, CSV, etc.) to make it easier to review.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you plz explain me what change to implement.

echo "Function: {$item['string']}\n\n";
}
} else {
echo "All translation functions have proper text domain.\n";
}
147 changes: 98 additions & 49 deletions includes/hyperswitch-webhook.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
<?php
/**
* Plugin Name: Hyperswitch WooCommerce Plugin
* Plugin URI: https://hyperswitch.io
* Description: WooCommerce payment gateway integration for Hyperswitch
* Version: 1.0.0
* Author: Hyperswitch
* Author URI: https://hyperswitch.io
* Text Domain: hyperswitch
* Domain Path: /locale
* Requires PHP: 7.0
*/
if ( ! defined( 'ABSPATH' ) )
exit; // Exit if accessed directly

Expand All @@ -10,72 +21,74 @@ class Hyperswitch_Webhook {
const PAYMENT_SUCCEEDED = 'payment_succeeded';
const PAYMENT_FAILED = 'payment_failed';
const PAYMENT_PROCESSING = 'payment_processing';
const ACTION_REQURIED = 'action_required';
const ACTION_REQUIRED = 'action_required';
const REFUND_SUCCEEDED = 'refund_succeeded';
// const REFUND_FAILED = 'refund_failed';
// const DISPUTE_OPENED = 'dispute_opened';
// const DISPUTE_EXPIRED = 'dispute_expired';
// const DISPUTE_ACCEPTED = 'dispute_accepted';
// const DISPUTE_CANCELLED = 'dispute_cancelled';
// const DISPUTE_CHALLENGED = 'dispute_challenged';
// const DISPUTE_WON = 'dispute_won';
// const DISPUTE_LOST = 'dispute_lost';

protected $eventsArray = [
self::PAYMENT_SUCCEEDED,
self::PAYMENT_FAILED,
self::PAYMENT_PROCESSING,
self::ACTION_REQURIED,
self::ACTION_REQUIRED,
self::REFUND_SUCCEEDED,
// self::REFUND_FAILED,
// self::DISPUTE_OPENED,
// self::DISPUTE_EXPIRED,
// self::DISPUTE_ACCEPTED,
// self::DISPUTE_CANCELLED,
// self::DISPUTE_CHALLENGED,
// self::DISPUTE_WON,
// self::DISPUTE_LOST
];

public function __construct() {
$this->hyperswitch = new Hyperswitch_Checkout();

// Load plugin text domain
add_action('init', array($this, 'load_plugin_textdomain'));
}

/**
* Load plugin textdomain.
*/
public function load_plugin_textdomain() {
load_plugin_textdomain(
'hyperswitch',
false,
dirname(plugin_basename(__FILE__)) . '/locale/'
);
}

public function process() {
if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
$raw_post_data = file_get_contents( 'php://input' );
if ( ! empty ( $raw_post_data ) ) {
if ( ! empty( $raw_post_data ) ) {
$data = json_decode( $raw_post_data, true );

$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE_512'];


if ( json_last_error() !== 0 ) {
return;
}

$enabled = $this->hyperswitch->get_option( 'enable_webhook' );

if ( ( $enabled === 'yes' ) and ( empty ( $data['event_type'] ) === false ) ) {
// Skip the webhook if webhooks are disabled, or the event type is unrecognised
if ( ( $enabled === 'yes' ) && ( ! empty( $data['event_type'] ) ) ) {
$payment_id = $data['content']['object']['payment_id'];
$this->hyperswitch->post_log( "WC_WEBHOOK_RECEIVED", $data['event_type'], $payment_id );
$this->hyperswitch->post_log(
/* translators: Webhook received log message */
__( 'WC_WEBHOOK_RECEIVED', 'hyperswitch' ),
$data['event_type'],
$payment_id
);

if ( $this->shouldConsumeWebhook( $data, $signature, $raw_post_data ) === false ) {
return;
}

switch ( $data['event_type'] ) {
case self::PAYMENT_SUCCEEDED:
return $this->paymentAuthorized( $data );

case self::PAYMENT_FAILED:
return $this->paymentHandle( $data, "failed" );
return $this->paymentHandle( $data, __( 'failed', 'hyperswitch' ) );

case self::PAYMENT_PROCESSING:
return $this->paymentHandle( $data, "processing" );
return $this->paymentHandle( $data, __( 'processing', 'hyperswitch' ) );

case self::ACTION_REQURIED:
return $this->paymentHandle( $data, "action required" );
case self::ACTION_REQUIRED:
return $this->paymentHandle( $data, __( 'action required', 'hyperswitch' ) );

case self::REFUND_SUCCEEDED:
return $this->refundedCreated( $data );
Expand All @@ -89,101 +102,137 @@ public function process() {
}

protected function paymentAuthorized( array $data ) {

$order_id = $data['content']['object']['metadata']['order_num'];

$order = wc_get_order( $order_id );

if ( $order ) {
$payment_id = $data['content']['object']['payment_id'];
$payment_method = $data['content']['object']['payment_method'];

if ( $order->status !== 'processing' ) {
$this->hyperswitch->post_log( "WC_ORDER_PLACED", null, $payment_id );
$this->hyperswitch->post_log(
/* translators: Order placed log message */
__( 'WC_ORDER_PLACED', 'hyperswitch' ),
null,
$payment_id
);
}

$order->payment_complete( $payment_id );
$order->add_order_note( 'Payment successful via ' . $payment_method . ' (Hyperswitch Payment ID: ' . $payment_id . ') (via Hyperswitch Webhook)' );
$order->add_order_note( sprintf(
/* translators: 1: Payment method 2: Payment ID */
__( 'Payment successful via %1$s (Hyperswitch Payment ID: %2$s) (via Hyperswitch Webhook)', 'hyperswitch' ),
$payment_method,
$payment_id
));

if ( $data['object']['capture_method'] === "automatic" ) {
$order->update_meta_data( 'payment_captured', 'yes' );
}
$this->hyperswitch->post_log( "WC_PAYMENT_SUCCEEDED_WEBHOOK", null, $payment_id );


$this->hyperswitch->post_log(
/* translators: Payment succeeded webhook log message */
__( 'WC_PAYMENT_SUCCEEDED_WEBHOOK', 'hyperswitch' ),
null,
$payment_id
);
} else {
exit; // Not a Woocommerce Order
exit; // Not a WooCommerce Order
}

exit;
}

protected function paymentHandle( array $data, $status ) {

$order_id = $data['content']['object']['metadata']['order_num'];

$order = wc_get_order( $order_id );

if ( $order ) {
$payment_id = $data['content']['object']['payment_id'];
$payment_method = $data['content']['object']['payment_method'];
$order->set_transaction_id( $payment_id );
if ( $status == 'processing' ) {

if ( $status == __( 'processing', 'hyperswitch' ) ) {
$order->update_status( $this->hyperswitch->processing_payment_order_status );
} else {
$order->update_status( 'pending' );
$order->update_status( __( 'pending', 'hyperswitch' ) );
}
$order->add_order_note( 'Payment ' . $status . ' via ' . $payment_method . ' (Hyperswitch Payment ID: ' . $payment_id . ') (via Hyperswitch Webhook)' );
$this->hyperswitch->post_log( "WC_PAYMENT_" . str_replace( " ", "_", strtoupper( $status ) ) . "_WEBHOOK", null, $payment_id );

$order->add_order_note( sprintf(
/* translators: 1: Payment status 2: Payment method 3: Payment ID */
__( 'Payment %1$s via %2$s (Hyperswitch Payment ID: %3$s) (via Hyperswitch Webhook)', 'hyperswitch' ),
$status,
$payment_method,
$payment_id
));

$this->hyperswitch->post_log(
/* translators: Payment status webhook log message */
__( sprintf('WC_PAYMENT_%s_WEBHOOK', str_replace( " ", "_", strtoupper( $status ) )), 'hyperswitch' ),
null,
$payment_id
);
}

exit;
}

protected function refundedCreated( array $data ) {
$payment_id = $data['content']['object']['payment_id'];
if ( isset ( $data['content']['object']['metadata']['order_num'] ) ) {
if ( isset( $data['content']['object']['metadata']['order_num'] ) ) {
$order_id = $data['content']['object']['metadata']['order_num'];
} else {
$payment_intent = $this->hyperswitch->retrieve_payment_intent( $payment_id );
$order_id = $payment_intent['metadata']['order_num'];
}

$refund_num = $data['content']['object']['metadata']['refund_num'];
$refund_id = $data['content']['object']['refund_id'];

$order = wc_get_order( $order_id );

if ( $order ) {
$refunds = $order->get_refunds();
$targetRefund = null;
if ( isset ( $refund_num ) ) {
if ( isset( $refund_num ) ) {
foreach ( $refunds as $refund ) {
if ( $refund->id == $refund_num ) {
$targetRefund = $refund;
break;
}
}
}
if ( ! isset ( $targetRefund ) ) { // Refund initiated via Hyperswitch Dashboard

if ( ! isset( $targetRefund ) ) { // Refund initiated via Hyperswitch Dashboard
$refund = new WC_Order_Refund;
$amount = $data['content']['object']['amount'];
$reason = $data['content']['object']['reason'];
$refund->set_amount( (float) $amount / 100 );
$refund->set_reason( $reason );
}
$order->add_order_note( 'Refund Successful (Hyperswitch Refund ID: ' . $refund_id . ') (via Hyperswitch Webhook)' );

$order->add_order_note( sprintf(
/* translators: %s: Refund ID */
__( 'Refund Successful (Hyperswitch Refund ID: %1$s) (via Hyperswitch Webhook)', 'hyperswitch' ),
$refund_id
));
$refund->set_refunded_payment( true );
} else {
exit; // Not a refund for a Woocommerce Order
exit; // Not a refund for a WooCommerce Order
}
// Graceful exit since payment is now refunded.

exit;
}


protected function shouldConsumeWebhook( $data, $signature, $payload ) {
$webhook_key = $this->hyperswitch->get_option( 'webhook_secret_key' );
$generated_signature = hash_hmac( 'sha512', $payload, $webhook_key );
$signature_verification_result = $generated_signature === $signature;

if (
( isset ( $data['event_type'] ) ) and
( in_array( $data['event_type'], $this->eventsArray ) && $signature_verification_result )
isset( $data['event_type'] ) &&
in_array( $data['event_type'], $this->eventsArray ) &&
$signature_verification_result
) {
return true;
}
Expand Down
Loading