116 lines
4.6 KiB
Swift
116 lines
4.6 KiB
Swift
//
|
|
// Copyright 2022 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import Foundation
|
|
|
|
// MARK: - Boost
|
|
|
|
public extension Paypal {
|
|
/// Create a payment and get a PayPal approval URL to present to the user.
|
|
static func createBoost(
|
|
amount: FiatMoney,
|
|
level: OneTimeBadgeLevel
|
|
) -> Promise<(URL, String)> {
|
|
firstly(on: DispatchQueue.sharedUserInitiated) {
|
|
let createBoostRequest = OWSRequestFactory.boostPaypalCreatePayment(
|
|
integerMoneyValue: DonationUtilities.integralAmount(for: amount),
|
|
inCurrencyCode: amount.currencyCode,
|
|
level: level.rawValue,
|
|
returnUrl: Self.webAuthReturnUrl,
|
|
cancelUrl: Self.webAuthCancelUrl
|
|
)
|
|
|
|
return SSKEnvironment.shared.networkManagerRef.makePromise(request: createBoostRequest)
|
|
}.map(on: DispatchQueue.sharedUserInitiated) { response throws -> (URL, String) in
|
|
guard let parser = ParamParser(responseObject: response.responseBodyJson) else {
|
|
throw OWSAssertionError("[Donations] Failed to decode JSON response")
|
|
}
|
|
|
|
let approvalUrlString: String = try parser.required(key: "approvalUrl")
|
|
let paymentId: String = try parser.required(key: "paymentId")
|
|
|
|
guard let approvalUrl = URL(string: approvalUrlString) else {
|
|
throw OWSAssertionError("[Donations] Approval URL was not a valid URL!")
|
|
}
|
|
|
|
return (approvalUrl, paymentId)
|
|
}
|
|
}
|
|
|
|
/// Confirms a payment after a successful authentication via PayPal's web
|
|
/// UI. Returns a payment ID that can be used to get receipt credentials.
|
|
static func confirmOneTimePayment(
|
|
amount: FiatMoney,
|
|
level: OneTimeBadgeLevel,
|
|
paymentId: String,
|
|
approvalParams: OneTimePaymentWebAuthApprovalParams
|
|
) -> Promise<String> {
|
|
firstly(on: DispatchQueue.sharedUserInitiated) {
|
|
let confirmOneTimePaymentRequest = OWSRequestFactory.oneTimePaypalConfirmPayment(
|
|
integerMoneyValue: DonationUtilities.integralAmount(for: amount),
|
|
inCurrencyCode: amount.currencyCode,
|
|
level: level.rawValue,
|
|
payerId: approvalParams.payerId,
|
|
paymentId: paymentId,
|
|
paymentToken: approvalParams.paymentToken
|
|
)
|
|
|
|
return SSKEnvironment.shared.networkManagerRef.makePromise(request: confirmOneTimePaymentRequest)
|
|
}.map(on: DispatchQueue.sharedUserInitiated) { response throws -> String in
|
|
guard let parser = ParamParser(responseObject: response.responseBodyJson) else {
|
|
throw OWSAssertionError("[Donations] Failed to decode JSON response")
|
|
}
|
|
|
|
return try parser.required(key: "paymentId")
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Subscription
|
|
|
|
public extension Paypal {
|
|
struct SubscriptionAuthorizationParams {
|
|
/// A URL to present to the user to authorize the subscription.
|
|
public let approvalUrl: URL
|
|
|
|
/// An opaque ID identifying the payment method, for API calls after
|
|
/// subscription authorization.
|
|
public let paymentMethodId: String
|
|
}
|
|
|
|
/// Create a payment method entry with the Signal service for a subscription
|
|
/// processed by PayPal.
|
|
///
|
|
/// - Returns
|
|
/// PayPal params used to authorize payment for the new subscription.
|
|
static func createSignalPaymentMethodForSubscription(
|
|
subscriberId: Data
|
|
) -> Promise<SubscriptionAuthorizationParams> {
|
|
firstly {
|
|
let request = OWSRequestFactory.subscriptionCreatePaypalPaymentMethodRequest(
|
|
subscriberID: subscriberId,
|
|
returnURL: Self.webAuthReturnUrl,
|
|
cancelURL: Self.webAuthCancelUrl
|
|
)
|
|
|
|
return SSKEnvironment.shared.networkManagerRef.makePromise(request: request)
|
|
}.map(on: DispatchQueue.sharedUserInitiated) { response in
|
|
guard let parser = ParamParser(responseObject: response.responseBodyJson) else {
|
|
throw OWSAssertionError("[Donations] Missing or invalid response.")
|
|
}
|
|
|
|
guard let approvalUrl = URL(string: try parser.required(key: "approvalUrl")) else {
|
|
throw OWSAssertionError("[Donations] Approval URL string was not valid URL!")
|
|
}
|
|
|
|
let paymentMethodId: String = try parser.required(key: "token")
|
|
|
|
return SubscriptionAuthorizationParams(
|
|
approvalUrl: approvalUrl,
|
|
paymentMethodId: paymentMethodId
|
|
)
|
|
}
|
|
}
|
|
}
|