{"id":369406,"date":"2026-09-18T09:24:42","date_gmt":"2026-09-18T09:24:42","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/sendit-ma-for-woocommerce\/"},"modified":"2026-09-18T09:24:25","modified_gmt":"2026-09-18T09:24:25","slug":"sendit-ma-integration","status":"publish","type":"plugin","link":"https:\/\/ps.wordpress.org\/plugins\/sendit-ma-integration\/","author":23566788,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"2.2.4","stable_tag":"2.2.4","tested":"7.1.1","requires":"5.8","requires_php":"7.4","requires_plugins":null,"header_name":"Sendit.ma for WooCommerce","header_author":"sendit.ma","header_description":"Automatise la cr\u00e9ation des livraisons via l'API Sendit.ma et g\u00e8re les mises \u00e0 jour de statut par Webhook.","assets_banners_color":"ffffff","last_updated":"2026-09-18 09:24:25","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/plugins.sendit.ma\/woocommerce","header_author_uri":"https:\/\/www.sendit.ma","rating":0,"author_block_rating":0,"active_installs":0,"downloads":32,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"2.2.4":{"tag":"2.2.4","author":"yssendit","date":"2026-09-18 09:24:25","revision":3701677}},"upgrade_notice":{"2.2.4":"<p>Hardens settings sanitisation against malformed input. Recommended for stores on WordPress 5.8 or 5.9, where it prevents a fatal error when saving settings.<\/p>","2.2.3":"<p>Security and maintenance: Select2 updated to 4.1.0, a missing permission check added to bulk label printing, and admin notices confined to the plugin&#039;s own settings page.<\/p>","2.2.2":"<p>Corrects the plugin and author links in the plugin header. No functional change.<\/p>","2.2.1":"<p>The city list now syncs itself when you save your API keys, and the weekly refresh finally reaches stores that updated in place. Also: stricter setting sanitisation, safer label downloads, and working translation support.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3701652,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3701652,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3701652,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3701652,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["2.2.4"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3701652,"resolution":"1","location":"assets","locale":"","width":1280,"height":1650},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3701652,"resolution":"2","location":"assets","locale":"","width":1105,"height":645},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3701652,"resolution":"3","location":"assets","locale":"","width":1280,"height":1148},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3701652,"resolution":"4","location":"assets","locale":"","width":310,"height":515}},"screenshots":{"1":"The settings page: API keys, activation mode, pickup city and webhook URL.","2":"Default parcel options (try on, opening) and the status that triggers automatic sending.","3":"The searchable \"Delivery City \/ District\" field at checkout, with the rate calculated automatically.","4":"The Sendit panel on an order: editable district, parcel code, last known status and options."}},"plugin_section":[],"plugin_tags":[13827,232984,188949,3546,286],"plugin_category":[45],"plugin_contributors":[281412],"plugin_business_model":[],"class_list":["post-369406","plugin","type-plugin","status-publish","hentry","plugin_tags-delivery","plugin_tags-morocco","plugin_tags-sendit","plugin_tags-shipping","plugin_tags-woocommerce","plugin_category-ecommerce","plugin_contributors-yssendit","plugin_committers-yssendit"],"banners":{"banner":"https:\/\/ps.w.org\/sendit-ma-integration\/assets\/banner-772x250.png?rev=3701652","banner_2x":"https:\/\/ps.w.org\/sendit-ma-integration\/assets\/banner-1544x500.png?rev=3701652","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/sendit-ma-integration\/assets\/icon-128x128.png?rev=3701652","icon_2x":"https:\/\/ps.w.org\/sendit-ma-integration\/assets\/icon-256x256.png?rev=3701652","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/sendit-ma-integration\/assets\/screenshot-1.png?rev=3701652","caption":"The settings page: API keys, activation mode, pickup city and webhook URL."},{"src":"https:\/\/ps.w.org\/sendit-ma-integration\/assets\/screenshot-2.png?rev=3701652","caption":"Default parcel options (try on, opening) and the status that triggers automatic sending."},{"src":"https:\/\/ps.w.org\/sendit-ma-integration\/assets\/screenshot-3.png?rev=3701652","caption":"The searchable \"Delivery City \/ District\" field at checkout, with the rate calculated automatically."},{"src":"https:\/\/ps.w.org\/sendit-ma-integration\/assets\/screenshot-4.png?rev=3701652","caption":"The Sendit panel on an order: editable district, parcel code, last known status and options."}],"raw_content":"<!--section=description-->\n<p>This plugin connects your WooCommerce store to your <strong>Sendit.ma<\/strong> account, a delivery service operating in Morocco. It removes double data entry: orders are sent to Sendit in one click (or automatically), shipping is priced from the customer's city, and delivery statuses flow back into WooCommerce.<\/p>\n\n<p>The plugin interface is in French, the working language of the merchants it serves.<\/p>\n\n<p><strong>Main features<\/strong><\/p>\n\n<ul>\n<li><strong>Parcel creation<\/strong> \u2014 send an order to Sendit from the order screen, as a bulk action, or automatically when an order reaches a status you choose.<\/li>\n<li><strong>Dynamic shipping rates<\/strong> \u2014 the rate comes from the Sendit district the customer selects at checkout. Enable it globally or product by product.<\/li>\n<li><strong>City \/ district selector<\/strong> \u2014 replaces the \"City\" field with a searchable list of Sendit districts. Works with both the classic checkout <strong>and<\/strong> the block checkout (WooCommerce 8.9+).<\/li>\n<li><strong>PDF labels<\/strong> \u2014 download the label for one order, or generate a combined PDF for a selection of orders.<\/li>\n<li><strong>Automatic status tracking<\/strong> \u2014 the Sendit webhook adds a timestamped note at each step and moves the order to \"Completed\", \"Cancelled\", \"Failed\" or \"On hold\" depending on the delivery outcome.<\/li>\n<li><strong>Parcel options<\/strong> \u2014 \"allow try on\" and \"allow opening\" can be set globally, per order, or in bulk, and are synced to Sendit.<\/li>\n<li><strong>Cities and rates kept current<\/strong> \u2014 the list is fetched when you save your API keys and refreshed weekly, so Sendit rate changes reach your store without anyone remembering to press a button.<\/li>\n<li><strong>HPOS compatible<\/strong> \u2014 works with WooCommerce High-Performance Order Storage.<\/li>\n<\/ul>\n\n<h4>External service required<\/h4>\n\n<p>This plugin is a connector: it only works with a <strong>Sendit.ma<\/strong> account. Sendit.ma is a Moroccan delivery service operated by Sendit (ICE 002745443000051, 120 Bd de la Grande Ceinture, Casablanca, Morocco). The plugin performs no delivery function of its own \u2014 it sends your orders to the Sendit API and displays what comes back.<\/p>\n\n<p><strong>What is sent, when, and where<\/strong><\/p>\n\n<ul>\n<li><code>https:\/\/app.sendit.ma\/api\/v1\/login<\/code> \u2014 when you save the settings and when you test the connection: your API keys, in exchange for a session token.<\/li>\n<li><code>https:\/\/app.sendit.ma\/api\/v1\/districts<\/code> \u2014 when you save API keys, once a week, and whenever you force a sync: no customer data, only a request for the list of cities and rates.<\/li>\n<li><code>https:\/\/app.sendit.ma\/api\/v1\/deliveries<\/code> \u2014 when a parcel is created, triggered by you or by the order status you configured: the customer's name, phone number and address, the order reference, the items and quantities, the amount to collect, and the parcel options.<\/li>\n<li><code>https:\/\/app.sendit.ma\/api\/v1\/deliveries\/getlabels<\/code> \u2014 when you download a label: the code of the parcel concerned.<\/li>\n<\/ul>\n\n<p>Nothing is transmitted until you enter your API keys. The plugin sends data to no other recipient, loads no external resources, and collects no usage statistics.<\/p>\n\n<p><strong>In the other direction<\/strong>: Sendit calls your store's webhook URL to report delivery progress. That URL carries a token, and requests without a valid token are rejected.<\/p>\n\n<p>By using this plugin you accept the terms of the Sendit service:<\/p>\n\n<ul>\n<li>Terms of use: https:\/\/plugins.sendit.ma\/terms<\/li>\n<li>Privacy policy: https:\/\/plugins.sendit.ma\/privacy<\/li>\n<\/ul>\n\n<p>The plugin is free and no feature is restricted. Physical deliveries carried out by Sendit.ma are billed separately, at Sendit.ma's published rates.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>In the WordPress admin, go to <strong>Plugins \u2192 Add New \u2192 Upload Plugin<\/strong> and upload the ZIP file.<\/li>\n<li>Activate the plugin. WooCommerce must be installed and active.<\/li>\n<li>Go to <strong>WooCommerce \u2192 Sendit.ma<\/strong>.<\/li>\n<li>Enter your <strong>Public Key<\/strong> and <strong>Secret Key<\/strong> (available in your Sendit.ma account).<\/li>\n<li>Save. The city list is fetched automatically as soon as valid keys are stored, and refreshed once a week from then on.<\/li>\n<li>Choose your pickup city and the activation mode that suits you, then save again.<\/li>\n<li>Copy the <strong>Webhook URL<\/strong> shown on the page and paste it into the Webhook section of your Sendit.ma account, so delivery statuses are reported automatically.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"the%20sendit%20shipping%20method%20does%20not%20appear%20at%20checkout\"><h3>The Sendit shipping method does not appear at checkout<\/h3><\/dt>\n<dd><p>Check three things: the city list has been synced, the activation mode in the Sendit settings matches what you need (\"Per Product\" requires ticking the box on each product), and a WooCommerce shipping zone covering Morocco contains the \"Sendit.ma Shipping\" method.<\/p><\/dd>\n<dt id=\"the%20list%20of%20cities%20is%20empty\"><h3>The list of cities is empty<\/h3><\/dt>\n<dd><p>Save the settings page with valid API keys: the list is fetched automatically. If it fails, the notice at the top of the page states the reason (invalid keys, network blocking, and so on). <strong>Force a city sync<\/strong> in <strong>WooCommerce \u2192 Sendit.ma<\/strong> retries immediately.<\/p><\/dd>\n<dt id=\"do%20i%20have%20to%20sync%20the%20cities%20by%20hand%3F\"><h3>Do I have to sync the cities by hand?<\/h3><\/dt>\n<dd><p>No. The list is fetched automatically when you save valid API keys, and refreshed once a week so rate changes made at Sendit reach your store on their own. The button is only there to force an immediate refresh.<\/p><\/dd>\n<dt id=\"delivery%20statuses%20are%20not%20updating\"><h3>Delivery statuses are not updating<\/h3><\/dt>\n<dd><p>The webhook URL must be saved in your Sendit.ma account exactly as shown, <strong>including its token<\/strong> (the <code>token=<\/code> parameter at the end). Without that token, requests are rejected for security reasons.<\/p><\/dd>\n<dt id=\"can%20i%20change%20the%20delivery%20district%20after%20the%20order%20is%20placed%3F\"><h3>Can I change the delivery district after the order is placed?<\/h3><\/dt>\n<dd><p>Yes, from the <strong>Sendit.ma Delivery Options<\/strong> panel on the order screen, as long as the parcel has not been created yet.<\/p><\/dd>\n<dt id=\"is%20the%20plugin%20free%3F\"><h3>Is the plugin free?<\/h3><\/dt>\n<dd><p>Yes. The plugin is free and no feature is gated. You need an active Sendit.ma account, and Sendit bills the physical deliveries separately at its published rates.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>2.2.4<\/h4>\n\n<ul>\n<li><strong>Settings sanitisation hardened against non-scalar input.<\/strong> Every <code>register_setting()<\/code> callback now rejects arrays and objects before passing anything to a string function. This matters on WordPress 5.8 and 5.9, which the plugin supports: <code>sanitize_key()<\/code> only gained its own <code>is_scalar()<\/code> guard in WordPress 6.0, so on those versions a crafted nested array in the auto-send status field reached <code>strtolower()<\/code> and caused a fatal error when saving the settings. The pickup-district option no longer uses <code>intval()<\/code> directly, which silently turned an array into district 1.<\/li>\n<\/ul>\n\n<h4>2.2.3<\/h4>\n\n<p>Addresses the points raised in the WordPress.org plugin review.<\/p>\n\n<ul>\n<li><strong>Select2 updated from 4.0.13 (2020) to 4.1.0.<\/strong> The bundled copy was five years old. The library version is now a constant used for cache-busting, so an upgraded store actually receives the new file instead of serving the old one from browser cache. Verified on the block checkout: the city list, its search, selection and the resulting rate all behave as before.<\/li>\n<li><strong>Permission check added to bulk label printing.<\/strong> WordPress validates the bulk-action nonce, but not authorisation. The other two bulk actions already checked <code>edit_shop_orders<\/code>; printing labels did not, so a user without rights over orders could have triggered label generation and obtained the parcel PDF address.<\/li>\n<li><strong>The city-sync notice is now confined to the Sendit settings page.<\/strong> It could previously appear on any admin screen.<\/li>\n<\/ul>\n\n<h4>2.2.2<\/h4>\n\n<ul>\n<li>Plugin URI and Author URI now point to different pages, as the directory requires: the plugin page at plugins.sendit.ma\/woocommerce, and the company site at www.sendit.ma.<\/li>\n<\/ul>\n\n<h4>2.2.1<\/h4>\n\n<p>Release preparation for the WordPress.org directory, plus automatic city syncing.<\/p>\n\n<ul>\n<li><strong>Cities now sync on their own.<\/strong> Saving valid API keys fetches the city and rate list immediately \u2014 the separate \"sync\" step is no longer something to remember. A sync only re-runs when the keys change or the list is empty, so saving the page repeatedly costs nothing. If it fails, the page says why, and the next save retries.<\/li>\n<li><strong>Weekly refresh now reaches existing stores.<\/strong> The weekly city refresh was only scheduled when the plugin was activated, so stores that updated in place never got it and could keep charging outdated rates. It is now scheduled on load as well.<\/li>\n<li>The manual button remains as \"Force a city sync\", for an immediate refresh.<\/li>\n<li>Plugin renamed to \"Sendit.ma for WooCommerce\" to follow the WooCommerce trademark naming rules.<\/li>\n<li>Readme rewritten in English, as the directory requires, and the external service Sendit.ma now fully documented.<\/li>\n<li>API keys and the shipping strategy option now go through explicit sanitisation callbacks.<\/li>\n<li>Label download now verifies that the PDF address returned by the API belongs to Sendit before redirecting to it.<\/li>\n<li>Translation identifier aligned with the plugin folder (<code>sendit-ma-integration<\/code>), which WordPress.org requires before it will distribute translations.<\/li>\n<li>Added the translation template <code>languages\/sendit-ma-integration.pot<\/code> (146 strings), previously missing: no translation could have been produced without it.<\/li>\n<\/ul>\n\n<h4>2.2.0<\/h4>\n\n<p>Version validated on a real store (WordPress 7.1, WooCommerce 11.1), on both the classic and block checkouts, with and without High-Performance Order Storage.<\/p>\n\n<p>Important fixes:<\/p>\n\n<ul>\n<li><strong>City search restored on the block checkout.<\/strong> The field listed 500+ cities as a raw list with no search: the library it needs was being removed from the page by WooCommerce right after it loaded. It is now bundled with the plugin. The field also keeps working after each address recalculation, which was not the case before.<\/li>\n<li><strong>Phone number now required at checkout.<\/strong> Sendit rejects any parcel without a phone number (HTTP 422). The block checkout left the field optional, so an order could be saved without a number and then fail to send indefinitely. This can be turned off.<\/li>\n<li><strong>No more accidental free shipping.<\/strong> A district missing from the rate list (removed at Sendit, stale customer address, unsynced list) offered \"Shipping: 0 MAD\". No rate is offered in that case now.<\/li>\n<li><strong>Consistent default parcel options.<\/strong> The settings showed \"try on: No\" while \"Yes\" was being sent to Sendit on a fresh install.<\/li>\n<li><strong>Native city, postcode and state fields hidden<\/strong> on the block checkout. The state field stayed visible next to the Sendit field, inviting customers to fill in the wrong one.<\/li>\n<li><strong>No resources loaded from an external CDN<\/strong>: the search library ships with the plugin.<\/li>\n<\/ul>\n\n<p>Performance:<\/p>\n\n<ul>\n<li>The city and rate lists (~22 KB) are no longer loaded on every page view of the site, only where they are used.<\/li>\n<li>Checkout styles and scripts are now real files, cached by the browser, instead of being re-injected into the HTML on every load (~320 lines).<\/li>\n<\/ul>\n\n<p>Other:<\/p>\n\n<ul>\n<li>Automatic weekly refresh of cities and rates.<\/li>\n<li>Deactivating the plugin no longer deletes the city list; deleting the plugin does erase all data, API keys included.<\/li>\n<li>The API test endpoint now checks user capabilities.<\/li>\n<li>Fixed an untranslatable label and translations inserted into JavaScript (a single apostrophe was enough to break the checkout script).<\/li>\n<li>Compatibility headers updated (WordPress 7.1, WooCommerce 11.1).<\/li>\n<\/ul>\n\n<h4>2.1.1<\/h4>\n\n<ul>\n<li>HPOS and block checkout compatibility declarations: WooCommerce no longer shows the plugin as incompatible.<\/li>\n<li>Fixed: the confirmation message for a manual send was displayed in red, like an error.<\/li>\n<li>Fixed: bulk label printing returned no message when none of the selected orders had a Sendit code.<\/li>\n<li>Fixed: possible PHP notice when saving an order whose city field was absent from the checkout.<\/li>\n<li>Added the required version headers (WordPress, PHP, WooCommerce) and the plugin documentation.<\/li>\n<\/ul>\n\n<h4>2.1<\/h4>\n\n<ul>\n<li>Compatibility with the WooCommerce block checkout (8.9+), with a searchable district selector.<\/li>\n<li>Automatic sending to Sendit when the order status changes.<\/li>\n<li>\"Send to Sendit\" bulk action and a direct send button on the order screen.<\/li>\n<li>Parcel options (try on \/ opening) configurable by default, per order, and in bulk.<\/li>\n<li>Webhook secured by token, with timestamped order notes at each delivery step.<\/li>\n<li>Product and variant details forwarded to Sendit.<\/li>\n<\/ul>","raw_excerpt":"Send WooCommerce orders to your Sendit.ma account: parcels, per-district shipping rates, PDF labels and automatic delivery status updates.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ps.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/369406","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ps.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/ps.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/ps.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=369406"}],"author":[{"embeddable":true,"href":"https:\/\/ps.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/yssendit"}],"wp:attachment":[{"href":"https:\/\/ps.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=369406"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/ps.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=369406"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/ps.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=369406"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/ps.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=369406"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/ps.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=369406"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/ps.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=369406"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}