{"id":351153,"date":"2026-08-16T14:50:48","date_gmt":"2026-08-16T14:50:48","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/texttango\/"},"modified":"2026-08-16T14:50:28","modified_gmt":"2026-08-16T14:50:28","slug":"texttango","status":"publish","type":"plugin","link":"https:\/\/test.wordpress.org\/plugins\/texttango\/","author":23545203,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.20.3","stable_tag":"0.20.3","tested":"7.0.4","requires":"6.4","requires_php":"8.1","requires_plugins":null,"header_name":"TextTango","header_author":"TextTango","header_description":"Send SMS from WordPress and WooCommerce with TextTango \u2014 passwordless OTP login, transactional order notifications, and delivery receipts.","assets_banners_color":"bfaccd","last_updated":"2026-08-16 14:50:28","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/texttango.com","rating":0,"author_block_rating":0,"active_installs":0,"downloads":40,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.20.3":{"tag":"0.20.3","author":"sefakor20","date":"2026-08-16 14:50:28"}},"upgrade_notice":{"0.20.3":"<p>If &quot;Role for new accounts&quot; (Settings \u2192 Sign in) was set to anything other than Subscriber or Customer, it now\nfalls back to Subscriber \u2014 pick a low-privilege role again from the dropdown if you want something specific.<\/p>","0.20.2":"<p>Nothing to do. Header metadata only \u2014 no behavior changes.<\/p>","0.20.1":"<p>Nothing to do. Documentation and packaging only \u2014 no behavior changes.<\/p>","0.15.0":"<p>Adds one index to the message log on first load after upgrading, which may take a moment on a large log. It also\nmakes the existing spend-cap check cheaper on every send.<\/p>","0.14.0":"<p>Nothing to do. Form triggers are off until you set one up under TextTango \u2192 Forms.<\/p>","0.13.0":"<p>Moves campaign history into its own table on first load after upgrading; existing history is carried over. Your\nspend caps count exactly as before.<\/p>","0.12.0":"<p>Nothing to do. Campaigns splits into two tabs; any campaign already scheduled or in flight is unaffected.<\/p>","0.11.0":"<p>Adds an index to the message log on first load after upgrading, which may take a moment on a large log. The\nlog can then be filtered and searched by number.<\/p>","0.10.0":"<p>Nothing to do. This one is about the first few minutes after installing: the plugin now says what it needs when\nyou activate it, and points its menu at the screen that helps.<\/p>","0.9.0":"<p>Campaigns can be narrowed to buyers of a particular product, and the password reset link can be texted as well\nas emailed. Both are off until you switch them on.<\/p>","0.8.0":"<p>Campaigns can be narrowed to part of your consenting audience. Fixes an uninstall that left data behind,\nincluding marketing consent recorded against orders \u2014 if you have uninstalled a previous version, some of that\nmay still be in your database.<\/p>","0.7.0":"<p>Adds a database table for consent recorded against a number rather than an account, created automatically on\nupgrade. Campaigns can now be scheduled for later and cancelled before they send.<\/p>","0.6.0":"<p>A campaign&#039;s audience is now an explicit choice \u2014 your consenting customers, numbers you supply, or both. A\ncampaign meant for a list you hold elsewhere no longer also goes to your customers. Three new notification\nevents, all off until you switch them on.<\/p>","0.5.0":"<p>Adds marketing campaigns, basket reminders and coupon blasts. All are off until you use them, and every one of\nthem requires marketing consent. Campaigns now count towards your spend caps, so a cap you set for order\nupdates also bounds a campaign.<\/p>","0.4.0":"<p>texttango_should_send now runs for every message rather than WooCommerce notifications alone, and its third\nargument is the send arguments rather than the order. If you filter it, branch on the event \u2014 it now also gates\nsign-in codes.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3649842,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3649842,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.jpg":{"filename":"banner-1544x500.jpg","revision":3649842,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.jpg":{"filename":"banner-772x250.jpg","revision":3649842,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.20.3"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"The Setup screen: every stage with its state and its controls in place.","2":"Notifications, with a live segment count as you write.","3":"The message log, with delivery status and the reason anything was skipped."}},"plugin_section":[262246],"plugin_tags":[4906,9210,711,9217,286],"plugin_category":[41,45],"plugin_contributors":[275991],"plugin_business_model":[],"class_list":["post-351153","plugin","type-plugin","status-publish","hentry","plugin_section-dashboard-widgets","plugin_tags-notifications","plugin_tags-otp","plugin_tags-sms","plugin_tags-two-factor","plugin_tags-woocommerce","plugin_category-communication","plugin_category-ecommerce","plugin_contributors-sefakor20","plugin_committers-sefakor20"],"banners":{"banner":"https:\/\/ps.w.org\/texttango\/assets\/banner-772x250.jpg?rev=3649842","banner_2x":"https:\/\/ps.w.org\/texttango\/assets\/banner-1544x500.jpg?rev=3649842","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/texttango\/assets\/icon-128x128.png?rev=3649842","icon_2x":"https:\/\/ps.w.org\/texttango\/assets\/icon-256x256.png?rev=3649842","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>TextTango connects your WordPress or WooCommerce site to your TextTango account and sends SMS for the moments\nthat matter.<\/p>\n\n<p><strong>Sign in by phone<\/strong><\/p>\n\n<ul>\n<li>Passwordless login with a one-time code, as a shortcode or on the WordPress login screen.<\/li>\n<li>Optional two-factor authentication, per role.<\/li>\n<li>Optionally require a customer to verify the phone number they check out with, on both classic and block\ncheckout, before an order can be placed. Off by default.<\/li>\n<li>Codes are hashed, single-use, rate limited per number and per address, and never written to the log in full.<\/li>\n<\/ul>\n\n<p><strong>WooCommerce order notifications<\/strong><\/p>\n\n<ul>\n<li>Seven events \u2014 payment received, completed, on hold, cancelled, refunded, payment failed, and a staff alert\non a new order \u2014 each switched on separately with its own wording.<\/li>\n<li>A live character and segment count while you write, so you can see before sending whether a message costs one\nSMS or two.<\/li>\n<li>Works with High-Performance Order Storage and block checkout.<\/li>\n<\/ul>\n\n<p><strong>Consent, kept properly<\/strong><\/p>\n\n<ul>\n<li>An unticked consent box at checkout and in the customer's account, recorded with a timestamp and a source.<\/li>\n<li>Optional double opt-in: agreeing sends one message to the number, and only an answer from that handset turns\nit into permission.<\/li>\n<li>Order updates are treated as service messages and keep sending; marketing needs consent.<\/li>\n<li>A number the platform refuses is added to an opt-out list, and nothing is sent to it again.<\/li>\n<\/ul>\n\n<p><strong>Marketing that respects the opt-out list<\/strong><\/p>\n\n<ul>\n<li>Send one message to everyone who agreed, with a review step showing recipients, cost and who was excluded \u2014\nand why \u2014 before anything is spent.<\/li>\n<li>The audience is built from your own consent records, so somebody who opted out an hour ago is left out.<\/li>\n<li>Basket reminders for signed-in customers who left without buying, cancelled the moment they order.<\/li>\n<li>Coupon campaigns that check the code is live and warn you if there is not enough of it to go round.<\/li>\n<li>Choose a campaign's audience: your consenting customers, numbers you supply, or both. Supplied numbers are\nstill filtered through your opt-out list, and using them is recorded against your name.<\/li>\n<\/ul>\n\n<p><strong>Delivery receipts you can prove<\/strong><\/p>\n\n<ul>\n<li>A signed webhook endpoint, registered with TextTango from the settings screen.<\/li>\n<li>A test event you can fire and watch arrive, so the loop is proven rather than assumed.<\/li>\n<li>A self-healing poller for receipts that never turn up.<\/li>\n<\/ul>\n\n<p><strong>Spending you can bound<\/strong><\/p>\n\n<ul>\n<li>Daily, monthly and per-number caps, with a per-number cap that catches a loop aimed at one customer.<\/li>\n<li>Marketing pauses first when the balance runs low. Sign-in codes are never held back by any limit.<\/li>\n<li>A circuit breaker that stops waiting on an API that is not answering.<\/li>\n<\/ul>\n\n<p><strong>Built to be built on<\/strong><\/p>\n\n<ul>\n<li>A public PHP API: <code>texttango_send_sms()<\/code>, <code>texttango_is_connected()<\/code>, <code>texttango_get_balance()<\/code>,\n  texttango_normalize_phone().<\/li>\n<li>Documented actions and filters, and six WP-CLI commands.<\/li>\n<li>An audit trail of who changed what \u2014 never of what a credential was.<\/li>\n<\/ul>\n\n<p><strong>Safe by default<\/strong><\/p>\n\n<ul>\n<li>Sandbox mode turns itself on outside production, so a staging clone never texts a real customer.<\/li>\n<li>Every notification is off until you switch it on, so connecting the plugin texts nobody by itself.<\/li>\n<li>Credentials are encrypted at rest and never reach JavaScript or any REST route.<\/li>\n<\/ul>\n\n<p>The plugin is a thin client of the TextTango v2 API. You need a TextTango account and an API token, created in\nthe TextTango dashboard under Profile \u2192 API Tokens.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin is a thin client of the TextTango SMS API (https:\/\/app.texttango.com\/docs\/api\/v2), operated by\nTextTango (rCodez). Every SMS the plugin sends \u2014 a sign-in code, a checkout verification code, a WooCommerce\norder notification, a form-submission alert, or a marketing campaign message \u2014 is delivered through this API, so\nit is required for the plugin's core functionality.<\/p>\n\n<p>What is sent, and when: the recipient's phone number and the text of the message, sent at the moment each of\nthose events fires (for example, the instant a customer requests a sign-in code, or the instant an order changes\nstatus and a notification is due). No other personal data is sent. TextTango sends delivery status back to the\nsite over a webhook the site owner registers from the Setup screen, so the plugin can show whether a message\nwas delivered.<\/p>\n\n<p>This service is provided by TextTango: Terms of Service (https:\/\/texttango.com\/terms), Privacy Policy\n(https:\/\/texttango.com\/privacy).<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin to <code>\/wp-content\/plugins\/texttango<\/code> and activate it.<\/li>\n<li>Go to <strong>TextTango \u2192 Setup<\/strong> and work down the stages: paste your API token, choose a sender ID, register the\nsite for delivery receipts, send yourself a test message, and switch on the notifications you want.<\/li>\n<li>Each stage tells you what it needs and shows its own state, so you can stop and come back.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"do%20i%20need%20woocommerce%3F\"><h3>Do I need WooCommerce?<\/h3><\/dt>\n<dd><p>No. Sign-in by phone, the public API and WP-CLI all work on any WordPress site. WooCommerce is needed only for\norder notifications.<\/p><\/dd>\n<dt id=\"can%20i%20create%20an%20api%20token%20from%20wordpress%3F\"><h3>Can I create an API token from WordPress?<\/h3><\/dt>\n<dd><p>No. Tokens are created in the TextTango dashboard and shown once. The Setup screen links you to the right page\nand lists the abilities the token needs.<\/p><\/dd>\n<dt id=\"will%20a%20staging%20site%20text%20my%20customers%3F\"><h3>Will a staging site text my customers?<\/h3><\/dt>\n<dd><p>No. Sandbox mode turns on automatically when the site environment is not <code>production<\/code>, and logs messages\ninstead of sending them. It is also the one setting that never travels in a settings export, so importing a\nproduction configuration into a staging clone cannot switch it off.<\/p><\/dd>\n<dt id=\"why%20can%20i%20not%20register%20the%20delivery-receipt%20url%20on%20my%20local%20site%3F\"><h3>Why can I not register the delivery-receipt URL on my local site?<\/h3><\/dt>\n<dd><p>TextTango only accepts a callback on a public HTTPS address, because it has to be able to reach it. Everything\nelse works locally; the Setup screen says so rather than letting the attempt fail.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20a%20message%20cannot%20be%20delivered%3F\"><h3>What happens if a message cannot be delivered?<\/h3><\/dt>\n<dd><p>It is recorded in the log with the reason. You can optionally have the plugin email the customer instead \u2014 but\nnever for a message somebody opted out of, never for a sign-in code, and never after a timeout, since the text\nmay have arrived after all.<\/p><\/dd>\n<dt id=\"does%20a%20spend%20cap%20stop%20sign-in%20codes%3F\"><h3>Does a spend cap stop sign-in codes?<\/h3><\/dt>\n<dd><p>No. Limits shed from the bottom up: marketing first, then order updates. A code that does not arrive locks\nsomebody out of their own account, so codes pass through every ceiling.<\/p><\/dd>\n<dt id=\"can%20i%20move%20a%20configuration%20between%20sites%3F\"><h3>Can I move a configuration between sites?<\/h3><\/dt>\n<dd><p>Yes \u2014 <strong>TextTango \u2192 Advanced<\/strong> exports the settings as JSON and imports them. Credentials are not included, and\nneither is sandbox mode.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.20.3<\/h4>\n\n<ul>\n<li>Updated the bundled Action Scheduler library from 3.9.3 to 4.1.0.<\/li>\n<li>The \"Role for new accounts\" setting for phone-based self-registration now only accepts roles with no\ncapabilities beyond WordPress's own <code>read<\/code> \u2014 the same ceiling a subscriber already has. Roles with real\ncapabilities (Editor, Shop Manager, or any custom role like them) are no longer selectable there, and any\nsuch value already saved falls back to a safe role automatically.<\/li>\n<\/ul>\n\n<h4>0.20.2<\/h4>\n\n<ul>\n<li>Removed the Plugin URI header \u2014 it had come to match the Author URI exactly, which wordpress.org's own\nsubmission form rejects as ambiguous. Author URI already says everything it did.<\/li>\n<\/ul>\n\n<h4>0.20.1<\/h4>\n\n<ul>\n<li>Documented the plugin's use of the TextTango API as an external service, with links to its Terms of Service\nand Privacy Policy.<\/li>\n<li>Fixed a broken Plugin URI.<\/li>\n<li><code>composer.json<\/code> now ships with the plugin, so its dependencies are inspectable.<\/li>\n<\/ul>\n\n<h4>0.20.0<\/h4>\n\n<ul>\n<li>An OTP step can now gate order placement: a customer verifies the phone number they checked out with before\nthe order goes through, on classic and block checkout alike. Off by default \u2014 a merchant switches it on from\nSign-in settings. Enforced server-side on both checkout paths, so it holds even with JavaScript disabled.<\/li>\n<\/ul>\n\n<h4>0.19.1<\/h4>\n\n<ul>\n<li>The customer-facing stylesheet (the sign-in form) no longer ships every admin-screen style alongside it \u2014\ntables, charts, badges, the setup checklist and the rest now build into a separate admin-only bundle. The\nstylesheet a storefront visitor downloads is about a fifth of the size it was.<\/li>\n<li>Gravity Forms' field-mapping logic \u2014 reading a composite field such as Name or Address, which Gravity Forms\nsplits into several numbered inputs rather than one \u2014 now has direct test coverage.<\/li>\n<\/ul>\n\n<h4>0.19.0<\/h4>\n\n<ul>\n<li>Campaigns can now be narrowed further: how many times somebody has ordered, which product category they bought\nfrom, and which country their orders were billed to \u2014 on top of the existing recency, spend and single-product\nfilters, and combinable with all of them the same way recency and spend already combine.<\/li>\n<li>The review screen's summary of who a campaign is going to reads as one sentence whatever combination of these\nyou choose.<\/li>\n<\/ul>\n\n<h4>0.18.0<\/h4>\n\n<ul>\n<li><strong>Fixed:<\/strong> personal discount codes were missing from WordPress's privacy tools. A data-subject export left\nout the codes issued to that person, an erasure left their number behind, and no retention setting ever\nremoved those rows. If you have answered a request since 0.17.0, the codes were not included.<\/li>\n<li><strong>Fixed:<\/strong> an erasure could also miss message-log rows matched only by phone number rather than by account,\nbecause it cleared the number from the profile before looking those rows up.<\/li>\n<li>Erasing somebody now unlinks the coupons minted for them and keeps the coupons themselves \u2014 a code already\nused is attached to a real order, and removing it would change that order's record.<\/li>\n<li>Your retention setting now covers campaign recipients as well as the message log.<\/li>\n<li><strong>New:<\/strong> open a personal campaign from its history row to see who it reached, the code each person was given,\nand whether it has been used.<\/li>\n<\/ul>\n\n<h4>0.17.2<\/h4>\n\n<ul>\n<li><strong>Fixed:<\/strong> a campaign you had just sent was missing from Analytics and the dashboard widget for several\nminutes. The figures were cached and nothing cleared the cache when you sent something, so both screens\nshowed the state of a few minutes ago without saying so.<\/li>\n<li>The Analytics screen now reads live every time you open it, and the dashboard widget is refreshed the moment\nanything is sent.<\/li>\n<li>A campaign is asked how it went about half a minute after it goes out, rather than on the next five-minute\ncheck, so its cost and delivered count appear while you are still looking.<\/li>\n<\/ul>\n\n<h4>0.17.1<\/h4>\n\n<ul>\n<li><strong>Fixed:<\/strong> the Spent figure on Analytics and the dashboard widget left campaigns out. It showed what your\nper-message sending had cost while counting campaign recipients in the Sent total beside it, so the two did\nnot describe the same thing. TextTango reports what a campaign cost and the plugin was not reading it.<\/li>\n<li>Campaigns sent before this update are priced up in the background over the next few minutes, so your older\nhistory fills in on its own.<\/li>\n<li>Where a campaign has not been priced yet, the screens say the total is still partial rather than showing a\nshort figure as if it were complete.<\/li>\n<\/ul>\n\n<h4>0.17.0<\/h4>\n\n<ul>\n<li>Coupon campaigns can now give every customer their own code instead of one shared one. Each code works once,\nfor one person, and expires with the coupon you built it from \u2014 so a code posted in a group chat is no use\nto anybody but its owner.<\/li>\n<li>The review says what that changes before you send: how many separate messages it is, how many batches, and\nthat a code is created only as its message goes out.<\/li>\n<li><strong>Fixed:<\/strong> campaigns sent to your whole consenting audience were not being recorded at all. The campaign went\nout, but it never appeared in your history \u2014 and your spend caps could not see it either, so a large send was\ninvisible to the ceiling meant to catch it.<\/li>\n<li><strong>Fixed:<\/strong> a fatal error on the Consent screen once anything appeared in the \"Agreed, with no account\" list.\nIts pager and the opt-out list's had been wired to each other's tables.<\/li>\n<\/ul>\n\n<h4>0.16.0<\/h4>\n\n<ul>\n<li>A new Audience screen under TextTango: everyone who has agreed to marketing, in one list \u2014 customers with an\naccount, guests who agreed at checkout, and numbers imported from a list.<\/li>\n<li>See why somebody is not getting your campaigns. Somebody who agreed but left no usable number now shows up\nwith a reason, instead of being silently absent.<\/li>\n<li>Search by number or by name. Type a number the way you read it off an order \u2014 <code>024 123 4567<\/code> finds it.<\/li>\n<li>Stop messaging one person, or allow them again, without waiting for them to opt out. Stopping a number stops\norder updates as well as marketing.<\/li>\n<li>Preparing a campaign is much faster on a large store. It used to ask the opt-out list about each recipient\none at a time \u2014 thousands of separate queries on a store with thousands of customers.<\/li>\n<\/ul>\n\n<h4>0.15.0<\/h4>\n\n<ul>\n<li>A new Analytics screen under TextTango: sends over time on a proper chart, a delivery-status ring, what it\ncost, which events are busiest, and a table of every event with how many were delivered, how many failed and\nwhat each one spent.<\/li>\n<li>Campaigns are counted too. They are sent in bulk and have no individual rows in the message log, so they\nused to be missing from every figure \u2014 the totals now cover them, with their credits shown beside what\nper-message sending cost.<\/li>\n<li>A TextTango widget on your WordPress dashboard with the same figures at a glance.<\/li>\n<li>Switch either between the last 7, 30 or 90 days.<\/li>\n<li>Charts are drawn on the server, so the plugin loads no charting library and they work with JavaScript off.<\/li>\n<\/ul>\n\n<h4>0.14.0<\/h4>\n\n<ul>\n<li>Send a text when somebody fills in a form \u2014 Contact Form 7, WPForms, Gravity Forms and Fluent Forms. Tell\nyourself an enquiry arrived, text the person back, or capture marketing consent from a checkbox on the form.<\/li>\n<li>Each form is set up separately, because only you know which of its fields holds a phone number.<\/li>\n<\/ul>\n\n<h4>0.13.0<\/h4>\n\n<ul>\n<li>Campaign history is no longer thrown away. It used to keep only the last fifty and delete the rest \u2014 what you\nsent, to how many people and what it cost is now kept and paged through.<\/li>\n<li>The opt-out list, consent list and audit trail can be paged through too. They showed the newest few with no\nway to reach the rest.<\/li>\n<li>Pagination now offers page numbers rather than only Newer and Older.<\/li>\n<li>The log's filter boxes are wide enough to read.<\/li>\n<\/ul>\n\n<h4>0.12.1<\/h4>\n\n<ul>\n<li>The new-campaign form is reorganised into Campaign, Audience, Message and Schedule \u2014 name it, choose who it\ngoes to, write it, then say when \u2014 and it is no longer as wide as the screen.<\/li>\n<\/ul>\n\n<h4>0.12.0<\/h4>\n\n<ul>\n<li>Campaigns is now two tabs \u2014 writing a new one, and the history of what has already gone. Sending takes you\nstraight to the history so you can watch it go.<\/li>\n<li>Every TextTango screen now opens with the logo, so Settings, Campaigns and Setup look like one product.<\/li>\n<\/ul>\n\n<h4>0.11.1<\/h4>\n\n<ul>\n<li>Each settings tab now carries an icon.<\/li>\n<\/ul>\n\n<h4>0.11.0<\/h4>\n\n<ul>\n<li>The message log can be searched. Filter by status or event, or type a customer's number \u2014 the whole number or\njust the last few digits \u2014 and page through the results. It used to show the fifty newest messages with no way\nto reach the fifty-first.<\/li>\n<li>Tables, buttons and focus outlines are consistent across every screen, and keyboard focus is now visible on\nbuttons.<\/li>\n<\/ul>\n\n<h4>0.10.0<\/h4>\n\n<ul>\n<li>Activating the plugin now tells you what it still needs, and the menu opens Setup until setup is done.<\/li>\n<li>Screens with nothing on them yet explain what would fill them, instead of only saying they are empty.<\/li>\n<\/ul>\n\n<h4>0.9.0<\/h4>\n\n<ul>\n<li>Narrow a campaign to people who bought a particular product.<\/li>\n<li>Text the password reset link as well as emailing it, to numbers customers have verified.<\/li>\n<\/ul>\n\n<h4>0.8.0<\/h4>\n\n<ul>\n<li>Narrow a campaign to customers who ordered recently, spent enough, or have never ordered at all.<\/li>\n<li>Uninstalling now removes everything the plugin wrote, including consent recorded against orders. Earlier\nversions left some of it behind.<\/li>\n<\/ul>\n\n<h4>0.7.0<\/h4>\n\n<ul>\n<li>Consent can now be recorded against a phone number with no account behind it, so an imported subscriber list\nno longer loses most of its people. Your opt-out list and any refusal on an account both still outrank it.<\/li>\n<li>Schedule a campaign for later, and stop it any time before it goes.<\/li>\n<\/ul>\n\n<h4>0.6.0<\/h4>\n\n<ul>\n<li>Three more events: order shipped when a tracking number appears, a welcome for new accounts, and a low-stock\nstaff alert. Each offers only the merge tags it can actually resolve.<\/li>\n<li>Choose who a campaign goes to: your consenting customers, numbers you supply, or both. Supplied numbers are\nfor consent you hold somewhere this plugin cannot see \u2014 they are counted separately, your opt-out list still\napplies to them, and the audit trail records who vouched for them.<\/li>\n<li>Send a failed message again from the log.<\/li>\n<li>An optional email when sending stops working \u2014 a refused token, no credit, or TextTango unreachable. Never\nfor a single failed message.<\/li>\n<li>Import your existing opt-in list from WP SMS.<\/li>\n<li>Fixed a database error logged on every upgrade check.<\/li>\n<li>Fixed the account balance showing two different figures: the settings screen read a value written only when\nyou pressed Test connection, while everywhere else showed the hourly reading.<\/li>\n<li>The TextTango logo now appears on the settings screen and in the admin menu.<\/li>\n<\/ul>\n\n<h4>0.5.0<\/h4>\n\n<ul>\n<li>Campaigns: one message to everyone who agreed, with a review step before anything is spent.<\/li>\n<li>The audience is gathered from your own consent records, not from a synced contact group.<\/li>\n<li>Campaigns count towards your spend caps, and one that will not fit under a cap is refused rather than trimmed.<\/li>\n<li>Quiet hours schedule a campaign with TextTango instead of holding it on your site.<\/li>\n<li>Abandoned basket reminders for signed-in customers, with an optional follow-up.<\/li>\n<li>Coupon campaigns with <code>{coupon_code}<\/code> and friends, refusing a code that cannot be redeemed and warning when\nthere is not enough of it for everyone it is going to.<\/li>\n<li>Fixed a database error logged on every upgrade check.<\/li>\n<\/ul>\n\n<h4>0.4.0<\/h4>\n\n<ul>\n<li>Public PHP API, documented action and filter surface, and WP-CLI commands.<\/li>\n<li>Spend caps with tiered pausing, hourly balance watching, and a circuit breaker.<\/li>\n<li>An audit trail of settings, credential, consent and opt-out changes.<\/li>\n<li>Optional email fallback for a message the phone could not receive.<\/li>\n<li>Delivery receipts: self-registration, a provable test event, and in-app secret rotation.<\/li>\n<li>Native Site Health checks and a support-safe debug panel.<\/li>\n<li>Settings import and export.<\/li>\n<li>A Setup screen that does each stage's work in place.<\/li>\n<\/ul>\n\n<h4>0.3.0<\/h4>\n\n<ul>\n<li>Marketing consent at checkout and in the account, with a recorded trail.<\/li>\n<li>Optional double opt-in, confirmed from the handset.<\/li>\n<li>Opt-out list, honoured for every message including order updates.<\/li>\n<li>Consent-gated contact sync with a nightly reconciliation sweep.<\/li>\n<li>WordPress personal-data export and erasure.<\/li>\n<li>Quiet hours that hold messages rather than dropping them, and log retention.<\/li>\n<\/ul>\n\n<h4>0.2.0<\/h4>\n\n<ul>\n<li>Delivery-receipt webhooks with signature verification and a self-healing poller.<\/li>\n<li>Message log with per-event delivery status.<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>Connection settings with an encrypted token, sandbox mode and a test send.<\/li>\n<li>Passwordless sign-in by phone, with optional two-factor.<\/li>\n<li>WooCommerce order notifications with editable templates.<\/li>\n<\/ul>","raw_excerpt":"Send SMS from WordPress and WooCommerce with TextTango \u2014 passwordless login, order notifications, delivery receipts and consent handling.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/351153","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=351153"}],"author":[{"embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/sefakor20"}],"wp:attachment":[{"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=351153"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=351153"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=351153"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=351153"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=351153"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=351153"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}