WP Manifestindependent plugin directory
manifest / ecommerce / woocommerce-authentication-with-zohal

WooCommerce Cardholder Name Match

Compare WooCommerce buyer and cardholder names using an external card-inquiry API, with HPOS support, privacy-safe caching, configurable provider settings, and audit logs. (With Zohal Webservice)

★ 0stars

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/amirrezashf/woocommerce-authentication-with-zohal/archive/refs/heads/main.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

A production-oriented WooCommerce administration plugin for comparing the buyer name on an order with the cardholder name returned by a card-inquiry provider, with Zohal configured as the default integration.

The plugin is designed for operational verification workflows where store staff need to review whether the name entered by the buyer reasonably matches the name associated with the payment card.

It provides:

  • configurable Zohal/API settings;
  • secure administrative checks from the WooCommerce order screen;
  • normalized Persian/Arabic name comparison;
  • a percentage-based similarity score;
  • privacy-conscious card caching;
  • audit logs;
  • customer-profile history;
  • WooCommerce HPOS compatibility.

This plugin is an operational comparison tool. A similarity score is not proof of identity, legal ownership, fraud, or authorization to use a payment card.

Plugin Identity

Plugin Name: WooCommerce Cardholder Name Match

Repository: WooCommerce-Cardholder-Name-Match

Version: 1.0.0

License: GPL-3.0

Author: Amirreza Shayesteh Far

The project may also be referred to operationally as WooCommerce Authentication With Zohal, because the supplied/default provider integration uses Zohal's card-inquiry service. The current public plugin name is intentionally provider-neutral at the feature level while keeping Zohal as the default configured provider.

Features

  • Manual cardholder-name inquiry from the WooCommerce order administration screen
  • Default integration with Zohal
  • Configurable API base URL
  • Configurable API endpoint
  • Configurable Bearer API token
  • Configurable WooCommerce order meta key containing the card number
  • Configurable cache lifetime from 1 to 365 days
  • No hardcoded production API credential
  • Iranian/Persian/Arabic digit normalization
  • Persian/Arabic character normalization for names
  • 16-digit card validation before API use
  • Cardholder name extraction from the provider response
  • Name similarity scoring
  • Token-based and string-similarity comparison
  • Human-readable match levels
  • Internal result cache
  • HMAC-based card fingerprint
  • Only the last four card digits stored for display
  • Full card number not persisted in the plugin's own result/log tables
  • Per-order last-result association
  • Per-order checked-at metadata
  • Per-order checked-by metadata
  • Operational audit logs
  • Source identification: API vs cache
  • WooCommerce customer-profile verification history
  • Filterable WooCommerce administration log page
  • Cache clearing tool
  • Log clearing tool
  • WooCommerce HPOS compatibility
  • WooCommerce CRUD for order meta
  • WordPress Settings API
  • Nonce-protected AJAX
  • manage_woocommerce capability enforcement
  • Extensible provider integration through WordPress filters

Requirements

  • WordPress 6.0+
  • PHP 7.4+
  • WooCommerce
  • mbstring is strongly recommended because multibyte string functions are used for Persian name comparison
  • An active Zohal account/API token when using the default provider
  • An order meta field containing the payment card number if the payment gateway does not expose it through another compatible integration

Installation

  1. Download the installable ZIP.
  2. Open WordPress administration.
  3. Go to Plugins → Add New → Upload Plugin.
  4. Upload the plugin ZIP.
  5. Install and activate the plugin.
  6. Make sure WooCommerce is active.
  7. Open WooCommerce → Cardholder Name Match.
  8. Configure the API settings.
  9. Enter the order meta key that contains the payment card number.
  10. Save the settings.
  11. Open a WooCommerce order and run a cardholder-name check.

Important Configuration Requirement: Card Meta Key

The plugin deliberately does not assume that every WooCommerce payment gateway stores a card number under the same order meta key.

The order meta key is configurable.

For example:

billing_paycard

is only an example.

The correct key depends on the payment gateway or custom integration used by the store.

If the configured meta key is wrong or empty, the plugin cannot retrieve a card number for the inquiry.

Why the key is configurable

WooCommerce itself does not define a universal order meta key for storing full payment card numbers.

Payment gateways differ significantly in what they store.

Some gateways should not store a full PAN at all.

Therefore the public plugin avoids hardcoding a store-specific or gateway-specific key.

Security Warning About Card Numbers

Full payment-card numbers are highly sensitive payment data.

This plugin does not intentionally create its own long-term copy of the full card number in its custom result or audit-log tables.

However, if another payment gateway/plugin stores a full card number in WooCommerce order meta, that storage exists independently of this plugin and must be reviewed under the store's own security, compliance, and payment-data obligations.

Do not introduce full PAN storage merely to make this plugin work.

Prefer provider/gateway architectures that avoid persistent raw-card storage whenever possible.

Zohal Default Integration

The default API configuration is:

API Base:
https://service.zohal.io/api/v0

Default endpoint:

/services/inquiry/card_inquiry

The plugin sends an HTTP POST request using the WordPress HTTP API.

Authentication is sent using:

Authorization: Bearer <API_TOKEN>

The JSON request body contains:

{
  "card_number": "..."
}

The default parser expects the provider response to contain cardholder-name data in the response structure used by the supplied Zohal integration.

API Configuration

The WooCommerce administration page contains these settings:

API Base URL

Default:

https://service.zohal.io/api/v0

Endpoint

Default:

/services/inquiry/card_inquiry

API Token

The Bearer token used for provider authentication.

The token is entered as a password-style setting field.

Leaving the field empty when saving settings preserves the previously stored token.

Order Meta Key

The WooCommerce order meta key from which the card number should be read.

Cache Lifetime

The result-cache lifetime in days.

Allowed range:

1–365 days

Default:

90 days

How an Order Check Works

When an authorized administrator runs a check:

  1. The plugin verifies the AJAX nonce.
  2. It verifies manage_woocommerce.
  3. It resolves the WooCommerce order.
  4. It builds the buyer's name from the order billing data.
  5. It reads the configured card-number meta field.
  6. Persian/Arabic digits are converted to English digits.
  7. Non-digit card characters are removed.
  8. The card number is checked for a valid 16-digit structure/checksum.
  9. A privacy-safe cache key is generated.
  10. The plugin checks for a non-expired cached result.
  11. If a cached result exists, no provider API request is required.
  12. Otherwise the card number is sent to the configured provider.
  13. The returned cardholder name is normalized.
  14. Buyer/cardholder names are compared.
  15. A score and human-readable result are generated.
  16. A privacy-conscious result record is stored.
  17. The result is associated with the WooCommerce order.
  18. An audit-log record is created.
  19. The administrator sees the result without reloading the complete order workflow.

Buyer Name

The buyer name is derived from the WooCommerce order billing name.

The comparison therefore depends on the quality of:

  • billing first name;
  • billing last name.

If checkout data is incomplete, abbreviated, organizational, or intentionally inaccurate, the similarity result can be misleading.

Name Normalization

Before comparison, the plugin normalizes several common Persian/Arabic text differences.

Examples include mapping variants such as:

ي → ی
ى → ی
ئ → ی
ك → ک
ة → ه
أ → ا
إ → ا
ٱ → ا
ؤ → و

Zero-width joiner/non-joiner characters are normalized to spaces.

Extra punctuation is removed.

Repeated whitespace is collapsed.

Persian and Arabic digits are converted to English digits.

This makes superficial Unicode differences less likely to reduce the match score unfairly.

Name Comparison Algorithm

The current comparison model combines multiple signals.

Exact normalized match

If the two normalized names are identical:

100%

is returned.

Similar-text score

PHP's string-similarity logic is used as one signal.

Weight:

60%

Common token score

The normalized names are split into words/tokens.

The proportion of common tokens is calculated.

Weight:

40%

Containment bonus

If one normalized name contains the other, an additional bonus is applied:

+8

The final score is capped at:

100%

Match Levels

The calculated percentage is mapped to a human-readable level.

90–100%

کاملاً مطابق

Description:

خیلی بالا

70–89.99%

نسبتاً مطابق

Description:

خوب

40–69.99%

کم‌تطابق

Description:

متوسط

Below 40%

بسیار غیر مطابق

Description:

ضعیف

These labels are heuristic operational indicators, not identity-verification decisions.

Why a Percentage Is Not Identity Verification

Names are imperfect identifiers.

Legitimate differences can occur because of:

  • spelling variants;
  • Persian/Arabic Unicode variants;
  • abbreviated names;
  • middle names;
  • prefixes/suffixes;
  • reversed token order;
  • married/family naming differences;
  • shared/family cards;
  • transliteration;
  • incorrect checkout input;
  • provider formatting;
  • payment made by another authorized person.

A low match does not automatically prove fraud.

A high match does not prove that the buyer is the legal cardholder.

The score should support human review rather than silently making high-risk financial decisions by itself.

Card Validation

The plugin normalizes the card value to digits only.

It then requires exactly:

16 digits

and applies the card checksum logic implemented by the plugin.

Invalid card values are rejected before the provider request.

This avoids unnecessary API calls for obviously invalid values.

Privacy-Safe Card Fingerprint

The plugin does not use the full raw card number as the persistent cache identifier.

Instead it creates an HMAC SHA-256 fingerprint using:

hash_hmac(
    'sha256',
    $normalized_card,
    wp_salt( 'auth' )
);

The fingerprint is designed to be non-reversible.

It is used internally for cache/result correlation.

Last Four Digits

For administrative display the plugin stores only:

last 4 digits

Example:

•••• •••• •••• 1234

The result table does not intentionally persist the complete card number.

Cache Architecture

Provider inquiries can be expensive, rate-limited, or slow.

The plugin caches a comparison result using a key derived from:

  • normalized buyer name;
  • card fingerprint.

If the same normalized buyer/card combination is checked again before expiration, the cached result can be reused.

The audit log records whether the result came from:

API

or:

Cache

Cache Expiration

Each cached result stores:

  • creation timestamp;
  • expiration timestamp.

Expired results are removed when encountered during cache lookup.

The configurable default lifetime is:

90 days

The administration screen also provides a manual cache-clearing action.

Custom Database Tables

The plugin creates two custom tables.

Results Table

{prefix}wccnm_results

Important fields include:

  • result ID
  • cache key
  • buyer name
  • normalized buyer name
  • card fingerprint
  • last four card digits
  • cardholder name
  • normalized cardholder name
  • API message
  • API error code
  • API result code
  • match percentage
  • match label
  • match description
  • created timestamp
  • expiration timestamp

Indexes are included for cache and operational lookup.

Logs Table

{prefix}wccnm_logs

Important fields include:

  • log ID
  • WooCommerce order ID
  • WooCommerce customer/user ID
  • result ID
  • administrator ID
  • administrator display name
  • source (api or cache)
  • created timestamp

Indexes support common order/user/admin/time lookups.

Why Custom Tables Are Used

This feature creates reusable cached verification results and potentially many audit-log rows.

Keeping these records in purpose-built indexed tables avoids turning WordPress post meta or user meta into an operational reporting database.

The WooCommerce order itself only stores compact references/metadata to the relevant result/check.

Order Metadata

The plugin stores these order meta values:

_wccnm_result_id
_wccnm_checked_at
_wccnm_checked_by

They represent:

  • the associated result record;
  • when the order was last checked;
  • which administrator performed the last check.

WooCommerce CRUD methods are used for these order meta values.

Order Administration Interface

Authorized WooCommerce managers can run the check from the order administration workflow.

The result UI can display:

  • buyer name;
  • provider-returned cardholder name;
  • masked card ending;
  • match percentage;
  • match label;
  • descriptive level;
  • provider message;
  • administrator who performed the check;
  • check date/time;
  • result source (API or internal cache).

Customer Profile History

The plugin integrates with WordPress user-profile administration.

For WooCommerce customers, authorized staff can review verification history associated with that user/customer.

This is intended as an operational history view, not as a customer-facing feature.

Audit Logs

The WooCommerce submenu contains a log interface.

Logs can be filtered by operational information such as:

  • search text;
  • administrator;
  • result source;
  • match category.

The table displays fields such as:

  • order;
  • buyer name;
  • cardholder name;
  • masked card;
  • percentage;
  • result;
  • administrator;
  • source;
  • date;
  • provider message.

Search and Filtering

The administration log view supports filtering by:

  • free-text search;
  • checking administrator;
  • API/cache source;
  • result category.

This helps investigate recent or historical checks without opening every order individually.

Destructive Administration Actions

The log/settings page provides actions for:

  • clearing cached results;
  • clearing audit logs.

These actions are nonce-protected.

They should be treated as destructive operations because they remove historical/operational records.

Settings Security

Settings are registered through the WordPress Settings API.

Input is sanitized.

The settings page and operational pages require:

manage_woocommerce

rather than checking for a hardcoded administrator role.

AJAX Security

The order-check action:

  • is only registered for authenticated WordPress AJAX;
  • requires the plugin nonce;
  • requires WooCommerce management capability;
  • validates the target order;
  • validates/normalizes data server-side.

There is no public unauthenticated endpoint for arbitrary card inquiries.

API Token Handling

The API token is not hardcoded in the public plugin source.

It is stored as a WordPress option with the plugin settings.

The settings form intentionally leaves the password input blank when rendered and preserves the previous token if the field is saved empty.

The token remains a sensitive secret.

Database backups, administrator accounts, debugging output, and unauthorized database access must therefore be secured appropriately.

API Request Timeout

The provider request uses a timeout of:

25 seconds

This is a synchronous administrative request.

A slow provider can therefore make the individual check feel slow.

Because the check is manually initiated by an administrator rather than performed on every checkout request, this is operationally safer than putting the external request directly in the customer's payment flow.

Provider Response Parsing

The default parser is designed for the response structure used by the supplied Zohal integration.

It extracts fields such as:

  • cardholder name;
  • provider message;
  • provider error code;
  • result code;
  • HTTP status.

Invalid JSON is treated as an error.

Provider Extensibility

The plugin includes filters that allow integrations to alter the external-provider behavior.

wccnm_api_url

Can modify the final API URL.

wccnm_api_request_args

Can modify the WordPress HTTP request arguments.

wccnm_parsed_api_response

Can replace/adjust the parsed provider response.

This means the architecture is not irreversibly tied to one response parser even though Zohal is the default implementation.

Example: Customize API URL

add_filter(
    'wccnm_api_url',
    function ( $url, $settings ) {
        return $url;
    },
    10,
    2
);

Example: Customize HTTP Arguments

add_filter(
    'wccnm_api_request_args',
    function ( $args, $card_number, $settings ) {
        return $args;
    },
    10,
    3
);

Example: Customize Provider Parser

add_filter(
    'wccnm_parsed_api_response',
    function ( $parsed, $json, $response ) {
        return $parsed;
    },
    10,
    3
);

WooCommerce HPOS Compatibility

The plugin declares compatibility with:

custom_order_tables

It works with WooCommerce order objects and uses WooCommerce CRUD for order-level metadata.

It does not require the order itself to remain an ordinary shop_order post for the core result association.

WooCommerce Dependency

WooCommerce must be installed and active.

If WooCommerce is unavailable, the plugin does not initialize its WooCommerce-specific workflow and shows an administration notice to users who can activate plugins.

Performance

The most expensive operation is the external API inquiry.

Performance is reduced through:

  • cached results;
  • indexed custom tables;
  • order-local metadata references;
  • manual/on-demand checks rather than checkout-wide API calls;
  • cache expiry;
  • limited administration queries;
  • source tracking to identify cache hits.

For high-volume deployments, administrators should still monitor:

  • provider latency;
  • provider rate limits;
  • result-table growth;
  • log-table growth;
  • retention policy;
  • backup volume.

Privacy

The plugin processes personal and payment-adjacent data.

Potentially processed information includes:

  • buyer name;
  • provider-returned cardholder name;
  • WooCommerce order ID;
  • customer/user ID;
  • administrator ID/name;
  • provider messages;
  • last four card digits;
  • card fingerprint.

The complete card number is transmitted to the configured inquiry provider when an API request is required.

The plugin's own result table intentionally stores only:

  • a non-reversible fingerprint;
  • the last four digits;

instead of the full card number.

Data Sent to the Provider

When a live provider request is made, the configured API receives the card number needed for the inquiry.

Store operators are responsible for ensuring that:

  • the provider is approved for their use case;
  • their privacy policy reflects the processing;
  • legal/contractual requirements are satisfied;
  • payment-data handling is compliant with their environment;
  • the provider's retention/security policies are acceptable.

Data Retention

The default cache lifetime is 90 days.

Audit logs do not have an automatic age-based purge in version 1.0.0.

The administration page provides manual clearing actions.

Production stores should define a deliberate retention policy for both:

  • cached verification results;
  • audit logs.

Keeping personal/operational data forever is not automatically desirable.

Security Considerations

The plugin includes:

  • manage_woocommerce capability checks;
  • WordPress nonces;
  • Settings API sanitization;
  • server-side validation;
  • card checksum validation;
  • prepared SQL for filtered/read queries;
  • WooCommerce CRUD;
  • masked card display;
  • HMAC card fingerprinting;
  • no public AJAX inquiry endpoint;
  • no production API token in source.

Security still depends on the surrounding WordPress installation and payment gateway.

Error Handling

Possible errors include:

  • API settings incomplete;
  • API token missing;
  • card meta key not configured;
  • card number missing;
  • invalid card number;
  • provider/network failure;
  • invalid JSON;
  • unsupported provider response shape;
  • provider error/result codes;
  • database result write failure;
  • order not found;
  • insufficient permissions;
  • invalid nonce.

The interface should display an operational error rather than silently treating failure as a successful mismatch.

Troubleshooting

“API settings are incomplete”

Verify:

  • API Base URL;
  • Endpoint;
  • API Token.

No card number is found

Verify the configured Order Meta Key.

Do not guess the key based on another payment gateway.

Inspect how the actual gateway stores or exposes the card data.

Card is rejected before API call

Verify that the normalized value is a valid 16-digit card number accepted by the plugin's checksum validation.

Provider returns invalid JSON

Check:

  • provider availability;
  • API endpoint;
  • authentication;
  • whether the provider API response format has changed.

Result always comes from cache

The combination of normalized buyer name and card fingerprint is still inside the configured cache lifetime.

Clear the plugin cache if a deliberate fresh provider request is needed.

Name score looks unexpectedly low

Check:

  • billing first/last name quality;
  • cardholder-name formatting;
  • spelling;
  • omitted middle/family-name tokens;
  • whether the payer is a different person.

The percentage is heuristic.

Known Limitations

  • The comparison is heuristic and not formal identity verification.
  • The default provider parser targets the supplied Zohal response structure.
  • A valid payment-card meta source must already exist.
  • The plugin does not itself capture a card number at checkout.
  • It should not be used as justification for introducing insecure card storage.
  • API requests are synchronous.
  • There is no automatic retry queue.
  • Audit logs do not automatically expire.
  • The algorithm does not perform advanced Persian NLP/entity resolution.
  • A high score does not prove authorization.
  • A low score does not prove fraud.
  • Shared/family/business payment cards can produce legitimate mismatches.
  • Provider availability and pricing are external to the plugin.

What the Plugin Does Not Do

The plugin does not:

  • perform payment authorization;
  • replace the payment gateway;
  • prove legal card ownership;
  • make autonomous fraud decisions;
  • block checkout by itself;
  • collect card numbers from customers;
  • provide PCI compliance;
  • guarantee provider accuracy;
  • automatically refund/cancel suspicious orders;
  • expose verification data to customers;
  • make a low match synonymous with fraud.

A reasonable workflow is:

  1. Staff opens an order that needs manual review.
  2. The plugin retrieves the configured card data.
  3. A provider inquiry is performed or a valid cache result is reused.
  4. Staff reviews the returned cardholder name.
  5. Staff reviews the similarity percentage.
  6. Staff considers other legitimate order/payment context.
  7. A human makes the final operational decision.

The plugin should be treated as a decision-support tool.

Database Cleanup

The administration page provides separate destructive actions for:

  • result cache;
  • audit logs.

These actions are protected by a WordPress administration nonce.

Clearing one does not necessarily have the same operational effect as clearing the other.

Uninstall Behavior

The current plugin does not advertise automatic deletion of all operational data on uninstall.

This is intentional from a data-loss perspective but means administrators who require complete erasure should perform a deliberate cleanup of plugin options, order metadata, and custom tables.

Suggested GitHub Description

Compare WooCommerce buyer and cardholder names using the Zohal card-inquiry API, with HPOS support, privacy-safe caching, configurable provider settings, and audit logs.

Repository

https://github.com/amirrezashf/WooCommerce-Cardholder-Name-Match

License

GPL-3.0

Author

Amirreza Shayesteh Far

GitHub:

https://github.com/amirrezashf

تطبیق نام خریدار و دارنده کارت در ووکامرس با زحل

WooCommerce Cardholder Name Match یک افزونه مدیریتی برای WooCommerce است که نام خریدار ثبت‌شده روی سفارش را با نام دارنده کارت بانکی که از سرویس استعلام کارت دریافت می‌شود مقایسه می‌کند.

سرویس پیش‌فرض افزونه Zohal / زحل است و به همین دلیل این پروژه ممکن است در Workflow داخلی با عنوان WooCommerce Authentication With Zohal نیز شناخته شود.

هدف افزونه این است که همکاران فروشگاه هنگام بررسی دستی سفارش بتوانند یک سیگنال کمکی درباره میزان شباهت نام خریدار و نام دارنده کارت دریافت کنند.

این افزونه سیستم احراز هویت قطعی، اثبات مالکیت کارت یا Fraud Detection قطعی نیست.

امکانات

  • استعلام دستی نام دارنده کارت از صفحه سفارش WooCommerce
  • اتصال پیش‌فرض به API زحل
  • امکان تغییر API Base URL
  • امکان تغییر Endpoint
  • تنظیم API Token از مدیریت WordPress
  • عدم Hardcode کردن Token واقعی در سورس عمومی
  • امکان تعیین Order Meta Key شماره کارت
  • عدم فرض یک Meta Key ثابت برای همه Payment Gatewayها
  • Normalize کردن اعداد فارسی، عربی و انگلیسی
  • Normalize کردن حروف فارسی و عربی نام
  • Validation اولیه شماره کارت
  • دریافت Cardholder Name از Provider
  • مقایسه نام خریدار و نام دارنده کارت
  • محاسبه درصد تطابق
  • نمایش Level قابل فهم برای نتیجه
  • Cache کردن نتیجه استعلام
  • استفاده از Fingerprint غیرقابل بازیابی کارت
  • ذخیره فقط چهار رقم آخر برای نمایش
  • عدم ذخیره Full Card Number در جداول اختصاصی افزونه
  • ثبت Audit Log
  • ثبت نام Admin بررسی‌کننده
  • ثبت زمان بررسی
  • مشخص‌کردن اینکه نتیجه از API یا Cache آمده
  • اتصال آخرین Result به Order
  • مشاهده History مرتبط با Customer در مدیریت
  • صفحه Log قابل Search و Filter
  • امکان پاک‌سازی Cache
  • امکان پاک‌سازی Log
  • HPOS Compatibility
  • استفاده از WooCommerce CRUD
  • Nonce Protection
  • manage_woocommerce Capability
  • قابلیت Customize کردن API Integration با Filter

این افزونه دقیقاً چه مشکلی را حل می‌کند؟

فرض کنید مشتری هنگام Checkout نام زیر را وارد کرده است:

امیررضا شایسته فر

اما کارت بانکی استفاده‌شده طبق پاسخ Provider متعلق به:

امیر رضا شایسته‌فر

است.

این دو String دقیقاً یکسان نیستند، اما از نظر انسانی ممکن است متعلق به یک نام باشند.

افزونه قبل از مقایسه:

  • حروف عربی و فارسی را Normalize می‌کند؛
  • فاصله‌های غیرضروری را حذف می‌کند؛
  • Zero-width Characterها را اصلاح می‌کند؛
  • نشانه‌گذاری را حذف می‌کند؛
  • Tokenهای نام را مقایسه می‌کند؛
  • Similarity رشته را نیز محاسبه می‌کند.

سپس یک درصد تقریبی و یک Label ارائه می‌دهد.

نکته بسیار مهم درباره مفهوم «Authentication»

نام Workflow ممکن است Authentication With Zohal باشد، اما این قابلیت نباید با احراز هویت قطعی اشتباه گرفته شود.

استعلام نام دارنده کارت فقط یک Signal است.

برای مثال ممکن است:

  • مشتری از کارت همسر خود استفاده کند؛
  • کارت متعلق به والدین باشد؛
  • کارت سازمانی باشد؛
  • نام Provider فرمت متفاوت داشته باشد؛
  • Billing Name ناقص ثبت شده باشد.

بنابراین Mismatch لزوماً Fraud نیست.

Match بالا نیز اثبات نمی‌کند شخصی که سفارش را ثبت کرده همان مالک قانونی کارت است.

نصب

  1. ZIP افزونه را دانلود کنید.
  2. وارد WordPress Admin شوید.
  3. به افزونه‌ها → افزودن افزونه تازه → بارگذاری افزونه بروید.
  4. ZIP را Upload کنید.
  5. افزونه را نصب و فعال کنید.
  6. WooCommerce باید فعال باشد.
  7. وارد منوی WooCommerce شوید.
  8. صفحه تطبیق نام کارت را باز کنید.
  9. API زحل را Configure کنید.
  10. Order Meta Key مربوط به Card Number را وارد کنید.
  11. تنظیمات را ذخیره کنید.
  12. یک Order را باز کنید و استعلام را اجرا کنید.

تنظیمات API

افزونه این موارد را قابل تنظیم می‌کند:

API Base URL

پیش‌فرض:

https://service.zohal.io/api/v0

Endpoint

پیش‌فرض:

/services/inquiry/card_inquiry

API Token

Token احراز هویت Provider.

Token در Source Code عمومی Hardcode نمی‌شود.

در UI نیز Input به‌صورت Password است و اگر هنگام Save خالی باشد، Token قبلی حفظ می‌شود.

Order Meta Key شماره کارت

کلیدی که Gateway فعلی فروشگاه Card Number را در آن قرار داده است.

Cache Days

مدت نگهداری Result Cache.

محدوده:

1 تا 365 روز

پیش‌فرض:

90 روز

چرا Order Meta Key قابل تنظیم است؟

WooCommerce یک Meta Key عمومی و استاندارد برای Full Card Number ندارد.

Payment Gatewayهای مختلف رفتار متفاوتی دارند.

بنابراین افزونه نباید چیزی مانند:

_billing_card

یا هر Key مخصوص یک فروشگاه را Hardcode کند.

مدیر سایت باید Key واقعی Integration خودش را مشخص کند.

هشدار مهم درباره ذخیره شماره کارت

Full Card Number داده بسیار حساس است.

این افزونه برای Cache/Log خودش Full PAN را ذخیره نمی‌کند.

اما اگر Gateway دیگری شماره کامل کارت را در Order Meta ذخیره کرده باشد، آن موضوع مستقل از این افزونه است.

برای استفاده از این افزونه نباید یک معماری ناامن جدید برای ذخیره شماره کامل کارت ایجاد شود.

اگر Provider/Gateway روشی دارد که Full PAN را Persist نمی‌کند، آن معماری ترجیح دارد.

نحوه انجام استعلام

وقتی Admin دکمه بررسی را اجرا می‌کند:

  1. Nonce بررسی می‌شود.
  2. Capability بررسی می‌شود.
  3. Order از WooCommerce Resolve می‌شود.
  4. نام Billing خریدار استخراج می‌شود.
  5. Card Number از Meta Key تنظیم‌شده خوانده می‌شود.
  6. Digitها Normalize می‌شوند.
  7. Characterهای غیرعددی حذف می‌شوند.
  8. اعتبار ساختاری کارت بررسی می‌شود.
  9. Card Fingerprint ساخته می‌شود.
  10. Cache Key ساخته می‌شود.
  11. Result Cache بررسی می‌شود.
  12. اگر Result معتبر وجود داشته باشد، API دوباره Call نمی‌شود.
  13. اگر Cache وجود نداشته باشد، Request به Provider ارسال می‌شود.
  14. Cardholder Name از Response استخراج می‌شود.
  15. نام‌ها Normalize می‌شوند.
  16. Similarity Score محاسبه می‌شود.
  17. Result ذخیره می‌شود.
  18. Result به Order متصل می‌شود.
  19. Audit Log ساخته می‌شود.
  20. نتیجه در همان Workflow مدیریتی نمایش داده می‌شود.

نام خریدار از کجا می‌آید؟

Buyer Name از Billing Name سفارش WooCommerce ساخته می‌شود.

بنابراین کیفیت Result به کیفیت اطلاعات Checkout نیز وابسته است.

اگر مشتری نام ناقص یا اشتباه وارد کرده باشد، Match Score می‌تواند پایین‌تر از واقعیت باشد.

Normalize نام فارسی

افزونه برخی تفاوت‌های متداول Unicode را Normalize می‌کند.

نمونه:

ي → ی
ى → ی
ئ → ی
ك → ک
ة → ه
أ → ا
إ → ا
ٱ → ا
ؤ → و

همچنین:

  • اعداد فارسی/عربی به English Digit تبدیل می‌شوند؛
  • Zero Width Joiner/Non-Joiner به Space تبدیل می‌شوند؛
  • علامت‌های غیرضروری حذف می‌شوند؛
  • Spaceهای تکراری Collapse می‌شوند.

الگوریتم تطابق نام

الگوریتم فعلی چند Signal را ترکیب می‌کند.

Exact Match

اگر Nameهای Normalizeشده برابر باشند:

100%

Similar Text

یک Similarity Percentage رشته‌ای محاسبه می‌شود.

وزن:

60%

Common Tokens

Tokenهای مشترک دو Name بررسی می‌شوند.

وزن:

40%

Contains Bonus

اگر یکی از نام‌ها داخل دیگری باشد:

+8

به Score اضافه می‌شود.

Final Result از 100 بیشتر نمی‌شود.

دسته‌بندی نتیجه

90 درصد و بیشتر

کاملاً مطابق

سطح:

خیلی بالا

70 تا کمتر از 90

نسبتاً مطابق

سطح:

خوب

40 تا کمتر از 70

کم‌تطابق

سطح:

متوسط

کمتر از 40

بسیار غیر مطابق

سطح:

ضعیف

این Thresholdها Operational هستند و نباید بدون بررسی انسانی به Rule قطعی Fraud تبدیل شوند.

Validation شماره کارت

Card Number ابتدا به Digit-only تبدیل می‌شود.

سپس افزونه بررسی می‌کند:

Length = 16

و Checksum داخلی را اجرا می‌کند.

اگر Card از Validation عبور نکند، Provider Call غیرضروری انجام نمی‌شود.

Fingerprint کارت

به‌جای اینکه Full Card Number به‌عنوان Cache Identifier ذخیره شود، افزونه یک Fingerprint تولید می‌کند.

روش فعلی:

hash_hmac(
    'sha256',
    $normalized_card,
    wp_salt( 'auth' )
);

Fingerprint یک مقدار یک‌طرفه است و برای Correlation/Cache استفاده می‌شود.

چهار رقم آخر

برای نمایش در Admin فقط چهار رقم آخر نگهداری می‌شود.

مثال:

•••• •••• •••• 1234

Cache

Resultهای API Cache می‌شوند تا:

  • Provider Call تکراری کمتر شود؛
  • Latency کاهش پیدا کند؛
  • هزینه/API Usage کمتر شود؛
  • بررسی مجدد Order سریع‌تر باشد.

Cache Key از ترکیب:

  • Normalized Buyer Name
  • Card Fingerprint

ساخته می‌شود.

بنابراین تغییر واقعی Buyer Name می‌تواند Cache Combination را تغییر دهد.

Source نتیجه

هر Log مشخص می‌کند Result از کدام Source آمده:

api

یا:

cache

این موضوع برای Audit و Troubleshooting مفید است.

جدول Resultها

افزونه جدول اختصاصی زیر را ایجاد می‌کند:

{prefix}wccnm_results

اطلاعات اصلی شامل:

  • Cache Key
  • Buyer Name
  • Normalized Buyer Name
  • Card Fingerprint
  • Last 4 Digits
  • Cardholder Name
  • Normalized Cardholder Name
  • API Message
  • API Error Code
  • API Result Code
  • Match Percent
  • Match Label
  • Match Text
  • Created At
  • Expires At

است.

Full Card Number داخل این Table ذخیره نمی‌شود.

جدول Logها

جدول:

{prefix}wccnm_logs

اطلاعاتی مانند:

  • Order ID
  • User ID
  • Result ID
  • Admin ID
  • Admin Name
  • Source
  • Created At

را نگهداری می‌کند.

چرا Custom Table؟

Result Cache و Audit Log می‌توانند تعداد رکورد زیادی داشته باشند.

استفاده از Table اختصاصی Indexed نسبت به تبدیل User Meta/Post Meta به سیستم Log/Reporting مقیاس‌پذیرتر و تمیزتر است.

Metaهای Order

افزونه این Metaها را روی Order نگهداری می‌کند:

_wccnm_result_id
_wccnm_checked_at
_wccnm_checked_by

این‌ها برای مشخص‌کردن:

  • آخرین Result
  • زمان Check
  • Admin بررسی‌کننده

استفاده می‌شوند.

Order Meta از طریق WooCommerce CRUD مدیریت می‌شود.

نمایش Result در Order

Result می‌تواند شامل موارد زیر باشد:

  • نام خریدار
  • نام دارنده کارت
  • Card Mask
  • Match Percent
  • Match Label
  • Description
  • API Message
  • Admin بررسی‌کننده
  • تاریخ بررسی
  • Source

این اطلاعات فقط در Admin Workflow نمایش داده می‌شوند.

History کاربر

در User Profile مدیریت WordPress، History مرتبط با Customer قابل مشاهده است.

این قابلیت برای بررسی Operational History توسط Staff است و Frontend Customer Feature نیست.

صفحه Log

در WooCommerce یک صفحه برای Logها وجود دارد.

می‌توان Resultها را بر اساس موارد مختلف Filter کرد.

از جمله:

  • Search
  • Admin
  • Source
  • Match Level

پاک‌سازی Cache

Action جداگانه برای:

Clear Cache

وجود دارد.

این Action جدول Result Cache را پاک می‌کند.

قبل از استفاده باید بدانید Resultهای Cacheشده از بین می‌روند و Inquiry بعدی ممکن است مجدداً Provider را Call کند.

پاک‌سازی Log

Action جداگانه برای:

Clear Logs

وجود دارد.

این Action Audit History را حذف می‌کند.

هر دو Action با Nonce محافظت شده‌اند.

دسترسی‌ها

Admin Featureها به Capability زیر وابسته هستند:

manage_woocommerce

به‌جای Hardcode کردن Role:

administrator

این روش با معماری Permission وردپرس سازگارتر است.

امنیت AJAX

Inquiry AJAX فقط برای User احراز هویت‌شده WordPress ثبت شده است.

قبل از پردازش:

  • Nonce بررسی می‌شود.
  • Capability بررسی می‌شود.
  • Order Validate می‌شود.
  • Inputها Server-side Normalize می‌شوند.

Public Guest Endpoint برای استعلام دلخواه کارت وجود ندارد.

API Token

Token در WordPress Options ذخیره می‌شود.

این داده Secret محسوب می‌شود.

بنابراین باید موارد زیر امن باشند:

  • WordPress Admin Accounts
  • Database
  • Backups
  • Debug Logs
  • Server Access

Timeout API

Timeout فعلی:

25 seconds

است.

Request به‌صورت Synchronous انجام می‌شود.

این طراحی چون Inquiry دستی Admin است، نسبت به اجرای API در هر Checkout ریسک Performance کمتری دارد.

Parsing پاسخ زحل

Parser پیش‌فرض Response Shape ارائه‌شده برای Zohal را می‌شناسد.

مواردی مانند:

  • name
  • message
  • error_code
  • result

از Response استخراج می‌شوند.

اگر JSON معتبر نباشد، Result موفق در نظر گرفته نمی‌شود.

Filterهای Integration

wccnm_api_url

برای تغییر URL نهایی API.

wccnm_api_request_args

برای تغییر Request Args.

wccnm_parsed_api_response

برای تغییر یا Replace کردن Parser Result.

بنابراین اگر Provider مشابهی Response متفاوت داشته باشد، Integrator می‌تواند بدون Fork کردن Core Plugin بخشی از Behavior را تغییر دهد.

HPOS

افزونه Compatibility با:

custom_order_tables

را اعلام می‌کند.

برای Order Meta از WooCommerce CRUD استفاده می‌شود.

بنابراین Result Association به Storage قدیمی Order Posts وابسته نیست.

Performance

راهکارهای Performance فعلی:

  • Cache Result
  • Custom Indexed Tables
  • On-demand Inquiry
  • عدم API Call در هر Page View
  • عدم API Call در هر Checkout
  • استفاده از Result Reference روی Order
  • Source Tracking
  • Cache Expiration

برای Store پرترافیک همچنان باید Table Growth و Retention بررسی شوند.

حریم خصوصی

این افزونه داده‌های حساس/شخصی را پردازش می‌کند.

از جمله:

  • Buyer Name
  • Cardholder Name
  • Order ID
  • User ID
  • Admin Identity
  • Last 4 Card Digits
  • Card Fingerprint
  • Provider Messages

Full Card Number هنگام Live Inquiry برای Provider ارسال می‌شود.

اما در Result Table اختصاصی افزونه Persist نمی‌شود.

Retention

Cache به‌صورت پیش‌فرض 90 روز اعتبار دارد.

Audit Log فعلاً Auto Purge بر اساس Age ندارد.

بنابراین برای Production باید مشخص شود:

  • Resultها چند روز نگهداری شوند؟
  • Logs چند روز/ماه نگهداری شوند؟
  • چه کسی حق مشاهده آن‌ها را دارد؟
  • چه زمانی باید پاک شوند؟

Security

مهم‌ترین Security Controls:

  • manage_woocommerce
  • Nonce
  • Settings Sanitization
  • Server-side Validation
  • Prepared SQL
  • Card Validation
  • Masked Display
  • HMAC Fingerprint
  • عدم Public Inquiry Endpoint
  • عدم Hardcode API Secret
  • WooCommerce CRUD

خطاهای رایج

تنظیمات API کامل نیست

API Base، Endpoint و Token را بررسی کنید.

Card Number پیدا نمی‌شود

Order Meta Key را بررسی کنید.

این Key برای هر Gateway می‌تواند متفاوت باشد.

Card نامعتبر است

ممکن است:

  • تعداد Digit اشتباه باشد؛
  • Character اضافی وجود داشته باشد؛
  • Checksum معتبر نباشد.

Provider JSON نامعتبر می‌دهد

ممکن است Endpoint/API تغییر کرده، Authentication مشکل داشته یا Provider Error داده باشد.

Result از Cache می‌آید

Cache Combination هنوز Expire نشده است.

اگر Fresh Inquiry لازم است، Cache را آگاهانه Clear کنید.

Score پایین است ولی نام‌ها شبیه‌اند

Formatting، Token Order، Middle Name، Prefix و تفاوت‌های نام را بررسی کنید.

الگوریتم Heuristic است.

محدودیت‌ها

  • سیستم Identity Verification قانونی نیست.
  • Fraud Detector قطعی نیست.
  • Provider پیش‌فرض Zohal است.
  • Parser پیش‌فرض بر اساس Response Shape فعلی Integration نوشته شده است.
  • Card Source باید از قبل توسط Integration دیگری وجود داشته باشد.
  • افزونه Card Number را در Checkout جمع‌آوری نمی‌کند.
  • API Request Sync است.
  • Retry Queue ندارد.
  • Auto Log Purge ندارد.
  • NLP پیشرفته نام فارسی ندارد.
  • کارت مشترک یا کارت فرد دیگر می‌تواند Legitimate Mismatch ایجاد کند.
  • Provider Availability/Price خارج از کنترل افزونه است.

چه کارهایی انجام نمی‌دهد؟

افزونه:

  • Checkout را به‌تنهایی Block نمی‌کند.
  • Payment را Authorize نمی‌کند.
  • جای Payment Gateway نیست.
  • Full Identity Verification انجام نمی‌دهد.
  • PCI Compliance ایجاد نمی‌کند.
  • Fraud را قطعی تشخیص نمی‌دهد.
  • Order را خودکار Cancel نمی‌کند.
  • Refund خودکار انجام نمی‌دهد.
  • Verification Data را برای Customer نمایش نمی‌دهد.
  • Low Score را به معنی Fraud قطعی نمی‌گیرد.

Workflow پیشنهادی

  1. Order نیازمند Review را باز کنید.
  2. Inquiry را اجرا کنید.
  3. Cardholder Name را بررسی کنید.
  4. Match Score را ببینید.
  5. Source نتیجه را بررسی کنید.
  6. سایر اطلاعات Order/Payment را نیز در نظر بگیرید.
  7. تصمیم نهایی را انسانی بگیرید.

حذف داده‌ها

Deactivate کردن افزونه به‌صورت خودکار تمام Resultها و Logها را پاک نمی‌کند.

برای حذف کامل باید Data Cleanup آگاهانه انجام شود.

این موضوع جلوی از بین رفتن ناخواسته Audit History را می‌گیرد، اما Retention Policy همچنان بر عهده Administrator است.

GitHub Description پیشنهادی

Compare WooCommerce buyer and cardholder names using the Zohal card-inquiry API, with HPOS support, privacy-safe caching, configurable provider settings, and audit logs.

Repository


https://github.com/amirrezashf/WooComm

This README is longer than the copy stored here. Read the rest on GitHub →