feat: [barobill] 독립 SMS API 연동 및 OTP 발송 전환

- BarobillService에 SMS WSDL 엔드포인트 추가
- sendSMSMessage, checkSMSFromNumber, getSMSFromNumbers 메서드 추가
- sendOtpViaSms를 알림톡 대체발송 → 독립 SMS API(SendSMSMessage)로 전환
This commit is contained in:
김보곤
2026-02-26 10:20:35 +09:00
parent 7044030ba8
commit 394dd258cd
2 changed files with 129 additions and 22 deletions

View File

@@ -614,7 +614,7 @@ public function downloadDocument(string $token): StreamedResponse|JsonResponse
// ─── Private ───
/**
* SMS로 OTP 발송 (바로빌 알림톡 SMS 대체발송 기능 활용)
* SMS로 OTP 발송 (바로빌 독립 SMS API 사용)
*/
private function sendOtpViaSms(EsignContract $contract, EsignSigner $signer, string $otpCode): bool
{
@@ -632,31 +632,17 @@ private function sendOtpViaSms(EsignContract $contract, EsignSigner $signer, str
$barobill = app(BarobillService::class);
$barobill->setServerMode($member->server_mode ?? 'production');
// 채널 ID 조회
$channelResult = $barobill->getKakaotalkChannels($member->biz_no);
$yellowId = '';
if ($channelResult['success'] ?? false) {
$chData = $channelResult['data'];
if (is_object($chData) && isset($chData->KakaotalkChannel)) {
$ch = is_array($chData->KakaotalkChannel) ? $chData->KakaotalkChannel[0] : $chData->KakaotalkChannel;
$yellowId = $ch->ChannelId ?? '';
}
}
$fromNumber = preg_replace('/[^0-9]/', '', $member->manager_hp);
$toNumber = preg_replace('/[^0-9]/', '', $signer->phone);
$smsText = "[SAM] 전자계약 인증코드: {$otpCode} (5분 이내 입력)";
$result = $barobill->sendATKakaotalkEx(
$result = $barobill->sendSMSMessage(
corpNum: $member->biz_no,
senderId: $member->barobill_id,
yellowId: $yellowId,
templateName: '인증코드',
receiverName: $signer->name,
receiverNum: preg_replace('/[^0-9]/', '', $signer->phone),
title: '',
message: $smsText,
buttons: [],
smsMessage: $smsText,
smsSenderNum: preg_replace('/[^0-9]/', '', $member->manager_hp),
fromNumber: $fromNumber,
toName: $signer->name,
toNumber: $toNumber,
contents: $smsText,
);
if ($result['success'] ?? false) {

View File

@@ -47,6 +47,11 @@ class BarobillService
*/
protected ?SoapClient $kakaotalkClient = null;
/**
* SOAP 클라이언트 (문자전송용 - SMS)
*/
protected ?SoapClient $smsClient = null;
/**
* CERTKEY (인증키)
*/
@@ -175,6 +180,7 @@ protected function initializeConfig(): void
'bankaccount' => $baseUrl.'/BANKACCOUNT.asmx?WSDL',
'card' => $baseUrl.'/CARD.asmx?WSDL',
'kakaotalk' => $baseUrl.'/KAKAOTALK.asmx?WSDL',
'sms' => $baseUrl.'/SMS.asmx?WSDL',
];
}
}
@@ -207,6 +213,7 @@ protected function buildSoapUrls(string $baseUrl): array
'bankaccount' => $baseUrl.'/BANKACCOUNT.asmx?WSDL',
'card' => $baseUrl.'/CARD.asmx?WSDL',
'kakaotalk' => $baseUrl.'/KAKAOTALK.asmx?WSDL',
'sms' => $baseUrl.'/SMS.asmx?WSDL',
];
}
@@ -329,6 +336,7 @@ protected function call(string $service, string $method, array $params = []): ar
'bankaccount' => $this->getBankAccountClient(),
'card' => $this->getCardClient(),
'kakaotalk' => $this->getKakaotalkClient(),
'sms' => $this->getSmsClient(),
default => null,
};
@@ -1637,4 +1645,117 @@ public function cancelReservedKakaotalk(string $corpNum, string $sendKey): array
return $this->call('kakaotalk', 'CancelReservedKakaotalk', $params);
}
// ========================================
// 문자 서비스 (SMS)
// ========================================
/**
* SMS SOAP 클라이언트 가져오기
*/
protected function getSmsClient(): ?SoapClient
{
if ($this->smsClient === null) {
try {
$this->smsClient = new SoapClient($this->soapUrls['sms'], [
'trace' => true,
'encoding' => 'UTF-8',
'exceptions' => true,
'connection_timeout' => 30,
'cache_wsdl' => WSDL_CACHE_NONE,
]);
} catch (Throwable $e) {
Log::error('바로빌 SMS SOAP 클라이언트 생성 실패', [
'error' => $e->getMessage(),
'url' => $this->soapUrls['sms'],
]);
return null;
}
}
return $this->smsClient;
}
/**
* SMS 단문 발송
*
* @param string $corpNum 회원사 사업자번호
* @param string $senderId 바로빌 계정 ID
* @param string $fromNumber 발신번호
* @param string $toName 수신자명
* @param string $toNumber 수신 전화번호
* @param string $contents 메시지 내용 (90바이트 이내)
* @param string $sendDT 예약일시 (빈값 = 즉시발송)
* @param string $refKey 참조키
*/
public function sendSMSMessage(
string $corpNum,
string $senderId,
string $fromNumber,
string $toName,
string $toNumber,
string $contents,
string $sendDT = '',
string $refKey = ''
): array {
$params = [
'CorpNum' => $this->formatBizNo($corpNum),
'SenderID' => $senderId,
'FromNumber' => $fromNumber,
'ToName' => $toName,
'ToNumber' => $toNumber,
'Contents' => $contents,
'SendDT' => $sendDT,
'RefKey' => $refKey,
];
return $this->call('sms', 'SendSMSMessage', $params);
}
/**
* 발신번호 등록 여부 확인
*
* @param string $corpNum 회원사 사업자번호
* @param string $fromNumber 확인할 발신번호
*/
public function checkSMSFromNumber(string $corpNum, string $fromNumber): array
{
$params = [
'CorpNum' => $this->formatBizNo($corpNum),
'FromNumber' => $fromNumber,
];
return $this->call('sms', 'CheckSMSFromNumber', $params);
}
/**
* 등록된 발신번호 목록 조회
*
* @param string $corpNum 회원사 사업자번호
*/
public function getSMSFromNumbers(string $corpNum): array
{
$params = [
'CorpNum' => $this->formatBizNo($corpNum),
];
return $this->call('sms', 'GetSMSFromNumbers', $params);
}
/**
* SMS 전송 상태 조회
*
* @param string $corpNum 회원사 사업자번호
* @param string $sendKey 전송키
*/
public function getSMSSendState(string $corpNum, string $sendKey): array
{
$params = [
'CorpNum' => $this->formatBizNo($corpNum),
'SendKey' => $sendKey,
];
return $this->call('sms', 'GetSMSSendState', $params);
}
}