# #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, вы также можете ознакомиться с образцом, который у нас есть здесь.