Some payment methods require the shopper to complete additional actions without leaving your checkout page, for example scanning a QR code or authenticating a payment with 3D Secure. When the shopper has completed the additional actions, Drop-in presents the payment result. You will get the payment outcome asynchronously, in a webhook sent to your server.
In most cases, a synchronous payment result is available as well. To get the synchronous result on your server, you must implement a /payments/details
call in addition to /sessions
.
Because a synchronous result is not always available, we strongly recommend that you only use it to communicate to your shopper. Use the webhooks to update your order management system.
Before you begin
This page assumes you've already built a Drop-in integration.
Step 1: Create an event handler
When creating a configuration
object, include:
onAdditionalDetails
: Called when the shopper has completed any additional action required by the payment method, for example scanning a QR code or authenticating a payment with 3D Secure.
Step 2: Confirm the result of an additional action
If the shopper performed additional action, Drop-in calls the onAdditionalDetails
event.
From your server, make a /payments/details request, and include the state.data
from the onAdditionalDetails
event:
curl https://checkout-test.adyen.com/v69/payments/details \
-H "x-API-key: YOUR_X-API-KEY" \
-H "content-type: application/json" \
-d '{hint:object passed from the front end or client app}STATE_DATA{/hint}'
require 'adyen-ruby-api-library'
# Set your X-API-KEY with the API key from the Customer Area.
adyen = Adyen::Client.new
adyen.env = :test
adyen.api_key = "YOUR_X-API-KEY"
# STATE_DATA is an object passed from the front end or client app, deserialized from JSON to a data structure.
request = STATE_DATA
response = adyen.checkout.payments.details(request)
# Check if further action is needed.
if response.body.has_key(:action)
# Pass the action object to your frontend
puts response.body[:action]
else
# No further action needed, pass the resultCode to your frontend
puts response.body[:resultCode]
end
// Set your X-API-KEY with the API key from the Customer Area.
String xApiKey = "YOUR_X-API-KEY";
Client client = new Client(xApiKey,Environment.TEST);
Checkout checkout = new Checkout(client);
// STATE_DATA is an object passed from the front end or client app, deserialized from JSON to a data structure.
PaymentsDetailsRequest paymentsDetailsRequest = STATE_DATA;
PaymentsResponse paymentsDetailsResponse = checkout.paymentsDetails(paymentsDetailsRequest);
// Set your X-API-KEY with the API key from the Customer Area.
$client = new \Adyen\Client();
$client->setEnvironment(\Adyen\Environment::TEST);
$client->setXApiKey("YOUR_X-API-KEY");
$service = new \Adyen\Service\Checkout($client);
// STATE_DATA is an object passed from the front end or client app, deserialized from JSON to a data structure.
$params = STATE_DATA;
$result = $service->paymentsDetails($params);
// Check if further action is needed
if (array_key_exists("action", $result)){
// Pass the action object to your frontend.
// $result["action"]
}
else {
// No further action needed, pass the resultCode to your front end
// $result['resultCode']
}
# Set your X-API-KEY with the API key from the Customer Area.
adyen = Adyen.Adyen()
adyen.payment.client.platform = "test"
adyen.client.xapikey = 'YOUR_X-API-KEY'
# STATE_DATA is an object passed from the front end or client app, deserialized from JSON to a data structure.
request = STATE_DATA
result = adyen.checkout.payments_details(request)
# Check if further action is needed.
if 'action' in result.message:
# Pass the action object to your front end
# result.message['action']
else:
# No further action needed, pass the resultCode to your front end
# result.message['resultCode']
// Set your X-API-KEY with the API key from the Customer Area.
string apiKey = "YOUR_X-API-KEY";
var client = new Client (apiKey, Environment.Test);
var checkout = new Checkout(client);
// STATE_DATA is an object passed from the front end or client app, deserialized from JSON to a data structure.
var paymentsDetailsRequest = STATE_DATA;
var paymentsDetailsResponse = checkout.PaymentDetails(paymentsDetailsRequest);
const {Client, Config, CheckoutAPI} = require('@adyen/api-library');
const config = new Config();
// Set your X-API-KEY with the API key from the Customer Area.
config.apiKey = '[YOUR_X-API-KEY]';
const client = new Client({ config });
client.setEnvironment("TEST");
const checkout = new CheckoutAPI(client);
// STATE_DATA is an object passed from the front end or client app, deserialized from JSON to a data structure.
checkout.paymentsDetails(STATE_DATA).then(res => res);
import (
"github.com/adyen/adyen-go-api-library/v5/src/checkout"
"github.com/adyen/adyen-go-api-library/v5/src/common"
"github.com/adyen/adyen-go-api-library/v5/src/adyen"
)
// Set your X-API-KEY with the API key from the Customer Area.
client := adyen.NewClient(&common.Config{
Environment: common.TestEnv,
ApiKey: "[YOUR_X-API-KEY]",
})
// STATE_DATA is an object passed from the front end or client app, deserialized from JSON to a data structure.
req := STATE_DATA;
res, httpRes, err := client.Checkout.PaymentsDetails(&req)
Then, use the resultCode
from the /payments/details response to present the payment result to the shopper.
Step 3: Present the payment result
After the shopper completes the payment, use the resultCode
to inform the shopper of the payment status.
resultCode | Description | Action to take |
---|---|---|
Authorised | The payment was successful. | Inform the shopper that the payment was successful. |
Error | Inform the shopper that there was an error processing their payment. | You'll receive a refusalReason in the same response, indicating the cause of the error. |
Pending | The shopper has completed the payment but the final result is not yet known. | Inform the shopper that you've received their order, and are waiting for the payment to be completed. |
PresentToShopper | Present the voucher or the QR code to the shopper. | For a voucher payment method, inform the shopper that you are waiting for their payment. For a qrCode payment method, wait for the AUTHORISATION notification before presenting the payment result to the shopper. |
Refused | The payment was refused. | Inform the shopper that the payment was refused. Ask the shopper to try the payment again using a different payment method or card. |
Received | For some payment methods, it can take some time before the final status of the payment is known. | Inform the shopper that you've received their order, and are waiting for the payment to clear. |
For other possible resultCode
values and recommended messages that you can present to your shopper, see Result codes.
Alternatively, you can use the dropin.setStatus
to show a customized message. For example:
// Show a success message
dropin.setStatus('success');
dropin.setStatus('success', { message: 'Payment successful!' });
// Show an error message
dropin.setStatus('error');
dropin.setStatus('error', { message: 'Something went wrong.'});
// Set a loading state
dropin.setStatus('loading'); // start the loading state
dropin.setStatus('ready'); // set back to the initial state