не удается правильно проанализировать Json, используя Firebase с полосой

# #ios #swift #xcode #firebase #stripe-payments

Вопрос:

Ошибка — Поток 7: «Не удалось проанализировать ответ эфемерного ключа по протоколу STPCustomerEphemeralKeyProvider. Убедитесь, что ваш сервер отправляет неизмененный JSON эфемерного ключа в ваше приложение. Для получения дополнительной информации см. https://stripe.com/docs/mobile/ios/standard#prepare-your-api»

скриншот ошибки — введите описание изображения здесьмой MyAPIClient —

     import Stripe
       import UIKit
         class MyAPIClient: NSObject, STPCustomerEphemeralKeyProvider {
let baseURL = URL(string: "https://api.stripe.com")!

    func createCustomerKey(withAPIVersion apiVersion: String, completion: @escaping STPJSONResponseCompletionBlock) {
        let url = self.baseURL.appendingPathComponent("ephemeral_keys")
        var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false)!
        urlComponents.queryItems = [URLQueryItem(name: "api_version", value: apiVersion)]
        var request = URLRequest(url: urlComponents.url!)
        request.httpMethod = "POST"
        let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
            guard let response = response as? HTTPURLResponse,
                response.statusCode == 200,
                let data = data,
                let json = ((try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any]) as [String : Any]??) else {
                completion(nil, error)
                return
            }
            completion(json, nil)
        })
        task.resume()
    }
}
 

код контроллера просмотра —

    import UIKit
   import Stripe
   import FirebaseFunctions

  class paymentViewController: UIViewController {

@IBOutlet weak var paymentMethodButton: UIButton!
@IBOutlet weak var proceedToCheckoutButton: UIButton!

var paymentContext: STPPaymentContext!

override func viewDidLoad() {
    super.viewDidLoad()
    setupStripeConfig()
}

@IBAction func checkoutButtonClicked(_ sender: Any) {
    paymentContext.requestPayment()
}

@IBAction func paymentMethodClicked(_ sender: Any) {
    print("Payment Method Button Clicked")
    paymentContext.presentPaymentOptionsViewController()
}

func setupStripeConfig() {
    let config = STPPaymentConfiguration.shared()
    config.requiredBillingAddressFields = .none
    config.requiredShippingAddressFields = .none

    let customerContext = STPCustomerContext(keyProvider: MyAPIClient())
    paymentContext = STPPaymentContext(customerContext: customerContext, configuration: config, theme: .default())
    paymentContext.paymentAmount = 1000

    paymentContext.delegate = self
    paymentContext.hostViewController = self
     }
    }

   extension paymentViewController: STPPaymentContextDelegate {

  func paymentContextDidChange(_ paymentContext: STPPaymentContext) {
    self.paymentMethodButton.titleLabel?.text = paymentContext.selectedPaymentOption?.label
}


func paymentContext(_ paymentContext: STPPaymentContext, didFailToLoadWithError error: Error) {
    //When stripeID isn't valid or Ephemeral key could not be retrieved for some reason. Handle this with UIAlert stating error and make user re-enter info
    self.navigationController?.popViewController(animated: true)
}

func paymentContext(_ paymentContext: STPPaymentContext, didCreatePaymentResult paymentResult: STPPaymentResult, completion: @escaping STPPaymentStatusBlock) {

    var data = [
        "customer":"Abhishek"
    ]
    //Pull Payment Method
    Functions.functions().httpsCallable("getPaymentMethods").call(data) { (result, err) in
        if err != nil {
            print("Error (String(describing: err))")
            return
        }

        print(result)
    }


       let idempotency = UUID().uuidString.replacingOccurrences(of: "-", with: "")
        var paymentMethod = paymentContext.selectedPaymentOption

    let dataToSend: [String : Any] = [
        "amount" : 5000,
        "customer" : "Abhishek",
    ]

       Functions.functions().httpsCallable("createPaymentIntent").call(dataToSend) { (result, err) in
        if err != nil {
            print("Error (String(describing: err))")
            return
           }

          //var paymentParam = STPPaymentIntentParams(clientSecret: result as! String)
        print(result)
       }
   }

  func paymentContext(_ paymentContext: STPPaymentContext, didFinishWith status: STPPaymentStatus, error: Error?) {

   }

  }
 

Как с этим разобраться ?

Ответ №1:

Запрос на создание эфемерного ключа должен быть сделан на стороне сервера (с секретным ключом), и ваш код iOS должен отправлять запрос на ваш собственный сервер, который, в свою очередь, вызывает API Stripe.

Прямо сейчас ваш код (в MyApiClient ) пытается напрямую вызвать API Stripe для создания эфемерного ключа на стороне клиента. Это не сработает, и если вы зарегистрируете ответ на запрос или проверите свою панель мониторинга, чтобы просмотреть последние запросы, вы, вероятно, увидите какое-то сообщение об ошибке.

Вам следует ознакомиться с документацией Stripe о том, как создать эфемерный ключ здесь — они проходят весь код, а также имеют конечную точку сбоя, которую вы можете использовать для тестирования. Поскольку вы используете Firebase, вы также можете ознакомиться с образцом, который у нас есть здесь.