docs/api-reference/tutorials/adyen-integration-guide-for-ios.mdx
spree_adyen spree extensionspree_adyen needs to be configured with return_url.
Return url tells where shopper should be redirect after the payment from outside your application (for example klarna or most of others buy now pay later systems).
Use the custom URL for your app, like my-app://adyen. Url can contain custom query params however do not include any personally identifiable information (PII) of your customer. Maximum length of the url is 1024 characters.
The list of available library versions can be found on Official Adyen Documentation for iOS integration Current newest version available at the moment of writing the tutorial is 5.19.2.
The integration consists of two main components:
repository URL:
https://github.com/Adyen/adyen-ios
use at least version 5.0.0
CocoaPods and Carthage instructions are available here.
Create the instance of APIContext that includes client key and environment setting.
// Set the client key and environment in an instance of APIContext.
let apiContext = APIContext(clientKey: clientKey, environment: Environment.test) // Set the environment to a live one when going live.
// Create the amount with the value in minor units and the currency code.
let amount = Amount(value: 1000, currencyCode: "EUR")
// Create the payment object with the amount and country code.
let payment = Payment(amount: amount, countryCode: "NL")
// Create an instance of AdyenContext, passing the instance of APIContext, and payment object.
let adyenContext = AdyenContext(apiContext: apiContext, payment:payment)
environment - Environment.test or Environment.live
clientKey - client_key from payment_sessions endpoint
Create a session using payment_session endpoint. Then set a configuration using data from the response:
let configuration = AdyenSession.Configuration(sessionIdentifier: sessionId,
initialSessionData: data)
data - available as adyen_data in payment_session API responsesessionId - available as adyen_id in payment_session API responseWith the configuration you initialize AdyenSession:
AdyenSession.initialize(with: configuration, delegate: self, presentationDelegate: self) { [weak self] result in
switch result {
case let .success(session):
//Store the session object.
self?.session = session
case let .failure(error):
//Handle the error.
}
}
let dropInConfiguration = DropInComponent.Configuration()
// Some payment methods have additional required or optional configuration.
// For example, an optional configuration to show the cardholder name field for cards.
dropInConfiguration.card.showsHolderNameField = true
let dropInComponent = DropInComponent(paymentMethods: session.sessionContext.paymentMethods,
context: adyenContext,
configuration: dropInConfiguration)
// Keep the instance of Drop-in to so that it doesn't get destroyed after the function is executed.
self.dropInComponent = dropInComponent
// Set the session as the delegate.
dropInComponent.delegate = session
// If you support gift cards, set the session as the partial payment delegate.
dropInComponent.partialPaymentDelegate = session
myCheckoutViewController.present(dropInComponent.viewController, animated: true)
If the action field is redirect you need to handle the redirect result.
If the action field returns redirect the shopper is completing the payment outside of your application. You need to inform the Drop-in when the shopper returns to your app.
Here an example for a Custom Url scheme:
UIApplicationDelegate:func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
return RedirectComponent.applicationDidOpen(from: url)
}
for Universal URL use this instead:
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let incomingURL = userActivity.webpageURL else { return false }
return RedirectComponent.applicationDidOpen(from: incomingURL)
}
When the payment flow is finished, your instance of AdyenSession calls the didComplete method. Implement the following in your Drop-in configuration object.
func didComplete(with result: AdyenSessionResult, // The session result.
component: Component, // The Drop-in component.
session: AdyenSession) // Your instance of AdyenSession.
Use the resultCode to inform your shopper about the current payment status. Possible resultCode values:
authorised - payment authorisedrefused - payment refusedpending - payment pending (for payments with asynchronous flow like iDEAL). When the shopper completes the payment webhook will process process the payment.cancelled - payment canceledreceived - some payments needs more time to be processed. When the status is available webhook will process the paymenterror - an error occurred when processing the payment. The response contains more details with the error code
Your instance of AdyenSession calls the didFail method containing the error.
func didFail(with error: Error, // The error object.
from component: Component, // The Drop-in component.
session: AdyenSession) // Your instance of AdyenSession.
backend after receiving webhook will change the state of payment_session to one of the following state:
pending - chosen payment method can take a while to completecompleted - payment resulted in success, order completedcanceled - payment canceled, payment is voidrefused - payment failedif succeed - order is processed and completed
if failed - payment can be retried using new payment session