Adyen hpp page integration in iOS always giving merchant signature not valid error

Viewed 110

I am trying to integrate Adyen payment in iOS through HPP method. Constantly getting Merchant signature was not valid error, I am suspecting some issue with the encoding part.

Following is the code snippet I use to create request body

var urlComponents = URLComponents()
urlComponents.queryItems = []
let contentKeys1: [String] = Array(content.keys)
for contentKey in contentKeys1 {
    if let contentValue = content[contentKey] {
        urlComponents.queryItems?.append(URLQueryItem(name: contentKey, value: contentValue))
    }
}
self.httpBody = urlComponents.query?.data(using: .utf8)

In Android, it's working fine and I used android created string in iOS to test and the payment page is launching without any error.

Following is the Android code snippet to create request body

val query = StringBuilder()
if (providerDataset != null) {
  for (providerData: ProviderData in providerDataset) {
      val key = providerData.key
      var value: String? = ""
      try {
           if (providerData.value != null)
               value = URLEncoder.encode(providerData.value, StandardCharsets.UTF_8.toString())
      } catch (e: UnsupportedEncodingException) {
           e.printStackTrace()
      }
      val str = "$key=$value"
      query.append(str).append("&")
  }
}
return query.deleteCharAt(query.length - 1).toString()

Do we have an encoding method in iOS that does the same job as Android in the above code?

Struggling for many days to figure this out. Any help is highly appreciable

1 Answers

You put the query parameters inside the httpBody. Instead, you need to add them to the URL.

To do this I use the following code generated by Paw:

protocol URLQueryParameterStringConvertible {
    var queryParameters: String {get}
}

extension Dictionary : URLQueryParameterStringConvertible {
    /**
     This computed property returns a query parameters string from the given NSDictionary. For
     example, if the input is @{@"day":@"Tuesday", @"month":@"January"}, the output
     string will be @"day=Tuesday&month=January".
     @return The computed parameters string.
    */
    var queryParameters: String {
        var parts: [String] = []
        for (key, value) in self {
            let part = String(format: "%@=%@",
                String(describing: key).addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!,
                String(describing: value).addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)
            parts.append(part as String)
        }
        return parts.joined(separator: "&")
    }
    
}

extension URL {
    /**
     Creates a new URL by adding the given query parameters.
     @param parametersDictionary The query parameter dictionary to add.
     @return A new URL.
    */
    func appendingQueryParameters(_ parametersDictionary : Dictionary<String, String>) -> URL {
        let URLString : String = String(format: "%@?%@", self.absoluteString, parametersDictionary.queryParameters)
        return URL(string: URLString)!
    }
}

Usage

let url = URL(string: "https://google.com/")!
    .appendingQueryParameters([
        "key1": "val1",
        "key2": "val2",
    ])
let request = URLRequest(url: url)
// run request
Related