Learn how webhooks work with KOMOJU

Webhooks allow you to subscribe to events in KOMOJU. When an event is triggered we will send your application a POST request containing a JSON object describing information about the event. Using webhooks your application can listen for important events like when a payment is captured, refunded, etc. and allow you to handle those events inside your application.

Creating a new webhook can be done from the webhooks creation page. Before creating a webhook you will need to setup an endpoint URL for your application to receive webhooks. Once you setup your endpoint URL you can create a new webhook. After creating the webhook we will immediately send you a ping event so you can test handling events.


Here is the list of events that your webhooks can subscribe to.

pingThe ping event. Used for testing.
payment.authorizedA payment was authorized.
payment.capturedA payment was captured.
payment.updatedA payment was changed.
payment.expiredA payment was expired.
payment.cancelledA payment was cancelled.
payment.refund.createdA refund was created (may be partial).
payment.refundedA payment was fully refunded.
payment.failedA payment failed.
customer.createdA customer was created.
customer.updatedA customer was updated.
customer.deletedA customer was deleted.
subscription.createdA subscription was created.
subscription.capturedA subscription was captured.
subscription.failedA subscription failed
subscription.suspendedA subscription was suspended
subscription.deletedA subscription was deleted
settlement.createdA settlement was created

Webhook Delivery

A webhook delivery is simply a POST request to your application's server containing information about the event. Each webhook delivery contains some metadata headers and a JSON object describing the event.

HTTP Headers

X-Komoju-IDUnique ID of the webhook delivery
X-Komoju-SignatureComputed SHA-2 HMAC using your security token and the request body of the webhook
X-Komoju-EventWebhook event name e.g. payment.captured

Request Body

The request body is a JSON object with the following attributes.

typeThe type of webhook event e.g. payment.captured
dataA polymorphic object, different for each event
created_atPrecise time of the event in ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ

Example Delivery

POST http://example.com/hook HTTP/1.1

Host: example.com
X-Komoju-Id: 6cul2yma626autvvxz2xre1qr
X-Komoju-Signature: 75e653443e6543ee4c4b0665c73a4818216c9464f4a3ac959bff5ebafc105693
X-Komoju-Event: payment.authorized
User-Agent: Komoju-Webhook
Content-Type: application/json
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept: */*
  "id": "dv7ywuavew3n2meqsllj5bbob",
  "type": "payment.authorized",
  "resource": "event",
  "data": {
    "id": "8xz5cn01gkt37cz0myd98k2f1",
    "resource": "payment",
    "status": "authorized",
    "amount": 1000,
    "tax": 80,
    "customer": null,
    "payment_deadline": "2018-11-20T14:59:59Z",
    "payment_details": {
      "type": "bank_transfer",
      "email": "[email protected]",
      "order_id": "Y5236584956",
      "bank_name": "三井住友銀行",
      "account_branch_name": "ひなぎく",
      "account_number": "6",
      "account_type": "普通預金",
      "account_name": "株式会社DEGICA(カブシキガイシャ デジカ)",
      "instructions_url": "https://komoju.com/ja/instructions/8xz5cn01gkt37cz0myd98k2f1"
    "payment_method_fee": 0,
    "total": 1080,
    "currency": "JPY",
    "description": null,
    "captured_at": null,
    "external_order_num": "123",
    "metadata": {
    "created_at": "2018-11-13T06:19:49Z",
    "amount_refunded": 0,
    "locale": "ja",
    "refunds": [

    "refund_requests": [

  "created_at": "2018-11-13T06:19:49Z"
POST http://example.com/hook HTTP/1.1

Host: example.com
X-Komoju-Id: 1lqjmj6k7li996cdiqxqqzf1k
X-Komoju-Signature: ee52defb62c1d48125741bfe92a13b6cbffc97b0b3a26b5cab582f766a4ae97e
X-Komoju-Event: ping
User-Agent: Komoju-Webhook
Content-Type: application/json
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept: */*
  "id": "do33foclbroj52ib9whb6yh4m",
  "type": "ping",
  "resource": "event",
  "data": {
    "id": "bll40gxhuhcw19vor5kx55akw",
    "resource": "webhook",
    "url": "http://example.com/hook",
    "active": true,
    "event_list": [
    "created_at": "2018-11-13T06:19:49Z"
  "created_at": "2018-11-13T06:19:49Z"

Secret Token

In order to ensure a webhook request came from KOMOJU we compute a SHA-2 HMAC signature using the secret token you provide when creating or updating a webhook on KOMOJU.

When the secret token is set requests will contain the customer header X-Komoju-Signature which is the computed HMAC of the request body using the secret token as the key. Using the secret token you are able to compute a signature and compare it with the one we send you.

Computing the Signature

require "sinatra"

WEBHOOK_SECRET_TOKEN = "keep it secret, keep it safe!"

post '/hook' do
  # NOTE: it's important to use the raw, unmodified request body here.
  # If you parse the body JSON and then re-encode, you might be unable to verify.
  request_body = request.body.read
  signature = OpenSSL::HMAC.hexdigest('sha256', WEBHOOK_SECRET_TOKEN, request_body)
  return 400 unless Rack::Utils.secure_compare(signature, request.env["HTTP_X_KOMOJU_SIGNATURE"])

  "Hello World"


In the event your server doesn’t respond with a successfull status code or KOMOJU is unable to establish a connection with your server, we will keep retrying the webhook 25 times before giving up. Each interval between attempts gets longer with the last interval lasting 100 hours. You will receive the last retry attempt 25 days later before the delivery is marked as failed.

In the case your server returned a non-error response code but did not process the event you can always re-deliver a webhook from the dashboard by viewing a payment.

KOMOJU's IP Addresses

Although we do provide IP addresses for our webhook servers we strongly recommend against IP-based access control. We encourage merchants to instead check use the method outlined in the Secret Token section to ensure a webhooks authenticity.

Please note that the following IP addresses may change without notice due to unavoidable circumstances.