Swift5 카카오 페이 api 호출 오류

카카오페이를 적용하기 위해서 테스트 api를 호출하고 있는데요 저한테 에러 메세지를 보여줍니다.

에러메세지는 [“code”: -2, “msg”: cid can’t be null.]

cid 값이 null 이라는것 같은데요. 저는 cid값을 폼데이터에 넣어서 보내고 있는데 왜 이런 메세지가 뜨는지 모르겠습니다.

override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let url: URL = URL(string: "https://kapi.kakao.com/v1/payment/ready")!
        var dict = [String:String]()
        dict["cid"] = "TC0ONETIME"
        dict["partner_order_id"] = "partner_order_id"
        dict["partner_user_id"] = "partner_user_id"
        dict["item_name"] = "초코파이"
        dict["quantity"] = "1"
        dict["total_amount"] = "2200"
        dict["vat_amount"] = "200"
        dict["tax_free_amount"] = "0"
        dict["approval_url"] = "https://developers.kakao.com/success"
        dict["fail_url"] = "https://developers.kakao.com/fail"
        dict["cancel_url"] = "https://developers.kakao.com/cancel"
        
        do {
            try Web.postKakao(url: url, dict, encoding: .utf8, completionHandler: { data, response, error in
                guard error == nil && data != nil else {
                    if let err = error {
                        print(err.localizedDescription)
                    }
                    return
                }
                
                do {
                    let json = try JSONSerialization.jsonObject(with: data!, options: [])
                    Log.Debug(json)
                    guard let jsonArray = json as? [String: Any] else {
                        return
                    }
                    Log.Debug(jsonArray)
                    
                } catch {
                    Log.Error(error)
                }
            })
        } catch {
            Log.Error(error)
        }
        
    }

...
func postKakao(url: URL, _ parameters: [String: String], encoding: String.Encoding, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) throws {
        
        var postRequest: URLRequest = URLRequest(url: url)
        postRequest.httpMethod = "POST"
        
        let makeRandom = { UInt32.random(in: (.min)...(.max)) }
        let boundary = String(format: "------------------------%08X%08X", makeRandom(), makeRandom())
        
        let contentType: String = "application/x-www-form-urlencoded;charset=utf-8"
        
        var body = Data()
        
        for (rawName, rawValue) in parameters {
            if !body.isEmpty {
                body.append("\r\n".data(using: .utf8)!)
            }
            
            body.append("--\(boundary)\r\n".data(using: .utf8)!)
            
            guard
                rawName.canBeConverted(to: encoding),
                let disposition = "Content-Disposition: form-data; name=\"\(rawName)\"\r\n".data(using: encoding) else {
                    throw IXError.characterSetName
            }
            body.append(disposition)
            
            body.append("\r\n".data(using: .utf8)!)
            
            guard let value = rawValue.data(using: encoding) else {
                throw IXError.characterSetName
            }
            
            body.append(value)
        }
        
        body.append("\r\n--\(boundary)--\r\n".data(using: .utf8)!)
        
        postRequest.setValue(contentType, forHTTPHeaderField: "Content-Type")
        postRequest.setValue("KakaoAK \(Global.kakaoAdminKey)", forHTTPHeaderField: "Authorization")
        postRequest.httpBody = body
        session.dataTask(with: postRequest, completionHandler: completionHandler).resume()
        
    }

@michael @MJ_ @richard.jeon 도와주세요~~

사이트에 도메인에 이동할 url을 등록한 후에 코드를 수정했습니다. 수정한 코드는 매우 비효율적인 코드 입니다. 이것은 수정이 필요합니다. 하지만 다르게 바꾸게 되면 데이터를 인식하지 못하기 때문에 방법이 없습니다. 왜 이렇게 보낼때만 인식이 되는지 알수 없습니다.

        func postKakao22(url: URL, _ parameters: String, encoding: String.Encoding, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void){
            var request = URLRequest(url: url)
            request.httpMethod = "POST"
            request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
            request.setValue("KakaoAK \(Global.kakaoAdminKey)", forHTTPHeaderField: "Authorization")
            let body = parameters.data(using:String.Encoding.utf8, allowLossyConversion: false)
            request.httpBody = body
            let session = URLSession.shared
            session.dataTask(with: request, completionHandler: completionHandler).resume()
            }


func kakaocall(){
        let url: URL = URL(string: "https://kapi.kakao.com/v1/payment/ready")!
        var paramString : String! = "cid=TC0ONETIME"
        paramString = paramString + "&partner_order_id=partner_order_id"
        paramString = paramString + "&partner_user_id=partner_user_id"
        paramString = paramString + "&item_name=초코파이"
        paramString = paramString + "&quantity=1"
        paramString = paramString + "&total_amount=2200"
        paramString = paramString + "&vat_amount=200"
        paramString = paramString + "&tax_free_amount=0"
        paramString = paramString + "&approval_url=\(global.api)"
        paramString = paramString + "&fail_url=\(global.api)"
        paramString = paramString + "&cancel_url=\(global.api)"
            postKakao22(url: url, paramString, encoding: .utf8, completionHandler: { data, response, error in
                guard error == nil && data != nil else {
                    if let err = error {
                        print(err.localizedDescription)
                    }
                    return
                }

                do {
                    let json = try JSONSerialization.jsonObject(with: data!, options: [])
                    Log.Debug(json)
                    guard let jsonArray = json as? [String: Any] else {
                        return
                    }
                    Log.Debug(jsonArray)
                    DispatchQueue.main.async {
                    let nextUrl : String = jsonArray["ios_app_scheme"] as! String
                    guard let myUrl = URL(string: nextUrl) else {
                        //report invalid URL
                        return
                    }
                    if UIApplication.shared.canOpenURL(myUrl) {
                        if #available(iOS 10.0, *) {
                             UIApplication.shared.open(myUrl, options: [:], completionHandler: { (success) in

                             })
                        } else {
                             UIApplication.shared.openURL(myUrl)
                        }
                    }
                    }
                } catch {
                    Log.Error(error)
                }
            })
}

@michael Restapi 담당자 신것 같아 문의 합니다 왜 이렇게 보낼때만 인식이 되나요? json데이터를 jsonString을 만든 후에 Data로 변환한 후 보내면 인식이 되지 않고 직접 스트링으로 입력해야 합니다.

안녕하세요. 카카오페이 입니다.
테스트CID의 경우 모든사용자분들이 올리시다보니 고객님께서 올리시는 로그를 확인하기 어렵습니다.
정확한 로그분석을 위해, partner_order_id, partner_user_id 를 일련번호형식으로 셋팅하여 요청부탁드립니다.
감사합니다.