Skip to main content

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.

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.

Transaction charge

TRANSACTION_CHARGE_REQUESTED

A synchronous webhook called inside a Celery 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 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 object. The new TransactionEvent object will have provided pspReference, and will be used in the recalculation of the transaction's amount process.

Request

Saleor will send a TRANSACTION_CHARGE_REQUESTED webhook by using the TransactionChargeRequested 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.

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

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

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

{
"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"
}
}
Expand ▼

Response

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 mutation.

The response in this case should have the following structure:

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

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 or CHARGE_FAILURE), and amount fields.

The response in this case should have the following structure:

{
"pspReference": "<[Optional for CHARGE_FAILURE] psp reference recieved from payment provider>",
"result": "<CHARGE_SUCCESS or CHARGE_FAILURE>",
"amount": "<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>"
}
caution

In the case when one of result, amount is provided and the second one is missing, the response will not be processed, and Saleor will create the failure event.

Transaction cancelation

TRANSACTION_CANCELATION_REQUESTED

A synchronous webhook called inside a Celery 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 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 object. The new TransactionEvent object will have provided pspReference, and will be used in the recalculation of the transaction's amount process.

Request

Saleor will send a TRANSACTION_CANCEL_REQUESTED webhook by using the TransactionCancelationRequested 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.

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

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

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

{
"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"
}
}
Expand ▼

Response

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 mutation.

The response in this case should have the following structure:

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

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 or CANCEL_FAILURE), and amount fields.

The response in this case should have the following structure:

{
"pspReference": "<[Optional for CANCEL_FAILURE] psp reference recieved from payment provider>",
"result": "<CANCEL_SUCCESS or CANCEL_FAILURE>",
"amount": "<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>"
}
caution

In the case when one of result, amount is provided and the second one is missing, the response will not be processed, and Saleor will create the failure event.

Transaction refund

TRANSACTION_REFUND_REQUESTED

A synchronous webhook called inside a Celery 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 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 object. The new TransactionEvent object will have provided pspReference, and will be used in the recalculation of the transaction's amount process.

Request

Saleor will send a TRANSACTION_REFUND_REQUESTED webhook by using the TransactionRefundRequested subscription type or with a pre-defined payload in case of a missing subscription query.

More details about building webhook subscription query can be found here.

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

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
}
}
}
}
}
}
}
}
Expand ▼
note

grantedRefund - This field contains the details about OrderGrantedRefund related to the the refund request action. The field will contain OrderGrantedRefund when a refund request was triggered by calling transactionRequestRefundForGrantedRefund mutation.

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

{
"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"
}
}
Expand ▼

Response

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 mutation.

The response in this case should have the following structure:

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

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 or REFUND_FAILURE), and amount fields.

The response in this case should have the following structure:

{
"pspReference": "<[Optional for REFUND_FAILURE] psp reference recieved from payment provider>",
"result": "<REFUND_SUCCESS or REFUND_FAILURE>",
"amount": "<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>"
}
caution

In the case when one of result, amount is provided and the second one is missing, the response will not be processed, and Saleor will create the failure event.

Initialize payment gateway session

PAYMENT_GATEWAY_INITIALIZE_SESSION

The synchronous 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.

Request

Saleor will send a PAYMENT_GATEWAY_INITIALIZE_SESSION webhook by using the PaymentGatewayInitializeSession subscription type or with a pre-defined payload in case of a missing subscription query.

More details about building webhook subscription query can be found here.

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

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

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

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

Response

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

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

Initialize transaction session

TRANSACTION_INITIALIZE_SESSION

The synchronous TRANSACTION_INITIALIZE_SESSION webhook is called when a customer begins processing a payment by calling the transactionInitialize 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.

Request

Saleor will send a TRANSACTION_INITIALIZE_SESSION webhook by using the TransactionInitializeSession subscription type or with a pre-defined payload in case of a missing subscription query.

More details about building webhook subscription query can be found here.

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

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
}
}
}
}
Expand ▼

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

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

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.

The response in this case should have the following structure:

{
"pspReference": "<[Optional for some results, see details below] psp reference recieved 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": "<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>"
}

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

Process transaction session

TRANSACTION_PROCESS_SESSION

The TRANSACTION_PROCESS_SESSION webhook is called synchronously when a customer needs to process additional actions received as a response from either the transactionInitialize or transactionProcess mutations. This webhook is triggered when the customer calls the transactionProcessmutation. It contains details about theOrderorCheckoutobject related to this action, thetransactionItemobject, details related to the requested action, and thedatapassed in the mutation input. Saleor expects the response to be in the proper format. Based on the response, the amount of thetransactionItem` 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.

Request

Saleor will send a TRANSACTION_PROCESS_SESSION webhook by using the TransactionProcessSession subscription type or with a pre-defined payload in case of a missing subscription query.

More details about building webhook subscription query can be found here.

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

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
}
}
}
}
Expand ▼

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

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

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.

The response in this case should have the following structure:

{
"pspReference": "[Optional for some results, see details below] <psp reference recieved 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": "<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>"
}

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