Documentation menu
PHP / SDK REFERENCE
WordPress / WooCommerce SDK Guide
The official WordPress plugin for sending Kakao Alimtalk, Brand Message and SMS — with automatic WooCommerce order notifications.
이 문서의 목차
- 패키지
- sendgo/wordpress
- 언어
- PHP
- 레지스트리
- Packagist
composer require sendgo/wordpressThe official WordPress plugin for sending Kakao Alimtalk, Brand Message and SMS, with automatic WooCommerce order notifications
sendgo/wordpress bundles the sendgo/php core through Composer and wires it into WordPress: a settings screen for your keys, and WooCommerce hooks that notify the buyer when an order changes state.
Requires PHP 8.2+.
Install
From wordpress.org or a zip (recommended)
The distributed zip bundles the core SDK in vendor/, so it runs without Composer.
Upload it under Plugins → Add New, or unpack it into wp-content/plugins/sendgo.
With Composer
composer require sendgo/wordpress
Or from inside the plugin directory:
cd wp-content/plugins/sendgo
composer install
composer install generates the vendor/autoload.php that contains the core SDK. A checkout
straight from source has no vendor/ directory, and without it the plugin cannot send —
client() returns null and an admin notice explains why.
Activate
Activate Sendgo under Plugins in the WordPress admin.
Configure
Open Settings → Sendgo:
| Field | Description |
|---|---|
| Access Key | Sendgo access key |
| Secret Key | Sendgo secret key |
| Kakao Sender Key | Kakao sender profile key (Alimtalk / Brand Message) |
| SMS Sender Key | SMS caller ID key (SMS / LMS / MMS) |
| API Version | v1 or v2 |
Sending stays disabled until both the access key and secret key are filled in. Keys are stored server-side in the sendgo_options option and never exposed to the front end.
The API version defaults to v1. Brand Message and Short URL need v2, so switch it if you plan to use those channels.
The API base URL is read from the
urloption but has no settings field. To point the plugin at a different host, set it programmatically:$options = get_option('sendgo_options', []); $options['url'] = 'https://staging.sendgo.io'; update_option('sendgo_options', $options);Before 1.2.4 this value was dropped the first time the settings form was saved. It now survives a save.
WooCommerce order notifications
With WooCommerce active, the plugin notifies the billing phone number on these transitions:
- Completed (
woocommerce_order_status_completed) - Processing (
woocommerce_order_status_processing)
Configure each state separately under Settings → Sendgo → WooCommerce Order Notifications:
| Field | Description |
|---|---|
[Order completed] Alimtalk template code |
Template sent on completion. The order number is passed as the first variable (#{var1}). |
[Order completed] SMS text used if Alimtalk fails |
Sent when the Alimtalk fails or no template code is set. Supports the {order_number} placeholder. |
[Processing] Alimtalk template code |
Template sent when the order enters processing. |
[Processing] SMS text used if Alimtalk fails |
SMS fallback for the processing state. |
A state you leave blank sends nothing. Filling in both means every order triggers two messages — one on processing, one on completion — so only configure the states you actually want to announce.
Each order notifies once per state. On a successful send the plugin records order meta (_sendgo_notified_completed / _sendgo_notified_processing), so re-saving the order in the admin or another plugin re-applying the status will not send again. A failed send is not recorded, so the next transition retries it.
A send failure never interrupts the checkout or order flow — it is caught and written to the WooCommerce log under source sendgo.
Upgrading from 1.0.x — earlier versions shared a single
order_template_codebetween both states, so an order moving processing → completed delivered the same message twice and billed the customer twice. Completed keeps the original option key; processing now needs its own field before it sends anything. Existing configurations keep working; only the duplicate goes away.
Phone numbers
The billing phone is reduced to digits (preg_replace('/[^0-9]/', ...)) before sending, so 010-1234-5678 and +82 10 1234 5678 both need to already be a Korean number the API accepts — the plugin strips punctuation but does not convert country codes. Orders with an empty billing phone are skipped silently.
Sending from your own code
Once the plugin is loaded, the core client is available directly:
$client = Sendgo_Plugin::instance()->client();
if ($client) {
// Alimtalk
$client->alimtalk->send([
'templateCode' => 'ORDER_CONFIRM_001',
'contacts' => [['contact' => '01012345678', 'var1' => 'ORD-001']],
]);
// SMS
$client->sms->sendSms([
'content' => 'Verification code: 123456',
'contacts' => [['contact' => '01012345678']],
]);
}
Always guard on $client — it is null when the keys are unset or vendor/autoload.php is missing, and calling a method on null would white-screen the page you are hooked into.
Every channel is a property on the client:
| Property | Channel |
|---|---|
$client->alimtalk |
Kakao Alimtalk |
$client->friendtalk |
Kakao Friendtalk |
$client->brandMessage |
Kakao Brand Message (v2 only) |
$client->sms |
SMS / LMS / MMS |
The client is memoised for the request, so calling Sendgo_Plugin::instance()->client() repeatedly is cheap.
Hook it to your own event
add_action('user_register', function (int $user_id): void {
$client = Sendgo_Plugin::instance()->client();
if (!$client) {
return;
}
$user = get_userdata($user_id);
$phone = preg_replace('/[^0-9]/', '', (string) get_user_meta($user_id, 'billing_phone', true));
if ('' === $phone) {
return;
}
try {
$client->alimtalk->send([
'templateCode' => 'WELCOME_001',
'contacts' => [['contact' => $phone, 'var1' => $user->display_name]],
]);
} catch (\Throwable $e) {
// Never let a messaging failure break registration.
error_log('Sendgo welcome message failed: ' . $e->getMessage());
}
}, 10, 1);
Wrapping the call in try/catch is the important part: an unhandled SendgoException inside a WordPress hook surfaces as a fatal error on whatever page fired it.
Brand Message
Friendtalk was discontinued on 2025-12-31. Since 2026-01-01 Kakao delivers Friendtalk requests as Brand Message (free-form) automatically.
friendtalkstill works and is still the only path for free-formFT/FI/FWto individual recipients — use Brand Message for template-based rich types (FL/FC/FM/FP/FA), non-friend targeting (N/I) and broadcasts (F). Brand Message is the successor channel to Friendtalk: it reaches recipients who are not channel friends ('targeting' => 'N') and can broadcast to every consenting channel friend ('targeting' => 'F'). Message types map one-to-one with Friendtalk (FT→BT,FI→BI,FW→BW,FL→BL,FC→BC,FM→BM,FP→BP,FA→BA).
v2 only. Set Settings → Sendgo → API Version to
v2; the plugin defaults tov1.
$client = Sendgo_Plugin::instance()->client();
// Single send — targeting M/N/I requires `contacts`
$client->brandMessage->send([
'targeting' => 'M',
'messageType' => 'FL',
'friendTemplateUuid' => '9cd5460b-6458-4edc-9b11-c26d3013c340',
'contacts' => [['contact' => '01012345678', 'var1' => '29,000 KRW']],
]);
// Broadcast — every consenting channel friend, no recipient list
$result = $client->brandMessage->broadcast([
'messageType' => 'FW',
'friendTemplateUuid' => '9cd5460b-6458-4edc-9b11-c26d3013c340',
]);
// A broadcast is asynchronous upstream, so poll for progress
$client->brandMessage->campaign($result['data']['campaignId']);
$client->brandMessage->campaigns(['count' => 10]);
A broadcast can reach your entire friend list, so trigger it from a deliberate admin action — a WP-CLI command or an admin-post handler behind a capability check — never from a public hook.
Error handling
use Sendgo\Php\Exception\SendgoException;
try {
$client->alimtalk->send([...]);
} catch (SendgoException $e) {
// Send failures should be logged, not surfaced to the shopper.
if (function_exists('wc_get_logger')) {
wc_get_logger()->error(
sprintf('Sendgo %d [%s]: %s', $e->getStatusCode(), $e->getErrorCode(), $e->getMessage()),
['source' => 'sendgo']
);
}
}
Branch on getErrorCode(), not on the message text — messages can change, codes are the contract.
TOKEN_EXPIRED and TOKEN_MISMATCH are handled inside the core SDK: the token is reissued and the request retried once.
FAQ
Can I use it without WooCommerce?
Yes. Sendgo_Plugin::instance()->client() works on any WordPress install; only the automatic order notifications depend on WooCommerce.
client() returns null.
Either the access key / secret key is unset, or the plugin came from source and composer install
was never run, so vendor/autoload.php does not exist. The second case raises an admin notice.
The distributed zip includes vendor/, so it cannot happen there.
Nothing sends and there is no error. Check that you registered the outbound IP of your WordPress site under Integrations → Integration Info in the console — a request from an unlisted address is rejected. On shared hosting or behind a CDN that address differs from the one your browser reports.
Where are the credentials stored?
Server-side in the sendgo_options option. They are never printed to the front end, and the secret key renders as a password field in the admin.
Does uninstalling clean everything up?
uninstall.php deletes the sendgo_options option. The _sendgo_notified_* order meta is left in place — it is harmless, and deleting it would mean a bulk write across every order.
Short URL
Short URLs shrink the links in your message body and count whether they were actually clicked. SMS is billed by byte, so a shorter link leaves more room for copy.
v2 only.
Shortening the same target URL again returns the existing link. Pass forceNew
to mint a new code when you want per-campaign reaction figures kept separate.
deactivate does not delete the link — it only stops the redirect. Use it when a link
in an already-sent message has to be killed; the accumulated stats stay, and visitors
to a stopped link get 410 Gone.
$client = Sendgo_Plugin::instance()->client();
if ($client) {
$short = $client->shortUrl->create([
'targetUrl' => get_permalink($post_id),
'title' => get_the_title($post_id),
]);
$link = $short['data']['shortUrl'];
}
stats returns a daily series (daily) plus breakdowns by device (byDevice), referrer (byReferer) and country (byCountry). The daily series is read from a pre-aggregated table, so response time stays flat no matter how many clicks accumulate.
External services
This plugin sends Kakao Alimtalk, Kakao Brand Message and SMS/LMS/MMS through the Sendgo API (https://sendgo.io). A Sendgo account is required and message delivery is a paid service.
- Before any send, the access key and secret key are exchanged for a short-lived token.
- When a WooCommerce order changes to
processingorcompletedand that state has a template code or SMS fallback configured, the buyer's billing phone number and the order number are sent along with your sender key and the template code. - When you call the client from your own code, the recipient numbers and body you pass are sent as is.
Nothing is sent when the plugin is merely installed or activated, or when both the template code and the SMS fallback are empty.
- Terms of service: https://sendgo.io/terms-of-service
- Privacy policy: https://sendgo.io/privacy-policy
Package information
- Package:
sendgo/wordpress(Packagist) - Repository: send-go/wordpress
- Registry: https://packagist.org/packages/sendgo/wordpress
- License: MIT
Getting your API keys
Sign in to Sendgo and open Integrations → Integration Info to issue an access key and secret key, and to register the IP addresses allowed to use them — a request from an unlisted address is rejected. Register a Kakao sender profile under Kakao Sender Profile to get your Kakao Sender Key, and a caller ID under Sender Management for SMS.
이 패키지로 할 수 있는 것
Send your first Kakao Alimtalk in 5 minutes →
From issuing an access key to sending a Kakao Alimtalk, with working code in Node.js, Python, PHP, Laravel, Java and Go.
Finish the Sendgo integration from your AI agent — MCP server and Account API →
Pick the organisation, issue API keys, register sender numbers and templates from a coding agent. Everything except topping up credit works without the console.
Alimtalk, Brand Message or SMS — choosing a messaging channel in Korea →
Kakao Alimtalk, Kakao Brand Message and SMS/LMS/MMS differ in what content they allow, what they cost and what you must set up first. Which to pick, by situation.
Sendgo API authentication — access keys and bearer tokens →
Exchange an accessKey and secretKey for a bearer token, and call the Sendgo API with it. Differences between v1 and v2, token caching, and the 401/403 codes.
Send a Kakao Alimtalk — PHP, Node.js, Python, Java, Go examples →
Send Kakao Alimtalk with an approved template code. Runnable code for Laravel, Node.js, Python, PHP, Java, Go, Ruby and .NET, plus every required field and why sends fail.
Send SMS, LMS and MMS in South Korea — code examples →
Send Korean SMS (90 bytes), LMS (long text) and MMS (with images) through Sendgo. Type selection, byte counting, verification-code patterns and advertising rules.
Send a Kakao Brand Message — the successor to Friendtalk →
Send Brand Messages to channel friends, non-friends, or every consenting friend at once. How targeting splits the request path, and when to keep using the Friendtalk endpoint.
SMS fallback when a Kakao Alimtalk fails →
Use replaceSms so a text message goes out when the Alimtalk cannot be delivered. Required fields, cost implications, and the mistake that silently sends nothing.
Bulk Alimtalk sending and per-recipient variables →
Send one template to many recipients with different values each, in batches. Batch sizing, partial failures, queue patterns and the data hygiene that prevents most incidents.
Scheduling an Alimtalk or SMS — scheduleType and at →
Send at a specific time with scheduleType SCHEDULED. Timestamp format, the KST timezone trap, and how scheduling interacts with the advertising night ban.
Doing everything over the API — operations automation for resellers →
Register Kakao channels, submit Alimtalk templates for review, file sender numbers, and sync opt-outs without ever sending anyone to sendgo.io. Includes webhook delivery of review outcomes.
Sendgo API error codes and retry strategy →
Every error code returned by the Sendgo send endpoints, and how to tell a failure worth retrying from one that will fail identically every time.
Short links in SMS and Alimtalk, with click tracking →
Shorten long URLs to fit inside an SMS and measure who clicked. Creating short links, reading click stats, and splitting stats per campaign.
Advertising message rules in Korea — (광고) prefix, opt-out, night ban →
What Korean law requires of promotional SMS and Kakao messages, and how to enforce it in code: the (광고) prefix, a free opt-out, and no sending between 21:00 and 08:00 KST.
Kakao Friendtalk shut down (2025-12-31) — migrating to Brand Message →
What happens to existing Friendtalk code now that the channel has ended, when you must migrate to Brand Message, and the one case where the Friendtalk endpoint is still the right call.
관련 패키지
PHP →
The pure-PHP SDK for sending Kakao Alimtalk, Brand Message and SMS from PHP — no framework required.
composer require sendgo/phpLaravel →
The official Laravel package for sending Kakao Alimtalk, Brand Message and SMS — auto-discovered service provider, facade and publishable config.
composer require sendgo/laravelSymfony →
The official Symfony bundle for sending Kakao Alimtalk, Brand Message and SMS — autowired service, config validation, Messenger-friendly.
composer require sendgo/symfony