This plugin is deprecated!
If you plan on building a new integration with Saleor, we recommend using the Adyen app instead.
Adyen
The Adyen plugin allows you to process customer transactions via Adyen with support for many payments methods.
Configuration
Go to Configuration -> Plugins -> Adyen and fill in the following fields:
-
Merchant Account: your Adyen account identifier as described in the getting started with Adyen guide
-
Supported currencies: your currency as an ISO 4217 3-letter code (eg.
USD
,EUR
,GBP
) -
Client Key: The client key is a public key that uniquely identifies a web service. See Adyen docs.
-
Live: Leave it blank if you want to use the test environment. See Adyen docs for production environments.
-
Assume all authorizations are automatically captured by Adyen: All authorized payments will be marked as captured. This should only be enabled if Adyen is configured to auto-capture payments. Saleor doesn’t support the delayed capture Adyen feature.
-
Automatically capture funds when a payment is made: If enabled, Saleor will automatically capture funds. If disabled, the funds are blocked but need to be captured manually.
-
HMAC secret key: key used to check if a received notification comes from Adyen. The key should be the same as on the Adyen side. Generate a new key in the Adyen customer area and copy it here. See Adyen docs.
-
Notification user: In addition to checking request signatures, you can confirm received notification by checking the provided user in the notification. Provide a user in the Authentication section of your Adyen customer area and copy it here. See Adyen docs.
-
Notification password: In addition to checking request signatures, you can confirm received notification by checking the provided user’s password in the notification . Provide a password in the Authentication section of your Adyen customer area and copy it here. See Adyen docs.
-
Enable native 3D Secure: Saleor uses 3D Secure redirect authentication by default. If you want to use native 3D Secure authentication, enable this option. For more details see Adyen documentation: native 3D Secure 2, redirect 3D Secure 1 and 2
-
Webhook endpoint: Endpoint which should be used to activate Adyen's webhooks. More details can be find here
-
Apple Pay certificate: Apple pay certificate in .pem format. Required to activate ApplePay payment method in
web
channel. See Adyen docs.
Activating the Adyen notification
Adyen uses a notification system. Enabling it is required for proper work of payment gateway.
- For
URL
use value fromWebhook endpoint
field. - For
SSL Version
use the newest one. - For
Method
use JSON.
- To protect your notification follow the Adyen docs about security.
- Copy the HMAC key into the Saleor's HMAC secret key field. (See Saleor configuration fields.)
- Copy the username from Authentication section and paste it to Saleor field Notification user. (See Saleor configuration fields.)
- Copy the password from Authentication section and paste it to Saleor field Notification password. (See Saleor configuration fields.)
- To test your configuration check the Adyen docs about testing the configuration.
Activating ApplePay
- Follow the Adyen docs for enabling Apple Pay.
- In section register merchant domain, for registration and verification, the domain uses your storefront domain.
- Upload the converted .pem certificate to the
Apple Pay certificate
field on the Saleor side.
Saleor uses Adyen's checkout API in version 64. If you're using drop-in or components integrations make sure that you're using Adyen's packages in a version lower than 5.0.0.
To use the Adyen plugin, make sure that you have configured the plugin.
Adding a payment form
Adding a payment form for Adyen requires Saleor to provide available payment methods and a client-key.
Both of these values can be fetched by calling checkout.availablePaymentGateways.config
.
The query returns all required fields to prepare a payment form with methods available for the checkout.
{
checkout(token: "14f11c1c-9bc7-4145-89f7-67b60ef943f2") {
availablePaymentGateways {
id
config {
field
value
}
}
}
}
As a result, we get the details required to render a payment form.
{
"data": {
"checkout": {
"availablePaymentGateways": [
{
"id": "mirumee.payments.adyen",
"config": [
{
"field": "client_key",
"value": "test_BBDTBL6GWVEJTOXY55TSPJFP54QBIOZ5"
},
{
"field": "config",
"value": "{\"groups\": [{\"name\": \"Credit Card\", \"types\": [\"visa\", \"mc\", \"amex\", \"diners\", \"discover\"]}], \"paymentMethods\": [{\"brands\": [\"visa\", \"mc\", \"amex\", \"diners\", \"discover\"], \"details\": [{\"key\": \"encryptedCardNumber\", \"type\": \"cardToken\"}, {\"key\": \"encryptedSecurityCode\", \"type\": \"cardToken\"}, {\"key\": \"encryptedExpiryMonth\", \"type\": \"cardToken\"}, {\"key\": \"encryptedExpiryYear\", \"type\": \"cardToken\"}, {\"key\": \"holderName\", \"optional\": true, \"type\": \"text\"}], \"name\": \"Credit Card\", \"supportsRecurring\": true, \"type\": \"scheme\"}, {\"configuration\": {\"intent\": \"capture\"}, \"name\": \"PayPal\", \"supportsRecurring\": true, \"type\": \"paypal\"}, {\"name\": \"Paysafecard\", \"supportsRecurring\": true, \"type\": \"paysafecard\"}, {\"configuration\": {\"merchantDisplayName\": \"SaleorECOM\", \"merchantIdentifier\": \"1000\"}, \"details\": [{\"key\": \"applepay.token\", \"type\": \"applePayToken\"}], \"name\": \"Apple Pay\", \"supportsRecurring\": true, \"type\": \"applepay\"}, {\"configuration\": {\"merchantId\": \"1000\", \"gatewayMerchantId\": \"SaleorECOM\"}, \"details\": [{\"key\": \"paywithgoogle.token\", \"type\": \"payWithGoogleToken\"}], \"name\": \"Google Pay\", \"supportsRecurring\": true, \"type\": \"paywithgoogle\"}]}"
}
]
}
]
}
}
}
Creating a payment in Saleor
To create a payment properly, you need to follow the steps described in Creating a checkout session and Selecting a shipping method.
The next step is to choose Adyen as the payment gateway we want to use to process the checkout. For the Adyen payment gateway, we need to provide:
-
checkoutId
: ID of the checkout, for which new payment should be created. -
input.gateway
: ID of the payment gateway which should be assigned to this payment. For Adyen, it will be:mirumee.payments.adyen
. -
input.amount
: Amount of payment to process. Must be equal tocheckout.totalPrice
. -
input.returnUrl
: URL to where the customer should be taken back to after a redirection.
mutation {
checkoutPaymentCreate(
checkoutId: "Q2hlY2tvdXQ6MWZiMmM1OGUtN2JhMy00YmY5LWI2ZDItNWY2ZWJiN2U3ZWJj"
input: {
gateway: "mirumee.payments.adyen"
amount: 45.61
returnUrl: "https://127.0.0.1:3001/checkout/payment-confirm"
}
) {
payment {
id
chargeStatus
}
errors {
field
message
}
}
}
Completing the checkout
After we create a payment object for the Adyen payment gateway,
we can call the checkoutComplete
mutation.
checkoutComplete
can accept additional parameters for Adyen as fields in the paymentData
input.
The following fields in paymentData
will be directly passed to Adyen's payments endpoint:
-
Required:
paymentMethod
- Received from the front-end payment form as astate.data.paymentMethod
when a customer provides payment details. Adyen's docs.
-
Optional:
channel
- The platform where a payment transaction takes place. Defaultweb
. Adyen's docs.originUrl
- Required for the 3D Secure 2 channelweb
integration. Value assigned toorigin
field. Adyen's docs.browserInfo
- The customer's browser information. Adyen's docs.billingAddress
- The billing address of the customer. If empty or missing, Saleor will fill out the field based on the checkout billing address. Adyen's docs.deliveryAddress
- The delivery address of the customer. If empty or missing, Saleor will fill out the field based on the checkout shipping address. Adyen's docs.shopperIP
- The customer's IP address. Adyen's docs.deviceFingerprint
- A string containing the customer's device fingerprint. Adyen's docs.shopperName
- The customer's full name. Adyen's docs.
mutation {
checkoutComplete(
token: "14f11c1c-9bc7-4145-89f7-67b60ef943f2"
paymentData: "{\"paymentMethod\": {\"type\": \"scheme\", \"encryptedCardNumber\": \"adyenjs_0_1_25$OneNKwaAZqAGM2Ksi7PLVw...\", \"encryptedExpiryMonth\": \"adyenjs_0_1_25$uablDTOYKywxbeeBdnkS...\", \"encryptedExpiryYear\": \"adyenjs_0_1_25$u8XBJQ92a//ZnAQtEvTDYqugoYtuYVmU14wEcl7DAjUS3OPcjj+hMvBlWctyKuG0aYG18L790...\", \"encryptedSecurityCode\": \"adyenjs_0_1_25$e7fZqa+exKs8ovFFPGLz+...\"}}"
) {
order {
id
}
confirmationNeeded
confirmationData
}
}
The checkoutComplete mutation has the following fields:
order
- Optional Order object.Null
when Saleor cannot finalize checkout or when additional action is required from the customer.confirmationNeeded
- Set totrue
when finalizing a checkout requires more action from the customer.confirmationData
- Action data that need to be processed on the frontend side before finalizing the payment. Adyen doc's.errors
- Saleor's errors related to thecheckoutComplete
action.
Completing the checkout without requiring any additional action
When payment doesn't require any additional action from the customer, Saleor will finalize a checkout, return an order, set confirmationNeeded
to false
and confirmationData
as an empty dict.
{
"data": {
"checkoutComplete": {
"order": {
"id": "T3JkZXI6MjkxMw=="
},
"confirmationNeeded": false,
"confirmationData": "{}"
}
}
}
To create an order, the payment must cover the order total. However, we do not verify if an overpayment occurs. In such cases, the order will still be created, and the excess amount must be handled manually.
Processing the checkout payment with additional actions required
When payment requires additional action from the customer like authentication payment with 3D Secure,
logging in to their bank's website or a redirect to the payment provider page, Saleor will set confirmationNeeded
to true
and provide all Adyen's action data required to finalize payment as a confirmationData
.
{
"data": {
"checkoutComplete": {
"order": {
"id": "T3JkZXI6MjkxMw=="
},
"confirmationNeeded": false,
"confirmationData": "{\"paymentData\": \"Ab02b4c0!BQABAgA1Xk1nQmoiOJCEtVVds....4n8OzNsVJGN3XHg7kMg=\",\"paymentMethodType\": \"scheme\",\"url\": \"https:\\/\\/checkoutshopper-test.adyen.com\\/checkoutshopper\\/threeDS2.shtml\",\"data\": {\"MD\": \"M2RzM...DRi\",\"PaReq\": \"BQABAg....Rz3hacE\",\"TermUrl\": \"http:\\/\\/mirumee.com\\/plugins\\/mirumee.payments.adyen\\/additional-actions?payment=UGF5bWVudDoxMDM%3D&checkout=08546530-4718-422c-a912-9a1642a9031c\"},\"method\": \"POST\",\"type\": \"redirect\"}"
}
}
}
After processing additional action by the customer, call checkoutComplete
a second time and pass data received from Adyen (state.data
) as a paymentData
field:
mutation {
checkoutComplete(
token: "14f11c1c-9bc7-4145-89f7-67b60ef943f2"
paymentData: "{\"additional-action\": \"data received from onAdditionalDetails\" ...,\"}"
) {
order {
id
}
confirmationNeeded
confirmationData
}
}
The response of the mutation will contain a created order or extra data required for the following additional action from a customer.
In case, when more actions are required, process them in the same way as the second checkoutComplete
call.
Processing a redirect additional action
If action.type
is redirect
, Adyen will redirect a customer to a page where the customer can finalize the payment.
After that, the customer will be redirected back. The request will go through the Saleor, which will confirm the current status of payment.
In the next step, Saleor will use returnUrl
provided in the checkoutPaymentCreate
mutation to redirect the shopper to the store page.
The returnUrl
will have attached the following parameters attached:
- Required:
checkout
- the ID of processed checkout.payment
- the ID of processed payment.resultCode
- status of the payment received from Adyen. Can be used to determine the current status of the payment. Docs
- Optional:
action
- action data if an additional action is required by customer.
If payment was successfully processed, Saleor will create an order. The next mutation checkoutComplete
call will return order
in the response.
When the notification is received for an inactive payment or, there will be an issue with order creation, the payment is refunded or voided (in case it wasn't charged yet).
Enabling native 3DS2
Saleor uses redirect 3D Secure 1 and 2 by default. Enabling native 3D Secure will add the additionalData.allow3DS2: true
flag
to all card transactions.
Make sure that you provide all required fields for native 3D Secure in checkoutComplete.input.paymentData
.
The mandatory fields for enabling native 3D Secure 2 can be found here.
Specific channel (iOS
, Android
, Web
) or solution type (Drop-in
, Components
) can require different fields.
Enabling on web channel
Each usage of Apple Pay on the web requires the initialization of the payment session.
Adyen's form(Drop-in,
Components) has handler onValidateMerchant
. To request the Apple Pay session,
call mutation paymentInitialize
inside onValidateMerchant
.
Mutation paymentInitialize
accepts the following fields:
channel
: channel slug, where the Apple Pay session should be initializedgateway
: - thegateway
is the id of the plugin, which for Adyen is -mirumee.payments.adyen
paymentData
: JSONString with all data required to initialize session.
PaymentData
for initializing Apple Pay session should contain the below structure.
{
"merchantIdentifier": "<your-apple-merchant-id>",
"displayName": "Merchant ID for Saleor and Adyen",
"domain": "The registered storefront domain",
"validationUrl": "<validationUrl>",
"paymentMethod": "applepay"
}
As a response, you will get initializedPayment
object. The initializedPayment.data
contains the session object which should be converted to JSON (from JSONString) and passed to the resolve method.
Testing Apple Pay
To use the test card with Apple Pay on the web, you need to follow the Apple's docs.