Shopify Netgsm SMS integration connects order, shipping and cancellation events in a Shopify store to Netgsm's SMS API and sends customers automatic messages under the brand's approved SMS sender name. It is part of the e-commerce communication stack and has two layers: on the Shopify side, a webhook or Flow trigger that captures the event; on the Netgsm side, the API that hands the message to the mobile operator. In the integrations we have built, most failures did not come from the API call itself but from the space between the two layers. Phone numbers arrive in the wrong format, the same order triggers two SMS, or a campaign message goes out without passing the İYS filter. There is also a current development: as of November 13, 2026, Netgsm's own Shopify app is not listed on the App Store. That makes choosing the setup path the first decision of the project.
What is Shopify Netgsm SMS integration and which messages does it automate?
Shopify Netgsm SMS integration is an automation that turns an event in Shopify (order created, shipped, cancelled) into an SMS request to the Netgsm API. Informational messages such as order confirmations and tracking numbers, and commercial messages such as cart reminders and campaigns, leave through the same infrastructure. The two are subject to different legal rules, however, and you need to design the integration around that split.
Netgsm is a Turkish communications company providing bulk SMS, OTP SMS and voice messaging services. According to Netgsm's official JavaScript SDK documentation, the current API has two parts: /sms/v3 for sending messages and /iys/v1 for consent records. Authentication runs through /auth/v3 with a token. The legacy api.netgsm.com.tr address still works; for new projects, use ext-api.netgsm.com.tr. The sandbox environment, delivery report webhooks and detailed error codes exist only in the new API.
The difference between informational and commercial SMS
Turkey's Law No. 6563 on the Regulation of Electronic Commerce classifies messages that promote, market or encourage the sale of goods or services as "commercial electronic messages". Before sending them, you need the recipient's consent, and you must record that consent in İYS (İleti Yönetim Sistemi, Turkey's national Message Management System). A message reporting the status of an order the customer placed is informational and does not require İYS consent.
The distinction is made by the content of the message, not its type. That is why the template design of the integration carries legal risk directly.
Critical Note: The moment you append "10% off your next order: KOD10" to an SMS containing a tracking number, the message counts as a commercial message and requires İYS consent. Keep coupons, campaigns and product recommendations out of your informational templates.
We explained step by step how İYS records map to Shopify customer data in our Shopify İYS integration guide. The SMS integration sits on top of that structure: if the consent data is wrong, even a cleanly built SMS flow creates legal risk.
Why Shopify's built-in SMS notifications are not enough
Shopify offers SMS templates for order confirmation and shipping updates under Settings > Notifications. In the stores we manage, we found these templates insufficient for the Turkish market for three reasons:
- Shopify sends these SMS only when the customer chooses a phone number as their contact method at checkout. A customer who orders with an email address but types a phone number into the shipping address receives no SMS.
- The sender name is not your brand's operator-approved SMS sender name. The customer receives the message from an unfamiliar number, and Turkish consumers, used to fraudulent messages, are less likely to click links in such SMS.
- Turkey-specific flows such as cash on delivery confirmation, bank transfer reminders or tracking numbers coming from an ERP do not exist in the built-in templates.
These limits become visible as the store grows. A "I didn't get an SMS" complaint that goes unnoticed at 20 orders a day turns into a daily workload for customer service at 300 orders a day.
Which Shopify event triggers which SMS?
Every SMS corresponds to an event in Shopify and to that event's webhook topic. The table below shows the standard flow we build for stores selling in Turkey:
| SMS type | Shopify webhook topic / Flow trigger | Message category | İYS consent required? |
|---|---|---|---|
| Order received | orders/create | Informational | No |
| Payment confirmed (bank transfer) | orders/paid | Informational | No |
| Cash on delivery order confirmation | orders/create + payment method filter | Informational | No |
| Shipped + tracking link | fulfillments/create | Informational | No |
| Delivered | fulfillments/update (status: delivered) | Informational | No |
| Order cancellation / refund | orders/cancelled, refunds/create | Informational | No |
| Abandoned cart reminder | Flow: "Customer abandons checkout" | Commercial | Yes |
| Campaign / coupon announcement | Customer segment + bulk send | Commercial | Yes |
The most frequently overlooked row in the table is cash on delivery. The orders/create webhook fires at the same moment for a cash on delivery order and for a card-paid order. If you do not set up a separate template per payment method, the cash on delivery customer receives a "Your payment has been received" message. At Nodus Works, in stores with a high cash on delivery share, we turn this SMS into a confirmation step: when the customer replies "EVET" (yes), the order is tagged in Shopify and only then reaches the warehouse. Netgsm's inbound message webhook (registerInboxWebhook) carries that reply back to the integration.
3 ways to connect Shopify to Netgsm: ready-made app, Shopify Flow and custom integration
You connect Shopify to Netgsm in one of three ways: a ready-made Shopify app that supports Netgsm, Shopify Flow with a small service placed in between, or a custom app that listens to Shopify webhooks. For stores that are fine with standard templates and send fewer than a few thousand SMS a month, a ready-made app is enough. If you have cash on delivery confirmation, shipping data coming from an ERP, or multi-warehouse fulfillment, a custom integration is required.
The question that decides the choice is this: does every piece of data in the SMS live inside Shopify? If the order number, product name and tracking link are in Shopify, a ready-made app does the job. If the tracking number comes from Nebim, Logo or a shipping aggregator, the app's template fields cannot see that data.
Option 1: A ready-made Shopify app that supports Netgsm
When we checked on November 13, 2026, the listing page of "Netgsm SMS", the app developed by Netgsm itself, showed the warning "not currently available on the Shopify App Store". For stores that installed the app earlier, this means new installations are not possible. Ask Netgsm directly whether the app will return.
One of the apps that connects Netgsm out of the box today is Sendzi: WhatsApp & SMS, developed by Gurmehub. The app manages Netgsm, Kobikom, Verimor and WhatsApp from a single panel. The plans on the listing page are:
- Free: $0/month, usage fee of $0.05 per message
- Basic: $9/month, first 1,000 messages free, then $0.03
- Growth: $19/month, first 3,000 messages free, Shopify Flow compatibility
- PRO: $49/month, unlimited messages
The app launched on August 12, 2026 and has a single review on its listing page so far. Before installing a young app, ask the developer two questions in writing. First, is the per-message fee in the listing charged on top of the SMS credit in your Netgsm account? Second, which İYS filter value is sent with commercial messages?
Option 2: Shopify Flow and a small service in between
Shopify Flow can send a request to an external address with the "Send HTTP request" action after a trigger such as "Order created" or "Customer abandons checkout". At first glance, connecting Flow directly to Netgsm looks possible. In practice, two obstacles appear:
- Netgsm's new API expects you to first obtain a token from
/auth/v3and then send. A single Flow HTTP request cannot build this two-step flow cleanly. - The Netgsm username and password are written into the Flow action. Every staff member with permission to edit Flow in the store can see them.
The solution is to put a Cloudflare Worker or a similar small serverless function in between. Flow sends a request to the Worker with a secret header (such as X-Webhook-Secret). The Worker obtains the token, formats the number and forwards the message to Netgsm. Netgsm's official SDK is written to run on Cloudflare Workers and needs no extra dependencies. Check in the Flow editor whether the HTTP request action is available on your plan.
Risk to Avoid: Do not put your Netgsm password in theme code, the theme.liquid file or a ScriptTag. This is why Netgsm's official SDK throws an error when run in a browser: every visitor in the browser can see your password and send SMS from your account.
Option 3: A custom Shopify app that listens to webhooks
A custom app is created for your store and installed only on your store. It subscribes to webhook topics such as orders/create, fulfillments/create and orders/cancelled, processes the incoming event on its own server and sends it to Netgsm. This is the only way to bring data from outside Shopify into the SMS content.
The point that demands the most care in a custom app is duplicate protection. According to Shopify's webhook documentation, if your app does not respond within 5 seconds, Shopify sends the same event again. Netgsm's SDK documentation states it plainly: the API does not deduplicate requests; a second request opens a second send job and the customer receives the message twice.
If Netgsm receives the same request twice, it sends two separate SMS; preventing the repeat is the job of the app on the Shopify side. So record the X-Shopify-Webhook-Id header of every webhook and skip the send when the same ID arrives a second time. Write the Shopify order number into the referenceId field of the Netgsm request; that way you can see in the delivery report which SMS belongs to which order.
In SMS flows that depend on data outside Shopify, such as cash on delivery confirmation, tracking numbers from an ERP or warehouse-based sender selection, the template fields of ready-made apps fall short. Our Shopify integration and custom app development service builds these flows into a single app together with webhook verification, duplicate protection and delivery reports.
Comparing the three options
| Criterion | Ready-made app (Sendzi etc.) | Shopify Flow + intermediate service | Custom app (webhook) |
|---|---|---|---|
| Setup time | 1-2 hours | 1-2 days | 1-3 weeks |
| Monthly app cost | $0-49 + message fees | A free tier is usually enough for the intermediate service | Server and maintenance cost |
| Data from outside Shopify (ERP, shipping aggregator) | None | Limited, added in code in the intermediate service | Full |
| Cash on delivery "EVET" confirmation | Depends on the app | Inbound message webhook must be set up separately | Yes |
| Duplicate SMS protection | Depends on the developer's design | Must be built in the intermediate service | Full control with X-Shopify-Webhook-Id |
| İYS filter control | Ask the developer | You choose iysFilter per message type | You choose iysFilter per message type |
| Best-fit store profile | Under 50 orders a day, standard flow | Store using Flow with a few custom flows | Store with an ERP, high cash on delivery share, multiple warehouses |
Our position is this: if the store is new, start with a ready-made app and measure over the first three months which SMS actually reduces complaints. Decide on a custom integration only with that data. Commissioning a custom app without knowing your flows means paying development costs for five templates nobody will use.
Before setup: Netgsm account, SMS sender name and API user
To send SMS through the Netgsm API, three things must be ready in your account: an approved sender name (SMS header), an assigned SMS package and a sub-user with API permission. According to the Netgsm knowledge base article "Sending SMS via API" and the Netgsm API documentation, the integration uses your subscriber number as the username, the API sub-user's password as the password, and the approved header as the sender.
The longest of these three preparations is header approval, because Netgsm forwards the application to a partner operator and the operator requests documents. Webhooks and templates are ready in a few days; none of them can go live before the header is approved. So start the header application on the same day as integration development.
How do you get an SMS sender name approved?
The SMS sender name is the name shown on the customer's phone instead of a number, for example NODUSSTORE. You apply from the Netgsm panel and are asked to document the link between the header and your trade name or brand. The required document list and approval time vary by operator; get the current list from the application screen or your Netgsm account representative.
Think about commercial messages when you get the header. According to the source code of Netgsm's official test server, in a send that uses the İYS filter, the API rejects the request with a REJECTED_IYS error if no İYS brand code is attached to the header. After the header is approved, ask Netgsm separately to link your İYS brand code to it.
API sub-user and IP restriction
Never write your main account password into any integration. The flow Netgsm recommends is:
- In the Netgsm panel, open Abonelik İşlemleri > Alt Kullanıcı Hesapları > Yeni Kayıt (Subscription > Sub-user Accounts > New Record).
- Select API Kullanıcısı (API User) as the user type and tick only the SMS service on the authorization screen.
- Enter the code sent to your registered mobile number and activate access by ticking the "API ile hesap erişimini onaylıyorum" (I approve account access via API) box.
Because the sub-user has a separate password, when you finish working with an agency you close only that user; your main account is unaffected.
IP restriction requires a separate decision. You can restrict the Netgsm API so it can only be used from certain IP addresses, which prevents a stolen password from being used on another server. However, Cloudflare Workers and similar serverless environments do not provide a fixed outbound IP. If IP restriction is enabled for an integration that sends from a serverless service, Netgsm rejects every request with error code 30, which means "invalid username, password or no API access permission". If you want IP restriction, send from a server with a fixed IP.
Free testing in the sandbox environment
According to Netgsm's official SDK documentation, the new API has three environments:
- Local mock (
127.0.0.1:4010): Requires no subscription and sends no SMS. Netgsm's open source test server is used to try error scenarios. - Sandbox (
ext-sandbox.netgsm.com.tr): Runs with the real network and token flow, uses demo accounts, sends no SMS and is free of charge. - Live (
ext-api.netgsm.com.tr): Real, paid sends.
The table below shows how the API responds when each preparation is missing. Use it as a checklist before going live:
| Preparation | Where is it done? | Response if missing |
|---|---|---|
| Approved SMS sender name | Netgsm panel, sender name request | Legacy API: 40 / New API: REJECTED_HEADER |
| SMS package or credit | Netgsm panel, package purchase | New API: INSUFFICIENT_CREDIT |
| API sub-user and access permission | Subscription > Sub-user Accounts | Legacy API: 30 / New API: HTTP 401 |
| İYS brand code linked to the header | Netgsm account representative + İYS account | New API: REJECTED_IYS (commercial sends only) |
| Correct number format | Integration code | New API: NO_DELIVERABLE_MESSAGES (HTTP 422) |
Risk to Avoid: İYS has neither a sandbox nor a mock. Netgsm's SDK documentation states clearly that every consent saved to İYS is a live legal record that cannot be edited afterwards. Do not test the İYS flow with test numbers or made-up records.
Step-by-step Shopify Netgsm SMS integration setup (HowTo)
You set up Shopify Netgsm SMS integration with webhooks in five steps: subscribe to order and shipping webhooks in Shopify, verify the signature of incoming requests, fill the template with order data, send to Netgsm and store the reference number, and connect the delivery report webhook. The steps below describe the custom app path; if you use Flow with an intermediate service, the same rules apply from step 3 onward.
1. Enable webhook subscriptions in Shopify
Give your custom app only the permissions it needs: read_orders for orders, read_customers for the customer's phone. The phone number falls under Shopify's protected customer data. If you do not request access to name, phone and address fields in the app configuration, those fields arrive empty in the webhook payload.
Then subscribe to these topics in the first phase: orders/create, fulfillments/create, fulfillments/update and orders/cancelled. Do not enable the abandoned cart flow until the İYS connection is complete.
2. Verify the webhook signature
Shopify sends every webhook with an HMAC signature in the X-Shopify-Hmac-Sha256 header, generated with the app's secret key. Compute the signature over the raw request body; if you parse the body into JSON and serialize it back, the signature will not match. Reject requests with an invalid signature with 401. If verification is skipped, anyone who knows your address can send SMS to your customers under your sender name.
According to Shopify's documentation, if your app does not respond within 5 seconds, the delivery counts as failed. So verify the signature, write the event to a queue and return 200 immediately. Send to Netgsm in a separate process that reads from the queue.
3. Fill the message template with order data
Sample shipping SMS template (in Turkish, as sent to customers in Turkey):
Merhaba Ayşe, #1042 numaralı siparişiniz Aras Kargo ile yola çıktı. Takip: https://kargotakip.araskargo.com.tr/?code=1234567890 Nodus StoreThis text is 139 characters long. In the Turkish character encoding (TURKISH), the letters "ş", "ı" and "ç" count as two characters each, so the weighted length becomes 145 and it fits into a single SMS. You take the template variables from Shopify as follows: customer name from shipping_address.first_name, order number from name, carrier and tracking link from the tracking_company and tracking_urls fields of the fulfillment object.
Test the template with the longest real value. In an order where "Muhammed Mustafa" replaces "Ayşe", the same text exceeds 155 characters and is split into two SMS. Netgsm's sms.measureLength operation returns how many parts the text will be split into before you send it.
4. Send to the Netgsm API and store the reference number
Send the queued job to Netgsm's POST /sms/v3/send endpoint. Always fill four fields in the request body:
sender: your approved SMS sender nameencoding:TURKISHfor Turkish textiysFilter:NONEfor informational SMS, the İYS filter for commercial SMS (explained in the next section)referenceId: the Shopify order number; it comes back in the delivery report and webhook
Store the jobId value from the response together with the order record. When a customer says "I didn't get an SMS", the support team finds out with this ID in two minutes whether the message reached the operator via the Netgsm report. Writing it to an order note or a metafield is enough.
5. Connect the delivery report webhook
Netgsm sends delivery reports to the address you define with registerReportWebhook. During registration, define a secret header such as X-Webhook-Secret and check it on every incoming request.
According to Netgsm's SDK documentation, if your address returns any 2xx response, the report counts as delivered; Netgsm does not resend failed deliveries. If your report receiver is down for a short time, the reports in between are lost. So once a day, fetch the previous day's jobs with sms.getReport and fill in the missing reports. The report query has per-account and per-job limits; use the webhook as the primary source instead of querying after every send.
Phone number format, Turkish characters and SMS length
The most common send error in Shopify Netgsm SMS integration is the number format: Shopify stores the number as +905321234567, the Netgsm SMS API expects 905321234567, and the İYS API again expects +905321234567. The second most common error comes from Turkish characters: the same text can be split into 1 or 3 SMS depending on the encoding, and that is how much it shows up on the bill.
Shopify gives +90, Netgsm expects 90, İYS wants +90
Shopify stores the phone field of the customer record in international E.164 format (+905321234567). Netgsm's SMS API expects the 12-digit 90XXXXXXXXXX format. For international numbers, you put a - in front and write the country code; your account needs international sending permission for this. İYS calls, in turn, want the +90 format again.
In the integration, pass the number through a single function before every send:
function netgsmNumber(raw) {
let n = String(raw || "").replace(/\D/g, ""); // strip non-digits
if (n.startsWith("0")) n = "9" + n; // 0532... -> 90532...
if (n.length === 10 && n.startsWith("5")) n = "90" + n; // 532... -> 90532...
return /^905\d{9}$/.test(n) ? n : null; // invalid: do not send
}When the function returns null, skip the send and add an "SMS not sent: invalid number" tag to the order. Sending an invalid number to Netgsm does not consume SMS credit, but it produces a NO_DELIVERABLE_MESSAGES error and floods the logs with noise.
How many characters does a Turkish-character SMS hold?
The length calculation in Netgsm's open source test server defines the limits of the three encodings as follows:
Encoding (encoding) | Single SMS limit | Per part in concatenated SMS | Upper limit (6 parts) | When to use |
|---|---|---|---|---|
DEFAULT | 160 characters | 153 characters | 917 characters | Text written without Turkish characters |
TURKISH | 155 characters | 148 characters | 888 characters | Most Turkish texts |
UNICODE | 70 characters | 66 characters | 396 characters | Emoji or non-Latin script present |
In the TURKISH encoding, the letters "ç, ğ, ı, ş, Ğ, İ, Ş" count as two characters each; "ö" and "ü" count as one. The 139-character shipping message from the previous section is a single SMS with TURKISH. Add a single 📦 emoji to the end of the same text and the encoding switches to UNICODE, the per-part limit drops to 66 and the message is split into 3 SMS. For a store sending 5,000 shipping SMS a month, that one emoji raises the bill from 5,000 SMS to 15,000 SMS.
What happens if the number is in the shipping address, not the customer record?
For a customer who checks out as a guest in Shopify, the phone often lives only in the shipping_address.phone field. This field is saved exactly as the customer typed it: it can arrive as 0532 123 45 67, 5321234567 or +90 (532) 123-4567. In the integration, look for the number in this order: customer.phone, shipping_address.phone, billing_address.phone. Whichever you find, pass it through the function above.
If you have not made the phone field mandatory at checkout, some orders will have no number at all. Since carriers already require a phone number for delivery, stores selling to Turkey should make the phone field in the shipping address mandatory under Settings > Checkout.
İYS and e-commerce law compliance: how does the consent filter work for commercial SMS?
You can send commercial SMS only to recipients whose consent is recorded in İYS, and Netgsm performs this check at send time with the iysFilter parameter. With the filter on, Netgsm removes numbers without İYS consent from the send. That way, even if the marketing consent in Shopify is out of date, no message goes to a number without a legal record.
This check does not take the legal responsibility off your shoulders. The filter checks only the record in İYS; entering that record at the right time and with the right source is the brand's job.
The four values of the iysFilter parameter
In Netgsm's new API, iysFilter takes four values:
NONE: No İYS check. Use it only for informational messages such as orders, shipping and refunds.BRAND: The send is filtered against the consents under the İYS brand code linked to the header. Most e-commerce stores selling their own brand use this value.RETAILER: The filter runs against the brand's retailer records.BRAND_AND_RETAILER: Checks both brand and retailer records.
In a Shopify Netgsm SMS integration, the iysFilter value must be tied to the message type, not the template. The informational queue must always run with NONE and the campaign queue always with BRAND. Sending both types from the same function and choosing via a parameter ends, one day, with a campaign message going out unfiltered.
How does Shopify marketing consent map to the İYS record?
Shopify stores the customer's SMS marketing consent in the sms_marketing_consent field. When the customer ticks the "Notify me about campaigns via SMS" box at checkout, this field becomes subscribed. When consent changes, the customers_marketing_consent/update webhook fires. This record does not reach İYS on its own, however.
In a correct setup, this webhook writes the consent to İYS through Netgsm's İYS API. The record contains the recipient type BIREYSEL (individual), consent type MESAJ (message), source website (HS_WEB) and the moment the consent was given. In the reverse direction, a rejection the customer submits through İYS must set the consent in Shopify to unsubscribed via the İYS webhook. We explained why the consent text must be kept separate from the KVKK (Turkey's personal data protection law) explicit consent text in our Shopify KVKK integration guide.
Tip: In an İYS consent query, theerrorCodevalue for a number with no record is81. If you query the numbers in the segment before a campaign and remove those that return 81, you do not prepare messages for numbers Netgsm would filter anyway, and you know the real send count in advance.
The consent flow is not a one-time setup. Consents change every day on the same data as the email newsletter, loyalty program and campaign segments. To handle consent sync between Shopify, Klaviyo and Netgsm together with segment and automation design, our email marketing and CRM automation service merges SMS and email consents into a single customer record; that way, a rejection in one channel also stops campaign sends in the other.
Delivery reports, error codes and duplicate SMS risk
An installed Shopify Netgsm SMS integration usually breaks silently: Shopify deletes a failing webhook subscription, the Netgsm balance runs out, or repeated requests send the customer duplicate SMS. If you did not put all three under monitoring from day one, you learn about the problem from a customer complaint.
Why does the Shopify webhook send the same order twice?
According to Shopify's documentation, Shopify retries a webhook that gets no response within 5 seconds eight times over four hours. If failures persist, it removes the subscription entirely. This has two consequences:
- If your app sends the SMS and then performs an operation taking longer than 5 seconds before responding, Shopify sends the same event again and the customer receives a second SMS.
- If your server is down for a few hours, the subscription is removed and no SMS goes out even after the server comes back. If nobody notices, the store runs without notifications for weeks.
The solution has two parts. Record the X-Shopify-Webhook-Id value of every webhook and skip processing when the same ID arrives a second time. In addition, run a daily check that lists webhook subscriptions through the Shopify API and recreates any missing one.
How should you interpret Netgsm error codes?
Netgsm's legacy API returns numeric codes; the new API returns text codes along with the HTTP status. The ones we encounter most often in the field, and what to do:
| Response | Meaning | What the integration should do |
|---|---|---|
Legacy API 00 | The SMS reached the Netgsm system | Write the returned job ID to the order record |
Legacy API 30 / HTTP 401 | Username, password or API permission wrong; request from outside the IP restriction | Do not retry, alert an administrator |
Legacy API 40 / REJECTED_HEADER | Header not defined in the account or not approved | Do not retry, compare the header name with the one in the Netgsm panel |
INSUFFICIENT_CREDIT | SMS credit has run out | Keep the message in the queue, send once credit is topped up |
NO_DELIVERABLE_MESSAGES (HTTP 422) | None of the numbers in the request can be delivered | Check the number formatting function |
HTTP 429 / 503 | Request limit exceeded or service temporarily unavailable | Wait for the Retry-After period, then retry |
| Timeout / connection error | Netgsm may have processed the request | Do not resend; query the report first |
The last row of the table describes the most expensive error. Netgsm's SDK flags this situation with the mayHaveBeenProcessed field: when the connection drops, Netgsm may have received the request and queued the SMS. An integration that blindly resends the SMS on a connection error sends duplicate messages to a group of customers on every day with network fluctuations.
Do orders silently stay without SMS when the balance runs out?
Yes. When credit runs out, Netgsm rejects the send but nothing changes in Shopify: the order is created, the shipment goes out, and the customer simply receives no SMS. Do not query the balance before every send. According to Netgsm, the balance query is limited to 60 requests per minute and the response is cached for 10 seconds. A check that queries once a day and sends an email alert when the balance falls below 3 times the average consumption of the previous 7 days is enough.
Webhook subscription checks, balance alerts and report backfilling are three jobs that must run every day after the integration goes live. If nobody on your team will track these checks, our Shopify technical support and maintenance service monitors them and steps in before a silent failure turns into a customer complaint.
From the field: the 5 most common mistakes we see in Netgsm integrations
At Nodus Works, the same five mistakes keep recurring in the SMS integrations we build and take over in Shopify stores in Turkey. None of them comes from the Netgsm API itself; all of them occur in the layer where Shopify data is turned into an SMS.
1. Shipping SMS sent without a tracking link
When the warehouse team first marks the order as "shipped" and enters the tracking number a few hours later, the fulfillments/create webhook arrives with an empty tracking field. If the integration sends the SMS immediately, the customer gets a "shipped" message without a link and asks customer service for the tracking number. The fix: send the SMS when the tracking_number field is filled. If the field is empty, wait for the fulfillments/update event. We explained the tracking number flow between carriers and Shopify carrier by carrier in our Shopify shipping integration guide.
2. "Your payment has been received" sent to a cash on delivery customer
The orders/create issue we described in the first section is the template mistake we see most often in integrations we take over. An integration that does not check the order's payment method (payment_gateway_names) tells the cash on delivery customer "your payment has been received". In stores with a high cash on delivery share, this message can lead the customer to refuse the parcel at the door, saying "I already paid".
3. Numbers starting with zero getting rejected
The number of a customer who types 0532... into the shipping address goes to Netgsm as 0532... without formatting and is rejected. This error shows up in the logs as NO_DELIVERABLE_MESSAGES, but since nobody reads the logs, it goes unnoticed. The formatting function in the previous section eliminates this error completely.
4. Serverless environment clashing with IP restriction
The integration developer enables IP restriction in the Netgsm panel for security but sends from a serverless environment with no fixed IP. Tests pass from the developer's own computer; in production every request returns code 30. Before going live, run the test from the environment where the integration will actually run.
5. Campaign message leaving through the informational queue
We have seen integrations send cart reminders from the same function as order SMS, with the same iysFilter: NONE setting. In that case, customers without İYS consent also receive SMS with discount codes. This error has no technical symptom; the send looks successful. Legally, however, it counts as an unsolicited commercial message. Split commercial and informational sends into separate queues with separate filter settings.
Frequently asked questions about Shopify Netgsm SMS integration
Can I send SMS for free with Netgsm on Shopify?
No, every SMS sent through Netgsm is deducted from the package in your account. The only free environment is Netgsm's sandbox (ext-sandbox.netgsm.com.tr); there you test the token and send flow end to end, but no real SMS goes out. If you use a ready-made app, also factor in the app's monthly or per-message fee on top of the Netgsm package price.
Why can't Netgsm's Shopify app be installed?
As of November 13, 2026, the Shopify App Store page of Netgsm's "Netgsm SMS" app shows that the app is not available in the store and directs you to Netgsm for support. You have three options: another ready-made app that supports Netgsm, Shopify Flow with an intermediate service, or a custom app that listens to webhooks. Ask Netgsm directly whether the app will return.
Do order and shipping SMS require İYS consent?
No. Order confirmation, shipping and refund messages reporting the status of an order the customer placed are informational and do not require İYS consent. However, if you add a discount code, campaign or product recommendation to these messages, the message counts as commercial and needs a consent record in İYS. Send these messages in Netgsm with iysFilter: NONE.
How many characters does a Turkish-character SMS have?
In Netgsm's TURKISH encoding, a single SMS is 155 characters; in messages split into multiple parts, each part holds 148 characters. In this encoding, the letters "ç, ğ, ı, ş, Ğ, İ, Ş" count as two characters each. If you add an emoji to the message, the encoding switches to UNICODE and the single SMS limit drops to 70 characters.
Can abandoned cart SMS be sent with Netgsm?
Yes. The only condition is that the customer's SMS consent is recorded in İYS. Shopify Flow's "Customer abandons checkout" trigger sends a request to Netgsm through an intermediate service. The send uses iysFilter: BRAND and Netgsm removes numbers without consent. Because the reminder counts as a commercial message, do not enable this flow before the İYS connection is set up.
What does Netgsm error code 30 mean?
Code 30 indicates that the username or password is wrong, or that the API sub-user lacks API access permission. If you enabled IP restriction and the request comes from outside the allowed IP, you get the same code. In sends from serverless environments (for example Cloudflare Workers), IP restriction produces this error because there is no fixed IP.
How do I stop the same customer from getting two SMS?
Shopify resends a webhook that gets no response within 5 seconds; Netgsm, in turn, does not deduplicate identical requests. Record the X-Shopify-Webhook-Id value of every webhook and skip repeats. If the connection drops during a Netgsm request, do not resend the SMS; query the report first.
Should I use WhatsApp or SMS for order notifications?
Use both, with separate roles. SMS reaches every phone without an internet connection or app; it leads for messages that must not be missed, such as shipping and cash on delivery confirmation. WhatsApp stands out in flows that need visuals, buttons and two-way conversation. We compared the options for adding a WhatsApp channel to your store in our Shopify WhatsApp plugin guide.
Conclusion: in what order should you build the SMS stack?
Do not build Shopify Netgsm SMS integration all at once; build it in order of risk. The order we recommend:
- Preparation: Open the header application and the API sub-user on day one.
- Informational flows: Take order, shipping and cancellation SMS live with
iysFilter: NONE. - Monitoring: Set up the delivery report webhook, balance alert and webhook subscription check.
- Commercial flows: Once İYS consent sync works, enable cart reminders and campaign SMS in a separate queue.
This order keeps commercial messages, which carry legal risk, out until the infrastructure is proven. An error in informational flows produces at worst a customer complaint; a filter error in the commercial flow counts as an unsolicited commercial message. Spend the first two weeks on informational SMS only and watch the failed send rate in the delivery reports. Once the rate falls below 2 percent and no duplicate SMS complaints come in, the infrastructure is ready for commercial flows.
If your store uses flows that ready-made apps cannot see, such as cash on delivery, an ERP or multi-warehouse fulfillment, let's plan the setup together through our Shopify integration and custom app development service; in the first call, we map your current flow and decide which SMS to build first.
If you are considering SMS not only for notifications but also for customer login, the next step is setting up one-time code login. Our Shopify SMS OTP login guide covers phone number login to customer accounts together with an identity provider and a KVKK-compliant signup form. Netgsm's sms.sendOtp operation can serve as the SMS service that sends the codes in that flow.

.png)


