본문 바로가기
← 패키지 목록

Laravel Webhook Server

spatie/laravel-webhook-server

제출자 Laravel Korea Discovery Bot
최신 v4.0.0라이센스 MIT배포 2026년 10월 24일
큐·작업

Laravel 앱에서 웹훅을 보내세요

Laravel 앱에서 웹훅 보내기

Latest Version on Packagist run-testsTotal Downloads

웹훅(webhook)은 한 앱에서 특정 이벤트가 발생했을 때 그 정보를 다른 앱에 알려주는 방식입니다. 두 앱은 단순한 HTTP 요청으로 서로 통신합니다.

이 패키지를 사용하면 Laravel 앱에서 웹훅을 손쉽게 설정하고 전송할 수 있습니다. 요청 서명, 재시도 및 백오프 전략을 지원합니다.

웹훅을 받아서 처리해야 한다면 laravel-webhook-client 패키지를 살펴보세요.

v4 문서와 업그레이드 가이드도 참고하세요.

후원하기

Spatie는 최고 수준의 오픈 소스 패키지를 만드는 데 많은 자원을 투자하고 있습니다. 유료 제품을 구매하여 후원해 주실 수 있습니다.

또한 사용 중인 패키지를 적어 고향에서 보낸 엽서를 보내 주시면 큰 힘이 됩니다. 주소는 연락처 페이지에서 확인할 수 있으며, 받은 모든 엽서는 가상 엽서 월에 게시됩니다.

설치

이 패키지는 PHP 8.4와 Laravel 13이 필요합니다. 이전 버전을 사용 중이라면 v3를 사용하세요.

Composer로 패키지를 설치합니다.

composer require spatie/laravel-webhook-server

설정 파일은 다음 명령으로 게시할 수 있습니다.

php artisan vendor:publish --provider="Spatie\WebhookServer\WebhookServerServiceProvider"

게시되는 config/webhook-server.php 파일의 내용은 다음과 같습니다.

use Spatie\WebhookServer\BackoffStrategy\ExponentialBackoffStrategy; use Spatie\WebhookServer\CallWebhookJob; use Spatie\WebhookServer\Signer\DefaultSigner; return [ /* * The default queue that should be used to send webhook requests. */ 'queue' => 'default', /* * The default queue connection that should be used to send webhook requests. */ 'connection' => null, /* * The default http verb to use. */ 'http_verb' => 'post', /* * Proxies to use for request. * * See https://docs.guzzlephp.org/en/stable/request-options.html#proxy */ 'proxy' => null, /* * This class is responsible for calculating the signature that will be added to * the headers of the webhook request. A webhook client can use the signature * to verify the request hasn't been tampered with. */ 'signer' => DefaultSigner::class, /* * This is the name of the header where the signature will be added. */ 'signature_header_name' => 'Signature', /* * This is the name of the header where the timestamp will be added. */ 'timestamp_header_name' => 'Timestamp', /* * Send the webhook UUID in this header. Set to null to disable it. */ 'webhook_id_header_name' => 'Webhook-Id', /* * These are the headers that will be added to all webhook requests. */ 'headers' => [ 'Content-Type' => 'application/json', ], /* * If a call to a webhook takes longer this amount of seconds * the attempt will be considered failed. */ 'timeout_in_seconds' => 3, /* * The amount of times the webhook should be called before we give up. */ 'tries' => 3, /* * This class determines how many seconds there should be between attempts. */ 'backoff_strategy' => ExponentialBackoffStrategy::class, /* * Retry all unsuccessful HTTP statuses by default. Set an array to limit them. * Connection failures are still retried. */ 'retryable_status_codes' => null, /* * Use the response's Retry-After header as a minimum retry delay. */ 'respect_retry_after' => false, /* * Randomize the backoff delay between zero and the strategy's delay. */ 'retry_with_jitter' => false, /* * This class is used to dispatch webhooks onto the queue. */ 'webhook_job' => CallWebhookJob::class, /* * By default we will verify that the ssl certificate of the destination * of the webhook is valid. */ 'verify_ssl' => true, /* * When set to true, an exception will be thrown when the last attempt fails */ 'throw_exception_on_failure' => false, /* * When using Laravel Horizon you can specify tags that should be used on the * underlying job that performs the webhook request. */ 'tags' => [], ];

이 패키지는 기본적으로 큐를 사용해 실패한 웹훅 요청을 재시도합니다. 로컬이 아닌 환경에서는 sync가 아닌 실제 큐 드라이버를 반드시 설정하세요.

사용법

웹훅을 호출하는 가장 간단한 방법은 다음과 같습니다.

WebhookCall::create() ->url('https://other-app.com/webhooks') ->payload(['key' => 'value']) ->useSecret('sign-using-this-secret') ->dispatch();

위 코드는 https://other-app.com/webhooks로 POST 요청을 보냅니다. 요청 본문은 payload에 전달한 배열을 JSON으로 인코딩한 값입니다. 요청에는 Signature라는 헤더가 포함되며, 수신 측 앱은 이 서명으로 페이로드가 변조되지 않았는지 검증할 수 있습니다. 웹훅 호출을 디스패치하면 DispatchingWebhookCallEvent 이벤트도 함께 발생합니다.

수신 측 앱이 2로 시작하는 응답 코드를 반환하지 않으면, 패키지는 10초 후에 웹훅을 다시 호출합니다. 두 번째 시도도 실패하면 100초 후에 마지막으로 한 번 더 호출하며, 이마저 실패하면 FinalWebhookCallFailedEvent 이벤트가 발생합니다.

웹훅 동기 전송

웹훅을 즉시(동기적으로) 호출하려면 dispatchSync 메서드를 사용하면 됩니다. 이 메서드를 사용하면 웹훅이 큐에 들어가지 않고 바로 실행됩니다. 웹훅 전송이 이미 큐에 올라간 더 큰 Job의 일부일 때 유용합니다.

WebhookCall::create() ... ->dispatchSync();

조건부 웹훅 전송

조건에 따라 웹훅을 디스패치하려면 dispatchIf, dispatchUnless, dispatchSyncIf, dispatchSyncUnless 메서드를 사용할 수 있습니다.

WebhookCall::create() ... ->dispatchIf($condition); WebhookCall::create() ... ->dispatchUnless($condition); WebhookCall::create() ... ->dispatchSyncIf($condition); WebhookCall::create() ... ->dispatchSyncUnless($condition);

요청 서명 방식

설정할 때는 보통 시크릿을 생성하고 저장한 뒤, 웹훅을 받으려는 앱과 공유합니다. 시크릿은 Illuminate\Support\Str::random()으로 생성할 수 있지만, 어떤 방식을 쓸지는 전적으로 자유입니다. 패키지는 이 시크릿을 사용해 웹훅 호출에 서명합니다.

기본적으로 패키지는 Signature라는 헤더를 추가하며, 수신 측 앱은 이 서명으로 페이로드가 변조되지 않았는지 확인할 수 있습니다. 서명은 다음과 같이 계산됩니다.

// $body contains the serialized request body. // $secret is the string given to useSecret(). $signature = hash_hmac('sha256', $body, $secret);

JSON 요청 본문의 경우, 패키지는 디스패치 전에 json_encode($payload, JSON_THROW_ON_ERROR)로 페이로드를 한 번 인코딩합니다. 서명은 정확히 이 바이트열을 대상으로 계산되며, 모든 재시도에서도 동일한 본문이 전송됩니다. 원시(raw) 본문은 JSON 인코딩 없이 그대로 서명됩니다. 유효하지 않은 JSON 페이로드는 서명을 비활성화했더라도 디스패치 전에 JsonException을 던집니다.

GET 웹훅은 이전과 같이 페이로드를 쿼리 파라미터로 전송하며, 빈 본문이 아니라 페이로드의 JSON 표현을 서명합니다. 서명하지 않는 GET 쿼리 파라미터는 JSON으로 인코딩되지 않습니다. 서명 이후에 본문을 변경하는 HTTP 미들웨어를 사용한다면 서명도 함께 갱신해야 합니다.

요청 서명 건너뛰기

권장하지는 않지만, 웹훅 요청에 서명하고 싶지 않다면 doNotSign 메서드를 호출하세요.

WebhookCall::create() ->doNotSign() ...

이 메서드를 호출하면 Signature 헤더가 설정되지 않습니다.

서명 방식 커스터마이징

서명 과정을 바꾸고 싶다면 직접 커스텀 서명자(signer)를 만들 수 있습니다. 서명자는 Spatie\WebhookServer\Signer\Signer를 구현한 모든 클래스입니다.

인터페이스는 다음과 같습니다.

namespace Spatie\WebhookServer\Signer; interface Signer { public function signatureHeaderName(): string; public function calculateSignature(string $webhookUrl, string $body, string $secret): string; }

서명자를 만든 뒤 webhook-server 설정 파일의 signer 키에 클래스 이름을 지정하면, 모든 웹훅 호출에서 기본으로 해당 서명자가 사용됩니다.

특정 웹훅 호출에만 서명자를 지정할 수도 있습니다.

WebhookCall::create() ->signUsing(YourCustomSigner::class) ... ->dispatch();

헤더 이름만 바꾸고 싶다면 커스텀 서명자 없이 webhook-server 설정 파일의 signature_header_name 값을 변경하면 됩니다.

커스텀 서명자는 이미 직렬화된 본문을 전달받습니다. 다시 JSON 인코딩하지 마세요. JSON 인코딩 방식을 바꾸거나 정규화(canonical) JSON을 사용하려면 CallWebhookJob을 상속하고 protected 메서드인 generateBody(): string을 오버라이드한 뒤, 해당 클래스를 webhook_job에 설정하세요. 패키지는 그 결과를 그대로 서명하고 전송합니다.

전송 ID(Delivery ID)

모든 웹훅에는 UUID를 담은 Webhook-Id 헤더가 포함됩니다. 이 ID는 재시도 간에도 동일하게 유지되므로, 수신 측에서 중복 전송을 걸러내는 데 사용할 수 있습니다. uuid('your-delivery-id')로 직접 ID를 지정할 수도 있습니다.

헤더 이름을 바꾸려면 webhook_id_header_name 설정 키를 사용하고, 비활성화하려면 null로 설정하세요. 웹훅 하나에만 적용하려면 withWebhookIdHeader('X-Delivery-Id') 또는 withWebhookIdHeader(null)을 사용합니다. 같은 이름의 헤더를 명시적으로 지정했다면 대소문자와 관계없이 그 값이 우선합니다.

기본 서명은 본문만 인증하며, 전송 ID나 다른 헤더는 인증하지 않습니다. 전송 ID는 재전송(replay) 공격 방어 수단이 아닙니다. 요청을 인증하고, 수신 측에서 처리 로직을 멱등하게(idempotent) 만드세요.

타임스탬프 사용

타임스탬프는 시도가 전송된 시각을 나타냅니다. 기본 서명자는 이 헤더를 서명에 포함하지 않으므로, 헤더만으로는 재전송 공격을 막을 수 없습니다. 재전송 방어가 필요하다면 서명되는 페이로드에 타임스탬프를 포함하고, 수신 측에서 그 경과 시간을 검증하세요.

타임스탬프는 기본적으로 비활성화되어 있으며, useTimestamp() 메서드를 호출해 활성화할 수 있습니다.

WebhookCall::create() ->useTimestamp() ... ->dispatch();

이 메서드를 호출하면 Timestamp 헤더가 설정됩니다.

실패한 웹훅 재시도

웹훅을 받는 앱이 2xx 상태 코드로 응답하지 못하면 패키지는 해당 호출을 실패로 간주합니다. 원격 앱이 3초 안에 응답하지 않는 경우에도 실패로 처리됩니다.

이 기본 타임아웃은 webhook-server 설정 파일의 timeout_in_seconds 키에서 설정할 수 있습니다. 특정 웹훅에 대해서만 타임아웃을 바꾸려면 다음과 같이 합니다.

WebhookCall::create() ->timeoutInSeconds(5) ... ->dispatch();

웹훅 호출이 실패하면 두 번 더 재시도합니다. 기본 재시도 횟수는 설정 파일의 tries 키에서 지정할 수 있으며, 특정 웹훅에 대해서만 시도 횟수를 지정하려면 다음과 같이 합니다.

WebhookCall::create() ->maximumTries(5) ... ->dispatch();

원격 앱에 과부하를 주지 않도록 시도 사이에 일정 시간을 기다립니다. 기본적으로 첫 번째와 두 번째 시도 사이에는 10초, 두 번째와 세 번째 사이에는 100초, 세 번째와 네 번째 사이에는 1000초를 기다리는 식으로 늘어납니다. 최대 대기 시간은 100,000초(약 27시간)입니다. 이 동작은 기본 ExponentialBackoffStrategy에 구현되어 있습니다.

Spatie\WebhookServer\BackoffStrategy\BackoffStrategy를 구현하는 클래스를 만들어 직접 백오프 전략을 정의할 수도 있습니다. 인터페이스는 다음과 같습니다.

namespace Spatie\WebhookServer\BackoffStrategy; interface BackoffStrategy { public function waitInSecondsAfterAttempt(int $attempt): int; }

webhook-server 설정 파일의 backoff_strategy에 커스텀 전략의 정규화된 클래스 이름(FQCN)을 지정하면 기본 전략으로 사용됩니다. 특정 웹훅에만 전략을 지정하려면 다음과 같이 합니다.

WebhookCall::create() ->useBackoffStrategy(YourBackoffStrategy::class) ... ->dispatch();

내부적으로 웹훅 호출의 재시도는 지연 디스패치로 구현되어 있습니다. Amazon SQS는 지연 시간의 최대값이 짧게 제한되어 있습니다. 큐로 Amazon SQS를 사용한다면 시도 간격이 15분을 넘지 않도록 패키지를 설정하세요.

응답 기반 재시도

기본적으로 성공하지 못한 모든 HTTP 상태 코드는 설정된 백오프 전략에 따라 재시도됩니다. 재시도할 상태 코드를 제한하거나, Retry-After 헤더를 따르거나, 완전 지터(full jitter)를 추가할 수 있습니다.

WebhookCall::create() ->url('https://other-app.com/webhooks') ->payload(['key' => 'value']) ->useSecret('your-secret') ->retryOn([408, 425, 429, 500, 502, 503, 504]) ->respectRetryAfter() ->withJitter() ->dispatch();

retryOn(null)은 성공하지 못한 모든 상태 코드를 재시도하는 기본 동작으로 되돌립니다. retryOn([])은 HTTP 상태 코드에 의한 재시도를 비활성화하며, 연결 실패는 계속 재시도됩니다. 제외된 상태 코드를 받으면 WebhookCallFailedEvent와 FinalWebhookCallFailedEvent가 즉시 모두 발생하고, throwExceptionOnFailure() 설정도 적용됩니다.

respectRetryAfter()는 0 이상의 초 단위 숫자 또는 HTTP 날짜를 받아들입니다. 이 헤더 값은 최소 대기 시간이며, 백오프 지연 시간을 줄이지는 않습니다. 유효하지 않은 값은 무시되고, 과거 날짜는 추가 지연을 만들지 않습니다.

withJitter()는 0부터 백오프 전략이 계산한 지연 시간까지(양 끝 포함) 사이에서 무작위 지연 시간을 선택합니다. respectRetryAfter()와 함께 사용하면, 수신 측이 요구한 최소 시간을 맞추도록 필요한 만큼 무작위 지연 시간이 늘어납니다. 두 옵션 모두 false를 전달해 호출 단위로 비활성화할 수 있습니다. 기본값을 바꾸려면 설정 파일의 retryable_status_codes, respect_retry_after, retry_with_jitter를 설정하세요. BackoffStrategy 인터페이스는 변경되지 않았습니다.

Retry-After 값을 포함한 최종 지연 시간이 큐 드라이버의 한도 안에 들어가는지 확인하세요. 이 옵션들은 큐를 통한 재시도에 영향을 주며, 프로세스 안에서 즉시 수행되는 HTTP 재시도에는 적용되지 않습니다. 동기 호출은 대기하거나 반복하지 않습니다.

HTTP 메서드 커스터마이징

기본적으로 모든 웹훅은 post 메서드를 사용합니다. webhook-server 설정 파일의 http_verb 키에 원하는 HTTP 메서드를 지정해 바꿀 수 있습니다.

useHttpVerb 메서드로 특정 호출에 대해서만 기본값을 재정의할 수도 있습니다.

WebhookCall::create() ->useHttpVerb('get') ... ->dispatch();

추가 헤더 지정

webhook-server 설정 파일의 headers 키에 헤더를 추가하면 모든 웹훅에 해당 헤더가 포함됩니다. 특정 웹훅에만 헤더를 추가하려면 withHeaders를 호출하세요.

WebhookCall::create() ->withHeaders([ 'Another Header' => 'Value of Another Header' ]) ... ->dispatch();

프록시 사용

webhook-server 설정 파일의 proxy 키를 지정하면 웹훅을 프록시를 거쳐 전송할 수 있습니다. 특정 요청에만 프록시를 설정하려면 useProxy를 호출하세요.

WebhookCall::create() ->useProxy('http://proxy.server:3128') ...

상호 TLS(mTLS) 인증 사용

웹훅 데이터 전송의 무결성을 지키려면, 페이로드를 받을 대상이 의도한 수신자가 맞는지 인증하는 것이 중요합니다. 상호 TLS(Mutual TLS)는 양쪽 모두를 인증합니다. 여러분의 애플리케이션은 수신 엔드포인트의 서버 인증서를 검증하고, 수신 엔드포인트는 TLS 핸드셰이크 과정에서 여러분 애플리케이션의 클라이언트 인증서를 검증합니다.

Note: 별도의 인증 기관(CA)을 포함해야 한다면 인증서 경로를 verifySsl() 메서드에 전달하세요.

WebhookCall::create() ->mutualTls( certPath: storage_path('path/to/cert.pem'), certPassphrase: 'optional_cert_passphrase', sslKeyPath: storage_path('path/to/key.pem'), sslKeyPassphrase: 'optional_key_passphrase' )

프록시 지정 형식은 guzzlehttp 프록시 형식을 따릅니다.

수신 앱의 SSL 인증서 검증

https://로 시작하는 URL을 사용하면 패키지는 수신 측의 SSL 인증서가 유효한지 검증합니다. 유효하지 않으면 해당 웹훅 호출을 실패로 간주합니다. 권장하지는 않지만, webhook-server 설정 파일의 verify_ssl 키를 false로 설정해 이 검증을 끌 수 있습니다.

doNotVerifySsl 메서드로 웹훅 호출 단위로 검증을 비활성화할 수도 있습니다.

WebhookCall::create() ->doNotVerifySsl() ... ->dispatch();

메타 정보 추가

웹훅에 추가 메타 정보를 담을 수 있습니다. 이 메타 정보는 전송되지 않으며, 이 패키지가 발생시키는 이벤트에 전달하는 용도로만 사용됩니다.

메타 정보는 다음과 같이 추가합니다.

WebhookCall::create() ->meta($arrayWithMetaInformation) ... ->dispatch();

태그 추가

큐에 Laravel Horizon을 사용 중이라면 태그도 지원한다는 점이 반가울 것입니다.

웹훅 호출을 수행하는 Job에 태그를 추가하려면 webhook-server 설정 파일의 tags 키에 지정하거나 withTags 메서드를 사용하세요.

WebhookCall::create() ->withTags($tags) ... ->dispatch();

예외 처리

기본적으로 패키지는 웹훅을 전송할 때 발생한 예외를 로그로 남기지 않습니다.

예외를 처리하려면 Spatie\WebhookServer\Events\WebhookCallFailedEvent 및/또는 Spatie\WebhookServer\Events\FinalWebhookCallFailedEvent 이벤트에 대한 리스너를 만들어야 합니다.

실패한 실행에서 예외 던지기

기본적으로 실패한 Job은 무시됩니다. Job의 마지막 시도가 실패했을 때 예외를 던지려면 throwExceptionOnFailure를 호출하세요.

WebhookCall::create() ->throwExceptionOnFailure() ... ->dispatch();

또는 webhook-server 설정 파일의 전역 옵션인 throw_exception_on_failure를 활성화해도 됩니다.

JSON 대신 원시 문자열 본문 전송

기본적으로 모든 웹훅은 페이로드를 JSON으로 변환합니다. JSON 대신 임의의 문자열을 보내려면 sendRawBody(string $body) 옵션을 사용하세요.

원시 본문도 JSON 페이로드와 마찬가지로 서명할 수 있습니다. sendRawBody를 사용하면 웹훅 이벤트에서 문자열 페이로드를 받게 됩니다. 수신 측에 맞는 Content-Type 헤더를 설정하세요.

WebhookCall::create() ->url('https://other-app.com/webhooks') ->sendRawBody('<root>someXMLContent</root>') ->withHeaders(['Content-Type' => 'application/xml']) ->useSecret('your-secret') ->dispatch();

이벤트

패키지는 다음 이벤트를 발생시킵니다.

  • DispatchingWebhookCallEvent: 웹훅 호출이 큐에 디스패치되기 직전에 발생합니다.
  • WebhookCallSucceededEvent: 원격 앱이 2xx 응답 코드로 응답했습니다.
  • WebhookCallFailedEvent: 원격 앱이 2xx가 아닌 응답 코드를 반환했거나 아예 응답하지 않았습니다.
  • FinalWebhookCallFailedEvent: 웹훅 호출의 마지막 시도가 실패했습니다.

모든 이벤트에는 다음 프로퍼티가 있습니다.

  • httpVerb: 요청에 사용한 HTTP 메서드
  • webhookUrl: 요청을 보낸 URL
  • payload: 사용한 페이로드
  • headers: 전송한 헤더. 이 배열에는 서명 헤더가 포함됩니다
  • meta: meta 호출로 웹훅에 전달한 값의 배열
  • tags: 사용한 태그의 배열
  • uuid: 이 호출을 식별하는 고유 문자열. 하나의 웹훅 호출에 대한 모든 시도에서 동일한 uuid가 사용됩니다.

DispatchingWebhookCallEvent를 제외한 모든 이벤트에는 다음 프로퍼티가 추가로 있습니다.

  • attempt: 시도 횟수
  • response: 원격 앱이 반환한 응답. \Illuminate\Http\Client\Response 인스턴스이거나 null일 수 있습니다.
  • errorType: 시도를 실패하게 만든 예외의 클래스 이름. 시도가 성공했다면 null
  • errorMessage: 해당 예외의 메시지. 시도가 성공했다면 null
  • transferStats: 요청의 소요 시간 정보를 담은 \GuzzleHttp\TransferStats 인스턴스 또는 null

리스너는 Laravel의 ShouldQueue 인터페이스를 구현할 수 있습니다. HTTP 응답 본문, 상태 코드, 헤더 배열, 쿠키, 전송 통계는 transferStats에 담긴 요청과 응답을 포함해 큐 직렬화 이후에도 유지됩니다. 리스너는 여전히 Illuminate\Http\Client\Response와 GuzzleHttp\TransferStats를 받으므로 별도의 결과 API가 필요하지 않습니다.

웹훅 Job과 이벤트는 Laravel의 JSON 큐 페이로드를 거치면서도 바이너리 원시/커스텀 본문, 헤더, 메타데이터, 오류 메시지를 보존하기 위해 base64 인코딩을 사용합니다. 이로 인해 메시지 크기가 커지며, 이는 암호화가 아닙니다. 큐의 크기 제한을 고려하고 민감한 데이터에 대한 접근을 보호하세요. 커스텀 메타데이터, 쿠키 저장소(cookie jar), 핸들러 데이터는 여전히 직렬화 가능해야 합니다. 커스텀 응답 서브클래스와 그에 추가된 런타임 상태는 보존되지 않습니다.

탐색(seek)이 불가능한 본문 스트림은 원본 스트림이 존재하는 동안 한 번만 읽혀 캐시되므로, 공유되는 응답/통계 스냅숏과 반복되는 직렬화에서도 동일한 바이트가 유지됩니다. 첫 번째 스냅숏이 탐색 불가능한 원본 스트림을 소비하므로, 동기 리스너도 이를 읽어야 한다면 이벤트를 디스패치하기 전에 버퍼링하거나 교체하세요. 미들웨어가 이미 소비한 바이트는 복구할 수 없습니다. 탐색 가능한 스트림은 원래 위치를 유지합니다.

테스트

composer testcomposer analysecomposer format-test

정적 분석은 Larastan과 PHPStan을 레벨 10, 베이스라인 없이 사용해 소스 코드와 설정을 검사합니다. CI는 PHP 8.4와 8.5에서 테스트와 정적 분석을 실행하고, PHP 8.4에서 코드 포맷을 확인합니다.

패키지의 포맷 규칙을 적용하려면 composer format을 실행하세요.

웹훅 테스트

자동화된 테스트에서 이 패키지를 사용할 때는, 실제 웹사이트로 웹훅이 전송되지 않도록 다음 중 하나를 수행하는 것이 좋습니다.

Bus

use Illuminate\Support\Facades\Bus; use Spatie\WebhookServer\CallWebhookJob; use Tests\TestCase; class TestFile extends TestCase { public function testJobIsDispatched() { Bus::fake(); ... Perform webhook call ... Bus::assertDispatched(CallWebhookJob::class); } }

Queue

use Illuminate\Support\Facades\Queue; use Spatie\WebhookServer\CallWebhookJob; use Tests\TestCase; class TestFile extends TestCase { public function testJobIsQueued() { Queue::fake(); ... Perform webhook call ... Queue::assertPushed(CallWebhookJob::class); } }

Http

웹훅은 Laravel의 HTTP 클라이언트로 전송되므로, Job을 그대로 실행시킨 뒤 실제로 보낸 요청을 검증할 수도 있습니다.

use Illuminate\Http\Client\Request; use Illuminate\Support\Facades\Http; use Tests\TestCase; class TestFile extends TestCase { public function testWebhookIsSent() { Http::fake(); ... Perform webhook call ... Http::assertSent(fn (Request $request) => $request->url() === 'https://other-app.com/webhooks'); } }

변경 이력

최근 변경 사항은 CHANGELOG를 참고하세요.

기여하기

자세한 내용은 CONTRIBUTING을 참고하세요.

보안

보안 관련 문제를 발견하셨다면 이슈 트래커 대신 freek@spatie.be로 이메일을 보내 주세요.

엽서웨어(Postcardware)

이 패키지는 자유롭게 사용할 수 있습니다. 다만 프로덕션 환경에서 사용하게 되었다면, 고향에서 보낸 엽서에 사용 중인 Spatie 패키지 이름을 적어 보내 주시면 큰 힘이 됩니다.

주소는 다음과 같습니다: Spatie, Kruikstraat 22, 2018 Antwerp, Belgium.

받은 모든 엽서는 회사 웹사이트에 게시합니다.

크레딧

라이선스

MIT 라이선스(MIT)를 따릅니다. 자세한 내용은 라이선스 파일을 참고하세요.