> Documentation index: [Saleor](/llms.txt) · [This section](/developer/llms.txt)
> Source: https://docs.saleor.io/developer/extending/webhooks/synchronous-events/transaction

# Transaction events

Transaction webhooks are synchronous webhooks that allow delegating the transaction's action to the Saleor App. Synchronous means that these webhooks expect a response of a particular shape to be returned from the App to continue processing in Saleor. Transaction webhooks only support the HTTP(S) protocol; they are sent as POST requests with the `application/json` body and expect the response of the same content type.

<a id="key-concepts"></a>

## Key concepts

The `HANDLE_PAYMENTS` permission is required for the App to receive transaction webhooks. The webhook notification is only sent to a specific app connected to a given transaction.

The usage of the webhook is strictly related to the payment flow handled by transactions. You can find more details about the transaction flow in the [_Payments_ documentation](/developer/payments/overview.md).

<a id="transaction-charge"></a>

## Transaction charge

`TRANSACTION_CHARGE_REQUESTED`

A synchronous webhook called inside a background task. It is triggered when a staff user requests the charge action.

The webhook expects to return at least the `pspReference` in the response. The `pspReference` will be attached to [`TransactionEvent`](/api-reference/payments/objects/transaction-event.md) with request details. When `pspReference` is attached to the `request` object, it means the app has successfully processed the webhook.

Optionally the result data can be provided. The data is used to provide the final status of the requested action, and it will be used to create a new [`TransactionEvent`](/api-reference/payments/objects/transaction-event.md) object. The new [`TransactionEvent`](/api-reference/payments/objects/transaction-event.md) object will have provided `pspReference`, and will be used in the [recalculation of the transaction's amount process](/developer/payments/lifecycle.md#transactions-recalculation-of-amounts).

<a id="request"></a>

### Request

Saleor will send a [`TRANSACTION_CHARGE_REQUESTED`](/api-reference/webhooks/enums/webhook-event-type-sync-enum.md#transaction-charge-requested) webhook by using the [`TransactionChargeRequested`](/api-reference/payments/objects/transaction-charge-requested.md) subscription type or with a pre-defined payload in case of a missing subscription query.

You can find more details about building webhook subscription queries in [subscription webhook payloads](/developer/extending/webhooks/subscription-webhook-payloads.md).

The example below shows a sample webhook subscription defined to handle charge requests:

```graphql
subscription {
  event {
    __typename
    ... on TransactionChargeRequested {
      action {
        actionType
        amount
      }
      transaction {
        id
        pspReference
        authorizedAmount {
          amount
          currency
        }
        order {
          id
        }
      }
    }
  }
}
```

The example below shows the pre-defined payload that will be used in the case when a subscription query is not provided:

```json
{
  "action": { "currency": "USD", "type": "charge", "value": "5.00" },
  "meta": {
    "issued_at": "2022-06-28T10:50:00+00:00",
    "issuing_principal": { "id": "Sample app objects", "type": "app" },
    "version": "3.13.0-a"
  },
  "transaction": {
    "authorized_value": "10.00",
    "available_actions": ["capture", "void"],
    "canceled_value": "0.00",
    "charged_value": "0.00",
    "checkout_id": null,
    "created_at": "2022-06-28T10:50:00Z",
    "currency": "USD",
    "message": "",
    "modified_at": "2022-06-28T10:50:00Z",
    "name": "Credit card",
    "order_id": "T3JkZXI6YjE1YzdlZTgtMzUxNy00MTczLWEzNWYtMmQxMDdkMWI4Yzhk",
    "psp_reference": "PSP ref",
    "reference": "PSP ref",
    "refunded_value": "0.00",
    "status": "Authorized",
    "type": "Credit card",
    "voided_value": "0.00"
  }
}
```

<a id="response"></a>

### Response

<a id="async-flow"></a>

#### Async flow

App needs to at least return the `pspReference` of the requested action. This is a common case when the payment provider doesn't return a status of the requested action in the response. In this situation, the status of the action is delivered by an asynchronous notification that should be handled by App, and passed to Saleor by using the [`transactionEventReport`](/developer/payments/transactions.md#reporting-actions-for-transactions) mutation.

The response in this case should have the following structure:

```json
{
  "pspReference": "<psp reference received from payment provider>"
}
```

<a id="sync-flow"></a>

#### Sync flow

The app has the possibility to report the status of the requested action immediately. This is a common case when the payment provider returns the status of the action in response to the requested action. The payload response has to contain at least `pspReference` (optional for `CHARGE_FAILURE`), `result` ( [`CHARGE_SUCCESS`](/api-reference/payments/enums/transaction-event-type-enum.md#charge-success) or [`CHARGE_FAILURE`](/api-reference/payments/enums/transaction-event-type-enum.md#charge-failure)). If the `amount` field is not provided, Saleor will default to using the requested amount from the original payload.

The response in this case should have the following structure:

```json
{
  "pspReference": "<[Optional for CHARGE_FAILURE] psp reference received from payment provider>",
  "result": "<CHARGE_SUCCESS or CHARGE_FAILURE>",
  "amount": "<[Optional since Saleor 3.21] Decimal amount of the processed action>",
  "time": "<[Optional] time of the action>",
  "externalUrl": "<[Optional] external url with action details>",
  "message": "<[Optional] message related to the action. The maximum length is 512 characters; any text exceeding this limit will be truncated>",
  "actions": "<[Optional] list of actions available for the transaction. Possible items: CHARGE, REFUND, CANCEL>"
}
```

<a id="transaction-cancelation"></a>

## Transaction cancelation

`TRANSACTION_CANCELATION_REQUESTED`

A synchronous webhook called inside a background task. They are called when a staff user requests the cancelation action. The webhook expects to return at least the `pspReference` in the response. The `pspReference` will be attached to [`TransactionEvent`](/api-reference/payments/objects/transaction-event.md) with request details. When `pspReference` is attached to the `request` object, it means the app has successfully processed the webhook. Optionally the result data can be provided. The data is used to provide the final status of the requested action, and it will be used to create a new [`TransactionEvent`](/api-reference/payments/objects/transaction-event.md) object. The new [`TransactionEvent`](/api-reference/payments/objects/transaction-event.md) object will have provided `pspReference`, and will be used in the [recalculation of the transaction's amount process](/developer/payments/lifecycle.md#transactions-recalculation-of-amounts).

<a id="request-1"></a>

### Request

Saleor will send a [`TRANSACTION_CANCEL_REQUESTED`](/api-reference/webhooks/enums/webhook-event-type-sync-enum.md#transaction-cancelation-requested) webhook by using the [`TransactionCancelationRequested`](/api-reference/payments/objects/transaction-cancelation-requested.md) subscription type or with a pre-defined payload in case of a missing subscription query. You can find more details about building webhook subscription query [here](/developer/extending/webhooks/subscription-webhook-payloads.md).

The example below shows a sample webhook subscription defined to handle cancelation requests:

```graphql
subscription {
  event {
    __typename
    ... on TransactionCancelationRequested {
      action {
        actionType
        amount
      }
      transaction {
        id
        pspReference
        authorizedAmount {
          amount
          currency
        }
        order {
          id
        }
      }
    }
  }
}
```

The example below shows the pre-defined payload that will be used in the case when a subscription query is not provided:

```json
{
  "action": { "currency": "USD", "type": "cancel", "value": "0.00" },
  "meta": {
    "issued_at": "2022-06-28T10:50:00+00:00",
    "issuing_principal": { "id": "Sample app objects", "type": "app" },
    "version": "3.13.0-a"
  },
  "transaction": {
    "authorized_value": "10.00",
    "available_actions": ["capture", "void"],
    "canceled_value": "0.00",
    "charged_value": "0.00",
    "checkout_id": null,
    "created_at": "2022-06-28T10:50:00Z",
    "currency": "USD",
    "message": "",
    "modified_at": "2022-06-28T10:50:00Z",
    "name": "Credit card",
    "order_id": "T3JkZXI6YWEzYzVhOTMtN2NlYS00OGZkLWJmYWUtMWFkYjI5YTRjMmY1",
    "psp_reference": "PSP ref",
    "reference": "PSP ref",
    "refunded_value": "0.00",
    "status": "Authorized",
    "type": "Credit card",
    "voided_value": "0.00"
  }
}
```

<a id="response-1"></a>

### Response

<a id="async-flow-1"></a>

#### Async flow

App needs to at least return the `pspReference` of the requested action. This is a common case when the payment provider doesn't return a status of the requested action in the response. In this situation, the status of the action is delivered by an asynchronous notification that should be handled by App, and passed to Saleor by using the [`transactionEventReport`](/developer/payments/transactions.md#reporting-actions-for-transactions) mutation.

The response in this case should have the following structure:

```json
{
  "pspReference": "<psp reference received from payment provider>"
}
```

<a id="sync-flow-1"></a>

#### Sync flow

The app has the possibility to report the status of the requested action immediately. This is a common case when the payment provider returns the status of the action in response to the requested action. The payload response has to contain at least `pspReference` (optional for `CANCEL_FAILURE`), `result` ( [`CANCEL_SUCCESS`](/api-reference/payments/enums/transaction-event-type-enum.md#cancel-success) or [`CANCEL_FAILURE`](/api-reference/payments/enums/transaction-event-type-enum.md#cancel-failure)). If the `amount` field is not provided, Saleor will default to using the requested amount from the original payload.

The response in this case should have the following structure:

```json
{
  "pspReference": "<[Optional for CANCEL_FAILURE] psp reference received from payment provider>",
  "result": "<CANCEL_SUCCESS or CANCEL_FAILURE>",
  "amount": "<[Optional since Saleor 3.21] Decimal amount of the processed action>",
  "time": "<[Optional] time of the action>",
  "externalUrl": "<[Optional] external url with action details>",
  "message": "<[Optional] message related to the action. The maximum length is 512 characters; any text exceeding this limit will be truncated.>",
  "actions": "<[Optional] list of actions available for the transaction. Possible items: CHARGE, REFUND, CANCEL>"
}
```

<a id="transaction-refund"></a>

## Transaction refund

`TRANSACTION_REFUND_REQUESTED`

A synchronous webhook called inside a background task. They are called when a staff user requests the refund action. The webhook expects to return at least the `pspReference` in the response. The `pspReference` will be attached to [`TransactionEvent`](/api-reference/payments/objects/transaction-event.md) with request details. When `pspReference` is attached to the `request` object, it means the app has successfully processed the webhook. Optionally the result data can be provided. The data is used to provide the final status of the requested action, and it will be used to create a new [`TransactionEvent`](/api-reference/payments/objects/transaction-event.md) object. The new [`TransactionEvent`](/api-reference/payments/objects/transaction-event.md) object will have provided `pspReference`, and will be used in the [recalculation of the transaction's amount process](/developer/payments/lifecycle.md#transactions-recalculation-of-amounts).

<a id="request-2"></a>

### Request

Saleor will send a [`TRANSACTION_REFUND_REQUESTED`](/api-reference/webhooks/enums/webhook-event-type-sync-enum.md#transaction-refund-requested) webhook by using the [`TransactionRefundRequested`](/api-reference/payments/objects/transaction-refund-requested.md) subscription type or with a pre-defined payload in case of a missing subscription query.

More details about building webhook subscription queries can be found in [subscription webhook payloads](/developer/extending/webhooks/subscription-webhook-payloads.md).

The example below shows a sample webhook subscription defined to handle refund requests:

```graphql
subscription {
  event {
    __typename
    ... on TransactionRefundRequested {
      action {
        actionType
        amount
      }
      transaction {
        id
        pspReference
        chargedAmount {
          amount
          currency
        }
        order {
          id
        }
      }
      grantedRefund {
        id
        amount {
          amount
        }
        lines {
          id
          quantity
          orderLine {
            unitPrice {
              gross {
                amount
              }
            }
          }
        }
      }
    }
  }
}
```

note

`grantedRefund` - This field contains the details about [`OrderGrantedRefund`](/api-reference/orders/objects/order-granted-refund.md) related to the the refund request action. The field will contain OrderGrantedRefund when a refund request was triggered by calling [`transactionRequestRefundForGrantedRefund`](/api-reference/payments/mutations/transaction-request-refund-for-granted-refund.md) mutation.

The example below shows the pre-defined payload that will be used in the case when a subscription query is not provided:

```json
{
  "action": { "currency": "USD", "type": "refund", "value": "9.00" },
  "meta": {
    "issued_at": "2022-06-28T10:50:00+00:00",
    "issuing_principal": { "id": "Sample app objects", "type": "app" },
    "version": "3.13.0-a"
  },
  "transaction": {
    "authorized_value": "10.00",
    "available_actions": ["capture", "void"],
    "canceled_value": "0.00",
    "charged_value": "0.00",
    "checkout_id": null,
    "created_at": "2022-06-28T10:50:00Z",
    "currency": "USD",
    "message": "",
    "modified_at": "2022-06-28T10:50:00Z",
    "name": "Credit card",
    "order_id": "T3JkZXI6NjdlYTYxNDAtMzEwZi00YTRlLThmODktNTU2NjliMjk4NjU5",
    "psp_reference": "PSP ref",
    "reference": "PSP ref",
    "refunded_value": "0.00",
    "status": "Authorized",
    "type": "Credit card",
    "voided_value": "0.00"
  }
}
```

<a id="response-2"></a>

### Response

<a id="async-flow-2"></a>

#### Async flow

App needs to at least return the `pspReference` of the requested action. This is a common case when the payment provider doesn't return a status of the requested action in the response. In this situation, the status of the action is delivered by an asynchronous notification that should be handled by App, and passed to Saleor by using the [`transactionEventReport`](/developer/payments/transactions.md#reporting-actions-for-transactions) mutation.

The response in this case should have the following structure:

```json
{
  "pspReference": "<psp reference received from payment provider>"
}
```

<a id="sync-flow-2"></a>

#### Sync flow

The app has the possibility to report the status of the requested action immediately. This is a common case when the payment provider returns the status of the action in response to the requested action. The payload response has to contain at least `pspReference` (optional for `REFUND_FAILURE`), `result` ( [`REFUND_SUCCESS`](/api-reference/payments/enums/transaction-event-type-enum.md#refund-success) or [`REFUND_FAILURE`](/api-reference/payments/enums/transaction-event-type-enum.md#refund-failure)). If the `amount` field is not provided, Saleor will default to using the requested amount from the original payload.

The response in this case should have the following structure:

```json
{
  "pspReference": "<[Optional for REFUND_FAILURE] psp reference received from payment provider>",
  "result": "<REFUND_SUCCESS or REFUND_FAILURE>",
  "amount": "<[Optional since Saleor 3.21] Decimal amount of the processed action>",
  "time": "<[Optional] time of the action>",
  "externalUrl": "<[Optional] external url with action details>",
  "message": "<[Optional] message related to the action. The maximum length is 512 characters; any text exceeding this limit will be truncated>",
  "actions": "<[Optional] list of actions available for the transaction. Possible items: CHARGE, REFUND, CANCEL>"
}
```

<a id="initialize-payment-gateway-session"></a>

## Initialize payment gateway session

`PAYMENT_GATEWAY_INITIALIZE_SESSION`

The synchronous [`PAYMENT_GATEWAY_INITIALIZE_SESSION`](/api-reference/webhooks/enums/webhook-event-type-sync-enum.md#payment-gateway-initialize-session) webhook is called when a customer requests payment gateway initialization by calling the `paymentGatewayInitialize` mutation. The webhook contains details about the object (`Order`/`Checkout`) for which the payment gateway initialization was requested, the requested amount, and the `data` received from the frontend. As a response, the webhook expects the `data` field with all initialization details that will be passed to the storefront.

<a id="request-3"></a>

### Request

Saleor will send a [`PAYMENT_GATEWAY_INITIALIZE_SESSION`](/api-reference/webhooks/enums/webhook-event-type-sync-enum.md#payment-gateway-initialize-session) webhook by using the [`PaymentGatewayInitializeSession`](/api-reference/payments/objects/payment-gateway-initialize-session.md) subscription type or with a pre-defined payload in case of a missing subscription query.

More details about building webhook subscription queries can be found in [subscription webhook payloads](/developer/extending/webhooks/subscription-webhook-payloads.md).

The example below shows a sample webhook subscription defined to handle payment gateway initialization requests:

```graphql
subscription PaymentGatewayInitialize {
  event {
    ... on PaymentGatewayInitializeSession {
      sourceObject {
        __typename
        ... on Checkout {
          id
          totalPrice {
            gross {
              amount
            }
          }
        }
        ... on Order {
          id
          total {
            gross {
              amount
            }
          }
        }
      }
      data
      amount
    }
  }
}
```

The example below shows the pre-defined payload that will be used in the case when a subscription query is not provided:

```json
{
  "id": "T3JkZXI6NGI2ZjEzMDctMTA1Yi00NGU4LWFlZjAtYWNjMGJmYjUwMjY1",
  "data": {
    "some": "request-data"
  },
  "amount": "10.00"
}
```

<a id="response-3"></a>

### Response

The app needs to return the `data` field. The `data` received from the webhook will be returned as a `paymentGatewayInitialize` mutation response.

```json
{
  "data": {
    "some": "init-data"
  }
}
```

<a id="initialize-transaction-session"></a>

## Initialize transaction session

`TRANSACTION_INITIALIZE_SESSION`

The synchronous [`TRANSACTION_INITIALIZE_SESSION`](/api-reference/webhooks/enums/webhook-event-type-sync-enum.md#transaction-initialize-session) webhook is called when a customer begins processing a payment by calling the [`transactionInitialize`](/developer/payments/payment-apps.md#initialize-transaction) mutation. The webhook contains details about the object (`Order`/`Checkout`) related to this action, the `transactionItem` object, details related to the requested action, and the `data` passed in the mutation input. Saleor expects the response to be in the proper format. Based on the response, the `transactionItem`'s amount can be marked as fully covered or marked as a transaction that requires additional actions from the customer, such as processing 3D secure action.

note

The `idempotencyKey` should be passed to the payment provider to recognize the retries of the same request.

<a id="request-4"></a>

### Request

Saleor will send a [`TRANSACTION_INITIALIZE_SESSION`](/api-reference/webhooks/enums/webhook-event-type-sync-enum.md#transaction-initialize-session) webhook by using the [`TransactionInitializeSession`](/api-reference/payments/objects/transaction-initialize-session.md) subscription type or with a pre-defined payload in case of a missing subscription query.

More details about building webhook subscription queries can be found in [subscription webhook payloads](/developer/extending/webhooks/subscription-webhook-payloads.md).

The example below shows a sample webhook subscription defined to handle transaction initialization requests:

```graphql
subscription TransactionInitialize {
  event {
    ... on TransactionInitializeSession {
      sourceObject {
        __typename
        ... on Checkout {
          id
          totalPrice {
            gross {
              amount
            }
          }
        }
        ... on Order {
          id
          total {
            gross {
              amount
            }
          }
        }
      }
      idempotencyKey
      data
      customerIpAddress
      merchantReference
      action {
        amount
        currency
        actionType
      }
      transaction {
        id
      }
    }
  }
}
```

The example below shows the pre-defined payload that will be used in the case when a subscription query is not provided:

```json
{
  "id": "Q2hlY2tvdXQ6Mjk2OWFkNTAtZTQwYS00ZThkLTgwNWItYjk5ZDI0ZGYwOTdm",
  "data": {
    "some": "request-data"
  },
  "amount": "10.00",
  "currency": "USD",
  "action_type": "CHARGE",
  "transaction_id": "VHJhbnNhY3Rpb25JdGVtOjNiZDUyNjQ2LTUxM2YtNGE1Ni1hOWUzLWY3NzEwN2Y2NTAxNA=="
}
```

<a id="response-4"></a>

### Response

The app must return a response in a specified format. Based on the payload, Saleor will determine the current status of the transaction. If the format is incorrect or the response is missing, Saleor will create either a `CHARGE_FAILURE` or `AUTHORIZATION_FAILURE` event, depending on the type of action that was requested. If the `amount` field is not provided, Saleor will default to using the requested amount from the original payload.

The response in this case should have the following structure:

```json
{
  "pspReference": "<[Optional for some results, see details below] <psp reference received from payment provider>",
  "result": "CHARGE_SUCCESS or CHARGE_FAILURE or CHARGE_REQUEST or AUTHORIZATION_SUCCESS or AUTHORIZATION_FAILURE or AUTHORIZATION_REQUEST or AUTHORIZATION_ACTION_REQUIRED or CHARGE_ACTION_REQUIRED>",
  "amount": "<[Optional since Saleor 3.21] Decimal amount of the processed action>",
  "data": "<[Optional] JSON data tha will be returned to storefront>",
  "time": "<[Optional] time of the action>",
  "externalUrl": "<[Optional] external url with action details.",
  "message": "<[Optional] message related to the action. The maximum length is 512 characters; any text exceeding this limit will be truncated>",
  "actions": "<[Optional] list of actions available for the transaction. Possible items: CHARGE, REFUND, CANCEL>",
  "paymentMethodDetails": "<[Optional]> information about the payment method used for this transaction."
}
```

Below are the possible `result` values and their explanations:

-   `result:CHARGE_SUCCESS`: The funds have been successfully charged. The event amount will be added to `transaction.chargedAmount`.
-   `result:AUTHORIZATION_SUCCESS`: The funds have been successfully authorized. The event amount will be added to `transaction.authorizedAmount`.
-   `result:CHARGE_REQUEST`: A charge has been requested. The event amount will be added to `transaction.chargePendingAmount`.
-   `result:AUTHORIZATION_REQUEST`: An authorization has been requested. The event amount will be added to `transaction.authorizePendingAmount`.
-   `result:AUTHORIZATION_ACTION_REQUIRED`: Additional actions are required from the customer to authorize the payment. Before finalizing these additional actions, the payment is treated as not processed.
-   `result:CHARGE_ACTION_REQUIRED`: Additional actions are required from the customer to charge the payment. Before finalizing these additional actions, the payment is treated as not processed.
-   `result:CHARGE_FAILURE`: Charging the payment has failed.
-   `result:AUTHORIZATION_FAILURE`: Authorizing the payment has failed.

The `pspReference` is required for the following `results`:

-   `result:CHARGE_SUCCESS`
-   `result:AUTHORIZATION_SUCCESS`
-   `result:CHARGE_REQUEST`
-   `result:AUTHORIZATION_REQUEST`

The `pspReference` is optional for the following `results`:

-   `result:AUTHORIZATION_ACTION_REQUIRED`
-   `result:CHARGE_ACTION_REQUIRED`
-   `result:CHARGE_FAILURE`
-   `result:AUTHORIZATION_FAILURE`

Below are the possible values for `paymentMethodDetails` and their descriptions. Saleor supports two types of payment method details: `CARD` and `OTHER`:

-   When `type` is `CARD`:

```json
"paymentMethodDetails": {
    "type": "CARD",
    "name": "Name of the payment method used for the transaction. Max length is 256 characters.",
    "brand": "<[Optional]> brand of the payment method used for the transaction. Max length is 40 characters.",
    "firstDigits": "<[Optional]> first digits of the card used for the transaction. Max length is 4 characters.",
    "lastDigits": "<[Optional]> last digits of the card used for the transaction. Max length is 4 characters.",
    "expMonth": "<[Optional]> expiration month of the card used for the transaction. Value must be between 1 and 12.",
    "expYear": "<[Optional]> expiration year of the card used for the transaction. Value must be between 2000 and 9999.",
}
```

-   When `type` is `OTHER`:

```json
"paymentMethodDetails": {
  "type": "OTHER",
  "name": "Name of the payment method used for the transaction. Max length is 256 characters."
}
```

The provided `paymentMethodDetails` are stored on the `TransactionItem` object and accessible via the `TransactionItem.paymentMethodDetails` field.

<a id="process-transaction-session"></a>

## Process transaction session

`TRANSACTION_PROCESS_SESSION`

The [`TRANSACTION_PROCESS_SESSION`](/api-reference/webhooks/enums/webhook-event-type-sync-enum.md#transaction-process-session) webhook is called synchronously when a customer needs to process additional actions received as a response from either the [`transactionInitialize`](/developer/payments/payment-apps.md#initialize-transaction) or `transactionProcess` mutations. This webhook is triggered when the customer calls the `transactionProcess` mutation. It contains details about the `Order` or `Checkout` object related to this action, the `transactionItem` object, details related to the requested action, and the `data` passed in the mutation input. Saleor expects the response to be in the proper format. Based on the response, the amount of the `transactionItem` can be marked as fully covered or marked as a transaction that requires additional actions from the customer, such as processing a 3D secure action.

<a id="request-5"></a>

### Request

Saleor will send a [`TRANSACTION_PROCESS_SESSION`](/api-reference/webhooks/enums/webhook-event-type-sync-enum.md#transaction-process-session) webhook by using the [`TransactionProcessSession`](/api-reference/payments/objects/transaction-process-session.md) subscription type or with a pre-defined payload in case of a missing subscription query.

More details about building webhook subscription queries can be found in [subscription webhook payloads](/developer/extending/webhooks/subscription-webhook-payloads.md).

The example below shows a sample webhook subscription defined to handle transaction process requests:

```graphql
subscription TransactionProcess {
  event {
    ... on TransactionProcessSession {
      sourceObject {
        __typename
        ... on Checkout {
          id
          totalPrice {
            gross {
              amount
            }
          }
        }
        ... on Order {
          id
          total {
            gross {
              amount
            }
          }
        }
      }
      data
      customerIpAddress
      merchantReference
      action {
        amount
        currency
        actionType
      }
      transaction {
        id
      }
    }
  }
}
```

The example below shows the pre-defined payload that will be used in the case when a subscription query is not provided:

```json
{
  "id": "Q2hlY2tvdXQ6NzMyNGJlMWMtMjg3Yy00NDQxLTkwOWYtMDhmYjg0YjNhYjNl",
  "data": {
    "some": "request-data"
  },
  "amount": "10.00",
  "currency": "USD",
  "action_type": "CHARGE",
  "transaction_id": "VHJhbnNhY3Rpb25JdGVtOjRhODMxNThkLTU0NTAtNDU2Mi04MDE5LTAzYzY4NjMyZjA1Mg=="
}
```

<a id="response-5"></a>

### Response

The app must return a response in a specified format. Based on the payload, Saleor will determine the current status of the transaction. If the format is incorrect or the response is missing, Saleor will create either a `CHARGE_FAILURE` or `AUTHORIZATION_FAILURE` event, depending on the type of action that was requested. If the `amount` field is not provided, Saleor will default to using the requested amount from the original payload.

The response in this case should have the following structure:

```json
{
  "pspReference": "<[Optional for some results, see details below] <psp reference received from payment provider>",
  "result": "CHARGE_SUCCESS or CHARGE_FAILURE or CHARGE_REQUEST or AUTHORIZATION_SUCCESS or AUTHORIZATION_FAILURE or AUTHORIZATION_REQUEST or AUTHORIZATION_ACTION_REQUIRED or CHARGE_ACTION_REQUIRED>",
  "amount": "<[Optional since Saleor 3.21] Decimal amount of the processed action>",
  "data": "<[Optional] JSON data tha will be returned to storefront>",
  "time": "<[Optional] time of the action>",
  "externalUrl": "<[Optional] external url with action details.",
  "message": "<[Optional] message related to the action. The maximum length is 512 characters; any text exceeding this limit will be truncated>",
  "actions": "<[Optional] list of actions available for the transaction. Possible items: CHARGE, REFUND, CANCEL>",
  "paymentMethodDetails": "<[Optional]> information about the payment method used for this transaction."
}
```

Below are the possible `result` values and their explanations:

-   `result:CHARGE_SUCCESS`: The funds have been successfully charged. The event amount will be added to `transaction.chargedAmount`.
-   `result:AUTHORIZATION_SUCCESS`: The funds have been successfully authorized. The event amount will be added to `transaction.authorizedAmount`.
-   `result:CHARGE_REQUEST`: A charge has been requested. The event amount will be added to `transaction.chargePendingAmount`.
-   `result:AUTHORIZATION_REQUEST`: An authorization has been requested. The event amount will be added to `transaction.authorizePendingAmount`.
-   `result:AUTHORIZATION_ACTION_REQUIRED`: Additional actions are required from the customer to authorize the payment. Before finalizing these additional actions, the payment is treated as not processed.
-   `result:CHARGE_ACTION_REQUIRED`: Additional actions are required from the customer to charge the payment. Before finalizing these additional actions, the payment is treated as not processed.
-   `result:CHARGE_FAILURE`: Charging the payment has failed.
-   `result:AUTHORIZATION_FAILURE`: Authorizing the payment has failed.

The `pspReference` is required for the following `results`:

-   `result:CHARGE_SUCCESS`
-   `result:AUTHORIZATION_SUCCESS`
-   `result:CHARGE_REQUEST`
-   `result:AUTHORIZATION_REQUEST`

The `pspReference` is optional for the following `results`:

-   `result:AUTHORIZATION_ACTION_REQUIRED`
-   `result:CHARGE_ACTION_REQUIRED`
-   `result:CHARGE_FAILURE`
-   `result:AUTHORIZATION_FAILURE`

Below are the possible values for `paymentMethodDetails` and their descriptions. Saleor supports two types of payment method details: `CARD` and `OTHER`:

-   When `type` is `CARD`:

```json
"paymentMethodDetails": {
    "type": "CARD",
    "name": "Name of the payment method used for the transaction. Max length is 256 characters.",
    "brand": "<[Optional]> brand of the payment method used for the transaction. Max length is 40 characters.",
    "firstDigits": "<[Optional]> first digits of the card used for the transaction. Max length is 4 characters.",
    "lastDigits": "<[Optional]> last digits of the card used for the transaction. Max length is 4 characters.",
    "expMonth": "<[Optional]> expiration month of the card used for the transaction. Value must be between 1 and 12.",
    "expYear": "<[Optional]> expiration year of the card used for the transaction. Value must be between 2000 and 9999.",
}
```

-   When `type` is `OTHER`:

```json
"paymentMethodDetails": {
  "type": "OTHER",
  "name": "Name of the payment method used for the transaction. Max length is 256 characters."
}
```

The provided `paymentMethodDetails` are stored on the `TransactionItem` object and accessible via the `TransactionItem.paymentMethodDetails` field.
