1. Go to this page and download the library: Download icomm-api/bizgo-sdk-comm library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
icomm-api / bizgo-sdk-comm example snippets
use Bizgo\BizgoClient;
use Bizgo\Environment;
$client = new BizgoClient(environment: Environment::Sandbox); // 키는 BIZGO_API_KEY에서 읽음
$result = $client->send->sms(to: '01000000000', from: '01000000000', text: '[비즈고] 인증번호는 123456 입니다.');
$result->msgKeys(); // 접수된 메시지 키
$result->failed(); // 접수 단계에서 거절된 수신자 (없으면 [])
$result->duplicates(); // 같은 idempotencyKey로 이미 접수된 수신자(수신자별 A301, 다시 발송되지 않음)
use Bizgo\Model\AlimtalkMessage;
use Bizgo\Model\Destination;
use Bizgo\Model\SmsMessage;
$result = $client->send->omni(
to: [new Destination(to: '01000000000', replaceWords: ['name' => '홍길동'])], // 최대 200명
messages: [
new AlimtalkMessage(senderKey: '...', templateCode: '...', msgType: 'AT', text: '#{name}님, 주문이 접수되었습니다.'),
new SmsMessage(from: '01000000000', text: '#{name}님, 주문이 접수되었습니다.'), // 알림톡 실패 시
],
idempotencyKey: 'order-20260923-0001', // 권장: 재시도해도 중복 발송되지 않음 (idempotencyTtl 기본 86400초)
ref: 'order-20260923-0001', // 리포트에 그대로 돌아오는 참조값
);
use Bizgo\Upload;
$uploaded = $client->files->uploadMms('banner.jpg'); // jpg, 최대 300KB (넘으면 보내기 전 오류)
if ($uploaded->fileKey !== null) {
$client->send->mms(to: '01000000000', from: '01000000000', text: '...', fileKeys: [$uploaded->fileKey]);
}
$client->files->uploadRcs('card.png'); // → ->media
$client->files->uploadBrandMessage('wide.jpg', kind: 'wide'); // → ->imgUrl
$client->files->uploadMms(Upload::fromContents($bytes, 'banner.jpg')); // 이미 가진 바이트
$client->reports->consume(function (array $reports) use ($db): void {
foreach ($reports as $report) {
$db->upsert($report->msgKey, $report->reportCode); // 같은 리포트가 다시 올 수 있으니 upsert
}
});
use Bizgo\Exception\WebhookPayloadException;
use Bizgo\Exception\WebhookVerificationException;
use Bizgo\Webhook\WebhookReceiver;
// secret이 없으면 빈 문자열 -> WebhookVerificationException(설정 오류)으로 바로 알 수 있음
$receiver = new WebhookReceiver((string) getenv('BIZGO_WEBHOOK_SECRET'));
try {
// PSR-7 요청, getallheaders(), $_SERVER 모두 가능
$report = $receiver->report($_SERVER, (string) file_get_contents('php://input'));
} catch (WebhookPayloadException) {
http_response_code(400); // 본문 형식 오류
exit;
} catch (WebhookVerificationException) {
http_response_code(401); // 서명·timestamp 오류
exit;
}
$db->upsert($report->msgKey, $report->reportCode); // 같은 리포트가 다시 올 수 있으니 upsert (무거운 처리는 비동기로)
echo json_encode(WebhookReceiver::ack($report->msgKey));
use DateTimeImmutable;
use DateTimeZone;
$client->messages->status($msgKey); // 단건 상태 (대체발송 시 채널별 항목)
$client->messages->statusByRequestId($requestId); // 동보 요청 전체 (msgKey에서 끝 3자리를 뺀 값)
$client->messages->statistics('20260901', '20260923', serviceType: 'SMS');
$kst = new DateTimeZone('Asia/Seoul');
foreach ($client->messages->iterHistory(new DateTimeImmutable('2026-09-23 09:00', $kst), serviceType: ['SMS', 'ALIMTALK']) as $m) {
// 페이지(lastSeq)를 자동으로 따라가는 generator
}
foreach ($client->messages->iterMoHistory(new DateTimeImmutable('2026-09-23 09:00', $kst)) as $mo) {
// MO(수신) 이력
}
use Bizgo\Model\ReservationCreateRequest;
// 요청 본문: 모델(보내기 전 검증) 또는 API 이름의 배열(모르는 키는 거절)
$reservation = $client->reservations->create(ReservationCreateRequest::fromArray([
'destinations' => [['to' => '01000000000']],
'messageFlow' => [['sms' => ['from' => '01000000000', 'text' => '예약 안내']]],
'resvSendTime' => '2026-12-01 10:00:00',
]));
echo $reservation->resvKey; // x-sdk-result: data -> resvKey와 수신자별 결과(data)를 함께 돌려줌
// 경로 -> 본문 -> 쿼리 순서의 named arguments. 한 페이지 메서드와 전체 순회 generator(iter<Method>)
$page = $client->alimtalk->templates->list(senderKey: 'SENDER_KEY_EXAMPLE', inspectionStatus: 'APR', limit: 100);
foreach ($client->alimtalk->templates->iterList(senderKey: 'SENDER_KEY_EXAMPLE') as $template) {
// 문서에 적힌 방식(offset·page·cursor) 그대로 다음 페이지를 가져오고, 빈 페이지·짧은 페이지·total·hasNext에서 멈춤
}
// multipart: 파일은 로컬 경로·스트림·Upload, JSON 파트는 모델 또는 배열
$client->rcs->templateImages->upload(brandId: 'BRAND_ID_EXAMPLE', file: 'card.png');
use Bizgo\Model\SmsMessage;
$result = $client->send->bulk(
to: $numbers, // 문자열·Destination·배열 목록 (개수 제한 없음)
messages: [new SmsMessage(from: '01000000000', text: '[비즈고] 점검 안내')],
chunkSize: 200,
idempotencyKeyPrefix: 'campaign-2026-09', // 권장: 같은 목록·같은 chunkSize로 재실행해도 중복 발송 없음
);
foreach ($result->errors as $error) {
// $error->chunkIndex, $error->start, $error->end(제외), $error->error - 수신번호는 담지 않음(인덱스만)
}
$result->msgKeys();
$result->failed();
$result->duplicates(); // 재실행 시 이미 접수된 수신자
use Bizgo\BizgoClient;
use Bizgo\RateLimit;
new BizgoClient(rateLimit: new RateLimit(send: 100, other: 5)); // 한도 변경
new BizgoClient(rateLimit: null); // 끄기
use Bizgo\Webhook\WebhookReceiver;
$event = WebhookReceiver::parseCounselMessage((string) file_get_contents('php://input')); // secret 없이 사용
echo json_encode(WebhookReceiver::counselAck());
use Bizgo\Exception;
use Bizgo\Model\SmsMessage;
try {
$client->send->omni(to: '01000000000', messages: [new SmsMessage(from: '01000000000', text: '안내')]);
} catch (Exception\ValidationException $e) { // 보내기 전 검증 실패. $e->errors: [['path' => ..., 'reason' => ...]]
} catch (Exception\AuthenticationException $e) { // 키가 틀렸거나 IP가 등록되지 않음
} catch (Exception\RateLimitException $e) { // 자동 재시도 후에도 한도 초과. $e->retryAfter
} catch (Exception\DuplicateRequestException $e) { // 요청 단위 A301: 같은 idempotencyKey가 이미 접수됨 (다시 발송되지 않음)
} catch (Exception\ApiException $e) { // 그 밖의 거절. $e->errorCode, $e->layer, $e->description, $e->trackingId
} catch (Exception\ConnectionException $e) { // 네트워크 오류(TimeoutException 포함). 발송은 접수됐을 수도 있음 → 상태 조회로 확인
}
use Bizgo\AppInfo;
use Bizgo\BizgoClient;
new BizgoClient(maxRetries: 3, timeout: 10.0, connectTimeout: 3.0);
// 프록시·사내 CA는 내장 cURL 전송의 옵션으로 (TLS 검증은 항상 켜져 있음)
new BizgoClient(proxy: 'http://proxy.example:3128', caInfo: '/etc/ssl/company-ca.pem');
// Guzzle·Symfony HttpClient도 받습니다: SDK가 리다이렉트·자체 인증·쿠키를 끄고 요청을 보냅니다.
// 재시도·리다이렉트 미들웨어가 있는 Guzzle, RetryableHttpClient, 그 밖의 PSR-18 클라이언트는 거부합니다(trustHttpClient 참고).
new BizgoClient(httpClient: new \GuzzleHttp\Client(['proxy' => 'http://proxy.example:3128']));
// 로그: PSR-3 로거에 시도마다 한 줄 (debug)
new BizgoClient(logger: $logger); // "POST /api/comm/v1/send/omni -> 200 (85 ms, attempt 1)" (경로 템플릿만)
// 앱 식별: User-Agent 끝에 app/<name>-<version> (영문·숫자·._-+만, 개인정보 금지)
new BizgoClient(appInfo: new AppInfo('myshop', '1.4.2'));
use Bizgo\Testing\FakeTransport;
use Bizgo\Webhook\WebhookReceiver;
$fake = new FakeTransport();
$client = $fake->client(); // test-api-key-not-real, sandbox, 속도 제한 끔, 실제 대기 없음
$client->send->sms(to: '01000000000', from: '01000000000', text: 'hello'); // 기본: 수신자마다 A000 + 가짜 msgKey
$fake->lastRequest()->operationId; // 'sendOmni'
$fake->lastRequest()->json; // 보냈을 JSON 본문 (헤더는 이름만 기록, 값과 키는 기록하지 않음)
$fake->on('sendOmni')->fail('service', 200, 'A020'); // 오류 주입 -> RateLimitException
$fake->on('sendOmni')->sendResult('A000', 'A306'); // 두 번째 수신자 거절
$fake->on('getReportPolling')->fail('gateway', 401, 'A401');
$fake->on('GET', '/api/comm/v1/report/inquiry/{msgKey}')->data(['report' => []]);
$fake->on('getMessageStatusByMsgKey')->networkError(); // 또는 ->timeout()
// 웹훅 테스트 요청: X-IB-Timestamp·X-IB-Signature 헤더와 본문 (리포트의 필수 필드를 모두 넣으세요)
$signed = FakeTransport::signWebhook('test-webhook-secret', [
'msgKey' => 'KEY001', 'serviceType' => 'SMS', 'reportTime' => '2026-09-23T09:00:00', 'reportType' => 'RS', 'reportCode' => '10000',
]);
$report = (new WebhookReceiver('test-webhook-secret'))->report($signed->headers, $signed->body);
use Bizgo\BizgoClient;
use Bizgo\Observability\Hook;
use Bizgo\Observability\RequestEvent;
final class Metrics implements Hook
{
public function onRequestStart(RequestEvent $event): void
{
}
public function onRequestEnd(RequestEvent $event): void
{
// $event->operationId, ->operation(`alimtalk.templates.list`), ->method, ->pathTemplate,
// ->status, ->layer, ->code, ->errorType, ->success, ->attempts, ->durationMs
}
}
$client = new BizgoClient(hooks: [new Metrics()]);
use Bizgo\BizgoClient;
use Bizgo\Observability\OpenTelemetryHook;
$otel = OpenTelemetryHook::create(); // Globals::tracerProvider()의 'bizgo' tracer
$client = new BizgoClient(hooks: $otel === null ? [] : [$otel]);
bash
composer install
vendor/bin/phpunit # 네트워크·키 없이 mock HTTP와 127.0.0.1 내장 서버로 실행
vendor/bin/phpstan analyse # level max + strict rules
vendor/bin/phpcs # PSR-12
php bin/generate-models.php # spec/openapi.yaml이 바뀌었을 때
php bin/generate-models.php --check # 생성 결과가 스펙과 같은지 (CI)
composer audit
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.