Payment events (legacy)
This is legacy API documentation for reference only for those that built python payment plugins.
Introduction
Payment webhooks are synchronously sent webhooks that allow delegating payment handling to Saleor Apps. Synchronous means that these webhooks expect a response of a particular shape to be returned from the App to continue processing in Saleor. Payment webhooks only support the HTTP(S) protocol, they are sent as POST requests with the application/json
body and expect a response of the same content type.
Available payment events are:
Name | Description |
---|---|
PAYMENT_AUTHORIZE | Authorize payment |
PAYMENT_CAPTURE | Capture payment |
PAYMENT_CONFIRM | Confirm payment |
PAYMENT_LIST_GATEWAYS | List payment gateways |
PAYMENT_PROCESS | Process payment |
PAYMENT_REFUND | Refund payment |
PAYMENT_VOID | Void payment |
First, you need to create an App to react to payment webhooks. You can read more about apps here.
Remember to make the App active and grant it the HANDLE_PAYMENTS
permission.
Register PAYMENT_LIST_GATEWAYS
webhook
When enabling payment webhooks, first, you need to subscribe to the PAYMENT_LIST_GATEWAYS
event. This event is called whenever Saleor lists available payment gateways in the API or internal use. This webhook needs to return information about payment methods defined in your App.
Below are two example cases when the PAYMENT_LIST_GATEWAYS
event is triggered:
Listing all available payment gateways
This query returns information about available payment gateways without any additional context:
{
shop {
availablePaymentGateways(currency: "USD", channel: "default-channel") {
name
id
config {
field
value
}
currencies
}
}
}
The availablePaymentGateways
field accepts the optional currency
argument. If provided, it will be passed in the webhook payload and can be used to return payment methods that support a particular currency.
Listing available payment gateways for a checkout
You can also query for the available payment gateways in the context of a specific checkout. It is helpful if payment methods depend on the current checkout (e.g. user’s shipping country etc.)
{
checkout(token: "checkout-uuid-token") {
availablePaymentGateways {
name
}
}
}
See the example payload sent from Saleor for this event: List payment gateways payload.
Expected webhook response
In the response, you should return a list of the supported payment methods, for example:
[
{
"id": "credit-card",
"name": "Credit Card",
"currencies": ["EUR"],
"config": []
},
{
"id": "apple-pay",
"name": "Apple Pay",
"currencies": ["EUR", "USD"],
"config": [
{
"field": "apple-pay-config-field",
"value": "value"
}
]
}
]
Each item on the list should have the following fields:
id
- the ID of a payment method. Must be unique within your App.name
- the name of the payment method.currencies
- a list of currencies supported by this payment method.config
- optional configuration, such as additional payment data that may be needed to proceed with the payment in the frontend.
Register webhooks for payment actions
To subscribe to particular payment events (such as capture or authorization), you can have multiple webhooks with separate URLs for each action or a single webhook that handles all events (each webhook has the Saleor-Event
header that contains the type of event).
List of payment events:
PAYMENT_AUTHORIZE
PAYMENT_CAPTURE
PAYMENT_CONFIRM
PAYMENT_PROCESS
PAYMENT_REFUND
PAYMENT_VOID
If an App has more than one webhook that listens to the same payment event, Saleor will always pick the first webhook from the list.
See the example payload sent from Saleor for these payment events: Payment actions payload.
For payments that require confirmation (such as 3D Secure) Saleor triggers the following events:
PAYMENT_PROCESS
- when thecheckoutComplete
mutation is run for the first time, a payment is created and waits for the user's confirmation.PAYMENT_CONFIRM
- when thecheckoutComplete
mutation is run for the second time, the payment is confirmed. Depending on the payment gateway, multiple events can be triggered.
For payments without a confirmation step, Saleor triggers only the PAYMENT_PROCESS
event.
Expected response
Below is the list of fields that a webhook can return in the JSON response for a payment action. All fields are optional:
action_required
- (boolean) determines if additional action (confirmation) is required.action_required_data
- (object) additional data that may be needed to confirm the payment. An example would be a URL to redirect the user to the confirmation page in the frontend.kind
- (string) Transaction kind, one of: action_to_confirm, auth, cancel, capture, capture_failed, confirm, external, pending, refund, refund_failed, refund_ongoing, refund_reversed, void.amount
- (number) transaction amount. Use this field only if the charged amount is different than the checkout's total.customer_id
- (string) gateway's customer ID.error
- (string) error message. If provided, the transaction will be marked as failed in Saleor and payment will have to be retried. Use this field if you need to return any errors.payment_method
- (object) information about the payment method chosen by the user.psp_reference
- (string) external payment reference id. Can be used for finding transactions in the payment provider dashboard or relevant orders in the Saleor dashboard.transaction_id
- (string) gateway's transaction ID.transaction_already_processed
- (boolean) use this field to mark a transaction as already processed in your gateway.
The response fields match the GatewayResponse
data class used in Saleor to represent a response from a payment gateway; you can read more about these fields here.
Example response for the PAYMENT_PROCESS
event when confirmation is required:
{
"action_required": true,
"action_required_data": {
"confirmation_url": "https://www.example.com/3ds-confirmation/"
},
"customer_id": "customer-1234",
"payment_method": {
"brand": "Visa",
"exp_month": "01",
"exp_year": "2025",
"last_4": "4242",
"name": "John Doe",
"type": "Credit card"
},
"transaction_id": "transaction-1234"
}
Example response for the PAYMENT_PROCESS
event when the payment should be authorized, but unpaid (e.g. to be captured in the dashboard):
{
"action_required": false,
"kind": "auth",
"customer_id": "customer-1234",
"payment_method": {
"brand": "Visa",
"exp_month": "01",
"exp_year": "2025",
"last_4": "4242",
"name": "John Doe",
"type": "Credit card"
},
"transaction_id": "transaction-1234"
}
Use the webhook's payment method in checkout
If payment webhooks are configured properly, you can use their payment methods in checkout. To do this, you need to list available payment methods for your checkout or shop. Each payment method from a payment webhook has an ID of this format: app:<app-database-id>:<id-returned-by-webhook>
Example: app:1:credit-card
To use this gateway in checkout, run checkoutPaymentCreate
mutation and pass this ID as the gateway
parameter:
mutation {
checkoutPaymentCreate(
checkoutId: "example-checkout-id"
input: { gateway: "app:1:credit-card", amount: 22.36 }
) {
payment {
id
}
}
}
Running the checkoutComplete
mutation afterward will use the payment method set above and trigger your payment webhook.
Read more about checkout mutations here.