Architecture
Webhook events
The Adyen App implements the following Saleor sync webhooks related to transactions:
PAYMENT_GATEWAY_INITIALIZE_SESSION
TRANSACTION_INITIALIZE_SESSION
TRANSACTION_PROCESS_SESSION
TRANSACTION_CHARGE_REQUESTED
TRANSACTION_CANCEL_REQUESTED
TRANSACTION_REFUND_REQUESTED
Furthermore, it's also prepared to handle async Adyen webhooks.
The Adyen App follows the flow described in detail in the Saleor Payment App documentation.
Limitations
This section contains known limitations of this App.
Maximum timeout for Adyen calls is 15 seconds
Saleor synchronous webhooks have a maximum response time limit of 20 seconds. The app restricts the Adyen response time to 15 seconds to allow graceful error handling. If Adyen surpasses this limit, the App will return a FAILURE status with an appropriate error message (Timeout Error).
Maximum timeout for Saleor API calls is 5 seconds
The app restricts Saleor API response time to 5 seconds for TransactionInitializeSession
and TransactionProcessSession
subscriptions. If Saleor API surpasses this limit, the App will gracefully continue processing.
If such timeout happens, the created TransactionItem
will not have the metadata from Adyen on additionalDetails
object, which includes payment method type, credit card brand, etc.
Granted refunds vs manual refunds
There are differences in how refunds are handled depending on whether a OrderGrantedRefund
was created in Saleor and a refund via transactionRequestRefundForGrantedRefund
mutation was requested, or a "manual refund" sent via transactionRequestAction
mutation was requested. The differences are in how lineItems
are reported to Adyen
Manual refund
A manual refund is initiated using the transactionRequestAction
mutation.
When a manual refund is requested, the app will send lineItems
to Adyen if the amount
is equal to or greater than the Order's total gross amount.
In other cases' app will not send lineItems
to Adyen.
Granted refund
Added in Saleor 3.15A granted refund is initiated using the transactionRequestRefundForGrantedRefund
mutation.
When granted refund is requested, app will map grantedRefund.lines.orderLines
to lineItems
reported to Adyen. Additionally, if grantedRefund.shippingCostIncluded
is set to true, the app will include a shipping line in the lineItems
sent to Adyen.
TransactionItem metadata
App sets metadata on each TransactionItem
it creates in Saleor. Metadata is set when app receives asynchronous confirmation from Adyen via webhook.
Configuring fields included in metadata
Adyen app sets fields on metadata from NotificationItem.additionalData
object it receives from Adyen. To configure which fields are included by Adyen go to Developres > Additional data
and select your preferred fields.
Remember to always include the following fields for proper notification handling:
Authorization amount
Authorisation amount (dynamic zero authorisation)
Recurring details
Merchant reference
For example, if you want to have data about used payment method, and it's variant choose:
Subvariant
Variant
Co-brand
Expiry date
Card summary
After choosing these settings, you will have the following fields set on your TransactionItem
metadata:
{
"cardSummary": "1111",
"expiryDate": "8/2018",
"paymentMethodVariant": "visadebit",
"paymentMethod": "visa",
"coBrandedWith": "visa",
"authorisedAmountCurrency": "EUR",
"authorisedAmountValue": "1000",
"recurring.shopperReference": "testshopper",
"recurring.recurringDetailReference": "1111111111111111",
"merchantReference": "ref_1234"
}
Subscribing to metadata changes
The best way to check metadata updates on TransactionItem is to subscribe to TRANSACTION_ITEM_METADATA_UPDATED
async webhook event. This way you can be sure that metadata is up-to-date in your external system (e.g. if you use metadata to store which payment method was used for tax purposes).
If you include metafields
or metadata
from TransactionItem
in any other subscription, it might not be set at all, or be out-of-date.
For example, if you use ORDER_CREATED
webhook to check TransactionItem.metadata
then if your customer has completed checkout very quickly, metadata might not yet be set on TransactionItem
. This means it won't be included in a notification from Saleor.
Example
Here's an example subscription query that listens to metadata changes
subscription {
event {
... on TransactionItemMetadataUpdated {
__typename
issuingPrincipal {
... on App {
identifier
}
}
transaction {
id
pspReference
order {
id
}
metafields
}
}
}
}
Capture delay
All payment methods that have "separate capture" feature available (to check availability, refer to Adyen docs and look for methods with "Separate captures" listed in the features) are impacted by capture delay setting in merchant account.
Capture is a transfer of previously locked funds to the merchant. In Adyen, you can either:
- capture funds immediately after authorization:
captureDelay: immediate
- delay it for a certain period of time:
captureDelay: x hours
- disable automatic capture and always do it manually:
captureDelay: manual
Remember that capture can expire after a certain period of time if it is not extended. This depends on used payment method. For example, most credit cards authorizations expire after 28 days.
To see expiration time for specific payment methods, see this documentation page in Adyen docs
Expired payments can be re-authorized, although this comes with some risk. See Adyen docs for more information
The delay can be set in the Adyen dashboard in the merchant account settings.
TransactionFlowStrategy
Saleor channel settings include a paymentSettings.defaultTransactionFlowStrategy
setting. Here's how it impacts payments done via Adyen App:
TransactionFlowStrategyEnum.CHARGE
- Behavior of merchant account capture delay settings will be used, no change is made by app:- If capture delay is set to immediate, capture will be created, there won't be authorization event in Transaction history
- If capture delay is set to x hours, first authorization will be made, then a Transaction will be automatically captured after x hours
- If capture delay is set to manual, authorization will be done instead of a charge, which must be captured either in Saleor Dashboard or Adyen Dashboard
TransactionFlowStrategyEnum.AUTHORIZE
- App will usemanualCapture: true
field when making payments, it behaves the same way as ifcaptureDelay: manual
was set in Adyen merchant account settings- If capture delay is set to immediate, behavior is changed, this setting will be ignored and authorization will be done instead
- If capture delay is set to x hours, behavior is changed, this setting will be ignored and authorization will be done instead
- If capture delay is set to manual, there is no change in behavior, authorization will be created
If payment method doesn't support "separate capture" feature, it will always be charged, no matter any setting in Adyen or Saleor.