Add macOS payment flow, but still with disabled UI

This commit is contained in:
Balazs Perlaki-Horvath 2024-11-30 14:18:00 +01:00 committed by Kelson
parent 93351694ee
commit ea40c54204
2 changed files with 35 additions and 15 deletions

View File

@ -60,6 +60,7 @@ struct Payment {
let completeSubject = PassthroughSubject<Void, Never>()
static let kiwixPaymentServer = URL(string: "https://api.donation.kiwix.org/v1/stripe")!
static let merchantSessionURL = URL(string: "https://apple-pay-gateway.apple.com" )!
static let merchantId = "merchant.org.kiwix.apple"
static let paymentSubscriptionManagingURL = "https://www.kiwix.org"
@ -140,6 +141,7 @@ struct Payment {
request.countryCode = "CH"
request.currencyCode = selectedAmount.currency
request.supportedNetworks = Self.supportedNetworks
request.merchantCapabilities = .threeDSecure
request.requiredBillingContactFields = [.emailAddress]
let recurring: PKRecurringPaymentRequest? = if selectedAmount.isMonthly {
PKRecurringPaymentRequest(paymentDescription: "payment.description.label".localized,
@ -170,7 +172,7 @@ struct Payment {
os_log("onPaymentAuthPhase: .didAuthorize")
// call our server to get payment / setup intent and return the client.secret
Task { @MainActor [resultHandler] in
let paymentServer = StripeKiwix(endPoint: URL(string: "https://api.donation.kiwix.org/v1/stripe")!,
let paymentServer = StripeKiwix(endPoint: Self.kiwixPaymentServer,
payment: payment)
do {
let publicKey = try await paymentServer.publishableKey()
@ -213,23 +215,13 @@ struct Payment {
@available(macOS 13.0, *)
func onMerchantSessionUpdate() async -> PKPaymentRequestMerchantSessionUpdate {
var request = URLRequest(url: Self.merchantSessionURL)
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
do {
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
(200..<300).contains(httpResponse.statusCode),
let dict = try JSONSerialization.jsonObject(with: data,
options: .allowFragments) as? [String: Any] else {
throw MerchantSessionError.invalidStatus
guard let session = await StripeKiwix.stripeSession(endPoint: Self.kiwixPaymentServer) else {
await MainActor.run {
Self.finalResult = .error
}
let session = PKPaymentMerchantSession(dictionary: dict)
return .init(status: .success, merchantSession: session)
} catch let error {
os_log("Merchant session not established: %@", type: .debug, error.localizedDescription)
return .init(status: .failure, merchantSession: nil)
}
return .init(status: .success, merchantSession: session)
}
}

View File

@ -15,6 +15,7 @@
import Foundation
import PassKit
import os
struct StripeKiwix {
@ -60,6 +61,30 @@ struct StripeKiwix {
return .failure(serverError)
}
}
static func stripeSession(endPoint: URL) async -> PKPaymentMerchantSession? {
do {
var request = URLRequest(url: endPoint.appending(path: "payment-session"))
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
request.httpBody = try encoder.encode(SessionParams())
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
(200..<300).contains(httpResponse.statusCode) else {
throw StripeError.serverError
}
guard let dictionary = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
os_log("Merchant session not established: unable to decode server response", type: .debug)
return nil
}
return PKPaymentMerchantSession(dictionary: dictionary)
} catch let serverError {
os_log("Merchant session not established: %@", type: .debug, serverError.localizedDescription)
return nil
}
}
}
/// Response structure for GET {endPoint}/config
@ -88,3 +113,6 @@ private struct SelectedPaymentAmount: Encodable {
assert(Payment.currencyCodes.contains(currency))
}
}
private struct SessionParams: Encodable {
let validationUrl = "apple-pay-gateway-cert.apple.com"
}