TANITARDevelopers
WebhooksEvent catalogShop

shop.order.reversed

Version 1 of the shop.order.reversed webhook event.

A settled Shop order was undone: by an attributed operator reversal, or by the Player's own self-cancel of a manual order an operator had not yet claimed. The currency is always credited back through one compensating, idempotent ledger operation; goods recovery is kind-dependent and stated per line - an award is revoked, a manual item was never delivered, and a delivered code cannot be un-delivered, so the loss is recorded and accepted explicitly. The consumed code itself is never disclosed here.

Event typeshop.order.reversed
Schema version1
Routing keyevent.shop.order.reversed.v1
Produced byReward Management
Schemaurn:defendr:contract:shop:order-reversed:1

data fields

FieldTypeRequiredDescription
orderIdstringyes
playerIdstringyes
initiator"operator", "player"yes
actorIdstring or nullyesThe operator who reversed the order; null for a Player self-cancel, whose actor is the Player already named by playerId.
reasonCodestringyes
reasonstringyes
refundarray of objectyesThe compensating credit returned to the Player's wallet, per currency leg.
refund[].currencyKeystringyes
refund[].amountstringyesA whole amount of the tenant's published currency, as a decimal string.
linesarray of objectyes
lines[].listingKeystringyes
lines[].fulfillmentKind"award", "code", "manual"yes
lines[].recovery"award-revoked", "never-delivered", "code-loss-accepted"yes
reversedAtstring (date-time)yes

Some fields are required only in particular states. The JSON Schema below is authoritative.

Example delivery

Signed with the example secret whsec_placeholder_example_webhooks_signing_secret, so you can check your verifier against it. See Verifying signatures.

POST /your/webhook/endpoint HTTP/1.1
content-type: application/json
webhook-id: whd_00000000-0000-4000-8000-000000000030
webhook-timestamp: 1800000000
webhook-signature: v1,paYP9zW1+MfTa5Y8rba1BHKVp0md0pNBw6x7qwXSLO4=
tanitar-event-type: shop.order.reversed
tanitar-schema-version: 1
tanitar-delivery-attempt: 1

{"messageId":"evt_00000000-0000-4000-8000-000000000030","kind":"event","type":"shop.order.reversed","schemaVersion":1,"occurredAt":"2027-01-15T10:00:00.000Z","producer":"reward-management-service","accountId":"acc_11111111-1111-4111-8111-111111111111","correlationId":"corr_00000000-0000-4000-8000-000000000030","data":{"orderId":"ord_0123456789abcdef0123456789abcdef","playerId":"player_demo","initiator":"operator","actorId":"operator_demo","reasonCode":"OPERATOR_CORRECTION","reason":"Listing was priced incorrectly.","refund":[{"currencyKey":"red","amount":"400"}],"lines":[{"listingKey":"founder-badge","fulfillmentKind":"award","recovery":"award-revoked"}],"reversedAt":"2026-09-27T00:00:00.000Z"}}

The same body, formatted:

{
  "messageId": "evt_00000000-0000-4000-8000-000000000030",
  "kind": "event",
  "type": "shop.order.reversed",
  "schemaVersion": 1,
  "occurredAt": "2027-01-15T10:00:00.000Z",
  "producer": "reward-management-service",
  "accountId": "acc_11111111-1111-4111-8111-111111111111",
  "correlationId": "corr_00000000-0000-4000-8000-000000000030",
  "data": {
    "orderId": "ord_0123456789abcdef0123456789abcdef",
    "playerId": "player_demo",
    "initiator": "operator",
    "actorId": "operator_demo",
    "reasonCode": "OPERATOR_CORRECTION",
    "reason": "Listing was priced incorrectly.",
    "refund": [
      {
        "currencyKey": "red",
        "amount": "400"
      }
    ],
    "lines": [
      {
        "listingKey": "founder-badge",
        "fulfillmentKind": "award",
        "recovery": "award-revoked"
      }
    ],
    "reversedAt": "2026-09-27T00:00:00.000Z"
  }
}

JSON Schema

urn:defendr:contract:shop:order-reversed:1
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:defendr:contract:shop:order-reversed:1",
  "title": "Shop order reversed",
  "description": "A settled Shop order was undone: by an attributed operator reversal, or by the Player's own self-cancel of a manual order an operator had not yet claimed. The currency is always credited back through one compensating, idempotent ledger operation; goods recovery is kind-dependent and stated per line - an `award` is revoked, a `manual` item was never delivered, and a delivered `code` cannot be un-delivered, so the loss is recorded and accepted explicitly. The consumed code itself is never disclosed here.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "orderId",
    "playerId",
    "initiator",
    "actorId",
    "reasonCode",
    "reason",
    "refund",
    "lines",
    "reversedAt"
  ],
  "properties": {
    "orderId": {
      "type": "string",
      "pattern": "^ord_[a-f0-9]{32}$"
    },
    "playerId": {
      "type": "string",
      "minLength": 1
    },
    "initiator": {
      "enum": [
        "operator",
        "player"
      ]
    },
    "actorId": {
      "type": [
        "string",
        "null"
      ],
      "description": "The operator who reversed the order; null for a Player self-cancel, whose actor is the Player already named by `playerId`."
    },
    "reasonCode": {
      "type": "string",
      "pattern": "^[A-Z0-9_]+$"
    },
    "reason": {
      "type": "string",
      "minLength": 1
    },
    "refund": {
      "type": "array",
      "minItems": 1,
      "description": "The compensating credit returned to the Player's wallet, per currency leg.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "currencyKey",
          "amount"
        ],
        "properties": {
          "currencyKey": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9-]*$"
          },
          "amount": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "A whole amount of the tenant's published currency, as a decimal string."
          }
        }
      }
    },
    "lines": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "listingKey",
          "fulfillmentKind",
          "recovery"
        ],
        "properties": {
          "listingKey": {
            "type": "string",
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
          },
          "fulfillmentKind": {
            "enum": [
              "award",
              "code",
              "manual"
            ]
          },
          "recovery": {
            "enum": [
              "award-revoked",
              "never-delivered",
              "code-loss-accepted"
            ]
          }
        },
        "allOf": [
          {
            "if": {
              "type": "object",
              "required": [
                "fulfillmentKind"
              ],
              "properties": {
                "fulfillmentKind": {
                  "const": "award"
                }
              }
            },
            "then": {
              "type": "object",
              "properties": {
                "recovery": {
                  "const": "award-revoked"
                }
              }
            }
          },
          {
            "if": {
              "type": "object",
              "required": [
                "fulfillmentKind"
              ],
              "properties": {
                "fulfillmentKind": {
                  "const": "manual"
                }
              }
            },
            "then": {
              "type": "object",
              "properties": {
                "recovery": {
                  "const": "never-delivered"
                }
              }
            }
          },
          {
            "if": {
              "type": "object",
              "required": [
                "fulfillmentKind"
              ],
              "properties": {
                "fulfillmentKind": {
                  "const": "code"
                }
              }
            },
            "then": {
              "type": "object",
              "properties": {
                "recovery": {
                  "const": "code-loss-accepted"
                }
              }
            }
          }
        ]
      }
    },
    "reversedAt": {
      "type": "string",
      "format": "date-time"
    }
  },
  "allOf": [
    {
      "if": {
        "type": "object",
        "required": [
          "initiator"
        ],
        "properties": {
          "initiator": {
            "const": "player"
          }
        }
      },
      "then": {
        "type": "object",
        "properties": {
          "actorId": {
            "type": "null"
          }
        }
      }
    },
    {
      "if": {
        "type": "object",
        "required": [
          "initiator"
        ],
        "properties": {
          "initiator": {
            "const": "operator"
          }
        }
      },
      "then": {
        "type": "object",
        "properties": {
          "actorId": {
            "type": "string"
          }
        }
      }
    }
  ]
}

On this page